96 lines
2.5 KiB
Go
96 lines
2.5 KiB
Go
package node
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
|
|
"github.com/Secured-Finance/dione/blockchain"
|
|
|
|
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 *blockchain.BlockChain
|
|
mempool *pool.Mempool
|
|
rpcClient *gorpc.Client
|
|
}
|
|
|
|
func NewNetworkService(bp *blockchain.BlockChain) *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) > policy.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)
|
|
}
|
|
}
|