Implement mempool synchronization

This commit is contained in:
ChronosX88 2021-06-02 22:45:55 +03:00
parent c0e69ff1d0
commit 2afe85853f
Signed by: ChronosXYZ
GPG Key ID: 085A69A82C8C511A
9 changed files with 206 additions and 38 deletions

View File

@ -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
}

View File

@ -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() {
}

View File

@ -1,5 +1,7 @@
package policy
const (
BlockMaxTransactionCount = 100
BlockMaxTransactionCount = 100
MaxBlockCountForRetrieving = 500 // we do it just like in Bitcoin
MaxTransactionCountForRetrieving = 50000
)

15
go.mod
View File

@ -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
View File

@ -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=

View File

@ -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)
}
}

View 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
}

View File

@ -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
View 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
}