From 2ca061c800519f341ffbf129223f73a1c25f2f60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CGheisMohammadi=E2=80=9D?= <36589218+GheisMohammadi@users.noreply.github.com> Date: Sat, 17 Jun 2023 18:28:59 +0800 Subject: [PATCH 01/13] initial version of client with required state sync functionalities --- consensus/engine/consensus_engine.go | 21 + core/blockchain.go | 15 + core/blockchain_impl.go | 18 + core/blockchain_stub.go | 12 + hmy/downloader/adapter_test.go | 4 + internal/chain/engine_test.go | 4 + p2p/stream/protocols/sync/chain.go | 53 ++ p2p/stream/protocols/sync/chain_test.go | 41 ++ p2p/stream/protocols/sync/client.go | 156 +++++ p2p/stream/protocols/sync/const.go | 8 + p2p/stream/protocols/sync/message/compose.go | 58 ++ p2p/stream/protocols/sync/message/msg.pb.go | 575 +++++++++++++++---- p2p/stream/protocols/sync/message/msg.proto | 19 + p2p/stream/protocols/sync/stream.go | 74 +++ test/chain/chain/chain_makers.go | 4 + 15 files changed, 947 insertions(+), 115 deletions(-) diff --git a/consensus/engine/consensus_engine.go b/consensus/engine/consensus_engine.go index 3e7cc3b348..5ac2c776b0 100644 --- a/consensus/engine/consensus_engine.go +++ b/consensus/engine/consensus_engine.go @@ -23,6 +23,27 @@ type ChainReader interface { // Config retrieves the blockchain's chain configuration. Config() *params.ChainConfig + // TrieNode retrieves a blob of data associated with a trie node + // either from ephemeral in-memory cache, or from persistent storage. + TrieNode(hash common.Hash) ([]byte, error) + + // ContractCode retrieves a blob of data associated with a contract + // hash either from ephemeral in-memory cache, or from persistent storage. + // + // If the code doesn't exist in the in-memory cache, check the storage with + // new code scheme. + ContractCode(hash common.Hash) ([]byte, error) + + // ValidatorCode retrieves a blob of data associated with a validator + // hash either from ephemeral in-memory cache, or from persistent storage. + // + // If the code doesn't exist in the in-memory cache, check the storage with + // new code scheme. + ValidatorCode(hash common.Hash) ([]byte, error) + + // GetReceiptsByHash retrieves the receipts for all transactions in a given block. + GetReceiptsByHash(hash common.Hash) types.Receipts + // CurrentHeader retrieves the current header from the local chain. CurrentHeader() *block.Header diff --git a/core/blockchain.go b/core/blockchain.go index 370f0d09e7..f7e956dbbe 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -80,6 +80,21 @@ type BlockChain interface { GetBlockByNumber(number uint64) *types.Block // GetReceiptsByHash retrieves the receipts for all transactions in a given block. GetReceiptsByHash(hash common.Hash) types.Receipts + // TrieNode retrieves a blob of data associated with a trie node + // either from ephemeral in-memory cache, or from persistent storage. + TrieNode(hash common.Hash) ([]byte, error) + // ContractCode retrieves a blob of data associated with a contract + // hash either from ephemeral in-memory cache, or from persistent storage. + // + // If the code doesn't exist in the in-memory cache, check the storage with + // new code scheme. + ContractCode(hash common.Hash) ([]byte, error) + // ValidatorCode retrieves a blob of data associated with a validator + // hash either from ephemeral in-memory cache, or from persistent storage. + // + // If the code doesn't exist in the in-memory cache, check the storage with + // new code scheme. + ValidatorCode(hash common.Hash) ([]byte, error) // Stop stops the blockchain service. If any imports are currently in progress // it will abort them using the procInterrupt. Stop() diff --git a/core/blockchain_impl.go b/core/blockchain_impl.go index 8294af26b8..698eaeebac 100644 --- a/core/blockchain_impl.go +++ b/core/blockchain_impl.go @@ -1098,6 +1098,24 @@ func (bc *BlockChainImpl) GetBlocksFromHash(hash common.Hash, n int) (blocks []* return } +// ContractCode retrieves a blob of data associated with a contract +// hash either from ephemeral in-memory cache, or from persistent storage. +// +// If the code doesn't exist in the in-memory cache, check the storage with +// new code scheme. +func (bc *BlockChainImpl) ContractCode(hash common.Hash) ([]byte, error) { + return bc.stateCache.ContractCode(common.Hash{}, hash) +} + +// ValidatorCode retrieves a blob of data associated with a validator +// hash either from ephemeral in-memory cache, or from persistent storage. +// +// If the code doesn't exist in the in-memory cache, check the storage with +// new code scheme. +func (bc *BlockChainImpl) ValidatorCode(hash common.Hash) ([]byte, error) { + return bc.stateCache.ValidatorCode(common.Hash{}, hash) +} + func (bc *BlockChainImpl) GetUnclesInChain(b *types.Block, length int) []*block.Header { uncles := []*block.Header{} for i := 0; b != nil && i < length; i++ { diff --git a/core/blockchain_stub.go b/core/blockchain_stub.go index bdab2494e9..5d83149a67 100644 --- a/core/blockchain_stub.go +++ b/core/blockchain_stub.go @@ -62,6 +62,10 @@ func (a Stub) StateAt(common.Hash) (*state.DB, error) { return nil, errors.Errorf("method StateAt not implemented for %s", a.Name) } +func (a Stub) TrieNode(hash common.Hash) ([]byte, error) { + return []byte{}, errors.Errorf("method TrieNode not implemented for %s", a.Name) +} + func (a Stub) HasBlock(hash common.Hash, number uint64) bool { return false } @@ -90,6 +94,14 @@ func (a Stub) GetReceiptsByHash(hash common.Hash) types.Receipts { return nil } +func (a Stub) ContractCode(hash common.Hash) ([]byte, error) { + return []byte{}, nil +} + +func (a Stub) ValidatorCode(hash common.Hash) ([]byte, error) { + return []byte{}, nil +} + func (a Stub) Stop() { } diff --git a/hmy/downloader/adapter_test.go b/hmy/downloader/adapter_test.go index 2d1f12e704..692ed8ad77 100644 --- a/hmy/downloader/adapter_test.go +++ b/hmy/downloader/adapter_test.go @@ -88,12 +88,16 @@ func (bc *testBlockChain) changeBlockNumber(val uint64) { func (bc *testBlockChain) ShardID() uint32 { return 0 } func (bc *testBlockChain) ReadShardState(epoch *big.Int) (*shard.State, error) { return nil, nil } +func (bc *testBlockChain) TrieNode(hash common.Hash) ([]byte, error) { return []byte{}, nil } func (bc *testBlockChain) Config() *params.ChainConfig { return nil } func (bc *testBlockChain) WriteCommitSig(blockNum uint64, lastCommits []byte) error { return nil } func (bc *testBlockChain) GetHeader(hash common.Hash, number uint64) *block.Header { return nil } func (bc *testBlockChain) GetHeaderByNumber(number uint64) *block.Header { return nil } func (bc *testBlockChain) GetHeaderByHash(hash common.Hash) *block.Header { return nil } func (bc *testBlockChain) GetBlock(hash common.Hash, number uint64) *types.Block { return nil } +func (bc *testBlockChain) GetReceiptsByHash(hash common.Hash) types.Receipts { return nil } +func (bc *testBlockChain) ContractCode(hash common.Hash) ([]byte, error) { return []byte{}, nil } +func (bc *testBlockChain) ValidatorCode(hash common.Hash) ([]byte, error) { return []byte{}, nil } func (bc *testBlockChain) ReadValidatorList() ([]common.Address, error) { return nil, nil } func (bc *testBlockChain) ReadCommitSig(blockNum uint64) ([]byte, error) { return nil, nil } func (bc *testBlockChain) ReadBlockRewardAccumulator(uint64) (*big.Int, error) { return nil, nil } diff --git a/internal/chain/engine_test.go b/internal/chain/engine_test.go index 067b265ca0..7654d9d6cd 100644 --- a/internal/chain/engine_test.go +++ b/internal/chain/engine_test.go @@ -323,8 +323,12 @@ func (bc *fakeBlockChain) CurrentHeader() *block.Header { func (bc *fakeBlockChain) GetBlock(hash common.Hash, number uint64) *types.Block { return nil } func (bc *fakeBlockChain) GetHeader(hash common.Hash, number uint64) *block.Header { return nil } func (bc *fakeBlockChain) GetHeaderByHash(hash common.Hash) *block.Header { return nil } +func (bc *fakeBlockChain) GetReceiptsByHash(hash common.Hash) types.Receipts { return nil } +func (bc *fakeBlockChain) ContractCode(hash common.Hash) ([]byte, error) { return []byte{}, nil } +func (bc *fakeBlockChain) ValidatorCode(hash common.Hash) ([]byte, error) { return []byte{}, nil } func (bc *fakeBlockChain) ShardID() uint32 { return 0 } func (bc *fakeBlockChain) ReadShardState(epoch *big.Int) (*shard.State, error) { return nil, nil } +func (bc *fakeBlockChain) TrieNode(hash common.Hash) ([]byte, error) { return []byte{}, nil } func (bc *fakeBlockChain) WriteCommitSig(blockNum uint64, lastCommits []byte) error { return nil } func (bc *fakeBlockChain) GetHeaderByNumber(number uint64) *block.Header { return nil } func (bc *fakeBlockChain) ReadValidatorList() ([]common.Address, error) { return nil, nil } diff --git a/p2p/stream/protocols/sync/chain.go b/p2p/stream/protocols/sync/chain.go index dbf2174f1d..630f328fee 100644 --- a/p2p/stream/protocols/sync/chain.go +++ b/p2p/stream/protocols/sync/chain.go @@ -2,10 +2,12 @@ package sync import ( "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/rlp" "github.com/harmony-one/harmony/block" "github.com/harmony-one/harmony/consensus/engine" "github.com/harmony-one/harmony/core/types" shardingconfig "github.com/harmony-one/harmony/internal/configs/sharding" + "github.com/harmony-one/harmony/internal/utils" "github.com/harmony-one/harmony/internal/utils/keylocker" "github.com/pkg/errors" ) @@ -16,6 +18,8 @@ type chainHelper interface { getBlockHashes(bns []uint64) []common.Hash getBlocksByNumber(bns []uint64) ([]*types.Block, error) getBlocksByHashes(hs []common.Hash) ([]*types.Block, error) + getNodeData(hs []common.Hash) ([][]byte, error) + getReceipts(hs []common.Hash) ([][]byte, error) } type chainHelperImpl struct { @@ -139,3 +143,52 @@ func (ch *chainHelperImpl) getBlockSigFromNextBlock(header *block.Header) []byte func (ch *chainHelperImpl) getBlockSigFromDB(header *block.Header) ([]byte, error) { return ch.chain.ReadCommitSig(header.Number().Uint64()) } + +// getNodeData assembles the response to a node data query. +func (ch *chainHelperImpl) getNodeData(hs []common.Hash) ([][]byte, error) { + var ( + bytes int + nodes [][]byte + ) + for _, hash := range hs { + // Retrieve the requested state entry + entry, err := ch.chain.TrieNode(hash) + if len(entry) == 0 || err != nil { + // Read the contract/validator code with prefix only to save unnecessary lookups. + entry, err = ch.chain.ContractCode(hash) + if len(entry) == 0 || err != nil { + entry, err = ch.chain.ValidatorCode(hash) + } + } + if err == nil && len(entry) > 0 { + nodes = append(nodes, entry) + bytes += len(entry) + } + } + return nodes, nil +} + +// getReceipts assembles the response to a receipt query. +func (ch *chainHelperImpl) getReceipts(hs []common.Hash) ([][]byte, error) { + var ( + bytes int + receipts [][]byte + ) + for _, hash := range hs { + // Retrieve the requested block's receipts + results := ch.chain.GetReceiptsByHash(hash) + if results == nil { + if header := ch.chain.GetHeaderByHash(hash); header == nil || header.ReceiptHash() != types.EmptyRootHash { + continue + } + } + // If known, encode and queue for response packet + if encoded, err := rlp.EncodeToBytes(results); err != nil { + utils.Logger().Err(err).Msg("Failed to encode receipt") + } else { + receipts = append(receipts, encoded) + bytes += len(encoded) + } + } + return receipts, nil +} \ No newline at end of file diff --git a/p2p/stream/protocols/sync/chain_test.go b/p2p/stream/protocols/sync/chain_test.go index 70e3e6ff6f..b3d3f463fc 100644 --- a/p2p/stream/protocols/sync/chain_test.go +++ b/p2p/stream/protocols/sync/chain_test.go @@ -46,6 +46,21 @@ func (tch *testChainHelper) getBlocksByHashes(hs []common.Hash) ([]*types.Block, return bs, nil } +func (tch *testChainHelper) getNodeData(hs []common.Hash) ([][]byte, error) { + data := makeTestNodeData(len(hs)) + return data, nil +} + +func (tch *testChainHelper) getReceipts(hs []common.Hash) ([][]byte, error) { + testReceipts := makeTestReceipts(len(hs), 3) + receipts := make([][]byte, 0, len(hs)*3) + for _, r := range testReceipts { + receiptByes, _ := rlp.EncodeToBytes(r) + receipts = append(receipts, receiptByes) + } + return receipts, nil +} + func numberToHash(bn uint64) common.Hash { var h common.Hash binary.LittleEndian.PutUint64(h[:], bn) @@ -90,6 +105,32 @@ func makeTestBlock(bn uint64) *types.Block { return types.NewBlockWithHeader(&block.Header{Header: header}) } +// makeTestReceipts creates fake node data +func makeTestNodeData(n int) [][]byte { + testData := make([][]byte, n) + for i := 0; i < n; i++ { + testData[i] = types.EmptyRootHash.Bytes() + } + return testData +} + +// makeTestReceipts creates fake receipts +func makeTestReceipts(n int, nPerBlock int) []types.Receipts { + receipts := make([]*types.Receipt, nPerBlock) + for i := 0; i < nPerBlock; i++ { + receipts[i] = &types.Receipt{ + Status: types.ReceiptStatusSuccessful, + CumulativeGasUsed: 0x888888888, + Logs: make([]*types.Log, 5), + } + } + allReceipts := make([]types.Receipts, n) + for i := 0; i < n; i++ { + allReceipts[i] = receipts + } + return allReceipts +} + func decodeBlocksBytes(bbs [][]byte) ([]*types.Block, error) { blocks := make([]*types.Block, 0, len(bbs)) diff --git a/p2p/stream/protocols/sync/client.go b/p2p/stream/protocols/sync/client.go index 7ad4798851..2a9c5ed9ca 100644 --- a/p2p/stream/protocols/sync/client.go +++ b/p2p/stream/protocols/sync/client.go @@ -15,6 +15,34 @@ import ( "github.com/pkg/errors" ) +// FetchNodeData do fetch node data through sync stream protocol. +// Return the state node data as result, and error +func (p *Protocol) FetchNodeData(ctx context.Context, hashes []common.Hash, opts ...Option) (data [][]byte, stid sttypes.StreamID, err error) { + timer := p.doMetricClientRequest("fetchNodeData") + defer p.doMetricPostClientRequest("fetchNodeData", err, timer) + + if len(hashes) == 0 { + err = fmt.Errorf("zero hashes array requested") + return + } + if len(hashes) > GetNodeDataCap { + err = fmt.Errorf("number of node data hashes cap of %v", GetNodeDataCap) + return + } + + req := newGetNodeDataRequest(hashes) + resp, stid, err := p.rm.DoRequest(ctx, req, opts...) + if err != nil { + // At this point, error can be context canceled, context timed out, or waiting queue + // is already full. + return + } + + // Parse and return blocks + data, err = req.getNodeDataResponse(resp) + return +} + // GetBlocksByNumber do getBlocksByNumberRequest through sync stream protocol. // Return the block as result, target stream id, and error func (p *Protocol) GetBlocksByNumber(ctx context.Context, bns []uint64, opts ...Option) (blocks []*types.Block, stid sttypes.StreamID, err error) { @@ -387,3 +415,131 @@ func (req *getBlocksByHashesRequest) getBlocksFromResponse(resp sttypes.Response } return blocks, nil } + +// getNodeDataRequest is the request for get node data which implements +// sttypes.Request interface +type getNodeDataRequest struct { + hashes []common.Hash + pbReq *syncpb.Request +} + +func newGetNodeDataRequest(hashes []common.Hash) *getNodeDataRequest { + pbReq := syncpb.MakeGetNodeDataRequest(hashes) + return &getNodeDataRequest{ + hashes: hashes, + pbReq: pbReq, + } +} + +func (req *getNodeDataRequest) ReqID() uint64 { + return req.pbReq.GetReqId() +} + +func (req *getNodeDataRequest) SetReqID(val uint64) { + req.pbReq.ReqId = val +} + +func (req *getNodeDataRequest) String() string { + ss := make([]string, 0, len(req.hashes)) + for _, h := range req.hashes { + ss = append(ss, h.String()) + } + hsStr := strings.Join(ss, ",") + return fmt.Sprintf("REQUEST [GetNodeData: %s]", hsStr) +} + +func (req *getNodeDataRequest) IsSupportedByProto(target sttypes.ProtoSpec) bool { + return target.Version.GreaterThanOrEqual(MinVersion) +} + +func (req *getNodeDataRequest) Encode() ([]byte, error) { + msg := syncpb.MakeMessageFromRequest(req.pbReq) + return protobuf.Marshal(msg) +} + +func (req *getNodeDataRequest) getNodeDataResponse(resp sttypes.Response) ([][]byte, error) { + sResp, ok := resp.(*syncResponse) + if !ok || sResp == nil { + return nil, errors.New("not sync response for node data") + } + dataBytes, err := req.parseNodeDataBytes(sResp) + if err != nil { + return nil, err + } + return dataBytes, nil +} + +func (req *getNodeDataRequest) parseNodeDataBytes(resp *syncResponse) ([][]byte, error) { + if errResp := resp.pb.GetErrorResponse(); errResp != nil { + return nil, errors.New(errResp.Error) + } + gbResp := resp.pb.GetGetNodeDataResponse() + if gbResp == nil { + return nil, errors.New("The response is not for GetNodeData") + } + return gbResp.DataBytes, nil +} + +// getReceiptsRequest is the request for get receipts which implements +// sttypes.Request interface +type getReceiptsRequest struct { + hashes []common.Hash + pbReq *syncpb.Request +} + +func newGetReceiptsRequest(hashes []common.Hash) *getReceiptsRequest { + pbReq := syncpb.MakeGetReceiptsRequest(hashes) + return &getReceiptsRequest{ + hashes: hashes, + pbReq: pbReq, + } +} + +func (req *getReceiptsRequest) ReqID() uint64 { + return req.pbReq.GetReqId() +} + +func (req *getReceiptsRequest) SetReqID(val uint64) { + req.pbReq.ReqId = val +} + +func (req *getReceiptsRequest) String() string { + ss := make([]string, 0, len(req.hashes)) + for _, h := range req.hashes { + ss = append(ss, h.String()) + } + hsStr := strings.Join(ss, ",") + return fmt.Sprintf("REQUEST [GetReceipts: %s]", hsStr) +} + +func (req *getReceiptsRequest) IsSupportedByProto(target sttypes.ProtoSpec) bool { + return target.Version.GreaterThanOrEqual(MinVersion) +} + +func (req *getReceiptsRequest) Encode() ([]byte, error) { + msg := syncpb.MakeMessageFromRequest(req.pbReq) + return protobuf.Marshal(msg) +} + +func (req *getReceiptsRequest) getReceiptsResponse(resp sttypes.Response) ([][]byte, error) { + sResp, ok := resp.(*syncResponse) + if !ok || sResp == nil { + return nil, errors.New("not sync response for receipts") + } + receiptsBytes, err := req.parseGetReceiptsBytes(sResp) + if err != nil { + return nil, err + } + return receiptsBytes, nil +} + +func (req *getReceiptsRequest) parseGetReceiptsBytes(resp *syncResponse) ([][]byte, error) { + if errResp := resp.pb.GetErrorResponse(); errResp != nil { + return nil, errors.New(errResp.Error) + } + gbResp := resp.pb.GetGetReceiptsResponse() + if gbResp == nil { + return nil, errors.New("The response is not for GetReceipts") + } + return gbResp.ReceiptsBytes, nil +} \ No newline at end of file diff --git a/p2p/stream/protocols/sync/const.go b/p2p/stream/protocols/sync/const.go index 1e1fc612f0..745ed35ba9 100644 --- a/p2p/stream/protocols/sync/const.go +++ b/p2p/stream/protocols/sync/const.go @@ -17,6 +17,14 @@ const ( // See comments for GetBlocksByNumAmountCap. GetBlocksByHashesAmountCap = 10 + // GetNodeDataCap is the cap of request of single GetNodeData request + // This number has an effect on maxMsgBytes as 20MB defined in github.com/harmony-one/harmony/p2p/stream/types. + GetNodeDataCap = 10 + + // GetReceiptsCap is the cap of request of single GetReceipts request + // This number has an effect on maxMsgBytes as 20MB defined in github.com/harmony-one/harmony/p2p/stream/types. + GetReceiptsCap = 10 + // MaxStreamFailures is the maximum allowed failures before stream gets removed MaxStreamFailures = 3 diff --git a/p2p/stream/protocols/sync/message/compose.go b/p2p/stream/protocols/sync/message/compose.go index 8a834e4de3..8cc9895383 100644 --- a/p2p/stream/protocols/sync/message/compose.go +++ b/p2p/stream/protocols/sync/message/compose.go @@ -46,6 +46,28 @@ func MakeGetBlocksByHashesRequest(hashes []common.Hash) *Request { } } +// MakeGetNodeDataRequest makes the GetNodeData request +func MakeGetNodeDataRequest(hashes []common.Hash) *Request { + return &Request{ + Request: &Request_GetNodeDataRequest{ + GetNodeDataRequest: &GetNodeDataRequest{ + NodeHashes: hashesToBytes(hashes), + }, + }, + } +} + +// MakeGetReceiptsRequest makes the GetReceipts request +func MakeGetReceiptsRequest(hashes []common.Hash) *Request { + return &Request{ + Request: &Request_GetReceiptsRequest{ + GetReceiptsRequest: &GetReceiptsRequest{ + BlockHashes: hashesToBytes(hashes), + }, + }, + } +} + // MakeErrorResponse makes the error response func MakeErrorResponseMessage(rid uint64, err error) *Message { resp := MakeErrorResponse(rid, err) @@ -138,6 +160,42 @@ func MakeGetBlocksByHashesResponse(rid uint64, blocksBytes [][]byte, sigs [][]by } } +// MakeGetNodeDataResponseMessage makes the GetNodeDataResponse of Message type +func MakeGetNodeDataResponseMessage(rid uint64, nodeData [][]byte) *Message { + resp := MakeGetNodeDataResponse(rid, nodeData) + return makeMessageFromResponse(resp) +} + +// MakeGetNodeDataResponse make the GetNodeDataResponse of Response type +func MakeGetNodeDataResponse(rid uint64, nodeData [][]byte) *Response { + return &Response{ + ReqId: rid, + Response: &Response_GetNodeDataResponse{ + GetNodeDataResponse: &GetNodeDataResponse{ + DataBytes: nodeData, + }, + }, + } +} + +// MakeGetReceiptsResponseMessage makes the GetReceiptsResponse of Message type +func MakeGetReceiptsResponseMessage(rid uint64, receiptsBytes [][]byte) *Message { + resp := MakeGetReceiptsResponse(rid, receiptsBytes) + return makeMessageFromResponse(resp) +} + +// MakeGetReceiptsResponse make the GetReceiptsResponse of Response type +func MakeGetReceiptsResponse(rid uint64, receiptsBytes [][]byte) *Response { + return &Response{ + ReqId: rid, + Response: &Response_GetReceiptsResponse{ + GetReceiptsResponse: &GetReceiptsResponse{ + ReceiptsBytes: receiptsBytes, + }, + }, + } +} + // MakeMessageFromRequest makes a message from the request func MakeMessageFromRequest(req *Request) *Message { return &Message{ diff --git a/p2p/stream/protocols/sync/message/msg.pb.go b/p2p/stream/protocols/sync/message/msg.pb.go index 5928a7dea4..154deac2f3 100644 --- a/p2p/stream/protocols/sync/message/msg.pb.go +++ b/p2p/stream/protocols/sync/message/msg.pb.go @@ -7,10 +7,11 @@ package message import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" sync "sync" + + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" ) const ( @@ -113,6 +114,8 @@ type Request struct { // *Request_GetBlockHashesRequest // *Request_GetBlocksByNumRequest // *Request_GetBlocksByHashesRequest + // *Request_GetNodeDataRequest + // *Request_GetReceiptsRequest Request isRequest_Request `protobuf_oneof:"request"` } @@ -190,6 +193,20 @@ func (x *Request) GetGetBlocksByHashesRequest() *GetBlocksByHashesRequest { return nil } +func (x *Request) GetGetNodeDataRequest() *GetNodeDataRequest { + if x, ok := x.GetRequest().(*Request_GetNodeDataRequest); ok { + return x.GetNodeDataRequest + } + return nil +} + +func (x *Request) GetGetReceiptsRequest() *GetReceiptsRequest { + if x, ok := x.GetRequest().(*Request_GetReceiptsRequest); ok { + return x.GetReceiptsRequest + } + return nil +} + type isRequest_Request interface { isRequest_Request() } @@ -210,6 +227,14 @@ type Request_GetBlocksByHashesRequest struct { GetBlocksByHashesRequest *GetBlocksByHashesRequest `protobuf:"bytes,5,opt,name=get_blocks_by_hashes_request,json=getBlocksByHashesRequest,proto3,oneof"` } +type Request_GetNodeDataRequest struct { + GetNodeDataRequest *GetNodeDataRequest `protobuf:"bytes,6,opt,name=get_node_data_request,json=getNodeDataRequest,proto3,oneof"` +} + +type Request_GetReceiptsRequest struct { + GetReceiptsRequest *GetReceiptsRequest `protobuf:"bytes,7,opt,name=get_receipts_request,json=getReceiptsRequest,proto3,oneof"` +} + func (*Request_GetBlockNumberRequest) isRequest_Request() {} func (*Request_GetBlockHashesRequest) isRequest_Request() {} @@ -218,6 +243,10 @@ func (*Request_GetBlocksByNumRequest) isRequest_Request() {} func (*Request_GetBlocksByHashesRequest) isRequest_Request() {} +func (*Request_GetNodeDataRequest) isRequest_Request() {} + +func (*Request_GetReceiptsRequest) isRequest_Request() {} + type GetBlockNumberRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -397,6 +426,100 @@ func (x *GetBlocksByHashesRequest) GetBlockHashes() [][]byte { return nil } +type GetNodeDataRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + NodeHashes [][]byte `protobuf:"bytes,1,rep,name=node_hashes,json=nodeHashes,proto3" json:"node_hashes,omitempty"` +} + +func (x *GetNodeDataRequest) Reset() { + *x = GetNodeDataRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_msg_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetNodeDataRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetNodeDataRequest) ProtoMessage() {} + +func (x *GetNodeDataRequest) ProtoReflect() protoreflect.Message { + mi := &file_msg_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetNodeDataRequest.ProtoReflect.Descriptor instead. +func (*GetNodeDataRequest) Descriptor() ([]byte, []int) { + return file_msg_proto_rawDescGZIP(), []int{6} +} + +func (x *GetNodeDataRequest) GetNodeHashes() [][]byte { + if x != nil { + return x.NodeHashes + } + return nil +} + +type GetReceiptsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + BlockHashes [][]byte `protobuf:"bytes,1,rep,name=block_hashes,json=blockHashes,proto3" json:"block_hashes,omitempty"` +} + +func (x *GetReceiptsRequest) Reset() { + *x = GetReceiptsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_msg_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetReceiptsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetReceiptsRequest) ProtoMessage() {} + +func (x *GetReceiptsRequest) ProtoReflect() protoreflect.Message { + mi := &file_msg_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetReceiptsRequest.ProtoReflect.Descriptor instead. +func (*GetReceiptsRequest) Descriptor() ([]byte, []int) { + return file_msg_proto_rawDescGZIP(), []int{7} +} + +func (x *GetReceiptsRequest) GetBlockHashes() [][]byte { + if x != nil { + return x.BlockHashes + } + return nil +} + type Response struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -410,13 +533,15 @@ type Response struct { // *Response_GetBlockHashesResponse // *Response_GetBlocksByNumResponse // *Response_GetBlocksByHashesResponse + // *Response_GetNodeDataResponse + // *Response_GetReceiptsResponse Response isResponse_Response `protobuf_oneof:"response"` } func (x *Response) Reset() { *x = Response{} if protoimpl.UnsafeEnabled { - mi := &file_msg_proto_msgTypes[6] + mi := &file_msg_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -429,7 +554,7 @@ func (x *Response) String() string { func (*Response) ProtoMessage() {} func (x *Response) ProtoReflect() protoreflect.Message { - mi := &file_msg_proto_msgTypes[6] + mi := &file_msg_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -442,7 +567,7 @@ func (x *Response) ProtoReflect() protoreflect.Message { // Deprecated: Use Response.ProtoReflect.Descriptor instead. func (*Response) Descriptor() ([]byte, []int) { - return file_msg_proto_rawDescGZIP(), []int{6} + return file_msg_proto_rawDescGZIP(), []int{8} } func (x *Response) GetReqId() uint64 { @@ -494,6 +619,20 @@ func (x *Response) GetGetBlocksByHashesResponse() *GetBlocksByHashesResponse { return nil } +func (x *Response) GetGetNodeDataResponse() *GetNodeDataResponse { + if x, ok := x.GetResponse().(*Response_GetNodeDataResponse); ok { + return x.GetNodeDataResponse + } + return nil +} + +func (x *Response) GetGetReceiptsResponse() *GetReceiptsResponse { + if x, ok := x.GetResponse().(*Response_GetReceiptsResponse); ok { + return x.GetReceiptsResponse + } + return nil +} + type isResponse_Response interface { isResponse_Response() } @@ -518,6 +657,14 @@ type Response_GetBlocksByHashesResponse struct { GetBlocksByHashesResponse *GetBlocksByHashesResponse `protobuf:"bytes,6,opt,name=get_blocks_by_hashes_response,json=getBlocksByHashesResponse,proto3,oneof"` } +type Response_GetNodeDataResponse struct { + GetNodeDataResponse *GetNodeDataResponse `protobuf:"bytes,7,opt,name=get_node_data_response,json=getNodeDataResponse,proto3,oneof"` +} + +type Response_GetReceiptsResponse struct { + GetReceiptsResponse *GetReceiptsResponse `protobuf:"bytes,8,opt,name=get_receipts_response,json=getReceiptsResponse,proto3,oneof"` +} + func (*Response_ErrorResponse) isResponse_Response() {} func (*Response_GetBlockNumberResponse) isResponse_Response() {} @@ -528,6 +675,10 @@ func (*Response_GetBlocksByNumResponse) isResponse_Response() {} func (*Response_GetBlocksByHashesResponse) isResponse_Response() {} +func (*Response_GetNodeDataResponse) isResponse_Response() {} + +func (*Response_GetReceiptsResponse) isResponse_Response() {} + type ErrorResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -539,7 +690,7 @@ type ErrorResponse struct { func (x *ErrorResponse) Reset() { *x = ErrorResponse{} if protoimpl.UnsafeEnabled { - mi := &file_msg_proto_msgTypes[7] + mi := &file_msg_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -552,7 +703,7 @@ func (x *ErrorResponse) String() string { func (*ErrorResponse) ProtoMessage() {} func (x *ErrorResponse) ProtoReflect() protoreflect.Message { - mi := &file_msg_proto_msgTypes[7] + mi := &file_msg_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -565,7 +716,7 @@ func (x *ErrorResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ErrorResponse.ProtoReflect.Descriptor instead. func (*ErrorResponse) Descriptor() ([]byte, []int) { - return file_msg_proto_rawDescGZIP(), []int{7} + return file_msg_proto_rawDescGZIP(), []int{9} } func (x *ErrorResponse) GetError() string { @@ -586,7 +737,7 @@ type GetBlockNumberResponse struct { func (x *GetBlockNumberResponse) Reset() { *x = GetBlockNumberResponse{} if protoimpl.UnsafeEnabled { - mi := &file_msg_proto_msgTypes[8] + mi := &file_msg_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -599,7 +750,7 @@ func (x *GetBlockNumberResponse) String() string { func (*GetBlockNumberResponse) ProtoMessage() {} func (x *GetBlockNumberResponse) ProtoReflect() protoreflect.Message { - mi := &file_msg_proto_msgTypes[8] + mi := &file_msg_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -612,7 +763,7 @@ func (x *GetBlockNumberResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetBlockNumberResponse.ProtoReflect.Descriptor instead. func (*GetBlockNumberResponse) Descriptor() ([]byte, []int) { - return file_msg_proto_rawDescGZIP(), []int{8} + return file_msg_proto_rawDescGZIP(), []int{10} } func (x *GetBlockNumberResponse) GetNumber() uint64 { @@ -633,7 +784,7 @@ type GetBlockHashesResponse struct { func (x *GetBlockHashesResponse) Reset() { *x = GetBlockHashesResponse{} if protoimpl.UnsafeEnabled { - mi := &file_msg_proto_msgTypes[9] + mi := &file_msg_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -646,7 +797,7 @@ func (x *GetBlockHashesResponse) String() string { func (*GetBlockHashesResponse) ProtoMessage() {} func (x *GetBlockHashesResponse) ProtoReflect() protoreflect.Message { - mi := &file_msg_proto_msgTypes[9] + mi := &file_msg_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -659,7 +810,7 @@ func (x *GetBlockHashesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetBlockHashesResponse.ProtoReflect.Descriptor instead. func (*GetBlockHashesResponse) Descriptor() ([]byte, []int) { - return file_msg_proto_rawDescGZIP(), []int{9} + return file_msg_proto_rawDescGZIP(), []int{11} } func (x *GetBlockHashesResponse) GetHashes() [][]byte { @@ -681,7 +832,7 @@ type GetBlocksByNumResponse struct { func (x *GetBlocksByNumResponse) Reset() { *x = GetBlocksByNumResponse{} if protoimpl.UnsafeEnabled { - mi := &file_msg_proto_msgTypes[10] + mi := &file_msg_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -694,7 +845,7 @@ func (x *GetBlocksByNumResponse) String() string { func (*GetBlocksByNumResponse) ProtoMessage() {} func (x *GetBlocksByNumResponse) ProtoReflect() protoreflect.Message { - mi := &file_msg_proto_msgTypes[10] + mi := &file_msg_proto_msgTypes[12] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -707,7 +858,7 @@ func (x *GetBlocksByNumResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetBlocksByNumResponse.ProtoReflect.Descriptor instead. func (*GetBlocksByNumResponse) Descriptor() ([]byte, []int) { - return file_msg_proto_rawDescGZIP(), []int{10} + return file_msg_proto_rawDescGZIP(), []int{12} } func (x *GetBlocksByNumResponse) GetBlocksBytes() [][]byte { @@ -736,7 +887,7 @@ type GetBlocksByHashesResponse struct { func (x *GetBlocksByHashesResponse) Reset() { *x = GetBlocksByHashesResponse{} if protoimpl.UnsafeEnabled { - mi := &file_msg_proto_msgTypes[11] + mi := &file_msg_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -749,7 +900,7 @@ func (x *GetBlocksByHashesResponse) String() string { func (*GetBlocksByHashesResponse) ProtoMessage() {} func (x *GetBlocksByHashesResponse) ProtoReflect() protoreflect.Message { - mi := &file_msg_proto_msgTypes[11] + mi := &file_msg_proto_msgTypes[13] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -762,7 +913,7 @@ func (x *GetBlocksByHashesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetBlocksByHashesResponse.ProtoReflect.Descriptor instead. func (*GetBlocksByHashesResponse) Descriptor() ([]byte, []int) { - return file_msg_proto_rawDescGZIP(), []int{11} + return file_msg_proto_rawDescGZIP(), []int{13} } func (x *GetBlocksByHashesResponse) GetBlocksBytes() [][]byte { @@ -779,6 +930,100 @@ func (x *GetBlocksByHashesResponse) GetCommitSig() [][]byte { return nil } +type GetNodeDataResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + DataBytes [][]byte `protobuf:"bytes,1,rep,name=data_bytes,json=dataBytes,proto3" json:"data_bytes,omitempty"` +} + +func (x *GetNodeDataResponse) Reset() { + *x = GetNodeDataResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_msg_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetNodeDataResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetNodeDataResponse) ProtoMessage() {} + +func (x *GetNodeDataResponse) ProtoReflect() protoreflect.Message { + mi := &file_msg_proto_msgTypes[14] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetNodeDataResponse.ProtoReflect.Descriptor instead. +func (*GetNodeDataResponse) Descriptor() ([]byte, []int) { + return file_msg_proto_rawDescGZIP(), []int{14} +} + +func (x *GetNodeDataResponse) GetDataBytes() [][]byte { + if x != nil { + return x.DataBytes + } + return nil +} + +type GetReceiptsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ReceiptsBytes [][]byte `protobuf:"bytes,1,rep,name=receipts_bytes,json=receiptsBytes,proto3" json:"receipts_bytes,omitempty"` +} + +func (x *GetReceiptsResponse) Reset() { + *x = GetReceiptsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_msg_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetReceiptsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetReceiptsResponse) ProtoMessage() {} + +func (x *GetReceiptsResponse) ProtoReflect() protoreflect.Message { + mi := &file_msg_proto_msgTypes[15] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetReceiptsResponse.ProtoReflect.Descriptor instead. +func (*GetReceiptsResponse) Descriptor() ([]byte, []int) { + return file_msg_proto_rawDescGZIP(), []int{15} +} + +func (x *GetReceiptsResponse) GetReceiptsBytes() [][]byte { + if x != nil { + return x.ReceiptsBytes + } + return nil +} + var File_msg_proto protoreflect.FileDescriptor var file_msg_proto_rawDesc = []byte{ @@ -793,7 +1038,7 @@ var file_msg_proto_rawDesc = []byte{ 0x61, 0x72, 0x6d, 0x6f, 0x6e, 0x79, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x2e, 0x73, 0x79, 0x6e, 0x63, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, 0x04, 0x72, 0x65, 0x73, 0x70, 0x42, 0x0d, 0x0a, 0x0b, 0x72, - 0x65, 0x71, 0x5f, 0x6f, 0x72, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x22, 0xf2, 0x03, 0x0a, 0x07, 0x52, + 0x65, 0x71, 0x5f, 0x6f, 0x72, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x22, 0xbd, 0x05, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x15, 0x0a, 0x06, 0x72, 0x65, 0x71, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x72, 0x65, 0x71, 0x49, 0x64, 0x12, 0x6d, 0x0a, 0x18, 0x67, 0x65, 0x74, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, @@ -824,77 +1069,117 @@ var file_msg_proto_rawDesc = []byte{ 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x42, 0x79, 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x18, 0x67, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x42, 0x79, 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x42, 0x09, 0x0a, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, - 0x17, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x75, 0x6d, 0x62, 0x65, - 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x2f, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x42, - 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x16, 0x0a, 0x04, 0x6e, 0x75, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x04, 0x42, - 0x02, 0x10, 0x01, 0x52, 0x04, 0x6e, 0x75, 0x6d, 0x73, 0x22, 0x2f, 0x0a, 0x15, 0x47, 0x65, 0x74, - 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x42, 0x79, 0x4e, 0x75, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x16, 0x0a, 0x04, 0x6e, 0x75, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x04, - 0x42, 0x02, 0x10, 0x01, 0x52, 0x04, 0x6e, 0x75, 0x6d, 0x73, 0x22, 0x3d, 0x0a, 0x18, 0x47, 0x65, - 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x42, 0x79, 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, - 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0b, 0x62, 0x6c, - 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0x22, 0xd5, 0x04, 0x0a, 0x08, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x15, 0x0a, 0x06, 0x72, 0x65, 0x71, 0x5f, 0x69, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x72, 0x65, 0x71, 0x49, 0x64, 0x12, 0x53, 0x0a, - 0x0e, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x68, 0x61, 0x72, 0x6d, 0x6f, 0x6e, 0x79, 0x2e, - 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x2e, 0x73, 0x79, 0x6e, 0x63, 0x2e, 0x6d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x48, 0x00, 0x52, 0x0d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x70, 0x0a, 0x19, 0x67, 0x65, 0x74, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, - 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x68, 0x61, 0x72, 0x6d, 0x6f, 0x6e, 0x79, 0x2e, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x64, 0x0a, 0x15, 0x67, 0x65, 0x74, 0x5f, 0x6e, 0x6f, 0x64, 0x65, + 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x68, 0x61, 0x72, 0x6d, 0x6f, 0x6e, 0x79, 0x2e, 0x73, 0x74, + 0x72, 0x65, 0x61, 0x6d, 0x2e, 0x73, 0x79, 0x6e, 0x63, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x2e, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x44, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x12, 0x67, 0x65, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x44, + 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x63, 0x0a, 0x14, 0x67, 0x65, + 0x74, 0x5f, 0x72, 0x65, 0x63, 0x65, 0x69, 0x70, 0x74, 0x73, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x68, 0x61, 0x72, 0x6d, 0x6f, + 0x6e, 0x79, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x2e, 0x73, 0x79, 0x6e, 0x63, 0x2e, 0x6d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x63, 0x65, 0x69, 0x70, + 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x12, 0x67, 0x65, 0x74, + 0x52, 0x65, 0x63, 0x65, 0x69, 0x70, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x42, + 0x09, 0x0a, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x17, 0x0a, 0x15, 0x47, 0x65, + 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x22, 0x2f, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, + 0x61, 0x73, 0x68, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x04, + 0x6e, 0x75, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x04, 0x42, 0x02, 0x10, 0x01, 0x52, 0x04, + 0x6e, 0x75, 0x6d, 0x73, 0x22, 0x2f, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, + 0x73, 0x42, 0x79, 0x4e, 0x75, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, + 0x04, 0x6e, 0x75, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x04, 0x42, 0x02, 0x10, 0x01, 0x52, + 0x04, 0x6e, 0x75, 0x6d, 0x73, 0x22, 0x3d, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, + 0x6b, 0x73, 0x42, 0x79, 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x65, + 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, + 0x73, 0x68, 0x65, 0x73, 0x22, 0x35, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x44, + 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x6e, 0x6f, + 0x64, 0x65, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, + 0x0a, 0x6e, 0x6f, 0x64, 0x65, 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0x22, 0x37, 0x0a, 0x12, 0x47, + 0x65, 0x74, 0x52, 0x65, 0x63, 0x65, 0x69, 0x70, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x65, + 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, + 0x73, 0x68, 0x65, 0x73, 0x22, 0xa6, 0x06, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x15, 0x0a, 0x06, 0x72, 0x65, 0x71, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x05, 0x72, 0x65, 0x71, 0x49, 0x64, 0x12, 0x53, 0x0a, 0x0e, 0x65, 0x72, 0x72, 0x6f, + 0x72, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x2a, 0x2e, 0x68, 0x61, 0x72, 0x6d, 0x6f, 0x6e, 0x79, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x2e, 0x73, 0x79, 0x6e, 0x63, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x45, + 0x72, 0x72, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, 0x0d, + 0x65, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x70, 0x0a, + 0x19, 0x67, 0x65, 0x74, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, + 0x72, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x33, 0x2e, 0x68, 0x61, 0x72, 0x6d, 0x6f, 0x6e, 0x79, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x2e, 0x73, 0x79, 0x6e, 0x63, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x47, + 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, 0x16, 0x67, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, + 0x6b, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x70, 0x0a, 0x19, 0x67, 0x65, 0x74, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x61, 0x73, + 0x68, 0x65, 0x73, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x68, 0x61, 0x72, 0x6d, 0x6f, 0x6e, 0x79, 0x2e, 0x73, 0x74, 0x72, + 0x65, 0x61, 0x6d, 0x2e, 0x73, 0x79, 0x6e, 0x63, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, 0x16, 0x67, 0x65, 0x74, 0x42, 0x6c, + 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x71, 0x0a, 0x1a, 0x67, 0x65, 0x74, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x5f, + 0x62, 0x79, 0x5f, 0x6e, 0x75, 0x6d, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x68, 0x61, 0x72, 0x6d, 0x6f, 0x6e, 0x79, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x2e, 0x73, 0x79, 0x6e, 0x63, 0x2e, 0x6d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x75, 0x6d, 0x62, - 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, 0x16, 0x67, 0x65, - 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x70, 0x0a, 0x19, 0x67, 0x65, 0x74, 0x5f, 0x62, 0x6c, 0x6f, 0x63, - 0x6b, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x68, 0x61, 0x72, 0x6d, 0x6f, 0x6e, - 0x79, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x2e, 0x73, 0x79, 0x6e, 0x63, 0x2e, 0x6d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, - 0x73, 0x68, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, 0x16, - 0x67, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x71, 0x0a, 0x1a, 0x67, 0x65, 0x74, 0x5f, 0x62, 0x6c, - 0x6f, 0x63, 0x6b, 0x73, 0x5f, 0x62, 0x79, 0x5f, 0x6e, 0x75, 0x6d, 0x5f, 0x72, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x68, 0x61, 0x72, - 0x6d, 0x6f, 0x6e, 0x79, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x2e, 0x73, 0x79, 0x6e, 0x63, - 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, - 0x6b, 0x73, 0x42, 0x79, 0x4e, 0x75, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, - 0x00, 0x52, 0x16, 0x67, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x42, 0x79, 0x4e, 0x75, - 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7a, 0x0a, 0x1d, 0x67, 0x65, 0x74, - 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x5f, 0x62, 0x79, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x65, - 0x73, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x36, 0x2e, 0x68, 0x61, 0x72, 0x6d, 0x6f, 0x6e, 0x79, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, + 0x61, 0x67, 0x65, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x42, 0x79, 0x4e, + 0x75, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, 0x16, 0x67, 0x65, + 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x42, 0x79, 0x4e, 0x75, 0x6d, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7a, 0x0a, 0x1d, 0x67, 0x65, 0x74, 0x5f, 0x62, 0x6c, 0x6f, 0x63, + 0x6b, 0x73, 0x5f, 0x62, 0x79, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, 0x5f, 0x72, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x36, 0x2e, 0x68, 0x61, + 0x72, 0x6d, 0x6f, 0x6e, 0x79, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x2e, 0x73, 0x79, 0x6e, + 0x63, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, + 0x63, 0x6b, 0x73, 0x42, 0x79, 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, 0x19, 0x67, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x73, + 0x42, 0x79, 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x67, 0x0a, 0x16, 0x67, 0x65, 0x74, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x64, 0x61, 0x74, + 0x61, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x30, 0x2e, 0x68, 0x61, 0x72, 0x6d, 0x6f, 0x6e, 0x79, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x2e, 0x73, 0x79, 0x6e, 0x63, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x47, - 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x42, 0x79, 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, 0x19, 0x67, 0x65, 0x74, 0x42, - 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x42, 0x79, 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x0a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x25, 0x0a, 0x0d, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x30, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x42, - 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x04, 0x52, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, 0x30, 0x0a, 0x16, 0x47, 0x65, - 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x0c, 0x52, 0x06, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, 0x22, 0x5a, 0x0a, 0x16, - 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x42, 0x79, 0x4e, 0x75, 0x6d, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, - 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0b, 0x62, 0x6c, - 0x6f, 0x63, 0x6b, 0x73, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, - 0x6d, 0x69, 0x74, 0x5f, 0x73, 0x69, 0x67, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x09, 0x63, - 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x53, 0x69, 0x67, 0x22, 0x5d, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x42, - 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x42, 0x79, 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x5f, - 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0b, 0x62, 0x6c, 0x6f, - 0x63, 0x6b, 0x73, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x6d, - 0x69, 0x74, 0x5f, 0x73, 0x69, 0x67, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x09, 0x63, 0x6f, - 0x6d, 0x6d, 0x69, 0x74, 0x53, 0x69, 0x67, 0x42, 0x0c, 0x5a, 0x0a, 0x2e, 0x2f, 0x3b, 0x6d, 0x65, + 0x65, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x44, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x48, 0x00, 0x52, 0x13, 0x67, 0x65, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x44, 0x61, 0x74, + 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x66, 0x0a, 0x15, 0x67, 0x65, 0x74, + 0x5f, 0x72, 0x65, 0x63, 0x65, 0x69, 0x70, 0x74, 0x73, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x68, 0x61, 0x72, 0x6d, 0x6f, + 0x6e, 0x79, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x2e, 0x73, 0x79, 0x6e, 0x63, 0x2e, 0x6d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x63, 0x65, 0x69, 0x70, + 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, 0x13, 0x67, 0x65, + 0x74, 0x52, 0x65, 0x63, 0x65, 0x69, 0x70, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x42, 0x0a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x25, 0x0a, + 0x0d, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, + 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x22, 0x30, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, + 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, + 0x0a, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, + 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, 0x30, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, + 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x16, 0x0a, 0x06, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, + 0x52, 0x06, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, 0x22, 0x5a, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x42, + 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x42, 0x79, 0x4e, 0x75, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x5f, 0x62, 0x79, 0x74, + 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, + 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, + 0x73, 0x69, 0x67, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x09, 0x63, 0x6f, 0x6d, 0x6d, 0x69, + 0x74, 0x53, 0x69, 0x67, 0x22, 0x5d, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, + 0x73, 0x42, 0x79, 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x5f, 0x62, 0x79, 0x74, 0x65, + 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x42, + 0x79, 0x74, 0x65, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x73, + 0x69, 0x67, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x09, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, + 0x53, 0x69, 0x67, 0x22, 0x34, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x44, 0x61, + 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x64, 0x61, + 0x74, 0x61, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x09, + 0x64, 0x61, 0x74, 0x61, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0x3c, 0x0a, 0x13, 0x47, 0x65, 0x74, + 0x52, 0x65, 0x63, 0x65, 0x69, 0x70, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x25, 0x0a, 0x0e, 0x72, 0x65, 0x63, 0x65, 0x69, 0x70, 0x74, 0x73, 0x5f, 0x62, 0x79, 0x74, + 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0d, 0x72, 0x65, 0x63, 0x65, 0x69, 0x70, + 0x74, 0x73, 0x42, 0x79, 0x74, 0x65, 0x73, 0x42, 0x0c, 0x5a, 0x0a, 0x2e, 0x2f, 0x3b, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } @@ -910,7 +1195,7 @@ func file_msg_proto_rawDescGZIP() []byte { return file_msg_proto_rawDescData } -var file_msg_proto_msgTypes = make([]protoimpl.MessageInfo, 12) +var file_msg_proto_msgTypes = make([]protoimpl.MessageInfo, 16) var file_msg_proto_goTypes = []interface{}{ (*Message)(nil), // 0: harmony.stream.sync.message.Message (*Request)(nil), // 1: harmony.stream.sync.message.Request @@ -918,30 +1203,38 @@ var file_msg_proto_goTypes = []interface{}{ (*GetBlockHashesRequest)(nil), // 3: harmony.stream.sync.message.GetBlockHashesRequest (*GetBlocksByNumRequest)(nil), // 4: harmony.stream.sync.message.GetBlocksByNumRequest (*GetBlocksByHashesRequest)(nil), // 5: harmony.stream.sync.message.GetBlocksByHashesRequest - (*Response)(nil), // 6: harmony.stream.sync.message.Response - (*ErrorResponse)(nil), // 7: harmony.stream.sync.message.ErrorResponse - (*GetBlockNumberResponse)(nil), // 8: harmony.stream.sync.message.GetBlockNumberResponse - (*GetBlockHashesResponse)(nil), // 9: harmony.stream.sync.message.GetBlockHashesResponse - (*GetBlocksByNumResponse)(nil), // 10: harmony.stream.sync.message.GetBlocksByNumResponse - (*GetBlocksByHashesResponse)(nil), // 11: harmony.stream.sync.message.GetBlocksByHashesResponse + (*GetNodeDataRequest)(nil), // 6: harmony.stream.sync.message.GetNodeDataRequest + (*GetReceiptsRequest)(nil), // 7: harmony.stream.sync.message.GetReceiptsRequest + (*Response)(nil), // 8: harmony.stream.sync.message.Response + (*ErrorResponse)(nil), // 9: harmony.stream.sync.message.ErrorResponse + (*GetBlockNumberResponse)(nil), // 10: harmony.stream.sync.message.GetBlockNumberResponse + (*GetBlockHashesResponse)(nil), // 11: harmony.stream.sync.message.GetBlockHashesResponse + (*GetBlocksByNumResponse)(nil), // 12: harmony.stream.sync.message.GetBlocksByNumResponse + (*GetBlocksByHashesResponse)(nil), // 13: harmony.stream.sync.message.GetBlocksByHashesResponse + (*GetNodeDataResponse)(nil), // 14: harmony.stream.sync.message.GetNodeDataResponse + (*GetReceiptsResponse)(nil), // 15: harmony.stream.sync.message.GetReceiptsResponse } var file_msg_proto_depIdxs = []int32{ 1, // 0: harmony.stream.sync.message.Message.req:type_name -> harmony.stream.sync.message.Request - 6, // 1: harmony.stream.sync.message.Message.resp:type_name -> harmony.stream.sync.message.Response + 8, // 1: harmony.stream.sync.message.Message.resp:type_name -> harmony.stream.sync.message.Response 2, // 2: harmony.stream.sync.message.Request.get_block_number_request:type_name -> harmony.stream.sync.message.GetBlockNumberRequest 3, // 3: harmony.stream.sync.message.Request.get_block_hashes_request:type_name -> harmony.stream.sync.message.GetBlockHashesRequest 4, // 4: harmony.stream.sync.message.Request.get_blocks_by_num_request:type_name -> harmony.stream.sync.message.GetBlocksByNumRequest 5, // 5: harmony.stream.sync.message.Request.get_blocks_by_hashes_request:type_name -> harmony.stream.sync.message.GetBlocksByHashesRequest - 7, // 6: harmony.stream.sync.message.Response.error_response:type_name -> harmony.stream.sync.message.ErrorResponse - 8, // 7: harmony.stream.sync.message.Response.get_block_number_response:type_name -> harmony.stream.sync.message.GetBlockNumberResponse - 9, // 8: harmony.stream.sync.message.Response.get_block_hashes_response:type_name -> harmony.stream.sync.message.GetBlockHashesResponse - 10, // 9: harmony.stream.sync.message.Response.get_blocks_by_num_response:type_name -> harmony.stream.sync.message.GetBlocksByNumResponse - 11, // 10: harmony.stream.sync.message.Response.get_blocks_by_hashes_response:type_name -> harmony.stream.sync.message.GetBlocksByHashesResponse - 11, // [11:11] is the sub-list for method output_type - 11, // [11:11] is the sub-list for method input_type - 11, // [11:11] is the sub-list for extension type_name - 11, // [11:11] is the sub-list for extension extendee - 0, // [0:11] is the sub-list for field type_name + 6, // 6: harmony.stream.sync.message.Request.get_node_data_request:type_name -> harmony.stream.sync.message.GetNodeDataRequest + 7, // 7: harmony.stream.sync.message.Request.get_receipts_request:type_name -> harmony.stream.sync.message.GetReceiptsRequest + 9, // 8: harmony.stream.sync.message.Response.error_response:type_name -> harmony.stream.sync.message.ErrorResponse + 10, // 9: harmony.stream.sync.message.Response.get_block_number_response:type_name -> harmony.stream.sync.message.GetBlockNumberResponse + 11, // 10: harmony.stream.sync.message.Response.get_block_hashes_response:type_name -> harmony.stream.sync.message.GetBlockHashesResponse + 12, // 11: harmony.stream.sync.message.Response.get_blocks_by_num_response:type_name -> harmony.stream.sync.message.GetBlocksByNumResponse + 13, // 12: harmony.stream.sync.message.Response.get_blocks_by_hashes_response:type_name -> harmony.stream.sync.message.GetBlocksByHashesResponse + 14, // 13: harmony.stream.sync.message.Response.get_node_data_response:type_name -> harmony.stream.sync.message.GetNodeDataResponse + 15, // 14: harmony.stream.sync.message.Response.get_receipts_response:type_name -> harmony.stream.sync.message.GetReceiptsResponse + 15, // [15:15] is the sub-list for method output_type + 15, // [15:15] is the sub-list for method input_type + 15, // [15:15] is the sub-list for extension type_name + 15, // [15:15] is the sub-list for extension extendee + 0, // [0:15] is the sub-list for field type_name } func init() { file_msg_proto_init() } @@ -1023,7 +1316,7 @@ func file_msg_proto_init() { } } file_msg_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Response); i { + switch v := v.(*GetNodeDataRequest); i { case 0: return &v.state case 1: @@ -1035,7 +1328,7 @@ func file_msg_proto_init() { } } file_msg_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ErrorResponse); i { + switch v := v.(*GetReceiptsRequest); i { case 0: return &v.state case 1: @@ -1047,7 +1340,7 @@ func file_msg_proto_init() { } } file_msg_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetBlockNumberResponse); i { + switch v := v.(*Response); i { case 0: return &v.state case 1: @@ -1059,7 +1352,7 @@ func file_msg_proto_init() { } } file_msg_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetBlockHashesResponse); i { + switch v := v.(*ErrorResponse); i { case 0: return &v.state case 1: @@ -1071,7 +1364,7 @@ func file_msg_proto_init() { } } file_msg_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetBlocksByNumResponse); i { + switch v := v.(*GetBlockNumberResponse); i { case 0: return &v.state case 1: @@ -1083,6 +1376,30 @@ func file_msg_proto_init() { } } file_msg_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetBlockHashesResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_msg_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetBlocksByNumResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_msg_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetBlocksByHashesResponse); i { case 0: return &v.state @@ -1094,6 +1411,30 @@ func file_msg_proto_init() { return nil } } + file_msg_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetNodeDataResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_msg_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetReceiptsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } file_msg_proto_msgTypes[0].OneofWrappers = []interface{}{ (*Message_Req)(nil), @@ -1104,13 +1445,17 @@ func file_msg_proto_init() { (*Request_GetBlockHashesRequest)(nil), (*Request_GetBlocksByNumRequest)(nil), (*Request_GetBlocksByHashesRequest)(nil), + (*Request_GetNodeDataRequest)(nil), + (*Request_GetReceiptsRequest)(nil), } - file_msg_proto_msgTypes[6].OneofWrappers = []interface{}{ + file_msg_proto_msgTypes[8].OneofWrappers = []interface{}{ (*Response_ErrorResponse)(nil), (*Response_GetBlockNumberResponse)(nil), (*Response_GetBlockHashesResponse)(nil), (*Response_GetBlocksByNumResponse)(nil), (*Response_GetBlocksByHashesResponse)(nil), + (*Response_GetNodeDataResponse)(nil), + (*Response_GetReceiptsResponse)(nil), } type x struct{} out := protoimpl.TypeBuilder{ @@ -1118,7 +1463,7 @@ func file_msg_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_msg_proto_rawDesc, NumEnums: 0, - NumMessages: 12, + NumMessages: 16, NumExtensions: 0, NumServices: 0, }, diff --git a/p2p/stream/protocols/sync/message/msg.proto b/p2p/stream/protocols/sync/message/msg.proto index 297df60858..420d21d859 100644 --- a/p2p/stream/protocols/sync/message/msg.proto +++ b/p2p/stream/protocols/sync/message/msg.proto @@ -17,6 +17,8 @@ message Request { GetBlockHashesRequest get_block_hashes_request = 3; GetBlocksByNumRequest get_blocks_by_num_request = 4; GetBlocksByHashesRequest get_blocks_by_hashes_request = 5; + GetNodeDataRequest get_node_data_request = 6; + GetReceiptsRequest get_receipts_request = 7; } } @@ -34,6 +36,14 @@ message GetBlocksByHashesRequest { repeated bytes block_hashes = 1; } +message GetNodeDataRequest { + repeated bytes node_hashes = 1; +} + +message GetReceiptsRequest { + repeated bytes block_hashes = 1; +} + message Response { uint64 req_id = 1; oneof response { @@ -42,6 +52,8 @@ message Response { GetBlockHashesResponse get_block_hashes_response = 4; GetBlocksByNumResponse get_blocks_by_num_response = 5; GetBlocksByHashesResponse get_blocks_by_hashes_response = 6; + GetNodeDataResponse get_node_data_response = 7; + GetReceiptsResponse get_receipts_response = 8; } } @@ -67,5 +79,12 @@ message GetBlocksByHashesResponse { repeated bytes commit_sig = 2; } +message GetNodeDataResponse { + repeated bytes data_bytes = 1; +} + +message GetReceiptsResponse { + repeated bytes receipts_bytes = 1; +} diff --git a/p2p/stream/protocols/sync/stream.go b/p2p/stream/protocols/sync/stream.go index 467588deaf..8b03021686 100644 --- a/p2p/stream/protocols/sync/stream.go +++ b/p2p/stream/protocols/sync/stream.go @@ -182,6 +182,12 @@ func (st *syncStream) handleReq(req *syncpb.Request) error { if bhReq := req.GetGetBlocksByHashesRequest(); bhReq != nil { return st.handleGetBlocksByHashesRequest(req.ReqId, bhReq) } + if ndReq := req.GetGetNodeDataRequest(); ndReq != nil { + return st.handleGetNodeDataRequest(req.ReqId, ndReq) + } + if rReq := req.GetGetReceiptsRequest(); rReq != nil { + return st.handleGetReceiptsRequest(req.ReqId, rReq) + } // unsupported request type return st.handleUnknownRequest(req.ReqId) } @@ -260,6 +266,48 @@ func (st *syncStream) handleGetBlocksByHashesRequest(rid uint64, req *syncpb.Get return errors.Wrap(err, "[GetBlocksByHashes]") } +func (st *syncStream) handleGetNodeDataRequest(rid uint64, req *syncpb.GetNodeDataRequest) error { + serverRequestCounterVec.With(prometheus.Labels{ + "topic": string(st.ProtoID()), + "request_type": "getNodeData", + }).Inc() + + hashes := bytesToHashes(req.NodeHashes) + resp, err := st.computeGetNodeData(rid, hashes) + if resp == nil && err != nil { + resp = syncpb.MakeErrorResponseMessage(rid, err) + } + if writeErr := st.writeMsg(resp); writeErr != nil { + if err == nil { + err = writeErr + } else { + err = fmt.Errorf("%v; [writeMsg] %v", err.Error(), writeErr) + } + } + return errors.Wrap(err, "[GetNodeData]") +} + +func (st *syncStream) handleGetReceiptsRequest(rid uint64, req *syncpb.GetReceiptsRequest) error { + serverRequestCounterVec.With(prometheus.Labels{ + "topic": string(st.ProtoID()), + "request_type": "getReceipts", + }).Inc() + + hashes := bytesToHashes(req.BlockHashes) + resp, err := st.computeGetReceipts(rid, hashes) + if resp == nil && err != nil { + resp = syncpb.MakeErrorResponseMessage(rid, err) + } + if writeErr := st.writeMsg(resp); writeErr != nil { + if err == nil { + err = writeErr + } else { + err = fmt.Errorf("%v; [writeMsg] %v", err.Error(), writeErr) + } + } + return errors.Wrap(err, "[GetReceipts]") +} + func (st *syncStream) handleUnknownRequest(rid uint64) error { serverRequestCounterVec.With(prometheus.Labels{ "topic": string(st.ProtoID()), @@ -367,6 +415,32 @@ func (st *syncStream) computeRespFromBlockHashes(rid uint64, hs []common.Hash) ( return syncpb.MakeGetBlocksByHashesResponseMessage(rid, blocksBytes, sigs), nil } +func (st *syncStream) computeGetNodeData(rid uint64, hs []common.Hash) (*syncpb.Message, error) { + if len(hs) > GetNodeDataCap { + err := fmt.Errorf("GetNodeData amount exceed cap: %v > %v", len(hs), GetNodeDataCap) + return nil, err + } + data, err := st.chain.getNodeData(hs) + if err != nil { + return nil, err + } + + return syncpb.MakeGetNodeDataResponseMessage(rid, data), nil +} + +func (st *syncStream) computeGetReceipts(rid uint64, hs []common.Hash) (*syncpb.Message, error) { + if len(hs) > GetReceiptsCap { + err := fmt.Errorf("GetReceipts amount exceed cap: %v > %v", len(hs), GetReceiptsCap) + return nil, err + } + receipts, err := st.chain.getReceipts(hs) + if err != nil { + return nil, err + } + + return syncpb.MakeGetReceiptsResponseMessage(rid, [][]byte(receipts)), nil +} + func bytesToHashes(bs [][]byte) []common.Hash { hs := make([]common.Hash, 0, len(bs)) for _, b := range bs { diff --git a/test/chain/chain/chain_makers.go b/test/chain/chain/chain_makers.go index 52c66b2692..be9096e575 100644 --- a/test/chain/chain/chain_makers.go +++ b/test/chain/chain/chain_makers.go @@ -248,7 +248,11 @@ func (cr *fakeChainReader) GetHeaderByNumber(number uint64) *block.Header func (cr *fakeChainReader) GetHeaderByHash(hash common.Hash) *block.Header { return nil } func (cr *fakeChainReader) GetHeader(hash common.Hash, number uint64) *block.Header { return nil } func (cr *fakeChainReader) GetBlock(hash common.Hash, number uint64) *types.Block { return nil } +func (cr *fakeChainReader) GetReceiptsByHash(hash common.Hash) types.Receipts { return nil } +func (cr *fakeChainReader) ContractCode(hash common.Hash) ([]byte, error) { return []byte{}, nil } +func (cr *fakeChainReader) ValidatorCode(hash common.Hash) ([]byte, error) { return []byte{}, nil } func (cr *fakeChainReader) ReadShardState(epoch *big.Int) (*shard.State, error) { return nil, nil } +func (cr *fakeChainReader) TrieNode(hash common.Hash) ([]byte, error) { return []byte{}, nil } func (cr *fakeChainReader) ReadValidatorList() ([]common.Address, error) { return nil, nil } func (cr *fakeChainReader) ValidatorCandidates() []common.Address { return nil } func (cr *fakeChainReader) SuperCommitteeForNextEpoch( From aa58cff0121167e9f9ce8f82a22b732f1261f9c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CGheisMohammadi=E2=80=9D?= <36589218+GheisMohammadi@users.noreply.github.com> Date: Sun, 18 Jun 2023 13:25:48 +0800 Subject: [PATCH 02/13] goimports --- p2p/stream/protocols/sync/chain.go | 2 +- p2p/stream/protocols/sync/client.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/p2p/stream/protocols/sync/chain.go b/p2p/stream/protocols/sync/chain.go index 630f328fee..3337c8b0a3 100644 --- a/p2p/stream/protocols/sync/chain.go +++ b/p2p/stream/protocols/sync/chain.go @@ -191,4 +191,4 @@ func (ch *chainHelperImpl) getReceipts(hs []common.Hash) ([][]byte, error) { } } return receipts, nil -} \ No newline at end of file +} diff --git a/p2p/stream/protocols/sync/client.go b/p2p/stream/protocols/sync/client.go index 2a9c5ed9ca..85730ada67 100644 --- a/p2p/stream/protocols/sync/client.go +++ b/p2p/stream/protocols/sync/client.go @@ -542,4 +542,4 @@ func (req *getReceiptsRequest) parseGetReceiptsBytes(resp *syncResponse) ([][]by return nil, errors.New("The response is not for GetReceipts") } return gbResp.ReceiptsBytes, nil -} \ No newline at end of file +} From ba6e516072b0a7a51d3865cc80ccfe99c060d87a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CGheisMohammadi=E2=80=9D?= <36589218+GheisMohammadi@users.noreply.github.com> Date: Mon, 19 Jun 2023 11:38:03 +0800 Subject: [PATCH 03/13] fix the issue of go generate changed working tree contents --- p2p/stream/protocols/sync/message/msg.pb.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/p2p/stream/protocols/sync/message/msg.pb.go b/p2p/stream/protocols/sync/message/msg.pb.go index 154deac2f3..c0cde1d98a 100644 --- a/p2p/stream/protocols/sync/message/msg.pb.go +++ b/p2p/stream/protocols/sync/message/msg.pb.go @@ -7,11 +7,10 @@ package message import ( - reflect "reflect" - sync "sync" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" ) const ( From 7f131d84ceffa7c10931c2227f7b97c984c024cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CGheisMohammadi=E2=80=9D?= <36589218+GheisMohammadi@users.noreply.github.com> Date: Thu, 22 Jun 2023 03:42:14 +0800 Subject: [PATCH 04/13] add tests for client new functionalities and fix the receipt and node data functions in protocol --- p2p/stream/protocols/sync/client.go | 111 +++++++++++------- p2p/stream/protocols/sync/client_test.go | 142 ++++++++++++++++++++++- 2 files changed, 205 insertions(+), 48 deletions(-) diff --git a/p2p/stream/protocols/sync/client.go b/p2p/stream/protocols/sync/client.go index 85730ada67..fc204fd555 100644 --- a/p2p/stream/protocols/sync/client.go +++ b/p2p/stream/protocols/sync/client.go @@ -15,34 +15,6 @@ import ( "github.com/pkg/errors" ) -// FetchNodeData do fetch node data through sync stream protocol. -// Return the state node data as result, and error -func (p *Protocol) FetchNodeData(ctx context.Context, hashes []common.Hash, opts ...Option) (data [][]byte, stid sttypes.StreamID, err error) { - timer := p.doMetricClientRequest("fetchNodeData") - defer p.doMetricPostClientRequest("fetchNodeData", err, timer) - - if len(hashes) == 0 { - err = fmt.Errorf("zero hashes array requested") - return - } - if len(hashes) > GetNodeDataCap { - err = fmt.Errorf("number of node data hashes cap of %v", GetNodeDataCap) - return - } - - req := newGetNodeDataRequest(hashes) - resp, stid, err := p.rm.DoRequest(ctx, req, opts...) - if err != nil { - // At this point, error can be context canceled, context timed out, or waiting queue - // is already full. - return - } - - // Parse and return blocks - data, err = req.getNodeDataResponse(resp) - return -} - // GetBlocksByNumber do getBlocksByNumberRequest through sync stream protocol. // Return the block as result, target stream id, and error func (p *Protocol) GetBlocksByNumber(ctx context.Context, bns []uint64, opts ...Option) (blocks []*types.Block, stid sttypes.StreamID, err error) { @@ -163,6 +135,51 @@ func (p *Protocol) GetBlocksByHashes(ctx context.Context, hs []common.Hash, opts return } +// GetReceipts do getBlocksByHashesRequest through sync stream protocol. +func (p *Protocol) GetReceipts(ctx context.Context, hs []common.Hash, opts ...Option) (receipts []*types.Receipt, stid sttypes.StreamID, err error) { + timer := p.doMetricClientRequest("getReceipts") + defer p.doMetricPostClientRequest("getReceipts", err, timer) + + if len(hs) == 0 { + err = fmt.Errorf("zero receipt hashes requested") + return + } + if len(hs) > GetReceiptsCap { + err = fmt.Errorf("number of requested hashes exceed limit") + return + } + req := newGetReceiptsRequest(hs) + resp, stid, err := p.rm.DoRequest(ctx, req, opts...) + if err != nil { + return + } + receipts, err = req.getReceiptsFromResponse(resp) + return +} + +// GetNodeData do getNodeData through sync stream protocol. +// Return the state node data as result, and error +func (p *Protocol) GetNodeData(ctx context.Context, hs []common.Hash, opts ...Option) (data [][]byte, stid sttypes.StreamID, err error) { + timer := p.doMetricClientRequest("getNodeData") + defer p.doMetricPostClientRequest("getNodeData", err, timer) + + if len(hs) == 0 { + err = fmt.Errorf("zero node data hashes requested") + return + } + if len(hs) > GetNodeDataCap { + err = fmt.Errorf("number of requested hashes exceed limit") + return + } + req := newGetNodeDataRequest(hs) + resp, stid, err := p.rm.DoRequest(ctx, req, opts...) + if err != nil { + return + } + data, err = req.getNodeDataFromResponse(resp) + return +} + // getBlocksByNumberRequest is the request for get block by numbers which implements // sttypes.Request interface type getBlocksByNumberRequest struct { @@ -457,10 +474,10 @@ func (req *getNodeDataRequest) Encode() ([]byte, error) { return protobuf.Marshal(msg) } -func (req *getNodeDataRequest) getNodeDataResponse(resp sttypes.Response) ([][]byte, error) { +func (req *getNodeDataRequest) getNodeDataFromResponse(resp sttypes.Response) ([][]byte, error) { sResp, ok := resp.(*syncResponse) if !ok || sResp == nil { - return nil, errors.New("not sync response for node data") + return nil, errors.New("not sync response") } dataBytes, err := req.parseNodeDataBytes(sResp) if err != nil { @@ -473,11 +490,11 @@ func (req *getNodeDataRequest) parseNodeDataBytes(resp *syncResponse) ([][]byte, if errResp := resp.pb.GetErrorResponse(); errResp != nil { return nil, errors.New(errResp.Error) } - gbResp := resp.pb.GetGetNodeDataResponse() - if gbResp == nil { - return nil, errors.New("The response is not for GetNodeData") + ndResp := resp.pb.GetGetNodeDataResponse() + if ndResp == nil { + return nil, errors.New("response not GetNodeData") } - return gbResp.DataBytes, nil + return ndResp.DataBytes, nil } // getReceiptsRequest is the request for get receipts which implements @@ -521,25 +538,33 @@ func (req *getReceiptsRequest) Encode() ([]byte, error) { return protobuf.Marshal(msg) } -func (req *getReceiptsRequest) getReceiptsResponse(resp sttypes.Response) ([][]byte, error) { +func (req *getReceiptsRequest) getReceiptsFromResponse(resp sttypes.Response) ([]*types.Receipt, error) { sResp, ok := resp.(*syncResponse) if !ok || sResp == nil { - return nil, errors.New("not sync response for receipts") + return nil, errors.New("not sync response") } - receiptsBytes, err := req.parseGetReceiptsBytes(sResp) + receipts, err := req.parseGetReceiptsBytes(sResp) if err != nil { return nil, err } - return receiptsBytes, nil + return receipts, nil } -func (req *getReceiptsRequest) parseGetReceiptsBytes(resp *syncResponse) ([][]byte, error) { +func (req *getReceiptsRequest) parseGetReceiptsBytes(resp *syncResponse) ([]*types.Receipt, error) { if errResp := resp.pb.GetErrorResponse(); errResp != nil { return nil, errors.New(errResp.Error) } - gbResp := resp.pb.GetGetReceiptsResponse() - if gbResp == nil { - return nil, errors.New("The response is not for GetReceipts") + grResp := resp.pb.GetGetReceiptsResponse() + if grResp == nil { + return nil, errors.New("response not GetReceipts") + } + receipts := make([]*types.Receipt, 0, len(grResp.ReceiptsBytes)) + for _, rcptBytes := range grResp.ReceiptsBytes { + var receipt *types.Receipt + if err := rlp.DecodeBytes(rcptBytes, &receipt); err != nil { + return nil, errors.Wrap(err, "[GetReceiptsResponse]") + } + receipts = append(receipts, receipt) } - return gbResp.ReceiptsBytes, nil + return receipts, nil } diff --git a/p2p/stream/protocols/sync/client_test.go b/p2p/stream/protocols/sync/client_test.go index 3509915ce8..9a675fa0d4 100644 --- a/p2p/stream/protocols/sync/client_test.go +++ b/p2p/stream/protocols/sync/client_test.go @@ -22,6 +22,7 @@ import ( var ( _ sttypes.Request = &getBlocksByNumberRequest{} _ sttypes.Request = &getBlockNumberRequest{} + _ sttypes.Request = &getReceiptsRequest{} _ sttypes.Response = &syncResponse{&syncpb.Response{}} ) @@ -35,11 +36,20 @@ var ( ) var ( - testHeader = &block.Header{Header: headerV3.NewHeader()} - testBlock = types.NewBlockWithHeader(testHeader) - testHeaderBytes, _ = rlp.EncodeToBytes(testHeader) - testBlockBytes, _ = rlp.EncodeToBytes(testBlock) - testBlockResponse = syncpb.MakeGetBlocksByNumResponse(0, [][]byte{testBlockBytes}, make([][]byte, 1)) + testHeader = &block.Header{Header: headerV3.NewHeader()} + testBlock = types.NewBlockWithHeader(testHeader) + testReceipt = &types.Receipt{ + Status: types.ReceiptStatusSuccessful, + CumulativeGasUsed: 0x888888888, + Logs: []*types.Log{}, + } + testNodeData = numberToHash(123456789).Bytes() + testHeaderBytes, _ = rlp.EncodeToBytes(testHeader) + testBlockBytes, _ = rlp.EncodeToBytes(testBlock) + testReceiptBytes, _ = rlp.EncodeToBytes(testReceipt) + testNodeDataBytes, _ = rlp.EncodeToBytes(testNodeData) + + testBlockResponse = syncpb.MakeGetBlocksByNumResponse(0, [][]byte{testBlockBytes}, make([][]byte, 1)) testCurBlockNumber uint64 = 100 testBlockNumberResponse = syncpb.MakeGetBlockNumberResponse(0, testCurBlockNumber) @@ -49,6 +59,10 @@ var ( testBlocksByHashesResponse = syncpb.MakeGetBlocksByHashesResponse(0, [][]byte{testBlockBytes}, make([][]byte, 1)) + testReceiptResponse = syncpb.MakeGetReceiptsResponse(0, [][]byte{testReceiptBytes}) + + testNodeDataResponse = syncpb.MakeGetNodeDataResponse(0, [][]byte{testNodeDataBytes}) + testErrorResponse = syncpb.MakeErrorResponse(0, errors.New("test error")) ) @@ -289,6 +303,124 @@ func TestProtocol_GetBlocksByHashes(t *testing.T) { } } +func TestProtocol_GetReceipts(t *testing.T) { + tests := []struct { + getResponse getResponseFn + expErr error + expStID sttypes.StreamID + }{ + { + getResponse: func(request sttypes.Request) (sttypes.Response, sttypes.StreamID) { + return &syncResponse{ + pb: testReceiptResponse, + }, makeTestStreamID(0) + }, + expErr: nil, + expStID: makeTestStreamID(0), + }, + { + getResponse: func(request sttypes.Request) (sttypes.Response, sttypes.StreamID) { + return &syncResponse{ + pb: testBlockResponse, + }, makeTestStreamID(0) + }, + expErr: errors.New("response not GetReceipts"), + expStID: makeTestStreamID(0), + }, + { + getResponse: nil, + expErr: errors.New("get response error"), + expStID: "", + }, + { + getResponse: func(request sttypes.Request) (sttypes.Response, sttypes.StreamID) { + return &syncResponse{ + pb: testErrorResponse, + }, makeTestStreamID(0) + }, + expErr: errors.New("test error"), + expStID: makeTestStreamID(0), + }, + } + + for i, test := range tests { + protocol := makeTestProtocol(test.getResponse) + receipts, stid, err := protocol.GetReceipts(context.Background(), []common.Hash{numberToHash(100)}) + + if assErr := assertError(err, test.expErr); assErr != nil { + t.Errorf("Test %v: %v", i, assErr) + continue + } + if stid != test.expStID { + t.Errorf("Test %v: unexpected st id: %v / %v", i, stid, test.expStID) + } + if test.expErr == nil { + if len(receipts) != 1 { + t.Errorf("Test %v: size not 1", i) + } + } + } +} + +func TestProtocol_GetNodeData(t *testing.T) { + tests := []struct { + getResponse getResponseFn + expErr error + expStID sttypes.StreamID + }{ + { + getResponse: func(request sttypes.Request) (sttypes.Response, sttypes.StreamID) { + return &syncResponse{ + pb: testNodeDataResponse, + }, makeTestStreamID(0) + }, + expErr: nil, + expStID: makeTestStreamID(0), + }, + { + getResponse: func(request sttypes.Request) (sttypes.Response, sttypes.StreamID) { + return &syncResponse{ + pb: testBlockResponse, + }, makeTestStreamID(0) + }, + expErr: errors.New("response not GetNodeData"), + expStID: makeTestStreamID(0), + }, + { + getResponse: nil, + expErr: errors.New("get response error"), + expStID: "", + }, + { + getResponse: func(request sttypes.Request) (sttypes.Response, sttypes.StreamID) { + return &syncResponse{ + pb: testErrorResponse, + }, makeTestStreamID(0) + }, + expErr: errors.New("test error"), + expStID: makeTestStreamID(0), + }, + } + + for i, test := range tests { + protocol := makeTestProtocol(test.getResponse) + receipts, stid, err := protocol.GetNodeData(context.Background(), []common.Hash{numberToHash(100)}) + + if assErr := assertError(err, test.expErr); assErr != nil { + t.Errorf("Test %v: %v", i, assErr) + continue + } + if stid != test.expStID { + t.Errorf("Test %v: unexpected st id: %v / %v", i, stid, test.expStID) + } + if test.expErr == nil { + if len(receipts) != 1 { + t.Errorf("Test %v: size not 1", i) + } + } + } +} + type getResponseFn func(request sttypes.Request) (sttypes.Response, sttypes.StreamID) type testHostRequestManager struct { From 656237ec934468ecdba59c452308d1f365bc93d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CGheisMohammadi=E2=80=9D?= <36589218+GheisMohammadi@users.noreply.github.com> Date: Thu, 22 Jun 2023 03:48:16 +0800 Subject: [PATCH 05/13] fix client comments --- p2p/stream/protocols/sync/client.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/p2p/stream/protocols/sync/client.go b/p2p/stream/protocols/sync/client.go index fc204fd555..62fff721e1 100644 --- a/p2p/stream/protocols/sync/client.go +++ b/p2p/stream/protocols/sync/client.go @@ -135,7 +135,8 @@ func (p *Protocol) GetBlocksByHashes(ctx context.Context, hs []common.Hash, opts return } -// GetReceipts do getBlocksByHashesRequest through sync stream protocol. +// GetReceipts do getReceiptsRequest through sync stream protocol. +// Return the receipts as result, target stream id, and error func (p *Protocol) GetReceipts(ctx context.Context, hs []common.Hash, opts ...Option) (receipts []*types.Receipt, stid sttypes.StreamID, err error) { timer := p.doMetricClientRequest("getReceipts") defer p.doMetricPostClientRequest("getReceipts", err, timer) @@ -158,7 +159,7 @@ func (p *Protocol) GetReceipts(ctx context.Context, hs []common.Hash, opts ...Op } // GetNodeData do getNodeData through sync stream protocol. -// Return the state node data as result, and error +// Return the state node data as result, target stream id, and error func (p *Protocol) GetNodeData(ctx context.Context, hs []common.Hash, opts ...Option) (data [][]byte, stid sttypes.StreamID, err error) { timer := p.doMetricClientRequest("getNodeData") defer p.doMetricPostClientRequest("getNodeData", err, timer) From 9d3244612f67b7f574c92be7100240aab863aeb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CGheisMohammadi=E2=80=9D?= <36589218+GheisMohammadi@users.noreply.github.com> Date: Fri, 23 Jun 2023 16:17:59 +0800 Subject: [PATCH 06/13] add new client functions to adapter as well --- api/service/stagedstreamsync/adapter.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/api/service/stagedstreamsync/adapter.go b/api/service/stagedstreamsync/adapter.go index ae7632889c..108f23fce0 100644 --- a/api/service/stagedstreamsync/adapter.go +++ b/api/service/stagedstreamsync/adapter.go @@ -18,6 +18,8 @@ type syncProtocol interface { GetRawBlocksByNumber(ctx context.Context, bns []uint64, opts ...syncproto.Option) ([][]byte, [][]byte, sttypes.StreamID, error) GetBlockHashes(ctx context.Context, bns []uint64, opts ...syncproto.Option) ([]common.Hash, sttypes.StreamID, error) GetBlocksByHashes(ctx context.Context, hs []common.Hash, opts ...syncproto.Option) ([]*types.Block, sttypes.StreamID, error) + GetReceipts(ctx context.Context, hs []common.Hash, opts ...syncproto.Option) (receipts []*types.Receipt, stid sttypes.StreamID, err error) + GetNodeData(ctx context.Context, hs []common.Hash, opts ...syncproto.Option) (data [][]byte, stid sttypes.StreamID, err error) RemoveStream(stID sttypes.StreamID) // If a stream delivers invalid data, remove the stream StreamFailed(stID sttypes.StreamID, reason string) From a4d6ffc0e0aada1b80b5326cce8eed2526cb803c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CGheisMohammadi=E2=80=9D?= <36589218+GheisMohammadi@users.noreply.github.com> Date: Thu, 6 Jul 2023 01:33:51 +0800 Subject: [PATCH 07/13] refactor client GetReceipts to be able to fetch array of multiple receipts --- api/service/stagedstreamsync/adapter.go | 2 +- p2p/stream/protocols/sync/chain.go | 22 +--- p2p/stream/protocols/sync/client.go | 20 ++-- p2p/stream/protocols/sync/message/compose.go | 8 +- p2p/stream/protocols/sync/message/msg.pb.go | 118 +++++++++++++++---- p2p/stream/protocols/sync/message/msg.proto | 8 +- p2p/stream/protocols/sync/stream.go | 16 ++- 7 files changed, 138 insertions(+), 56 deletions(-) diff --git a/api/service/stagedstreamsync/adapter.go b/api/service/stagedstreamsync/adapter.go index 108f23fce0..ca9c6a6787 100644 --- a/api/service/stagedstreamsync/adapter.go +++ b/api/service/stagedstreamsync/adapter.go @@ -18,7 +18,7 @@ type syncProtocol interface { GetRawBlocksByNumber(ctx context.Context, bns []uint64, opts ...syncproto.Option) ([][]byte, [][]byte, sttypes.StreamID, error) GetBlockHashes(ctx context.Context, bns []uint64, opts ...syncproto.Option) ([]common.Hash, sttypes.StreamID, error) GetBlocksByHashes(ctx context.Context, hs []common.Hash, opts ...syncproto.Option) ([]*types.Block, sttypes.StreamID, error) - GetReceipts(ctx context.Context, hs []common.Hash, opts ...syncproto.Option) (receipts []*types.Receipt, stid sttypes.StreamID, err error) + GetReceipts(ctx context.Context, hs []common.Hash, opts ...syncproto.Option) (receipts []types.Receipts, stid sttypes.StreamID, err error) GetNodeData(ctx context.Context, hs []common.Hash, opts ...syncproto.Option) (data [][]byte, stid sttypes.StreamID, err error) RemoveStream(stID sttypes.StreamID) // If a stream delivers invalid data, remove the stream diff --git a/p2p/stream/protocols/sync/chain.go b/p2p/stream/protocols/sync/chain.go index 3337c8b0a3..14e3be5f8e 100644 --- a/p2p/stream/protocols/sync/chain.go +++ b/p2p/stream/protocols/sync/chain.go @@ -2,12 +2,10 @@ package sync import ( "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/rlp" "github.com/harmony-one/harmony/block" "github.com/harmony-one/harmony/consensus/engine" "github.com/harmony-one/harmony/core/types" shardingconfig "github.com/harmony-one/harmony/internal/configs/sharding" - "github.com/harmony-one/harmony/internal/utils" "github.com/harmony-one/harmony/internal/utils/keylocker" "github.com/pkg/errors" ) @@ -19,7 +17,7 @@ type chainHelper interface { getBlocksByNumber(bns []uint64) ([]*types.Block, error) getBlocksByHashes(hs []common.Hash) ([]*types.Block, error) getNodeData(hs []common.Hash) ([][]byte, error) - getReceipts(hs []common.Hash) ([][]byte, error) + getReceipts(hs []common.Hash) ([]types.Receipts, error) } type chainHelperImpl struct { @@ -169,12 +167,10 @@ func (ch *chainHelperImpl) getNodeData(hs []common.Hash) ([][]byte, error) { } // getReceipts assembles the response to a receipt query. -func (ch *chainHelperImpl) getReceipts(hs []common.Hash) ([][]byte, error) { - var ( - bytes int - receipts [][]byte - ) - for _, hash := range hs { +func (ch *chainHelperImpl) getReceipts(hs []common.Hash) ([]types.Receipts, error) { + var receipts []types.Receipts + + for i, hash := range hs { // Retrieve the requested block's receipts results := ch.chain.GetReceiptsByHash(hash) if results == nil { @@ -182,13 +178,7 @@ func (ch *chainHelperImpl) getReceipts(hs []common.Hash) ([][]byte, error) { continue } } - // If known, encode and queue for response packet - if encoded, err := rlp.EncodeToBytes(results); err != nil { - utils.Logger().Err(err).Msg("Failed to encode receipt") - } else { - receipts = append(receipts, encoded) - bytes += len(encoded) - } + receipts[i] = append(receipts[i], results...) } return receipts, nil } diff --git a/p2p/stream/protocols/sync/client.go b/p2p/stream/protocols/sync/client.go index 62fff721e1..0b8a2a2fd9 100644 --- a/p2p/stream/protocols/sync/client.go +++ b/p2p/stream/protocols/sync/client.go @@ -137,7 +137,7 @@ func (p *Protocol) GetBlocksByHashes(ctx context.Context, hs []common.Hash, opts // GetReceipts do getReceiptsRequest through sync stream protocol. // Return the receipts as result, target stream id, and error -func (p *Protocol) GetReceipts(ctx context.Context, hs []common.Hash, opts ...Option) (receipts []*types.Receipt, stid sttypes.StreamID, err error) { +func (p *Protocol) GetReceipts(ctx context.Context, hs []common.Hash, opts ...Option) (receipts []types.Receipts, stid sttypes.StreamID, err error) { timer := p.doMetricClientRequest("getReceipts") defer p.doMetricPostClientRequest("getReceipts", err, timer) @@ -539,7 +539,7 @@ func (req *getReceiptsRequest) Encode() ([]byte, error) { return protobuf.Marshal(msg) } -func (req *getReceiptsRequest) getReceiptsFromResponse(resp sttypes.Response) ([]*types.Receipt, error) { +func (req *getReceiptsRequest) getReceiptsFromResponse(resp sttypes.Response) ([]types.Receipts, error) { sResp, ok := resp.(*syncResponse) if !ok || sResp == nil { return nil, errors.New("not sync response") @@ -551,7 +551,7 @@ func (req *getReceiptsRequest) getReceiptsFromResponse(resp sttypes.Response) ([ return receipts, nil } -func (req *getReceiptsRequest) parseGetReceiptsBytes(resp *syncResponse) ([]*types.Receipt, error) { +func (req *getReceiptsRequest) parseGetReceiptsBytes(resp *syncResponse) ([]types.Receipts, error) { if errResp := resp.pb.GetErrorResponse(); errResp != nil { return nil, errors.New(errResp.Error) } @@ -559,13 +559,15 @@ func (req *getReceiptsRequest) parseGetReceiptsBytes(resp *syncResponse) ([]*typ if grResp == nil { return nil, errors.New("response not GetReceipts") } - receipts := make([]*types.Receipt, 0, len(grResp.ReceiptsBytes)) - for _, rcptBytes := range grResp.ReceiptsBytes { - var receipt *types.Receipt - if err := rlp.DecodeBytes(rcptBytes, &receipt); err != nil { - return nil, errors.Wrap(err, "[GetReceiptsResponse]") + receipts := make([]types.Receipts, len(grResp.Receipts)) + for i, blockReceipts := range grResp.Receipts { + for _, rcptBytes := range blockReceipts.ReceiptBytes { + var receipt *types.Receipt + if err := rlp.DecodeBytes(rcptBytes, &receipt); err != nil { + return nil, errors.Wrap(err, "[GetReceiptsResponse]") + } + receipts[i] = append(receipts[i], receipt) } - receipts = append(receipts, receipt) } return receipts, nil } diff --git a/p2p/stream/protocols/sync/message/compose.go b/p2p/stream/protocols/sync/message/compose.go index 8cc9895383..2c0c367098 100644 --- a/p2p/stream/protocols/sync/message/compose.go +++ b/p2p/stream/protocols/sync/message/compose.go @@ -179,18 +179,18 @@ func MakeGetNodeDataResponse(rid uint64, nodeData [][]byte) *Response { } // MakeGetReceiptsResponseMessage makes the GetReceiptsResponse of Message type -func MakeGetReceiptsResponseMessage(rid uint64, receiptsBytes [][]byte) *Message { - resp := MakeGetReceiptsResponse(rid, receiptsBytes) +func MakeGetReceiptsResponseMessage(rid uint64, receipts map[uint64]*Receipts) *Message { + resp := MakeGetReceiptsResponse(rid, receipts) return makeMessageFromResponse(resp) } // MakeGetReceiptsResponse make the GetReceiptsResponse of Response type -func MakeGetReceiptsResponse(rid uint64, receiptsBytes [][]byte) *Response { +func MakeGetReceiptsResponse(rid uint64, receipts map[uint64]*Receipts) *Response { return &Response{ ReqId: rid, Response: &Response_GetReceiptsResponse{ GetReceiptsResponse: &GetReceiptsResponse{ - ReceiptsBytes: receiptsBytes, + Receipts: receipts, }, }, } diff --git a/p2p/stream/protocols/sync/message/msg.pb.go b/p2p/stream/protocols/sync/message/msg.pb.go index c0cde1d98a..be7a95995f 100644 --- a/p2p/stream/protocols/sync/message/msg.pb.go +++ b/p2p/stream/protocols/sync/message/msg.pb.go @@ -976,18 +976,65 @@ func (x *GetNodeDataResponse) GetDataBytes() [][]byte { return nil } +type Receipts struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ReceiptBytes [][]byte `protobuf:"bytes,1,rep,name=receipt_bytes,json=receiptBytes,proto3" json:"receipt_bytes,omitempty"` +} + +func (x *Receipts) Reset() { + *x = Receipts{} + if protoimpl.UnsafeEnabled { + mi := &file_msg_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Receipts) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Receipts) ProtoMessage() {} + +func (x *Receipts) ProtoReflect() protoreflect.Message { + mi := &file_msg_proto_msgTypes[15] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Receipts.ProtoReflect.Descriptor instead. +func (*Receipts) Descriptor() ([]byte, []int) { + return file_msg_proto_rawDescGZIP(), []int{15} +} + +func (x *Receipts) GetReceiptBytes() [][]byte { + if x != nil { + return x.ReceiptBytes + } + return nil +} + type GetReceiptsResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - ReceiptsBytes [][]byte `protobuf:"bytes,1,rep,name=receipts_bytes,json=receiptsBytes,proto3" json:"receipts_bytes,omitempty"` + Receipts map[uint64]*Receipts `protobuf:"bytes,1,rep,name=receipts,proto3" json:"receipts,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` } func (x *GetReceiptsResponse) Reset() { *x = GetReceiptsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_msg_proto_msgTypes[15] + mi := &file_msg_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1000,7 +1047,7 @@ func (x *GetReceiptsResponse) String() string { func (*GetReceiptsResponse) ProtoMessage() {} func (x *GetReceiptsResponse) ProtoReflect() protoreflect.Message { - mi := &file_msg_proto_msgTypes[15] + mi := &file_msg_proto_msgTypes[16] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1013,12 +1060,12 @@ func (x *GetReceiptsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetReceiptsResponse.ProtoReflect.Descriptor instead. func (*GetReceiptsResponse) Descriptor() ([]byte, []int) { - return file_msg_proto_rawDescGZIP(), []int{15} + return file_msg_proto_rawDescGZIP(), []int{16} } -func (x *GetReceiptsResponse) GetReceiptsBytes() [][]byte { +func (x *GetReceiptsResponse) GetReceipts() map[uint64]*Receipts { if x != nil { - return x.ReceiptsBytes + return x.Receipts } return nil } @@ -1174,12 +1221,25 @@ var file_msg_proto_rawDesc = []byte{ 0x53, 0x69, 0x67, 0x22, 0x34, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x44, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x09, - 0x64, 0x61, 0x74, 0x61, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0x3c, 0x0a, 0x13, 0x47, 0x65, 0x74, - 0x52, 0x65, 0x63, 0x65, 0x69, 0x70, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x25, 0x0a, 0x0e, 0x72, 0x65, 0x63, 0x65, 0x69, 0x70, 0x74, 0x73, 0x5f, 0x62, 0x79, 0x74, - 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0d, 0x72, 0x65, 0x63, 0x65, 0x69, 0x70, - 0x74, 0x73, 0x42, 0x79, 0x74, 0x65, 0x73, 0x42, 0x0c, 0x5a, 0x0a, 0x2e, 0x2f, 0x3b, 0x6d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x64, 0x61, 0x74, 0x61, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0x2f, 0x0a, 0x08, 0x52, 0x65, 0x63, + 0x65, 0x69, 0x70, 0x74, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x63, 0x65, 0x69, 0x70, 0x74, + 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0c, 0x72, 0x65, + 0x63, 0x65, 0x69, 0x70, 0x74, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0xd5, 0x01, 0x0a, 0x13, 0x47, + 0x65, 0x74, 0x52, 0x65, 0x63, 0x65, 0x69, 0x70, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x5a, 0x0a, 0x08, 0x72, 0x65, 0x63, 0x65, 0x69, 0x70, 0x74, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3e, 0x2e, 0x68, 0x61, 0x72, 0x6d, 0x6f, 0x6e, 0x79, 0x2e, 0x73, + 0x74, 0x72, 0x65, 0x61, 0x6d, 0x2e, 0x73, 0x79, 0x6e, 0x63, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x63, 0x65, 0x69, 0x70, 0x74, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x63, 0x65, 0x69, 0x70, 0x74, 0x73, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x72, 0x65, 0x63, 0x65, 0x69, 0x70, 0x74, 0x73, 0x1a, 0x62, + 0x0a, 0x0d, 0x52, 0x65, 0x63, 0x65, 0x69, 0x70, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, + 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x03, 0x6b, 0x65, + 0x79, 0x12, 0x3b, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x25, 0x2e, 0x68, 0x61, 0x72, 0x6d, 0x6f, 0x6e, 0x79, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x2e, 0x73, 0x79, 0x6e, 0x63, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x52, + 0x65, 0x63, 0x65, 0x69, 0x70, 0x74, 0x73, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, + 0x38, 0x01, 0x42, 0x0c, 0x5a, 0x0a, 0x2e, 0x2f, 0x3b, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1194,7 +1254,7 @@ func file_msg_proto_rawDescGZIP() []byte { return file_msg_proto_rawDescData } -var file_msg_proto_msgTypes = make([]protoimpl.MessageInfo, 16) +var file_msg_proto_msgTypes = make([]protoimpl.MessageInfo, 18) var file_msg_proto_goTypes = []interface{}{ (*Message)(nil), // 0: harmony.stream.sync.message.Message (*Request)(nil), // 1: harmony.stream.sync.message.Request @@ -1211,7 +1271,9 @@ var file_msg_proto_goTypes = []interface{}{ (*GetBlocksByNumResponse)(nil), // 12: harmony.stream.sync.message.GetBlocksByNumResponse (*GetBlocksByHashesResponse)(nil), // 13: harmony.stream.sync.message.GetBlocksByHashesResponse (*GetNodeDataResponse)(nil), // 14: harmony.stream.sync.message.GetNodeDataResponse - (*GetReceiptsResponse)(nil), // 15: harmony.stream.sync.message.GetReceiptsResponse + (*Receipts)(nil), // 15: harmony.stream.sync.message.Receipts + (*GetReceiptsResponse)(nil), // 16: harmony.stream.sync.message.GetReceiptsResponse + nil, // 17: harmony.stream.sync.message.GetReceiptsResponse.ReceiptsEntry } var file_msg_proto_depIdxs = []int32{ 1, // 0: harmony.stream.sync.message.Message.req:type_name -> harmony.stream.sync.message.Request @@ -1228,12 +1290,14 @@ var file_msg_proto_depIdxs = []int32{ 12, // 11: harmony.stream.sync.message.Response.get_blocks_by_num_response:type_name -> harmony.stream.sync.message.GetBlocksByNumResponse 13, // 12: harmony.stream.sync.message.Response.get_blocks_by_hashes_response:type_name -> harmony.stream.sync.message.GetBlocksByHashesResponse 14, // 13: harmony.stream.sync.message.Response.get_node_data_response:type_name -> harmony.stream.sync.message.GetNodeDataResponse - 15, // 14: harmony.stream.sync.message.Response.get_receipts_response:type_name -> harmony.stream.sync.message.GetReceiptsResponse - 15, // [15:15] is the sub-list for method output_type - 15, // [15:15] is the sub-list for method input_type - 15, // [15:15] is the sub-list for extension type_name - 15, // [15:15] is the sub-list for extension extendee - 0, // [0:15] is the sub-list for field type_name + 16, // 14: harmony.stream.sync.message.Response.get_receipts_response:type_name -> harmony.stream.sync.message.GetReceiptsResponse + 17, // 15: harmony.stream.sync.message.GetReceiptsResponse.receipts:type_name -> harmony.stream.sync.message.GetReceiptsResponse.ReceiptsEntry + 15, // 16: harmony.stream.sync.message.GetReceiptsResponse.ReceiptsEntry.value:type_name -> harmony.stream.sync.message.Receipts + 17, // [17:17] is the sub-list for method output_type + 17, // [17:17] is the sub-list for method input_type + 17, // [17:17] is the sub-list for extension type_name + 17, // [17:17] is the sub-list for extension extendee + 0, // [0:17] is the sub-list for field type_name } func init() { file_msg_proto_init() } @@ -1423,6 +1487,18 @@ func file_msg_proto_init() { } } file_msg_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Receipts); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_msg_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetReceiptsResponse); i { case 0: return &v.state @@ -1462,7 +1538,7 @@ func file_msg_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_msg_proto_rawDesc, NumEnums: 0, - NumMessages: 16, + NumMessages: 18, NumExtensions: 0, NumServices: 0, }, diff --git a/p2p/stream/protocols/sync/message/msg.proto b/p2p/stream/protocols/sync/message/msg.proto index 420d21d859..f48341868f 100644 --- a/p2p/stream/protocols/sync/message/msg.proto +++ b/p2p/stream/protocols/sync/message/msg.proto @@ -83,8 +83,10 @@ message GetNodeDataResponse { repeated bytes data_bytes = 1; } -message GetReceiptsResponse { - repeated bytes receipts_bytes = 1; +message Receipts { + repeated bytes receipt_bytes = 1; } - +message GetReceiptsResponse { + map receipts = 1; +} diff --git a/p2p/stream/protocols/sync/stream.go b/p2p/stream/protocols/sync/stream.go index 8b03021686..56419767f0 100644 --- a/p2p/stream/protocols/sync/stream.go +++ b/p2p/stream/protocols/sync/stream.go @@ -437,8 +437,20 @@ func (st *syncStream) computeGetReceipts(rid uint64, hs []common.Hash) (*syncpb. if err != nil { return nil, err } - - return syncpb.MakeGetReceiptsResponseMessage(rid, [][]byte(receipts)), nil + var normalizedReceipts = make(map[uint64]*syncpb.Receipts, len(receipts)) + for i, blkReceipts := range receipts { + normalizedReceipts[uint64(i)] = &syncpb.Receipts{ + ReceiptBytes: make([][]byte, 0), + } + for _, receipt := range blkReceipts { + receiptBytes, err := rlp.EncodeToBytes(receipt) + if err != nil { + return nil, err + } + normalizedReceipts[uint64(i)].ReceiptBytes = append(normalizedReceipts[uint64(i)].ReceiptBytes, receiptBytes) + } + } + return syncpb.MakeGetReceiptsResponseMessage(rid, normalizedReceipts), nil } func bytesToHashes(bs [][]byte) []common.Hash { From 985332e558e268981ba27cc7c536f513934cafc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CGheisMohammadi=E2=80=9D?= <36589218+GheisMohammadi@users.noreply.github.com> Date: Thu, 6 Jul 2023 01:34:28 +0800 Subject: [PATCH 08/13] fix client tests for GetReceipts --- p2p/stream/protocols/sync/chain_test.go | 17 ++++++----------- p2p/stream/protocols/sync/client_test.go | 9 ++++++++- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/p2p/stream/protocols/sync/chain_test.go b/p2p/stream/protocols/sync/chain_test.go index b3d3f463fc..8883d7cb5d 100644 --- a/p2p/stream/protocols/sync/chain_test.go +++ b/p2p/stream/protocols/sync/chain_test.go @@ -51,12 +51,11 @@ func (tch *testChainHelper) getNodeData(hs []common.Hash) ([][]byte, error) { return data, nil } -func (tch *testChainHelper) getReceipts(hs []common.Hash) ([][]byte, error) { +func (tch *testChainHelper) getReceipts(hs []common.Hash) ([]types.Receipts, error) { testReceipts := makeTestReceipts(len(hs), 3) - receipts := make([][]byte, 0, len(hs)*3) - for _, r := range testReceipts { - receiptByes, _ := rlp.EncodeToBytes(r) - receipts = append(receipts, receiptByes) + receipts := make([]types.Receipts, len(hs)*3) + for i, _ := range hs { + receipts[i] = testReceipts } return receipts, nil } @@ -115,7 +114,7 @@ func makeTestNodeData(n int) [][]byte { } // makeTestReceipts creates fake receipts -func makeTestReceipts(n int, nPerBlock int) []types.Receipts { +func makeTestReceipts(n int, nPerBlock int) []*types.Receipt { receipts := make([]*types.Receipt, nPerBlock) for i := 0; i < nPerBlock; i++ { receipts[i] = &types.Receipt{ @@ -124,11 +123,7 @@ func makeTestReceipts(n int, nPerBlock int) []types.Receipts { Logs: make([]*types.Log, 5), } } - allReceipts := make([]types.Receipts, n) - for i := 0; i < n; i++ { - allReceipts[i] = receipts - } - return allReceipts + return receipts } func decodeBlocksBytes(bbs [][]byte) ([]*types.Block, error) { diff --git a/p2p/stream/protocols/sync/client_test.go b/p2p/stream/protocols/sync/client_test.go index 9a675fa0d4..edfa126d0b 100644 --- a/p2p/stream/protocols/sync/client_test.go +++ b/p2p/stream/protocols/sync/client_test.go @@ -15,6 +15,7 @@ import ( "github.com/harmony-one/harmony/core/types" "github.com/harmony-one/harmony/p2p/stream/common/ratelimiter" "github.com/harmony-one/harmony/p2p/stream/common/streammanager" + "github.com/harmony-one/harmony/p2p/stream/protocols/sync/message" syncpb "github.com/harmony-one/harmony/p2p/stream/protocols/sync/message" sttypes "github.com/harmony-one/harmony/p2p/stream/types" ) @@ -59,7 +60,10 @@ var ( testBlocksByHashesResponse = syncpb.MakeGetBlocksByHashesResponse(0, [][]byte{testBlockBytes}, make([][]byte, 1)) - testReceiptResponse = syncpb.MakeGetReceiptsResponse(0, [][]byte{testReceiptBytes}) + testReceipsMap = map[uint64]*message.Receipts{ + 0: {ReceiptBytes: [][]byte{testReceiptBytes}}, + } + testReceiptResponse = syncpb.MakeGetReceiptsResponse(0, testReceipsMap) testNodeDataResponse = syncpb.MakeGetNodeDataResponse(0, [][]byte{testNodeDataBytes}) @@ -358,6 +362,9 @@ func TestProtocol_GetReceipts(t *testing.T) { if len(receipts) != 1 { t.Errorf("Test %v: size not 1", i) } + if len(receipts[0]) != 1 { + t.Errorf("Test %v: block receipts size not 1", i) + } } } } From 5b636f2badafb080ae22a6461970faeec319d425 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CGheisMohammadi=E2=80=9D?= <36589218+GheisMohammadi@users.noreply.github.com> Date: Tue, 11 Jul 2023 21:35:05 +0800 Subject: [PATCH 09/13] fix kill_node script --- test/kill_node.sh | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/test/kill_node.sh b/test/kill_node.sh index 569a40947a..1f6f200e1f 100755 --- a/test/kill_node.sh +++ b/test/kill_node.sh @@ -1,3 +1,11 @@ #!/bin/bash -pkill -9 '^(harmony|soldier|commander|profiler|bootnode)$' | sed 's/^/Killed process: /' -rm -rf db-127.0.0.1-* + +# list of process name to be killed +targetProcess=( "harmony" "bootnode" "soldier" "commander" "profiler" ) + +for pname in "${targetProcess[@]}" +do + sudo pkill -9 -e "^(${pname})$" +done + +rm -rf db-127.0.0.1-* \ No newline at end of file From 98871365bfda0c84123535b016638053e5f4f515 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CGheisMohammadi=E2=80=9D?= <36589218+GheisMohammadi@users.noreply.github.com> Date: Thu, 13 Jul 2023 15:12:12 +0800 Subject: [PATCH 10/13] fix travis checker path issue --- scripts/travis_rosetta_checker.sh | 7 +++++-- scripts/travis_rpc_checker.sh | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/scripts/travis_rosetta_checker.sh b/scripts/travis_rosetta_checker.sh index 6576b4e07e..b9b565d4f2 100644 --- a/scripts/travis_rosetta_checker.sh +++ b/scripts/travis_rosetta_checker.sh @@ -5,11 +5,14 @@ echo $TRAVIS_PULL_REQUEST_BRANCH DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)" echo $DIR echo $GOPATH -cd $GOPATH/src/github.com/harmony-one/harmony-test -git fetch +cd $GOPATH/src/github.com/harmony-one/harmony +git fetch --all git checkout $TRAVIS_PULL_REQUEST_BRANCH || true git pull git branch --show-current +cd $GOPATH/src/github.com/harmony-one/harmony-test +git pull +git branch --show-current cd localnet docker build -t harmonyone/localnet-test . docker run -v "$DIR/../:/go/src/github.com/harmony-one/harmony" harmonyone/localnet-test -r \ No newline at end of file diff --git a/scripts/travis_rpc_checker.sh b/scripts/travis_rpc_checker.sh index 5de2ef93b8..64de1e75c6 100755 --- a/scripts/travis_rpc_checker.sh +++ b/scripts/travis_rpc_checker.sh @@ -5,11 +5,14 @@ echo $TRAVIS_PULL_REQUEST_BRANCH DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)" echo $DIR echo $GOPATH -cd $GOPATH/src/github.com/harmony-one/harmony-test -git fetch +cd $GOPATH/src/github.com/harmony-one/harmony +git fetch --all git checkout $TRAVIS_PULL_REQUEST_BRANCH || true git pull git branch --show-current +cd $GOPATH/src/github.com/harmony-one/harmony-test +git pull +git branch --show-current cd localnet docker build -t harmonyone/localnet-test . docker run -v "$DIR/../:/go/src/github.com/harmony-one/harmony" harmonyone/localnet-test -n \ No newline at end of file From 524f98189d7dc597419b4fe31b583de4da1597cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CGheisMohammadi=E2=80=9D?= <36589218+GheisMohammadi@users.noreply.github.com> Date: Thu, 13 Jul 2023 17:41:10 +0800 Subject: [PATCH 11/13] remove redundant lines, travis already has the latest changes in target branch --- scripts/travis_rosetta_checker.sh | 7 +------ scripts/travis_rpc_checker.sh | 7 +------ 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/scripts/travis_rosetta_checker.sh b/scripts/travis_rosetta_checker.sh index b9b565d4f2..b2e395fdba 100644 --- a/scripts/travis_rosetta_checker.sh +++ b/scripts/travis_rosetta_checker.sh @@ -1,16 +1,11 @@ #!/usr/bin/env bash set -e -echo $TRAVIS_PULL_REQUEST_BRANCH DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)" echo $DIR echo $GOPATH -cd $GOPATH/src/github.com/harmony-one/harmony -git fetch --all -git checkout $TRAVIS_PULL_REQUEST_BRANCH || true -git pull -git branch --show-current cd $GOPATH/src/github.com/harmony-one/harmony-test +git fetch git pull git branch --show-current cd localnet diff --git a/scripts/travis_rpc_checker.sh b/scripts/travis_rpc_checker.sh index 64de1e75c6..b057452f88 100755 --- a/scripts/travis_rpc_checker.sh +++ b/scripts/travis_rpc_checker.sh @@ -1,16 +1,11 @@ #!/usr/bin/env bash set -e -echo $TRAVIS_PULL_REQUEST_BRANCH DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)" echo $DIR echo $GOPATH -cd $GOPATH/src/github.com/harmony-one/harmony -git fetch --all -git checkout $TRAVIS_PULL_REQUEST_BRANCH || true -git pull -git branch --show-current cd $GOPATH/src/github.com/harmony-one/harmony-test +git fetch git pull git branch --show-current cd localnet From 8656c7ae8165fa2370bfac595e2ee875dc641ee8 Mon Sep 17 00:00:00 2001 From: Konstantin <355847+Frozen@users.noreply.github.com> Date: Tue, 18 Jul 2023 20:18:55 -0400 Subject: [PATCH 12/13] Fixed concurrent map access. (#4469) --- consensus/checks.go | 2 +- consensus/consensus.go | 43 ++++++++++++++---------- consensus/consensus_service.go | 2 +- consensus/consensus_test.go | 3 +- consensus/consensus_v2.go | 33 ++++++++----------- consensus/double_sign.go | 6 ++-- consensus/fbft_log.go | 60 +++++++++++++++++++++++++++++++++- consensus/leader.go | 10 +++--- consensus/threshold.go | 2 +- consensus/validator.go | 18 +++++----- consensus/view_change.go | 10 +++--- consensus/view_change_msg.go | 8 ++--- node/node_explorer.go | 12 +++---- 13 files changed, 133 insertions(+), 76 deletions(-) diff --git a/consensus/checks.go b/consensus/checks.go index 28da66ad7b..32f59fb938 100644 --- a/consensus/checks.go +++ b/consensus/checks.go @@ -68,7 +68,7 @@ func (consensus *Consensus) isRightBlockNumAndViewID(recvMsg *FBFTMessage) bool } func (consensus *Consensus) onAnnounceSanityChecks(recvMsg *FBFTMessage) bool { - logMsgs := consensus.FBFTLog.GetMessagesByTypeSeqView( + logMsgs := consensus.fBFTLog.GetMessagesByTypeSeqView( msg_pb.MessageType_ANNOUNCE, recvMsg.BlockNum, recvMsg.ViewID, ) if len(logMsgs) > 0 { diff --git a/consensus/consensus.go b/consensus/consensus.go index ddbea9ec46..09bdef51ae 100644 --- a/consensus/consensus.go +++ b/consensus/consensus.go @@ -46,7 +46,7 @@ type VerifyBlockFunc func(*types.Block) error type Consensus struct { Decider quorum.Decider // FBFTLog stores the pbft messages and blocks during FBFT process - FBFTLog *FBFTLog + fBFTLog *FBFTLog // phase: different phase of FBFT protocol: pre-prepare, prepare, commit, finish etc phase FBFTPhase // current indicates what state a node is in @@ -84,7 +84,7 @@ type Consensus struct { // IgnoreViewIDCheck determines whether to ignore viewID check IgnoreViewIDCheck *abool.AtomicBool // consensus mutex - mutex sync.RWMutex + mutex *sync.RWMutex // ViewChange struct vc *viewChange // Signal channel for proposing a new block and start new consensus @@ -140,6 +140,13 @@ func (consensus *Consensus) Blockchain() core.BlockChain { return consensus.registry.GetBlockchain() } +func (consensus *Consensus) FBFTLog() FBFT { + return threadsafeFBFTLog{ + log: consensus.fBFTLog, + mu: consensus.mutex, + } +} + // ChainReader returns the chain reader. // This is mostly the same as Blockchain, but it returns only read methods, so we assume it's safe for concurrent use. func (consensus *Consensus) ChainReader() engine.ChainReader { @@ -165,11 +172,11 @@ func (consensus *Consensus) Beaconchain() core.BlockChain { // VerifyBlock is a function used to verify the block and keep trace of verified blocks. func (consensus *Consensus) verifyBlock(block *types.Block) error { - if !consensus.FBFTLog.IsBlockVerified(block.Hash()) { + if !consensus.fBFTLog.IsBlockVerified(block.Hash()) { if err := consensus.BlockVerifier(block); err != nil { return errors.Errorf("Block verification failed: %s", err) } - consensus.FBFTLog.MarkBlockVerified(block) + consensus.fBFTLog.MarkBlockVerified(block) } return nil } @@ -261,21 +268,21 @@ func New( Decider quorum.Decider, minPeers int, aggregateSig bool, ) (*Consensus, error) { consensus := Consensus{ - ShardID: shard, + mutex: &sync.RWMutex{}, + ShardID: shard, + fBFTLog: NewFBFTLog(), + phase: FBFTAnnounce, + current: State{mode: Normal}, + Decider: Decider, + registry: registry, + MinPeers: minPeers, + AggregateSig: aggregateSig, + host: host, + msgSender: NewMessageSender(host), + BlockNumLowChan: make(chan struct{}, 1), + // FBFT timeout + consensusTimeout: createTimeout(), } - consensus.Decider = Decider - consensus.registry = registry - consensus.MinPeers = minPeers - consensus.AggregateSig = aggregateSig - consensus.host = host - consensus.msgSender = NewMessageSender(host) - consensus.BlockNumLowChan = make(chan struct{}, 1) - // FBFT related - consensus.FBFTLog = NewFBFTLog() - consensus.phase = FBFTAnnounce - consensus.current = State{mode: Normal} - // FBFT timeout - consensus.consensusTimeout = createTimeout() if multiBLSPriKey != nil { consensus.priKey = multiBLSPriKey diff --git a/consensus/consensus_service.go b/consensus/consensus_service.go index af40c42bcb..5229f0ed31 100644 --- a/consensus/consensus_service.go +++ b/consensus/consensus_service.go @@ -575,7 +575,7 @@ func (consensus *Consensus) selfCommit(payload []byte) error { copy(blockHash[:], payload[:32]) // Leader sign and add commit message - block := consensus.FBFTLog.GetBlockByHash(blockHash) + block := consensus.fBFTLog.GetBlockByHash(blockHash) if block == nil { return errGetPreparedBlock } diff --git a/consensus/consensus_test.go b/consensus/consensus_test.go index d2397a64aa..697ba49525 100644 --- a/consensus/consensus_test.go +++ b/consensus/consensus_test.go @@ -22,7 +22,6 @@ func TestConsensusInitialization(t *testing.T) { assert.NoError(t, err) messageSender := &MessageSender{host: host, retryTimes: int(phaseDuration.Seconds()) / RetryIntervalInSec} - fbtLog := NewFBFTLog() state := State{mode: Normal} timeouts := createTimeout() @@ -37,7 +36,7 @@ func TestConsensusInitialization(t *testing.T) { assert.IsType(t, make(chan struct{}), consensus.BlockNumLowChan) // FBFTLog - assert.Equal(t, fbtLog, consensus.FBFTLog) + assert.NotNil(t, consensus.FBFTLog()) assert.Equal(t, FBFTAnnounce, consensus.phase) diff --git a/consensus/consensus_v2.go b/consensus/consensus_v2.go index 262cbe37d6..38bb06ff4a 100644 --- a/consensus/consensus_v2.go +++ b/consensus/consensus_v2.go @@ -161,10 +161,10 @@ func (consensus *Consensus) finalCommit() { network.Bytes, network.FBFTMsg commitSigAndBitmap := FBFTMsg.Payload - consensus.FBFTLog.AddVerifiedMessage(FBFTMsg) + consensus.fBFTLog.AddVerifiedMessage(FBFTMsg) // find correct block content curBlockHash := consensus.blockHash - block := consensus.FBFTLog.GetBlockByHash(curBlockHash) + block := consensus.fBFTLog.GetBlockByHash(curBlockHash) if block == nil { consensus.getLogger().Warn(). Str("blockHash", hex.EncodeToString(curBlockHash[:])). @@ -278,7 +278,7 @@ func (consensus *Consensus) BlockCommitSigs(blockNum uint64) ([]byte, error) { lastCommits, err := consensus.Blockchain().ReadCommitSig(blockNum) if err != nil || len(lastCommits) < bls.BLSSignatureSizeInBytes { - msgs := consensus.FBFTLog.GetMessagesByTypeSeq( + msgs := consensus.FBFTLog().GetMessagesByTypeSeq( msg_pb.MessageType_COMMITTED, blockNum, ) if len(msgs) != 1 { @@ -482,7 +482,7 @@ func (consensus *Consensus) getLastMileBlockIter(bnStart uint64, cb func(iter *L } return cb(&LastMileBlockIter{ blockCandidates: blocks, - fbftLog: consensus.FBFTLog, + fbftLog: consensus.fBFTLog, verify: consensus.BlockVerifier, curIndex: 0, logger: consensus.getLogger(), @@ -513,7 +513,7 @@ func (consensus *Consensus) getLastMileBlocksAndMsg(bnStart uint64) ([]*types.Bl msgs []*FBFTMessage ) for blockNum := bnStart; ; blockNum++ { - blk, msg, err := consensus.FBFTLog.GetCommittedBlockAndMsgsFromNumber(blockNum, consensus.getLogger()) + blk, msg, err := consensus.fBFTLog.GetCommittedBlockAndMsgsFromNumber(blockNum, consensus.getLogger()) if err != nil { if err == errFBFTLogNotFound { break @@ -551,7 +551,7 @@ func (consensus *Consensus) preCommitAndPropose(blk *types.Block) error { network.Bytes, network.FBFTMsg bareMinimumCommit := FBFTMsg.Payload - consensus.FBFTLog.AddVerifiedMessage(FBFTMsg) + consensus.fBFTLog.AddVerifiedMessage(FBFTMsg) if err := consensus.verifyLastCommitSig(bareMinimumCommit, blk); err != nil { return errors.Wrap(err, "[preCommitAndPropose] failed verifying last commit sig") @@ -567,16 +567,16 @@ func (consensus *Consensus) preCommitAndPropose(blk *types.Block) error { nodeconfig.NewGroupIDByShardID(nodeconfig.ShardID(consensus.ShardID)), }, p2p.ConstructMessage(msgToSend)); err != nil { - consensus.getLogger().Warn().Err(err).Msg("[preCommitAndPropose] Cannot send committed message") + consensus.GetLogger().Warn().Err(err).Msg("[preCommitAndPropose] Cannot send committed message") } else { - consensus.getLogger().Info(). + consensus.GetLogger().Info(). Str("blockHash", blk.Hash().Hex()). Uint64("blockNum", consensus.BlockNum()). Hex("lastCommitSig", bareMinimumCommit). Msg("[preCommitAndPropose] Sent Committed Message") } - if _, err := consensus.Blockchain().InsertChain([]*types.Block{blk}, !consensus.FBFTLog.IsBlockVerified(blk.Hash())); err != nil { + if _, err := consensus.Blockchain().InsertChain([]*types.Block{blk}, !consensus.FBFTLog().IsBlockVerified(blk.Hash())); err != nil { consensus.getLogger().Error().Err(err).Msg("[preCommitAndPropose] Failed to add block to chain") return } @@ -661,7 +661,7 @@ func (consensus *Consensus) tryCatchup() error { func (consensus *Consensus) commitBlock(blk *types.Block, committedMsg *FBFTMessage) error { if consensus.Blockchain().CurrentBlock().NumberU64() < blk.NumberU64() { - if _, err := consensus.Blockchain().InsertChain([]*types.Block{blk}, !consensus.FBFTLog.IsBlockVerified(blk.Hash())); err != nil { + if _, err := consensus.Blockchain().InsertChain([]*types.Block{blk}, !consensus.fBFTLog.IsBlockVerified(blk.Hash())); err != nil { consensus.getLogger().Error().Err(err).Msg("[commitBlock] Failed to add block to chain") return err } @@ -785,7 +785,7 @@ func (consensus *Consensus) setupForNewConsensus(blk *types.Block, committedMsg if blk.IsLastBlockInEpoch() { consensus.setMode(consensus.updateConsensusInformation()) } - consensus.FBFTLog.PruneCacheBeforeBlock(blk.NumberU64()) + consensus.fBFTLog.PruneCacheBeforeBlock(blk.NumberU64()) consensus.resetState() } @@ -920,19 +920,12 @@ func (consensus *Consensus) ValidateVdfAndProof(headerObj *block.Header) bool { func (consensus *Consensus) DeleteBlocksLessThan(number uint64) { consensus.mutex.Lock() defer consensus.mutex.Unlock() - consensus.FBFTLog.deleteBlocksLessThan(number) + consensus.fBFTLog.deleteBlocksLessThan(number) } // DeleteMessagesLessThan deletes messages less than given block number. func (consensus *Consensus) DeleteMessagesLessThan(number uint64) { consensus.mutex.Lock() defer consensus.mutex.Unlock() - consensus.FBFTLog.deleteMessagesLessThan(number) -} - -// DeleteBlockByNumber deletes block by given block number. -func (consensus *Consensus) DeleteBlockByNumber(number uint64) { - consensus.mutex.Lock() - defer consensus.mutex.Unlock() - consensus.FBFTLog.deleteBlockByNumber(number) + consensus.fBFTLog.deleteMessagesLessThan(number) } diff --git a/consensus/double_sign.go b/consensus/double_sign.go index b9bf818cbd..3a8d559fd6 100644 --- a/consensus/double_sign.go +++ b/consensus/double_sign.go @@ -22,7 +22,7 @@ func (consensus *Consensus) checkDoubleSign(recvMsg *FBFTMessage) bool { ); alreadyCastBallot != nil { for _, pubKey1 := range alreadyCastBallot.SignerPubKeys { if bytes.Compare(pubKey2.Bytes[:], pubKey1[:]) == 0 { - for _, blk := range consensus.FBFTLog.GetBlocksByNumber(recvMsg.BlockNum) { + for _, blk := range consensus.fBFTLog.GetBlocksByNumber(recvMsg.BlockNum) { firstSignedHeader := blk.Header() areHeightsEqual := firstSignedHeader.Number().Uint64() == recvMsg.BlockNum areViewIDsEqual := firstSignedHeader.ViewID().Uint64() == recvMsg.ViewID @@ -138,8 +138,8 @@ func (consensus *Consensus) couldThisBeADoubleSigner( recvMsg *FBFTMessage, ) bool { num, hash := consensus.BlockNum(), recvMsg.BlockHash - suspicious := !consensus.FBFTLog.HasMatchingAnnounce(num, hash) || - !consensus.FBFTLog.HasMatchingPrepared(num, hash) + suspicious := !consensus.fBFTLog.HasMatchingAnnounce(num, hash) || + !consensus.fBFTLog.HasMatchingPrepared(num, hash) if suspicious { consensus.getLogger().Debug(). Str("message", recvMsg.String()). diff --git a/consensus/fbft_log.go b/consensus/fbft_log.go index 5a4fe21889..982aecab75 100644 --- a/consensus/fbft_log.go +++ b/consensus/fbft_log.go @@ -3,6 +3,7 @@ package consensus import ( "encoding/binary" "fmt" + "sync" "github.com/ethereum/go-ethereum/common" bls_core "github.com/harmony-one/bls/ffi/go/bls" @@ -97,6 +98,16 @@ func (m *FBFTMessage) id() fbftMsgID { return id } +type FBFT interface { + GetMessagesByTypeSeq(typ msg_pb.MessageType, blockNum uint64) []*FBFTMessage + IsBlockVerified(hash common.Hash) bool + DeleteBlockByNumber(number uint64) + GetBlockByHash(hash common.Hash) *types.Block + AddVerifiedMessage(msg *FBFTMessage) + AddBlock(block *types.Block) + GetMessagesByTypeSeqHash(typ msg_pb.MessageType, blockNum uint64, blockHash common.Hash) []*FBFTMessage +} + // FBFTLog represents the log stored by a node during FBFT process type FBFTLog struct { blocks map[common.Hash]*types.Block // store blocks received in FBFT @@ -157,7 +168,7 @@ func (log *FBFTLog) deleteBlocksLessThan(number uint64) { } // DeleteBlockByNumber deletes block of specific number -func (log *FBFTLog) deleteBlockByNumber(number uint64) { +func (log *FBFTLog) DeleteBlockByNumber(number uint64) { for h, block := range log.blocks { if block.NumberU64() == number { delete(log.blocks, h) @@ -360,3 +371,50 @@ func (log *FBFTLog) PruneCacheBeforeBlock(bn uint64) { log.deleteBlocksLessThan(bn - 1) log.deleteMessagesLessThan(bn - 1) } + +type threadsafeFBFTLog struct { + log *FBFTLog + mu *sync.RWMutex +} + +func (t threadsafeFBFTLog) GetMessagesByTypeSeq(typ msg_pb.MessageType, blockNum uint64) []*FBFTMessage { + t.mu.RLock() + defer t.mu.RUnlock() + return t.log.GetMessagesByTypeSeq(typ, blockNum) +} + +func (t threadsafeFBFTLog) IsBlockVerified(hash common.Hash) bool { + t.mu.RLock() + defer t.mu.RUnlock() + return t.log.IsBlockVerified(hash) +} + +func (t threadsafeFBFTLog) DeleteBlockByNumber(number uint64) { + t.mu.Lock() + defer t.mu.Unlock() + t.log.DeleteBlockByNumber(number) +} + +func (t threadsafeFBFTLog) GetBlockByHash(hash common.Hash) *types.Block { + t.mu.RLock() + defer t.mu.RUnlock() + return t.log.GetBlockByHash(hash) +} + +func (t threadsafeFBFTLog) AddVerifiedMessage(msg *FBFTMessage) { + t.mu.Lock() + defer t.mu.Unlock() + t.log.AddVerifiedMessage(msg) +} + +func (t threadsafeFBFTLog) AddBlock(block *types.Block) { + t.mu.Lock() + defer t.mu.Unlock() + t.log.AddBlock(block) +} + +func (t threadsafeFBFTLog) GetMessagesByTypeSeqHash(typ msg_pb.MessageType, blockNum uint64, blockHash common.Hash) []*FBFTMessage { + t.mu.RLock() + defer t.mu.RUnlock() + return t.log.GetMessagesByTypeSeqHash(typ, blockNum, blockHash) +} diff --git a/consensus/leader.go b/consensus/leader.go index 1b10c96086..82ba3069bb 100644 --- a/consensus/leader.go +++ b/consensus/leader.go @@ -44,13 +44,13 @@ func (consensus *Consensus) announce(block *types.Block) { } msgToSend, FPBTMsg := networkMessage.Bytes, networkMessage.FBFTMsg - consensus.FBFTLog.AddVerifiedMessage(FPBTMsg) + consensus.fBFTLog.AddVerifiedMessage(FPBTMsg) consensus.getLogger().Debug(). Str("MsgBlockHash", FPBTMsg.BlockHash.Hex()). Uint64("MsgViewID", FPBTMsg.ViewID). Uint64("MsgBlockNum", FPBTMsg.BlockNum). Msg("[Announce] Added Announce message in FPBT") - consensus.FBFTLog.AddBlock(block) + consensus.fBFTLog.AddBlock(block) // Leader sign the block hash itself for i, key := range consensus.priKey { @@ -94,7 +94,7 @@ func (consensus *Consensus) announce(block *types.Block) { func (consensus *Consensus) onPrepare(recvMsg *FBFTMessage) { // TODO(audit): make FBFT lookup using map instead of looping through all items. - if !consensus.FBFTLog.HasMatchingViewAnnounce( + if !consensus.fBFTLog.HasMatchingViewAnnounce( consensus.getBlockNum(), consensus.getCurBlockViewID(), recvMsg.BlockHash, ) { consensus.getLogger().Debug(). @@ -226,7 +226,7 @@ func (consensus *Consensus) onCommit(recvMsg *FBFTMessage) { } // Must have the corresponding block to verify commit signature. - blockObj := consensus.FBFTLog.GetBlockByHash(recvMsg.BlockHash) + blockObj := consensus.fBFTLog.GetBlockByHash(recvMsg.BlockHash) if blockObj == nil { consensus.getLogger().Info(). Uint64("blockNum", recvMsg.BlockNum). @@ -295,7 +295,7 @@ func (consensus *Consensus) onCommit(recvMsg *FBFTMessage) { if !quorumWasMet && quorumIsMet { logger.Info().Msg("[OnCommit] 2/3 Enough commits received") - consensus.FBFTLog.MarkBlockVerified(blockObj) + consensus.fBFTLog.MarkBlockVerified(blockObj) if !blockObj.IsLastBlockInEpoch() { // only do early commit if it's not epoch block to avoid problems diff --git a/consensus/threshold.go b/consensus/threshold.go index 11e65709e6..e611eaedcd 100644 --- a/consensus/threshold.go +++ b/consensus/threshold.go @@ -36,7 +36,7 @@ func (consensus *Consensus) didReachPrepareQuorum() error { networkMessage.OptionalAggregateSignature consensus.aggregatedPrepareSig = aggSig - consensus.FBFTLog.AddVerifiedMessage(FBFTMsg) + consensus.fBFTLog.AddVerifiedMessage(FBFTMsg) // Leader add commit phase signature var blockObj types.Block if err := rlp.DecodeBytes(consensus.block, &blockObj); err != nil { diff --git a/consensus/validator.go b/consensus/validator.go index c67765cc8a..ee30d8c006 100644 --- a/consensus/validator.go +++ b/consensus/validator.go @@ -37,7 +37,7 @@ func (consensus *Consensus) onAnnounce(msg *msg_pb.Message) { Uint64("MsgViewID", recvMsg.ViewID). Uint64("MsgBlockNum", recvMsg.BlockNum). Msg("[OnAnnounce] Announce message Added") - consensus.FBFTLog.AddVerifiedMessage(recvMsg) + consensus.fBFTLog.AddVerifiedMessage(recvMsg) consensus.blockHash = recvMsg.BlockHash // we have already added message and block, skip check viewID // and send prepare message if is in ViewChanging mode @@ -77,10 +77,10 @@ func (consensus *Consensus) ValidateNewBlock(recvMsg *FBFTMessage) (*types.Block return consensus.validateNewBlock(recvMsg) } func (consensus *Consensus) validateNewBlock(recvMsg *FBFTMessage) (*types.Block, error) { - if consensus.FBFTLog.IsBlockVerified(recvMsg.BlockHash) { + if consensus.fBFTLog.IsBlockVerified(recvMsg.BlockHash) { var blockObj *types.Block - blockObj = consensus.FBFTLog.GetBlockByHash(recvMsg.BlockHash) + blockObj = consensus.fBFTLog.GetBlockByHash(recvMsg.BlockHash) if blockObj == nil { var blockObj2 types.Block if err := rlp.DecodeBytes(recvMsg.Block, &blockObj2); err != nil { @@ -106,7 +106,7 @@ func (consensus *Consensus) validateNewBlock(recvMsg *FBFTMessage) (*types.Block return nil, errors.New("Failed parsing new block") } - consensus.FBFTLog.AddBlock(&blockObj) + consensus.fBFTLog.AddBlock(&blockObj) // let this handle it own logs if !consensus.newBlockSanityChecks(&blockObj, recvMsg) { @@ -118,7 +118,7 @@ func (consensus *Consensus) validateNewBlock(recvMsg *FBFTMessage) (*types.Block copy(blockPayload[:], recvMsg.Block[:]) consensus.block = blockPayload recvMsg.Block = []byte{} // save memory space - consensus.FBFTLog.AddVerifiedMessage(recvMsg) + consensus.fBFTLog.AddVerifiedMessage(recvMsg) consensus.getLogger().Debug(). Uint64("MsgViewID", recvMsg.ViewID). Uint64("MsgBlockNum", recvMsg.BlockNum). @@ -272,7 +272,7 @@ func (consensus *Consensus) onPrepared(recvMsg *FBFTMessage) { curBlockNum := consensus.BlockNum() consensus.mutex.Lock() defer consensus.mutex.Unlock() - for _, committedMsg := range consensus.FBFTLog.GetNotVerifiedCommittedMessages(blockObj.NumberU64(), blockObj.Header().ViewID().Uint64(), blockObj.Hash()) { + for _, committedMsg := range consensus.fBFTLog.GetNotVerifiedCommittedMessages(blockObj.NumberU64(), blockObj.Header().ViewID().Uint64(), blockObj.Hash()) { if committedMsg != nil { consensus.onCommitted(committedMsg) } @@ -309,10 +309,10 @@ func (consensus *Consensus) onCommitted(recvMsg *FBFTMessage) { } // Optimistically add committedMessage in case of receiving committed before prepared - consensus.FBFTLog.AddNotVerifiedMessage(recvMsg) + consensus.fBFTLog.AddNotVerifiedMessage(recvMsg) // Must have the corresponding block to verify committed message. - blockObj := consensus.FBFTLog.GetBlockByHash(recvMsg.BlockHash) + blockObj := consensus.fBFTLog.GetBlockByHash(recvMsg.BlockHash) if blockObj == nil { consensus.getLogger().Info(). Uint64("blockNum", recvMsg.BlockNum). @@ -345,7 +345,7 @@ func (consensus *Consensus) onCommitted(recvMsg *FBFTMessage) { consensus.getLogger().Error().Err(err).Msg("[OnCommitted] readSignatureBitmapPayload failed") return } - consensus.FBFTLog.AddVerifiedMessage(recvMsg) + consensus.fBFTLog.AddVerifiedMessage(recvMsg) consensus.aggregatedCommitSig = aggSig consensus.commitBitmap = mask diff --git a/consensus/view_change.go b/consensus/view_change.go index 151074817a..3927714e9a 100644 --- a/consensus/view_change.go +++ b/consensus/view_change.go @@ -274,7 +274,7 @@ func (consensus *Consensus) startViewChange() { // init my own payload if err := consensus.vc.InitPayload( - consensus.FBFTLog, + consensus.fBFTLog, nextViewID, consensus.getBlockNum(), consensus.priKey, @@ -394,7 +394,7 @@ func (consensus *Consensus) onViewChange(recvMsg *FBFTMessage) { consensus.vc.AddViewIDKeyIfNotExist(recvMsg.ViewID, members) // do it once only per viewID/Leader - if err := consensus.vc.InitPayload(consensus.FBFTLog, + if err := consensus.vc.InitPayload(consensus.fBFTLog, recvMsg.ViewID, recvMsg.BlockNum, consensus.priKey, @@ -403,7 +403,7 @@ func (consensus *Consensus) onViewChange(recvMsg *FBFTMessage) { return } - err = consensus.vc.ProcessViewChangeMsg(consensus.FBFTLog, consensus.Decider, recvMsg) + err = consensus.vc.ProcessViewChangeMsg(consensus.fBFTLog, consensus.Decider, recvMsg) if err != nil { consensus.getLogger().Error().Err(err). Uint64("viewID", recvMsg.ViewID). @@ -517,10 +517,10 @@ func (consensus *Consensus) onNewView(recvMsg *FBFTMessage) { copy(preparedMsg.Payload[:], recvMsg.Payload[32:]) preparedMsg.SenderPubkeys = []*bls.PublicKeyWrapper{senderKey} - consensus.FBFTLog.AddVerifiedMessage(&preparedMsg) + consensus.fBFTLog.AddVerifiedMessage(&preparedMsg) if preparedBlock != nil { - consensus.FBFTLog.AddBlock(preparedBlock) + consensus.fBFTLog.AddBlock(preparedBlock) } } diff --git a/consensus/view_change_msg.go b/consensus/view_change_msg.go index c241450306..fdb3f3afe2 100644 --- a/consensus/view_change_msg.go +++ b/consensus/view_change_msg.go @@ -32,14 +32,14 @@ func (consensus *Consensus) constructViewChangeMessage(priKey *bls.PrivateKeyWra }, } - preparedMsgs := consensus.FBFTLog.GetMessagesByTypeSeq( + preparedMsgs := consensus.fBFTLog.GetMessagesByTypeSeq( msg_pb.MessageType_PREPARED, consensus.getBlockNum(), ) - preparedMsg := consensus.FBFTLog.FindMessageByMaxViewID(preparedMsgs) + preparedMsg := consensus.fBFTLog.FindMessageByMaxViewID(preparedMsgs) var encodedBlock []byte if preparedMsg != nil { - block := consensus.FBFTLog.GetBlockByHash(preparedMsg.BlockHash) + block := consensus.fBFTLog.GetBlockByHash(preparedMsg.BlockHash) consensus.getLogger().Info(). Interface("Block", block). Interface("preparedMsg", preparedMsg). @@ -115,7 +115,7 @@ func (consensus *Consensus) constructNewViewMessage(viewID uint64, priKey *bls.P } vcMsg := message.GetViewchange() - vcMsg.Payload, vcMsg.PreparedBlock = consensus.vc.GetPreparedBlock(consensus.FBFTLog) + vcMsg.Payload, vcMsg.PreparedBlock = consensus.vc.GetPreparedBlock(consensus.fBFTLog) vcMsg.M2Aggsigs, vcMsg.M2Bitmap = consensus.vc.GetM2Bitmap(viewID) vcMsg.M3Aggsigs, vcMsg.M3Bitmap = consensus.vc.GetM3Bitmap(viewID) if vcMsg.M3Bitmap == nil || vcMsg.M3Aggsigs == nil { diff --git a/node/node_explorer.go b/node/node_explorer.go index 0dd7319761..fbb5b88985 100644 --- a/node/node_explorer.go +++ b/node/node_explorer.go @@ -58,13 +58,13 @@ func (node *Node) explorerMessageHandler(ctx context.Context, msg *msg_pb.Messag return nil } - block := node.Consensus.FBFTLog.GetBlockByHash(recvMsg.BlockHash) + block := node.Consensus.FBFTLog().GetBlockByHash(recvMsg.BlockHash) if block == nil { utils.Logger().Info(). Uint64("msgBlock", recvMsg.BlockNum). Msg("[Explorer] Haven't received the block before the committed msg") - node.Consensus.FBFTLog.AddVerifiedMessage(recvMsg) + node.Consensus.FBFTLog().AddVerifiedMessage(recvMsg) return errBlockBeforeCommit } @@ -94,9 +94,9 @@ func (node *Node) explorerMessageHandler(ctx context.Context, msg *msg_pb.Messag return err } // Add the block into FBFT log. - node.Consensus.FBFTLog.AddBlock(blockObj) + node.Consensus.FBFTLog().AddBlock(blockObj) // Try to search for MessageType_COMMITTED message from pbft log. - msgs := node.Consensus.FBFTLog.GetMessagesByTypeSeqHash( + msgs := node.Consensus.FBFTLog().GetMessagesByTypeSeqHash( msg_pb.MessageType_COMMITTED, blockObj.NumberU64(), blockObj.Hash(), @@ -148,7 +148,7 @@ func (node *Node) TraceLoopForExplorer() { // AddNewBlockForExplorer add new block for explorer. func (node *Node) AddNewBlockForExplorer(block *types.Block) { if node.HarmonyConfig.General.RunElasticMode && node.HarmonyConfig.TiKV.Role == tikv.RoleReader { - node.Consensus.DeleteBlockByNumber(block.NumberU64()) + node.Consensus.FBFTLog().DeleteBlockByNumber(block.NumberU64()) return } @@ -159,7 +159,7 @@ func (node *Node) AddNewBlockForExplorer(block *types.Block) { node.Consensus.UpdateConsensusInformation() } // Clean up the blocks to avoid OOM. - node.Consensus.DeleteBlockByNumber(block.NumberU64()) + node.Consensus.FBFTLog().DeleteBlockByNumber(block.NumberU64()) // if in tikv mode, only master writer node need dump all explorer block if !node.HarmonyConfig.General.RunElasticMode || node.Blockchain().IsTikvWriterMaster() { From 0e4b629fbe76f4a1df83372f0766037513022fbd Mon Sep 17 00:00:00 2001 From: Konstantin <355847+Frozen@users.noreply.github.com> Date: Thu, 20 Jul 2023 22:59:04 -0400 Subject: [PATCH 13/13] Consensus Mask. Removed unnecessary argument. (#4466) * Removed unnecessary argument. * Fixed comment. --- consensus/consensus_service.go | 13 +++++------- consensus/construct.go | 6 +----- consensus/view_change_construct.go | 20 +++++++++--------- consensus/view_change_msg.go | 10 ++------- core/state/journal.go | 3 ++- crypto/bls/mask.go | 18 +++------------- crypto/bls/mask_test.go | 34 +++++++++++++++++------------- hmy/blockchain.go | 5 +---- internal/chain/sig.go | 6 +----- staking/availability/measure.go | 5 +---- 10 files changed, 45 insertions(+), 75 deletions(-) diff --git a/consensus/consensus_service.go b/consensus/consensus_service.go index 5229f0ed31..3ebfa5e307 100644 --- a/consensus/consensus_service.go +++ b/consensus/consensus_service.go @@ -145,9 +145,9 @@ func (consensus *Consensus) updateBitmaps() { Str("MessageType", consensus.phase.String()). Msg("[UpdateBitmaps] Updating consensus bitmaps") members := consensus.Decider.Participants() - prepareBitmap, _ := bls_cosi.NewMask(members, nil) - commitBitmap, _ := bls_cosi.NewMask(members, nil) - multiSigBitmap, _ := bls_cosi.NewMask(members, nil) + prepareBitmap := bls_cosi.NewMask(members) + commitBitmap := bls_cosi.NewMask(members) + multiSigBitmap := bls_cosi.NewMask(members) consensus.prepareBitmap = prepareBitmap consensus.commitBitmap = commitBitmap consensus.multiSigBitmap = multiSigBitmap @@ -627,11 +627,8 @@ func (consensus *Consensus) NumSignaturesIncludedInBlock(block *types.Block) uin count := uint32(0) members := consensus.Decider.Participants() // TODO(audit): do not reconstruct the Mask - mask, err := bls.NewMask(members, nil) - if err != nil { - return count - } - err = mask.SetMask(block.Header().LastCommitBitmap()) + mask := bls.NewMask(members) + err := mask.SetMask(block.Header().LastCommitBitmap()) if err != nil { return count } diff --git a/consensus/construct.go b/consensus/construct.go index eaa6fd83f1..10488816c7 100644 --- a/consensus/construct.go +++ b/consensus/construct.go @@ -82,11 +82,7 @@ func (consensus *Consensus) construct( ) } else { // TODO: use a persistent bitmap to report bitmap - mask, err := bls.NewMask(consensus.Decider.Participants(), nil) - if err != nil { - utils.Logger().Warn().Err(err).Msg("unable to setup mask for multi-sig message") - return nil, err - } + mask := bls.NewMask(consensus.Decider.Participants()) for _, key := range priKeys { mask.SetKey(key.Pub.Bytes, true) } diff --git a/consensus/view_change_construct.go b/consensus/view_change_construct.go index 089ec2ef87..061d2a795c 100644 --- a/consensus/view_change_construct.go +++ b/consensus/view_change_construct.go @@ -69,15 +69,15 @@ func (vc *viewChange) AddViewIDKeyIfNotExist(viewID uint64, members multibls.Pub vc.viewIDSigs[viewID] = map[string]*bls_core.Sign{} } if _, ok := vc.bhpBitmap[viewID]; !ok { - bhpBitmap, _ := bls_cosi.NewMask(members, nil) + bhpBitmap := bls_cosi.NewMask(members) vc.bhpBitmap[viewID] = bhpBitmap } if _, ok := vc.nilBitmap[viewID]; !ok { - nilBitmap, _ := bls_cosi.NewMask(members, nil) + nilBitmap := bls_cosi.NewMask(members) vc.nilBitmap[viewID] = nilBitmap } if _, ok := vc.viewIDBitmap[viewID]; !ok { - viewIDBitmap, _ := bls_cosi.NewMask(members, nil) + viewIDBitmap := bls_cosi.NewMask(members) vc.viewIDBitmap[viewID] = viewIDBitmap } } @@ -290,7 +290,7 @@ func (vc *viewChange) ProcessViewChangeMsg( } vc.bhpSigs[recvMsg.ViewID][senderKeyStr] = recvMsg.ViewchangeSig if _, ok := vc.bhpBitmap[recvMsg.ViewID]; !ok { - bhpBitmap, _ := bls_cosi.NewMask(decider.Participants(), nil) + bhpBitmap := bls_cosi.NewMask(decider.Participants()) vc.bhpBitmap[recvMsg.ViewID] = bhpBitmap } vc.bhpBitmap[recvMsg.ViewID].SetKey(senderKey.Bytes, true) // Set the bitmap indicating that this validator signed. @@ -305,7 +305,7 @@ func (vc *viewChange) ProcessViewChangeMsg( vc.viewIDSigs[recvMsg.ViewID][senderKeyStr] = recvMsg.ViewidSig if _, ok := vc.viewIDBitmap[recvMsg.ViewID]; !ok { - viewIDBitmap, _ := bls_cosi.NewMask(decider.Participants(), nil) + viewIDBitmap := bls_cosi.NewMask(decider.Participants()) vc.viewIDBitmap[recvMsg.ViewID] = viewIDBitmap } // Set the bitmap indicating that this validator signed. @@ -350,7 +350,7 @@ func (vc *viewChange) ProcessViewChangeMsg( vc.nilSigs[recvMsg.ViewID][senderKeyStr] = recvMsg.ViewchangeSig if _, ok := vc.nilBitmap[recvMsg.ViewID]; !ok { - nilBitmap, _ := bls_cosi.NewMask(decider.Participants(), nil) + nilBitmap := bls_cosi.NewMask(decider.Participants()) vc.nilBitmap[recvMsg.ViewID] = nilBitmap } vc.nilBitmap[recvMsg.ViewID].SetKey(senderKey.Bytes, true) // Set the bitmap indicating that this validator signed. @@ -366,7 +366,7 @@ func (vc *viewChange) ProcessViewChangeMsg( // Set the bitmap indicating that this validator signed. if _, ok := vc.viewIDBitmap[recvMsg.ViewID]; !ok { - viewIDBitmap, _ := bls_cosi.NewMask(decider.Participants(), nil) + viewIDBitmap := bls_cosi.NewMask(decider.Participants()) vc.viewIDBitmap[recvMsg.ViewID] = viewIDBitmap } vc.viewIDBitmap[recvMsg.ViewID].SetKey(senderKey.Bytes, true) @@ -411,7 +411,7 @@ func (vc *viewChange) InitPayload( for _, key := range privKeys { // update the dictionary key if the viewID is first time received if _, ok := vc.bhpBitmap[viewID]; !ok { - bhpBitmap, _ := bls_cosi.NewMask(members, nil) + bhpBitmap := bls_cosi.NewMask(members) vc.bhpBitmap[viewID] = bhpBitmap } if err := vc.bhpBitmap[viewID].SetKey(key.Pub.Bytes, true); err != nil { @@ -435,7 +435,7 @@ func (vc *viewChange) InitPayload( vc.getLogger().Info().Uint64("viewID", viewID).Uint64("blockNum", blockNum).Msg("[InitPayload] add my M2 (NIL) type messaage") for _, key := range privKeys { if _, ok := vc.nilBitmap[viewID]; !ok { - nilBitmap, _ := bls_cosi.NewMask(members, nil) + nilBitmap := bls_cosi.NewMask(members) vc.nilBitmap[viewID] = nilBitmap } if err := vc.nilBitmap[viewID].SetKey(key.Pub.Bytes, true); err != nil { @@ -467,7 +467,7 @@ func (vc *viewChange) InitPayload( vc.getLogger().Info().Uint64("viewID", viewID).Uint64("blockNum", blockNum).Msg("[InitPayload] add my M3 (ViewID) type messaage") for _, key := range privKeys { if _, ok := vc.viewIDBitmap[viewID]; !ok { - viewIDBitmap, _ := bls_cosi.NewMask(members, nil) + viewIDBitmap := bls_cosi.NewMask(members) vc.viewIDBitmap[viewID] = viewIDBitmap } if err := vc.viewIDBitmap[viewID].SetKey(key.Pub.Bytes, true); err != nil { diff --git a/consensus/view_change_msg.go b/consensus/view_change_msg.go index fdb3f3afe2..6c4b080055 100644 --- a/consensus/view_change_msg.go +++ b/consensus/view_change_msg.go @@ -222,10 +222,7 @@ func ParseNewViewMessage(msg *msg_pb.Message, members multibls.PublicKeys) (*FBF if err != nil { return nil, err } - m3mask, err := bls_cosi.NewMask(members, nil) - if err != nil { - return nil, err - } + m3mask := bls_cosi.NewMask(members) m3mask.SetMask(vcMsg.M3Bitmap) FBFTMsg.M3AggSig = &m3Sig FBFTMsg.M3Bitmap = m3mask @@ -237,10 +234,7 @@ func ParseNewViewMessage(msg *msg_pb.Message, members multibls.PublicKeys) (*FBF if err != nil { return nil, err } - m2mask, err := bls_cosi.NewMask(members, nil) - if err != nil { - return nil, err - } + m2mask := bls_cosi.NewMask(members) m2mask.SetMask(vcMsg.M2Bitmap) FBFTMsg.M2AggSig = &m2Sig FBFTMsg.M2Bitmap = m2mask diff --git a/core/state/journal.go b/core/state/journal.go index 210f38808f..c5e3f743e7 100644 --- a/core/state/journal.go +++ b/core/state/journal.go @@ -156,7 +156,8 @@ func (v validatorWrapperChange) dirtied() *common.Address { } // revert undoes the changes introduced by this journal entry. -func (v validatorWrapperChange) revert(*DB) { +func (v validatorWrapperChange) revert(s *DB) { + s.stateValidators[*(v.address)] = v.prev } func (ch createObjectChange) revert(s *DB) { diff --git a/crypto/bls/mask.go b/crypto/bls/mask.go index b033838f02..2bd908fd7c 100644 --- a/crypto/bls/mask.go +++ b/crypto/bls/mask.go @@ -72,10 +72,8 @@ type Mask struct { } // NewMask returns a new participation bitmask for cosigning where all -// cosigners are disabled by default. If a public key is given it verifies that -// it is present in the list of keys and sets the corresponding index in the -// bitmask to 1 (enabled). -func NewMask(publics []PublicKeyWrapper, myKey *PublicKeyWrapper) (*Mask, error) { +// cosigners are disabled by default. +func NewMask(publics []PublicKeyWrapper) *Mask { index := map[SerializedPublicKey]int{} publicKeys := make([]*PublicKeyWrapper, len(publics)) for i, key := range publics { @@ -88,17 +86,7 @@ func NewMask(publics []PublicKeyWrapper, myKey *PublicKeyWrapper) (*Mask, error) } m.Bitmap = make([]byte, m.Len()) m.AggregatePublic = &bls.PublicKey{} - if myKey != nil { - i, found := m.PublicsIndex[myKey.Bytes] - if found { - m.SetBit(i, true) - found = true - } - if !found { - return nil, errors.New("key not found") - } - } - return m, nil + return m } // Clear clears the existing bits and aggregate public keys. diff --git a/crypto/bls/mask_test.go b/crypto/bls/mask_test.go index 58231add67..17770fd668 100644 --- a/crypto/bls/mask_test.go +++ b/crypto/bls/mask_test.go @@ -16,7 +16,8 @@ func TestNewMask(test *testing.T) { pubKey1.Bytes.FromLibBLSPublicKey(pubKey1.Object) pubKey2.Bytes.FromLibBLSPublicKey(pubKey2.Object) pubKey3.Bytes.FromLibBLSPublicKey(pubKey3.Object) - mask, err := NewMask([]PublicKeyWrapper{pubKey1, pubKey2, pubKey3}, &pubKey1) + mask := NewMask([]PublicKeyWrapper{pubKey1, pubKey2, pubKey3}) + err := mask.SetKey(pubKey1.Bytes, true) if err != nil { test.Errorf("Failed to create a new Mask: %s", err) @@ -51,16 +52,12 @@ func TestNewMaskWithAbsentPublicKey(test *testing.T) { pubKey3.Bytes.FromLibBLSPublicKey(pubKey3.Object) pubKey4.Bytes.FromLibBLSPublicKey(pubKey4.Object) - mask, err := NewMask([]PublicKeyWrapper{pubKey1, pubKey2, pubKey3}, &pubKey4) + mask := NewMask([]PublicKeyWrapper{pubKey1, pubKey2, pubKey3}) + err := mask.SetKey(pubKey4.Bytes, true) if err == nil { - test.Errorf("Failed to create a new Mask: %s", err) - } - - if mask != nil { - test.Errorf("Expected failure to create a new mask") + test.Errorf("Failed to set a key: %s", err) } - } func TestThreshHoldPolicy(test *testing.T) { @@ -71,7 +68,8 @@ func TestThreshHoldPolicy(test *testing.T) { pubKey1.Bytes.FromLibBLSPublicKey(pubKey1.Object) pubKey2.Bytes.FromLibBLSPublicKey(pubKey2.Object) pubKey3.Bytes.FromLibBLSPublicKey(pubKey3.Object) - mask, err := NewMask([]PublicKeyWrapper{pubKey1, pubKey2, pubKey3}, &pubKey1) + mask := NewMask([]PublicKeyWrapper{pubKey1, pubKey2, pubKey3}) + err := mask.SetKey(pubKey1.Bytes, true) if err != nil { test.Errorf("Failed to create a new Mask: %s", err) @@ -110,7 +108,8 @@ func TestCompletePolicy(test *testing.T) { pubKey1.Bytes.FromLibBLSPublicKey(pubKey1.Object) pubKey2.Bytes.FromLibBLSPublicKey(pubKey2.Object) pubKey3.Bytes.FromLibBLSPublicKey(pubKey3.Object) - mask, err := NewMask([]PublicKeyWrapper{pubKey1, pubKey2, pubKey3}, &pubKey1) + mask := NewMask([]PublicKeyWrapper{pubKey1, pubKey2, pubKey3}) + err := mask.SetKey(pubKey1.Bytes, true) if err != nil { test.Errorf("Failed to create a new Mask: %s", err) @@ -184,7 +183,8 @@ func TestEnableKeyFunctions(test *testing.T) { pubKey2.Bytes.FromLibBLSPublicKey(pubKey2.Object) pubKey3.Bytes.FromLibBLSPublicKey(pubKey3.Object) pubKey4.Bytes.FromLibBLSPublicKey(pubKey4.Object) - mask, err := NewMask([]PublicKeyWrapper{pubKey1, pubKey2, pubKey3}, &pubKey1) + mask := NewMask([]PublicKeyWrapper{pubKey1, pubKey2, pubKey3}) + err := mask.SetKey(pubKey1.Bytes, true) if err != nil { test.Errorf("Failed to create a new Mask: %s", err) @@ -238,7 +238,8 @@ func TestGetSignedPubKeysFromBitmap(test *testing.T) { pubKey2.Bytes.FromLibBLSPublicKey(pubKey2.Object) pubKey3.Bytes.FromLibBLSPublicKey(pubKey3.Object) pubKey4.Bytes.FromLibBLSPublicKey(pubKey4.Object) - mask, err := NewMask([]PublicKeyWrapper{pubKey1, pubKey2, pubKey3}, &pubKey1) + mask := NewMask([]PublicKeyWrapper{pubKey1, pubKey2, pubKey3}) + err := mask.SetKey(pubKey1.Bytes, true) if err != nil { test.Errorf("Failed to create a new Mask: %s", err) @@ -273,7 +274,8 @@ func TestSetKeyAtomic(test *testing.T) { pubKey2.Bytes.FromLibBLSPublicKey(pubKey2.Object) pubKey3.Bytes.FromLibBLSPublicKey(pubKey3.Object) pubKey4.Bytes.FromLibBLSPublicKey(pubKey4.Object) - mask, err := NewMask([]PublicKeyWrapper{pubKey1, pubKey2, pubKey3}, &pubKey1) + mask := NewMask([]PublicKeyWrapper{pubKey1, pubKey2, pubKey3}) + err := mask.SetKey(pubKey1.Bytes, true) if err != nil { test.Errorf("Failed to create a new Mask: %s", err) @@ -315,7 +317,8 @@ func TestCopyParticipatingMask(test *testing.T) { pubKey1.Bytes.FromLibBLSPublicKey(pubKey1.Object) pubKey2.Bytes.FromLibBLSPublicKey(pubKey2.Object) - mask, _ := NewMask([]PublicKeyWrapper{pubKey1, pubKey2}, &pubKey1) + mask := NewMask([]PublicKeyWrapper{pubKey1, pubKey2}) + _ = mask.SetKey(pubKey1.Bytes, true) clonedMask := mask.Mask() @@ -331,7 +334,8 @@ func TestSetMask(test *testing.T) { pubKey1.Bytes.FromLibBLSPublicKey(pubKey1.Object) pubKey2.Bytes.FromLibBLSPublicKey(pubKey2.Object) - mask, _ := NewMask([]PublicKeyWrapper{pubKey1, pubKey2}, &pubKey1) + mask := NewMask([]PublicKeyWrapper{pubKey1, pubKey2}) + _ = mask.SetKey(pubKey1.Bytes, true) _ = mask maskBytes := []byte{3} diff --git a/hmy/blockchain.go b/hmy/blockchain.go index 45bd099f1f..25a6d3aa7f 100644 --- a/hmy/blockchain.go +++ b/hmy/blockchain.go @@ -67,10 +67,7 @@ func (hmy *Harmony) GetBlockSigners( Object: key, } } - mask, err := internal_bls.NewMask(pubKeys, nil) - if err != nil { - return nil, nil, err - } + mask := internal_bls.NewMask(pubKeys) err = mask.SetMask(blockWithSigners.Header().LastCommitBitmap()) if err != nil { return nil, nil, err diff --git a/internal/chain/sig.go b/internal/chain/sig.go index e898b8e6f9..23b51d5f1b 100644 --- a/internal/chain/sig.go +++ b/internal/chain/sig.go @@ -40,11 +40,7 @@ func DecodeSigBitmap(sigBytes bls.SerializedSignature, bitmap []byte, pubKeys [] if err != nil { return nil, nil, errors.New("unable to deserialize multi-signature from payload") } - mask, err := bls.NewMask(pubKeys, nil) - if err != nil { - utils.Logger().Warn().Err(err).Msg("onNewView unable to setup mask for prepared message") - return nil, nil, errors.New("unable to setup mask from payload") - } + mask := bls.NewMask(pubKeys) if err := mask.SetMask(bitmap); err != nil { utils.Logger().Warn().Err(err).Msg("mask.SetMask failed") return nil, nil, errors.New("mask.SetMask failed") diff --git a/staking/availability/measure.go b/staking/availability/measure.go index d79181c32c..680092aa0d 100644 --- a/staking/availability/measure.go +++ b/staking/availability/measure.go @@ -31,10 +31,7 @@ func BlockSigners( if err != nil { return nil, nil, err } - mask, err := bls.NewMask(committerKeys, nil) - if err != nil { - return nil, nil, err - } + mask := bls.NewMask(committerKeys) if err := mask.SetMask(bitmap); err != nil { return nil, nil, err }