Implement mempool synchronization
This commit is contained in:
parent
c0e69ff1d0
commit
2afe85853f
@ -2,6 +2,7 @@ package pool
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
@ -17,6 +18,10 @@ const (
|
||||
DefaultTxPrefix = "tx_"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrTxNotFound = errors.New("tx isn't found in mempool")
|
||||
)
|
||||
|
||||
type Mempool struct {
|
||||
cache cache.Cache
|
||||
}
|
||||
@ -35,9 +40,9 @@ func (mp *Mempool) StoreTx(tx *types2.Transaction) error {
|
||||
return err
|
||||
}
|
||||
|
||||
func (mp *Mempool) GetTxsForNewBlock() []*types2.Transaction {
|
||||
func (mp *Mempool) GetTransactionsForNewBlock() []*types2.Transaction {
|
||||
var txForBlock []*types2.Transaction
|
||||
allTxs := mp.GetAllTxs()
|
||||
allTxs := mp.GetAllTransactions()
|
||||
sort.Slice(allTxs, func(i, j int) bool {
|
||||
return allTxs[i].Timestamp.Before(allTxs[j].Timestamp)
|
||||
})
|
||||
@ -54,7 +59,7 @@ func (mp *Mempool) GetTxsForNewBlock() []*types2.Transaction {
|
||||
return txForBlock
|
||||
}
|
||||
|
||||
func (mp *Mempool) GetAllTxs() []*types2.Transaction {
|
||||
func (mp *Mempool) GetAllTransactions() []*types2.Transaction {
|
||||
var allTxs []*types2.Transaction
|
||||
|
||||
for _, v := range mp.cache.Items() {
|
||||
@ -64,7 +69,18 @@ func (mp *Mempool) GetAllTxs() []*types2.Transaction {
|
||||
return allTxs
|
||||
}
|
||||
|
||||
func removeItemFromStringSlice(s []string, i int) []string {
|
||||
s[len(s)-1], s[i] = s[i], s[len(s)-1]
|
||||
return s[:len(s)-1]
|
||||
func (mp *Mempool) GetTransaction(hash []byte) (*types2.Transaction, error) {
|
||||
hashStr := hex.EncodeToString(hash)
|
||||
var tx types2.Transaction
|
||||
err := mp.cache.Get(DefaultTxPrefix+hashStr, &tx)
|
||||
|
||||
if err != nil {
|
||||
if errors.Is(err, cache.ErrNotFound) {
|
||||
return nil, ErrTxNotFound
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return &tx, nil
|
||||
}
|
||||
|
@ -3,18 +3,19 @@ package sync
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/Secured-Finance/dione/consensus/policy"
|
||||
|
||||
"github.com/wealdtech/go-merkletree/keccak256"
|
||||
|
||||
"github.com/wealdtech/go-merkletree"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/Secured-Finance/dione/node"
|
||||
|
||||
"github.com/Secured-Finance/dione/node/wire"
|
||||
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
@ -32,7 +33,8 @@ type SyncManager interface {
|
||||
}
|
||||
|
||||
type syncManager struct {
|
||||
blockPool *pool.BlockPool
|
||||
blockpool *pool.BlockPool
|
||||
mempool *pool.Mempool
|
||||
wg sync.WaitGroup
|
||||
ctx context.Context
|
||||
ctxCancelFunc context.CancelFunc
|
||||
@ -44,7 +46,7 @@ type syncManager struct {
|
||||
func NewSyncManager(bp *pool.BlockPool, p2pRPCClient *gorpc.Client, bootstrapPeer peer.ID) SyncManager {
|
||||
ctx, cancelFunc := context.WithCancel(context.Background())
|
||||
return &syncManager{
|
||||
blockPool: bp,
|
||||
blockpool: bp,
|
||||
ctx: ctx,
|
||||
ctxCancelFunc: cancelFunc,
|
||||
initialSyncCompleted: false,
|
||||
@ -56,7 +58,16 @@ func NewSyncManager(bp *pool.BlockPool, p2pRPCClient *gorpc.Client, bootstrapPee
|
||||
func (sm *syncManager) Start() {
|
||||
sm.wg.Add(1)
|
||||
|
||||
sm.doInitialSync()
|
||||
err := sm.doInitialBlockPoolSync()
|
||||
if err != nil {
|
||||
logrus.Error(err)
|
||||
}
|
||||
|
||||
err = sm.doInitialMempoolSync()
|
||||
if err != nil {
|
||||
logrus.Error(err)
|
||||
}
|
||||
|
||||
go sm.syncLoop()
|
||||
}
|
||||
|
||||
@ -65,15 +76,15 @@ func (sm *syncManager) Stop() {
|
||||
sm.wg.Wait()
|
||||
}
|
||||
|
||||
func (sm *syncManager) doInitialSync() error {
|
||||
func (sm *syncManager) doInitialBlockPoolSync() error {
|
||||
if sm.initialSyncCompleted {
|
||||
return nil
|
||||
}
|
||||
|
||||
ourLastHeight, err := sm.blockPool.GetLatestBlockHeight()
|
||||
ourLastHeight, err := sm.blockpool.GetLatestBlockHeight()
|
||||
if err == pool.ErrLatestHeightNil {
|
||||
gBlock := types2.GenesisBlock()
|
||||
err = sm.blockPool.StoreBlock(gBlock) // commit genesis block
|
||||
err = sm.blockpool.StoreBlock(gBlock) // commit genesis block
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -96,16 +107,16 @@ func (sm *syncManager) doInitialSync() error {
|
||||
for heightCount > 0 {
|
||||
from = to + 1
|
||||
var addedVal uint64
|
||||
if heightCount < node.MaxBlockCountForRetrieving {
|
||||
if heightCount < policy.MaxBlockCountForRetrieving {
|
||||
addedVal = heightCount
|
||||
} else {
|
||||
addedVal = node.MaxBlockCountForRetrieving
|
||||
addedVal = policy.MaxBlockCountForRetrieving
|
||||
}
|
||||
heightCount -= addedVal
|
||||
to += addedVal
|
||||
var getBlocksReply wire.GetBlocksReply
|
||||
arg := wire.GetBlocksArg{From: from, To: to}
|
||||
err = sm.rpcClient.Call(sm.bootstrapPeer, "NetworkService", "GetBlocks", arg, &getBlocksReply)
|
||||
var getBlocksReply wire.GetRangeOfBlocksReply
|
||||
arg := wire.GetRangeOfBlocksArg{From: from, To: to}
|
||||
err = sm.rpcClient.Call(sm.bootstrapPeer, "NetworkService", "GetRangeOfBlocks", arg, &getBlocksReply)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -129,9 +140,59 @@ func (sm *syncManager) doInitialSync() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sm *syncManager) doInitialMempoolSync() error {
|
||||
var reply wire.InvMessage
|
||||
err := sm.rpcClient.Call(sm.bootstrapPeer, "NetworkService", "Mempool", nil, &reply)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var txsToRetrieve [][]byte
|
||||
|
||||
for _, v := range reply.Inventory {
|
||||
_, err = sm.mempool.GetTransaction(v.Hash)
|
||||
if errors.Is(err, pool.ErrTxNotFound) {
|
||||
txsToRetrieve = append(txsToRetrieve, v.Hash)
|
||||
}
|
||||
}
|
||||
|
||||
for {
|
||||
var txHashes [][]byte
|
||||
|
||||
if len(txsToRetrieve) == 0 {
|
||||
break
|
||||
}
|
||||
|
||||
if len(txsToRetrieve) > policy.MaxTransactionCountForRetrieving {
|
||||
txHashes = txsToRetrieve[:policy.MaxTransactionCountForRetrieving]
|
||||
txsToRetrieve = txsToRetrieve[policy.MaxTransactionCountForRetrieving:]
|
||||
} else {
|
||||
txHashes = txsToRetrieve
|
||||
}
|
||||
|
||||
getMempoolTxArg := wire.GetMempoolTxsArg{
|
||||
Items: txHashes,
|
||||
}
|
||||
var getMempoolTxReply wire.GetMempoolTxsReply
|
||||
err := sm.rpcClient.Call(sm.bootstrapPeer, "NetworkService", "GetMempoolTxs", getMempoolTxArg, &getMempoolTxReply)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, v := range getMempoolTxReply.Transactions {
|
||||
err := sm.mempool.StoreTx(&v)
|
||||
if err != nil {
|
||||
logrus.Warnf(err.Error())
|
||||
}
|
||||
}
|
||||
// FIXME handle not found transactions
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sm *syncManager) processReceivedBlock(block types2.Block) error {
|
||||
// validate block
|
||||
previousBlockHeader, err := sm.blockPool.FetchBlockHeaderByHeight(block.Header.Height - 1)
|
||||
previousBlockHeader, err := sm.blockpool.FetchBlockHeaderByHeight(block.Header.Height - 1)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to retrieve previous block %d", block.Header.Height-1)
|
||||
}
|
||||
@ -163,7 +224,7 @@ func (sm *syncManager) processReceivedBlock(block types2.Block) error {
|
||||
}
|
||||
}
|
||||
|
||||
err = sm.blockPool.StoreBlock(&block)
|
||||
err = sm.blockpool.StoreBlock(&block)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to store block in blockpool: %s", err.Error())
|
||||
}
|
||||
@ -172,5 +233,4 @@ func (sm *syncManager) processReceivedBlock(block types2.Block) error {
|
||||
}
|
||||
|
||||
func (sm *syncManager) syncLoop() {
|
||||
|
||||
}
|
||||
|
@ -2,4 +2,6 @@ package policy
|
||||
|
||||
const (
|
||||
BlockMaxTransactionCount = 100
|
||||
MaxBlockCountForRetrieving = 500 // we do it just like in Bitcoin
|
||||
MaxTransactionCountForRetrieving = 50000
|
||||
)
|
||||
|
15
go.mod
15
go.mod
@ -29,20 +29,21 @@ require (
|
||||
github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect
|
||||
github.com/huin/goupnp v1.0.1-0.20200620063722-49508fba0031 // indirect
|
||||
github.com/ipfs/go-log v1.0.4
|
||||
github.com/ipfs/go-log/v2 v2.1.3 // indirect
|
||||
github.com/jmoiron/sqlx v1.2.0
|
||||
github.com/karalabe/usb v0.0.0-20191104083709-911d15fe12a9 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.0.6 // indirect
|
||||
github.com/ledgerwatch/lmdb-go v1.17.8
|
||||
github.com/libp2p/go-libp2p v0.13.0
|
||||
github.com/libp2p/go-libp2p-core v0.8.0
|
||||
github.com/libp2p/go-libp2p-gorpc v0.1.2
|
||||
github.com/libp2p/go-libp2p-core v0.8.5
|
||||
github.com/libp2p/go-libp2p-gorpc v0.1.3
|
||||
github.com/libp2p/go-libp2p-pubsub v0.4.2-0.20210212194758-6c1addf493eb
|
||||
github.com/mattn/go-sqlite3 v1.11.0
|
||||
github.com/miguelmota/go-ethereum-hdwallet v0.0.0-20210314074952-8dd49aa599b9
|
||||
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1
|
||||
github.com/mitchellh/hashstructure/v2 v2.0.1
|
||||
github.com/mitchellh/mapstructure v1.3.3 // indirect
|
||||
github.com/multiformats/go-multiaddr v0.3.1
|
||||
github.com/multiformats/go-multiaddr v0.3.2
|
||||
github.com/multiformats/go-multihash v0.0.15 // indirect
|
||||
github.com/olekukonko/tablewriter v0.0.4 // indirect
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible
|
||||
@ -56,15 +57,17 @@ require (
|
||||
github.com/status-im/keycard-go v0.0.0-20200402102358-957c09536969 // indirect
|
||||
github.com/stretchr/testify v1.7.0
|
||||
github.com/tyler-smith/go-bip39 v1.1.0 // indirect
|
||||
github.com/ugorji/go v1.2.6 // indirect
|
||||
github.com/valyala/fasthttp v1.17.0
|
||||
github.com/wealdtech/go-merkletree v1.0.1-0.20190605192610-2bb163c2ea2a
|
||||
github.com/whyrusleeping/cbor-gen v0.0.0-20210219115102-f37d292932f2
|
||||
github.com/xorcare/golden v0.6.1-0.20191112154924-b87f686d7542
|
||||
go.uber.org/zap v1.16.0
|
||||
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b
|
||||
go.uber.org/multierr v1.7.0 // indirect
|
||||
go.uber.org/zap v1.17.0
|
||||
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect
|
||||
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 // indirect
|
||||
golang.org/x/sys v0.0.0-20210426230700-d19ff857e887 // indirect
|
||||
golang.org/x/sys v0.0.0-20210601080250-7ecdf8ef093b // indirect
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1
|
||||
honnef.co/go/tools v0.0.1-2020.1.3 // indirect
|
||||
nhooyr.io/websocket v1.8.6 // indirect
|
||||
|
20
go.sum
20
go.sum
@ -760,6 +760,8 @@ github.com/ipfs/go-log/v2 v2.0.8/go.mod h1:eZs4Xt4ZUJQFM3DlanGhy7TkwwawCZcSByscw
|
||||
github.com/ipfs/go-log/v2 v2.1.1/go.mod h1:2v2nsGfZsvvAJz13SyFzf9ObaqwHiHxsPLEHntrv9KM=
|
||||
github.com/ipfs/go-log/v2 v2.1.2-0.20200626104915-0016c0b4b3e4 h1:3bijxqzQ1O9yg7gd7Aqk80oaEvsJ+uXw0zSvi2qR3Jw=
|
||||
github.com/ipfs/go-log/v2 v2.1.2-0.20200626104915-0016c0b4b3e4/go.mod h1:2v2nsGfZsvvAJz13SyFzf9ObaqwHiHxsPLEHntrv9KM=
|
||||
github.com/ipfs/go-log/v2 v2.1.3 h1:1iS3IU7aXRlbgUpN8yTTpJ53NXYjAe37vcI5+5nYrzk=
|
||||
github.com/ipfs/go-log/v2 v2.1.3/go.mod h1:/8d0SH3Su5Ooc31QlL1WysJhvyOTDCjcCZ9Axpmri6g=
|
||||
github.com/ipfs/go-merkledag v0.0.3/go.mod h1:Oc5kIXLHokkE1hWGMBHw+oxehkAaTOqtEb7Zbh6BhLA=
|
||||
github.com/ipfs/go-merkledag v0.0.6/go.mod h1:QYPdnlvkOg7GnQRofu9XZimC5ZW5Wi3bKys/4GQQfto=
|
||||
github.com/ipfs/go-merkledag v0.2.3/go.mod h1:SQiXrtSts3KGNmgOzMICy5c0POOpUNQLvB3ClKnBAlk=
|
||||
@ -1017,6 +1019,8 @@ github.com/libp2p/go-libp2p-core v0.6.1/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJB
|
||||
github.com/libp2p/go-libp2p-core v0.7.0/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8=
|
||||
github.com/libp2p/go-libp2p-core v0.8.0 h1:5K3mT+64qDTKbV3yTdbMCzJ7O6wbNsavAEb8iqBvBcI=
|
||||
github.com/libp2p/go-libp2p-core v0.8.0/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8=
|
||||
github.com/libp2p/go-libp2p-core v0.8.5 h1:aEgbIcPGsKy6zYcC+5AJivYFedhYa4sW7mIpWpUaLKw=
|
||||
github.com/libp2p/go-libp2p-core v0.8.5/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8=
|
||||
github.com/libp2p/go-libp2p-crypto v0.0.1/go.mod h1:yJkNyDmO341d5wwXxDUGO0LykUVT72ImHNUqh5D/dBE=
|
||||
github.com/libp2p/go-libp2p-crypto v0.0.2/go.mod h1:eETI5OUfBnvARGOHrJz2eWNyTUxEGZnBxMcbUjfIj4I=
|
||||
github.com/libp2p/go-libp2p-crypto v0.1.0 h1:k9MFy+o2zGDNGsaoZl0MA3iZ75qXxr9OOoAZF+sD5OQ=
|
||||
@ -1032,6 +1036,8 @@ github.com/libp2p/go-libp2p-discovery v0.5.0 h1:Qfl+e5+lfDgwdrXdu4YNCWyEo3fWuP+W
|
||||
github.com/libp2p/go-libp2p-discovery v0.5.0/go.mod h1:+srtPIU9gDaBNu//UHvcdliKBIcr4SfDcm0/PfPJLug=
|
||||
github.com/libp2p/go-libp2p-gorpc v0.1.2 h1:jHL0F79uDVPNsflS9byf8Wk23MQ0G+r5nUnLChoUn8A=
|
||||
github.com/libp2p/go-libp2p-gorpc v0.1.2/go.mod h1:ulZShaJCp3JHlBMHiA20efUmiqDECza+JvGFNXJyKdI=
|
||||
github.com/libp2p/go-libp2p-gorpc v0.1.3 h1:b0bRXD4PEfqIvXbivDhNnaSQ8ERoaYd0vM7mDIDLQCQ=
|
||||
github.com/libp2p/go-libp2p-gorpc v0.1.3/go.mod h1:ulZShaJCp3JHlBMHiA20efUmiqDECza+JvGFNXJyKdI=
|
||||
github.com/libp2p/go-libp2p-host v0.0.1/go.mod h1:qWd+H1yuU0m5CwzAkvbSjqKairayEHdR5MMl7Cwa7Go=
|
||||
github.com/libp2p/go-libp2p-host v0.0.3/go.mod h1:Y/qPyA6C8j2coYyos1dfRm0I8+nvd4TGrDGt4tA7JR8=
|
||||
github.com/libp2p/go-libp2p-interface-connmgr v0.0.1/go.mod h1:GarlRLH0LdeWcLnYM/SaBykKFl9U5JFnbBGruAk/D5k=
|
||||
@ -1350,6 +1356,8 @@ github.com/multiformats/go-multiaddr v0.2.2/go.mod h1:NtfXiOtHvghW9KojvtySjH5y0u
|
||||
github.com/multiformats/go-multiaddr v0.3.0/go.mod h1:dF9kph9wfJ+3VLAaeBqo9Of8x4fJxp6ggJGteB8HQTI=
|
||||
github.com/multiformats/go-multiaddr v0.3.1 h1:1bxa+W7j9wZKTZREySx1vPMs2TqrYWjVZ7zE6/XLG1I=
|
||||
github.com/multiformats/go-multiaddr v0.3.1/go.mod h1:uPbspcUPd5AfaP6ql3ujFY+QWzmBD8uLLL4bXW0XfGc=
|
||||
github.com/multiformats/go-multiaddr v0.3.2 h1:vapLUGlFpvvkaemMvKGGxjruOzaIzQbn41J6R9vxeyU=
|
||||
github.com/multiformats/go-multiaddr v0.3.2/go.mod h1:lCKNGP1EQ1eZ35Za2wlqnabm9xQkib3fyB+nZXHLag0=
|
||||
github.com/multiformats/go-multiaddr-dns v0.0.1/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q=
|
||||
github.com/multiformats/go-multiaddr-dns v0.0.2/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q=
|
||||
github.com/multiformats/go-multiaddr-dns v0.0.3/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q=
|
||||
@ -1703,10 +1711,14 @@ github.com/uber/jaeger-lib v2.2.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6
|
||||
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
|
||||
github.com/ugorji/go v1.1.13 h1:nB3O5kBSQGjEQAcfe1aLUYuxmXdFKmYgBZhY32rQb6Q=
|
||||
github.com/ugorji/go v1.1.13/go.mod h1:jxau1n+/wyTGLQoCkjok9r5zFa/FxT6eI5HiHKQszjc=
|
||||
github.com/ugorji/go v1.2.6 h1:tGiWC9HENWE2tqYycIqFTNorMmFRVhNwCpDOpWqnk8E=
|
||||
github.com/ugorji/go v1.2.6/go.mod h1:anCg0y61KIhDlPZmnH+so+RQbysYVyDko0IMgJv0Nn0=
|
||||
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
||||
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
|
||||
github.com/ugorji/go/codec v1.1.13 h1:013LbFhocBoIqgHeIHKlV4JWYhqogATYWZhIcH0WHn4=
|
||||
github.com/ugorji/go/codec v1.1.13/go.mod h1:oNVt3Dq+FO91WNQ/9JnHKQP2QJxTzoN7wCBFCq1OeuU=
|
||||
github.com/ugorji/go/codec v1.2.6 h1:7kbGefxLoDBuYXOms4yD7223OpNMMPNPZxXk5TvFcyQ=
|
||||
github.com/ugorji/go/codec v1.2.6/go.mod h1:V6TCNZ4PHqoHGFZuSG1W8nrCzzdgA2DozYxWFFpvxTw=
|
||||
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/urfave/cli v1.22.2 h1:gsqYFH8bb9ekPA12kRo0hfjngWQjkJPlN9R0N78BoUo=
|
||||
@ -1847,6 +1859,8 @@ go.uber.org/multierr v1.4.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+
|
||||
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
|
||||
go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
|
||||
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
|
||||
go.uber.org/multierr v1.7.0 h1:zaiO/rmgFjbmCXdSYJWQcdvOCsthmdaHfr3Gm2Kx4Ec=
|
||||
go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak=
|
||||
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
|
||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
|
||||
@ -1854,6 +1868,8 @@ go.uber.org/zap v1.14.1/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc=
|
||||
go.uber.org/zap v1.15.0/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc=
|
||||
go.uber.org/zap v1.16.0 h1:uFRZXykJGK9lLY4HtgSw44DnIcAM+kRBP7x5m+NpAOM=
|
||||
go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ=
|
||||
go.uber.org/zap v1.17.0 h1:MTjgFu6ZLKvY6Pvaqk97GlxNBuMpV4Hy/3P6tRGlI2U=
|
||||
go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=
|
||||
go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE=
|
||||
go4.org v0.0.0-20200411211856-f5505b9728dd h1:BNJlw5kRTzdmyfh5U8F93HA2OwkP7ZGwA51eJ/0wKOU=
|
||||
go4.org v0.0.0-20200411211856-f5505b9728dd/go.mod h1:CIiUVy99QCPfoE13bO4EZaz5GZMZXMSBGhxRdsvzbkg=
|
||||
@ -1901,6 +1917,8 @@ golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWP
|
||||
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b h1:7mWr3k41Qtv8XlltBkDkl8LoP3mpSgBW8BUoxtEdbXg=
|
||||
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a h1:kr2P4QFmQr29mSLA43kwrOcgcReGTfbE9N577tCTuBc=
|
||||
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
@ -2099,6 +2117,8 @@ golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210426230700-d19ff857e887 h1:dXfMednGJh/SUUFjTLsWJz3P+TQt9qnR11GgeI3vWKs=
|
||||
golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210601080250-7ecdf8ef093b h1:qh4f65QIVFjq9eBURLEYWqaEXmOyqdUyiBSgaXWccWk=
|
||||
golang.org/x/sys v0.0.0-20210601080250-7ecdf8ef093b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
|
@ -2,20 +2,23 @@ package node
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
gorpc "github.com/libp2p/go-libp2p-gorpc"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/Secured-Finance/dione/consensus/policy"
|
||||
"github.com/Secured-Finance/dione/node/wire"
|
||||
|
||||
"github.com/Secured-Finance/dione/blockchain/pool"
|
||||
)
|
||||
|
||||
const (
|
||||
MaxBlockCountForRetrieving = 500 // we do it just like in Bitcoin
|
||||
)
|
||||
|
||||
type NetworkService struct {
|
||||
blockpool *pool.BlockPool
|
||||
mempool *pool.Mempool
|
||||
rpcClient *gorpc.Client
|
||||
}
|
||||
|
||||
func NewNetworkService(bp *pool.BlockPool) *NetworkService {
|
||||
@ -24,7 +27,7 @@ func NewNetworkService(bp *pool.BlockPool) *NetworkService {
|
||||
}
|
||||
}
|
||||
|
||||
func (s *NetworkService) LastBlockHeight(ctx context.Context, arg interface{}, reply *wire.LastBlockHeightReply) {
|
||||
func (s *NetworkService) LastBlockHeight(ctx context.Context, arg struct{}, reply *wire.LastBlockHeightReply) {
|
||||
height, err := s.blockpool.GetLatestBlockHeight()
|
||||
if err != nil {
|
||||
reply.Error = err
|
||||
@ -33,13 +36,13 @@ func (s *NetworkService) LastBlockHeight(ctx context.Context, arg interface{}, r
|
||||
reply.Height = height
|
||||
}
|
||||
|
||||
func (s *NetworkService) GetBlocks(ctx context.Context, arg wire.GetBlocksArg, reply *wire.GetBlocksReply) {
|
||||
func (s *NetworkService) GetRangeOfBlocks(ctx context.Context, arg wire.GetRangeOfBlocksArg, reply *wire.GetRangeOfBlocksReply) {
|
||||
if arg.From > arg.To {
|
||||
errText := "incorrect arguments: from > to"
|
||||
reply.Error = &errText
|
||||
return
|
||||
}
|
||||
if arg.To-arg.From > MaxBlockCountForRetrieving {
|
||||
if arg.To-arg.From > policy.MaxBlockCountForRetrieving {
|
||||
errText := "incorrect arguments: count of block for retrieving is exceeded the limit"
|
||||
reply.Error = &errText
|
||||
return
|
||||
@ -54,3 +57,37 @@ func (s *NetworkService) GetBlocks(ctx context.Context, arg wire.GetBlocksArg, r
|
||||
reply.Blocks = append(reply.Blocks, *block)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *NetworkService) Mempool(ctx context.Context, arg struct{}, reply *wire.InvMessage) {
|
||||
txs := s.mempool.GetAllTransactions()
|
||||
|
||||
// extract hashes of txs
|
||||
for _, v := range txs {
|
||||
reply.Inventory = append(reply.Inventory, wire.InvItem{
|
||||
Type: wire.TxInvType,
|
||||
Hash: v.Hash,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (s *NetworkService) GetMempoolTxs(ctx context.Context, arg wire.GetMempoolTxsArg, reply *wire.GetMempoolTxsReply) {
|
||||
if len(arg.Items) > MaxTransactionCountForRetrieving {
|
||||
pid, _ := gorpc.GetRequestSender(ctx)
|
||||
logrus.Warnf("Max tx count limit exceeded for GetMempoolTxs request of node %s", pid)
|
||||
reply.Error = fmt.Errorf("max tx count limit exceeded")
|
||||
return
|
||||
}
|
||||
|
||||
for _, v := range arg.Items {
|
||||
tx, err := s.mempool.GetTransaction(v)
|
||||
if err != nil {
|
||||
if errors.Is(err, pool.ErrTxNotFound) {
|
||||
reply.NotFoundTxs = append(reply.NotFoundTxs, v)
|
||||
} else {
|
||||
reply.Error = err
|
||||
return
|
||||
}
|
||||
}
|
||||
reply.Transactions = append(reply.Transactions, *tx)
|
||||
}
|
||||
}
|
||||
|
13
node/wire/get_mempool_tx.go
Normal file
13
node/wire/get_mempool_tx.go
Normal file
@ -0,0 +1,13 @@
|
||||
package wire
|
||||
|
||||
import "github.com/Secured-Finance/dione/blockchain/types"
|
||||
|
||||
type GetMempoolTxsArg struct {
|
||||
Items [][]byte
|
||||
}
|
||||
|
||||
type GetMempoolTxsReply struct {
|
||||
Transactions []types.Transaction
|
||||
NotFoundTxs [][]byte
|
||||
Error error
|
||||
}
|
@ -2,12 +2,12 @@ package wire
|
||||
|
||||
import "github.com/Secured-Finance/dione/blockchain/types"
|
||||
|
||||
type GetBlocksArg struct {
|
||||
type GetRangeOfBlocksArg struct {
|
||||
From uint64
|
||||
To uint64
|
||||
}
|
||||
|
||||
type GetBlocksReply struct {
|
||||
type GetRangeOfBlocksReply struct {
|
||||
Blocks []types.Block
|
||||
FailedBlockHeights []uint64 // list of block heights the node was unable to retrieve
|
||||
Error *string
|
17
node/wire/inv.go
Normal file
17
node/wire/inv.go
Normal file
@ -0,0 +1,17 @@
|
||||
package wire
|
||||
|
||||
type InvType int
|
||||
|
||||
const (
|
||||
InvalidInvType = iota
|
||||
TxInvType
|
||||
)
|
||||
|
||||
type InvMessage struct {
|
||||
Inventory []InvItem
|
||||
}
|
||||
|
||||
type InvItem struct {
|
||||
Type InvType
|
||||
Hash []byte
|
||||
}
|
Loading…
Reference in New Issue
Block a user