dione/node/network_service.go
2021-06-02 22:45:55 +03:00

94 lines
2.4 KiB
Go

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"
)
type NetworkService struct {
blockpool *pool.BlockPool
mempool *pool.Mempool
rpcClient *gorpc.Client
}
func NewNetworkService(bp *pool.BlockPool) *NetworkService {
return &NetworkService{
blockpool: bp,
}
}
func (s *NetworkService) LastBlockHeight(ctx context.Context, arg struct{}, reply *wire.LastBlockHeightReply) {
height, err := s.blockpool.GetLatestBlockHeight()
if err != nil {
reply.Error = err
return
}
reply.Height = height
}
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 > policy.MaxBlockCountForRetrieving {
errText := "incorrect arguments: count of block for retrieving is exceeded the limit"
reply.Error = &errText
return
}
for i := arg.From; i <= arg.To; i++ {
block, err := s.blockpool.FetchBlockByHeight(i)
if err != nil {
logrus.Warnf("failed to retrieve block from blockpool with height %d", i)
reply.FailedBlockHeights = append(reply.FailedBlockHeights, i)
continue
}
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)
}
}