From a65f92d0aeb95c944f84651a2afec72e44754953 Mon Sep 17 00:00:00 2001 From: UncertainBadg3r <139782199+UncertainBadg3r@users.noreply.github.com> Date: Mon, 23 Oct 2023 12:19:55 -0400 Subject: [PATCH 01/19] Fix typo in README test steps (#4541) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Casey Gardiner <117784577+ONECasey@users.noreply.github.com> Co-authored-by: Max <82761650+MaxMustermann2@users.noreply.github.com> Co-authored-by: Soph <35721420+sophoah@users.noreply.github.com> Co-authored-by: Konstantin <355847+Frozen@users.noreply.github.com> Co-authored-by: Nita Neou (Soph) Co-authored-by: Diego Nava Co-authored-by: Diego Nava <8563843+diego1q2w@users.noreply.github.com> Co-authored-by: Gheis Mohammadi Co-authored-by: “GheisMohammadi” <36589218+GheisMohammadi@users.noreply.github.com> Co-authored-by: Adam Androulidakis <37982984+adsorptionenthalpy@users.noreply.github.com> --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0f2aa11f9..998832b35 100644 --- a/README.md +++ b/README.md @@ -150,7 +150,7 @@ make debug-kill To keep things consistent, we have a docker image to run all tests. **These are the same tests ran on the pull request checks**. -Note that all testing docker container binds a couple of ports to the host machine for your convince. The ports are: +Note that all test Docker containers bind several ports to the host machine for your convenience. The ports are: * `9500` - Shard 0 RPC for a validator * `9501` - Shard 1 RPC for a validator * `9599` - Shard 0 RPC for an explorer From 5faeb5f79a5a48cddf5576a8a7302729f89f2ac0 Mon Sep 17 00:00:00 2001 From: Konstantin <355847+Frozen@users.noreply.github.com> Date: Mon, 23 Oct 2023 08:20:27 -0800 Subject: [PATCH 02/19] Call `UpdateConsensusInformation` after bingo. (#4542) --- node/node_handler.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/node/node_handler.go b/node/node_handler.go index 92c3396d4..eeaf90f2d 100644 --- a/node/node_handler.go +++ b/node/node_handler.go @@ -350,6 +350,9 @@ func (node *Node) PostConsensusProcessing(newBlock *types.Block) error { Int("numStakingTxns", len(newBlock.StakingTransactions())). Uint32("numSignatures", numSignatures). Msg("BINGO !!! Reached Consensus") + if node.Consensus.Mode() == consensus.Syncing { + node.Consensus.SetMode(node.Consensus.UpdateConsensusInformation()) + } node.Consensus.UpdateValidatorMetrics(float64(numSignatures), float64(newBlock.NumberU64())) From d49715e8f731f70c1b4ec6614adf6309d5ca394d Mon Sep 17 00:00:00 2001 From: Gheis Mohammadi Date: Wed, 25 Oct 2023 07:05:20 +0800 Subject: [PATCH 03/19] add new functions to p2p stream client for sharing the full states (#4540) * add new functions to p2p stream client for sharing the full states * remove extra comments, add bytes checking * add client tests for new p2p stream client functions * rename new client functions * complete tests for new functions of p2p stream client --- consensus/engine/consensus_engine.go | 8 + core/blockchain.go | 5 + core/blockchain_impl.go | 5 + core/blockchain_stub.go | 9 + go.mod | 68 +- go.sum | 121 +- hmy/downloader/adapter_test.go | 4 + internal/chain/engine_test.go | 6 + p2p/stream/protocols/sync/chain.go | 295 +++ p2p/stream/protocols/sync/chain_test.go | 174 ++ p2p/stream/protocols/sync/client.go | 417 ++++ p2p/stream/protocols/sync/client_test.go | 326 ++++ p2p/stream/protocols/sync/const.go | 33 + p2p/stream/protocols/sync/message/compose.go | 128 ++ p2p/stream/protocols/sync/message/msg.pb.go | 1802 ++++++++++++++---- p2p/stream/protocols/sync/message/msg.proto | 70 + p2p/stream/protocols/sync/message/parse.go | 64 + p2p/stream/protocols/sync/stream.go | 170 ++ p2p/stream/protocols/sync/stream_test.go | 108 ++ test/chain/chain/chain_makers.go | 6 + 20 files changed, 3372 insertions(+), 447 deletions(-) diff --git a/consensus/engine/consensus_engine.go b/consensus/engine/consensus_engine.go index 5ac2c776b..37c4ea590 100644 --- a/consensus/engine/consensus_engine.go +++ b/consensus/engine/consensus_engine.go @@ -4,9 +4,11 @@ import ( "math/big" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/trie" "github.com/harmony-one/harmony/block" "github.com/harmony-one/harmony/consensus/reward" "github.com/harmony-one/harmony/core/state" + "github.com/harmony-one/harmony/core/state/snapshot" "github.com/harmony-one/harmony/core/types" "github.com/harmony-one/harmony/crypto/bls" "github.com/harmony-one/harmony/internal/params" @@ -23,6 +25,9 @@ type ChainReader interface { // Config retrieves the blockchain's chain configuration. Config() *params.ChainConfig + // TrieDB returns trie database + TrieDB() *trie.Database + // 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) @@ -62,6 +67,9 @@ type ChainReader interface { // GetBlock retrieves a block from the database by hash and number. GetBlock(hash common.Hash, number uint64) *types.Block + // Snapshots returns the blockchain snapshot tree. + Snapshots() *snapshot.Tree + // ReadShardState retrieves sharding state given the epoch number. // This api reads the shard state cached or saved on the chaindb. // Thus, only should be used to read the shard state of the current chain. diff --git a/core/blockchain.go b/core/blockchain.go index 24272a91e..0adc96925 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -6,6 +6,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/event" + "github.com/ethereum/go-ethereum/trie" "github.com/harmony-one/harmony/block" "github.com/harmony-one/harmony/consensus/engine" "github.com/harmony-one/harmony/consensus/reward" @@ -62,6 +63,10 @@ type BlockChain interface { State() (*state.DB, error) // StateAt returns a new mutable state based on a particular point in time. StateAt(root common.Hash) (*state.DB, error) + // Snapshots returns the blockchain snapshot tree. + Snapshots() *snapshot.Tree + // TrieDB returns trie database + TrieDB() *trie.Database // HasBlock checks if a block is fully present in the database or not. HasBlock(hash common.Hash, number uint64) bool // HasState checks if state trie is fully present in the database or not. diff --git a/core/blockchain_impl.go b/core/blockchain_impl.go index 3b5bc6bb1..e9eca1f4c 100644 --- a/core/blockchain_impl.go +++ b/core/blockchain_impl.go @@ -1122,6 +1122,11 @@ func (bc *BlockChainImpl) GetUnclesInChain(b *types.Block, length int) []*block. return uncles } +// TrieDB returns trie database +func (bc *BlockChainImpl) TrieDB() *trie.Database { + return bc.stateCache.TrieDB() +} + // TrieNode retrieves a blob of data associated with a trie node (or code hash) // either from ephemeral in-memory cache, or from persistent storage. func (bc *BlockChainImpl) TrieNode(hash common.Hash) ([]byte, error) { diff --git a/core/blockchain_stub.go b/core/blockchain_stub.go index 804b48a00..e9ef10ce9 100644 --- a/core/blockchain_stub.go +++ b/core/blockchain_stub.go @@ -8,6 +8,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/event" + "github.com/ethereum/go-ethereum/trie" "github.com/harmony-one/harmony/block" "github.com/harmony-one/harmony/consensus/engine" "github.com/harmony-one/harmony/consensus/reward" @@ -64,6 +65,14 @@ func (a Stub) StateAt(common.Hash) (*state.DB, error) { return nil, errors.Errorf("method StateAt not implemented for %s", a.Name) } +func (a Stub) Snapshots() *snapshot.Tree { + return nil +} + +func (a Stub) TrieDB() *trie.Database { + return nil +} + func (a Stub) TrieNode(hash common.Hash) ([]byte, error) { return []byte{}, errors.Errorf("method TrieNode not implemented for %s", a.Name) } diff --git a/go.mod b/go.mod index 8644ba7bd..b1cf4fbc2 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( github.com/coinbase/rosetta-sdk-go v0.7.0 github.com/davecgh/go-spew v1.1.1 github.com/deckarep/golang-set v1.8.0 - github.com/ethereum/go-ethereum v1.11.2 + github.com/ethereum/go-ethereum v1.13.4 github.com/go-redis/redis/v8 v8.11.5 github.com/golang/mock v1.6.0 github.com/golang/protobuf v1.5.3 @@ -38,7 +38,7 @@ require ( github.com/pborman/uuid v1.2.0 github.com/pelletier/go-toml v1.9.5 github.com/pkg/errors v0.9.1 - github.com/prometheus/client_golang v1.14.0 + github.com/prometheus/client_golang v1.17.0 github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 github.com/rjeczalik/notify v0.9.2 github.com/rs/cors v1.7.0 @@ -52,14 +52,14 @@ require ( github.com/whyrusleeping/timecache v0.0.0-20160911033111-cfcb2f1abfee go.uber.org/ratelimit v0.1.0 go.uber.org/zap v1.24.0 - golang.org/x/crypto v0.9.0 - golang.org/x/net v0.10.0 // indirect - golang.org/x/sync v0.2.0 - golang.org/x/sys v0.8.0 // indirect + golang.org/x/crypto v0.14.0 + golang.org/x/net v0.17.0 // indirect + golang.org/x/sync v0.4.0 + golang.org/x/sys v0.13.0 // indirect golang.org/x/time v0.3.0 - golang.org/x/tools v0.9.3 // indirect + golang.org/x/tools v0.14.0 // indirect google.golang.org/grpc v1.55.0 - google.golang.org/protobuf v1.30.0 + google.golang.org/protobuf v1.31.0 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6 @@ -76,27 +76,27 @@ require ( require ( github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 // indirect - github.com/BurntSushi/toml v1.2.0 // indirect - github.com/DataDog/zstd v1.5.2 // indirect + github.com/BurntSushi/toml v1.3.2 // indirect + github.com/DataDog/zstd v1.5.5 // indirect github.com/OpenPeeDeeP/depguard v1.0.1 // indirect github.com/VictoriaMetrics/metrics v1.23.1 // indirect github.com/benbjohnson/clock v1.3.0 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/bits-and-blooms/bitset v1.5.0 // indirect + github.com/bits-and-blooms/bitset v1.7.0 // indirect github.com/bombsimon/wsl/v2 v2.0.0 // indirect github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect github.com/btcsuite/btcd/chaincfg/chainhash v1.0.2 // indirect github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect - github.com/cockroachdb/errors v1.9.1 // indirect + github.com/cockroachdb/errors v1.11.1 // indirect github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect github.com/cockroachdb/pebble v0.0.0-20230302152029-717cbce0c2e3 // indirect - github.com/cockroachdb/redact v1.1.3 // indirect + github.com/cockroachdb/redact v1.1.5 // indirect github.com/containerd/cgroups v1.1.0 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect - github.com/deckarep/golang-set/v2 v2.3.0 // indirect - github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect + github.com/deckarep/golang-set/v2 v2.3.1 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect github.com/dgraph-io/badger v1.6.2 // indirect github.com/dgraph-io/ristretto v0.0.3 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect @@ -109,10 +109,10 @@ require ( github.com/francoispqt/gojay v1.2.13 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff // indirect - github.com/getsentry/sentry-go v0.18.0 // indirect + github.com/getsentry/sentry-go v0.25.0 // indirect github.com/go-critic/go-critic v0.4.0 // indirect github.com/go-lintpack/lintpack v0.5.2 // indirect - github.com/go-ole/go-ole v1.2.6 // indirect + github.com/go-ole/go-ole v1.3.0 // indirect github.com/go-stack/stack v1.8.1 // indirect github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/go-toolsmith/astcast v1.0.0 // indirect @@ -126,7 +126,7 @@ require ( github.com/godbus/dbus/v5 v5.1.0 // indirect github.com/gofrs/flock v0.8.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang/snappy v0.0.4 // indirect + github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2 // indirect github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a // indirect github.com/golangci/errcheck v0.0.0-20181223084120-ef45e06d44b6 // indirect @@ -152,8 +152,8 @@ require ( github.com/hashicorp/golang-lru/v2 v2.0.2 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/holiman/big v0.0.0-20221017200358-a027dc42d04e // indirect - github.com/holiman/uint256 v1.2.2 // indirect - github.com/huin/goupnp v1.1.0 // indirect + github.com/holiman/uint256 v1.2.3 // indirect + github.com/huin/goupnp v1.3.0 // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/ipfs/go-cid v0.4.1 // indirect github.com/ipfs/go-datastore v0.6.0 // indirect @@ -167,7 +167,7 @@ require ( github.com/jbenet/goprocess v0.1.4 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/kisielk/gotool v1.0.0 // indirect - github.com/klauspost/compress v1.16.4 // indirect + github.com/klauspost/compress v1.17.1 // indirect github.com/klauspost/cpuid/v2 v2.2.4 // indirect github.com/koron/go-ssdp v0.0.4 // indirect github.com/kr/pretty v0.3.1 // indirect @@ -188,7 +188,7 @@ require ( github.com/matoous/godox v0.0.0-20190911065817-5d6d842e92eb // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.18 // indirect - github.com/mattn/go-runewidth v0.0.14 // indirect + github.com/mattn/go-runewidth v0.0.15 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/miekg/dns v1.1.53 // indirect github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect @@ -220,10 +220,10 @@ require ( github.com/pingcap/log v0.0.0-20211215031037-e024ba4eb0ee // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e // indirect - github.com/prometheus/client_model v0.3.0 // indirect - github.com/prometheus/common v0.42.0 // indirect - github.com/prometheus/procfs v0.9.0 // indirect - github.com/prometheus/tsdb v0.10.0 // indirect + github.com/prometheus/client_model v0.5.0 // indirect + github.com/prometheus/common v0.44.0 // indirect + github.com/prometheus/procfs v0.12.0 // indirect + github.com/prometheus/tsdb v0.7.1 // indirect github.com/quic-go/qpack v0.4.0 // indirect github.com/quic-go/qtls-go1-19 v0.3.3 // indirect github.com/quic-go/qtls-go1-20 v0.2.3 // indirect @@ -231,7 +231,7 @@ require ( github.com/quic-go/webtransport-go v0.5.2 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/rivo/uniseg v0.4.4 // indirect - github.com/rogpeppe/go-internal v1.9.0 // indirect + github.com/rogpeppe/go-internal v1.11.0 // indirect github.com/securego/gosec v0.0.0-20191002120514-e680875ea14d // indirect github.com/shirou/gopsutil v3.21.11+incompatible // indirect github.com/sirupsen/logrus v1.9.0 // indirect @@ -245,8 +245,8 @@ require ( github.com/subosito/gotenv v1.4.1 // indirect github.com/tikv/pd/client v0.0.0-20220216070739-26c668271201 // indirect github.com/timakin/bodyclose v0.0.0-20190930140734-f7f2e9bca95e // indirect - github.com/tklauser/go-sysconf v0.3.11 // indirect - github.com/tklauser/numcpus v0.6.0 // indirect + github.com/tklauser/go-sysconf v0.3.12 // indirect + github.com/tklauser/numcpus v0.6.1 // indirect github.com/tommy-muehle/go-mnd v1.1.1 // indirect github.com/torquem-ch/mdbx-go v0.27.10 // indirect github.com/tyler-smith/go-bip39 v1.1.0 // indirect @@ -256,16 +256,16 @@ require ( github.com/valyala/fastrand v1.1.0 // indirect github.com/valyala/histogram v1.2.0 // indirect github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect - github.com/yusufpapurcu/wmi v1.2.2 // indirect + github.com/yusufpapurcu/wmi v1.2.3 // indirect go.opencensus.io v0.24.0 // indirect go.uber.org/atomic v1.10.0 // indirect go.uber.org/dig v1.16.1 // indirect go.uber.org/fx v1.19.2 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 // indirect - golang.org/x/mod v0.10.0 // indirect - golang.org/x/term v0.8.0 // indirect - golang.org/x/text v0.9.0 // indirect + golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect + golang.org/x/mod v0.13.0 // indirect + golang.org/x/term v0.13.0 // indirect + golang.org/x/text v0.13.0 // indirect google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect diff --git a/go.sum b/go.sum index d5200066d..115ec6eba 100644 --- a/go.sum +++ b/go.sum @@ -60,8 +60,9 @@ github.com/Azure/azure-sdk-for-go/sdk/internal v0.8.3/go.mod h1:KLF4gFr6DcKFZwSu github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v0.3.0/go.mod h1:tPaiy8S5bQ+S5sOiDlINkp7+Ef339+Nz5L5XO+cnOHo= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= -github.com/BurntSushi/toml v1.2.0 h1:Rt8g24XnyGTyglgET/PRUNlrUeu9F5L+7FilkXfZgs0= github.com/BurntSushi/toml v1.2.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= +github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/CloudyKit/fastprinter v0.0.0-20170127035650-74b38d55f37a/go.mod h1:EFZQ978U7x8IRnstaskI3IysnWY5Ao3QgZUKOXlsAdw= github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno= @@ -71,8 +72,9 @@ github.com/CloudyKit/jet/v6 v6.1.0/go.mod h1:d3ypHeIRNo2+XyqnGA8s+aphtcVpjP5hPwP github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= github.com/DataDog/zstd v1.4.1/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= -github.com/DataDog/zstd v1.5.2 h1:vUG4lAyuPCXO0TLbXvPv7EB7cNK1QV/luu55UHLrrn8= github.com/DataDog/zstd v1.5.2/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= +github.com/DataDog/zstd v1.5.5 h1:oWf5W7GtOLgp6bciQYDmhHHjdhYkALu6S/5Ni9ZgSvQ= +github.com/DataDog/zstd v1.5.5/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= github.com/Joker/jade v1.0.1-0.20190614124447-d475f43051e7/go.mod h1:6E6s8o2AE4KhCrqr6GRJjdC/gNfTdxkIXvuGZZda2VM= @@ -138,8 +140,8 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= -github.com/bits-and-blooms/bitset v1.5.0 h1:NpE8frKRLGHIcEzkR+gZhiioW1+WbYV6fKwD6ZIpQT8= -github.com/bits-and-blooms/bitset v1.5.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= +github.com/bits-and-blooms/bitset v1.7.0 h1:YjAGVd3XmtK9ktAbX8Zg2g2PwLIMjGREZJHlV4j7NEo= +github.com/bits-and-blooms/bitset v1.7.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM= github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/bmizerany/pat v0.0.0-20170815010413-6226ea591a40/go.mod h1:8rLXio+WjiTceGBHIoTvn60HIbs7Hm7bcHjyrSqYB9c= @@ -204,8 +206,9 @@ github.com/cockroachdb/datadriven v1.0.2 h1:H9MtNqVoVhvd9nCBwOyDjUEdZCREqbIdCJD9 github.com/cockroachdb/datadriven v1.0.2/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= github.com/cockroachdb/errors v1.6.1/go.mod h1:tm6FTP5G81vwJ5lC0SizQo374JNCOPrHyXGitRJoDqM= github.com/cockroachdb/errors v1.8.1/go.mod h1:qGwQn6JmZ+oMjuLwjWzUNqblqk0xl4CVV3SQbGwK7Ac= -github.com/cockroachdb/errors v1.9.1 h1:yFVvsI0VxmRShfawbt/laCIDy/mtTqqnvoNgiy5bEV8= github.com/cockroachdb/errors v1.9.1/go.mod h1:2sxOtL2WIc096WSZqZ5h8fa17rdDq9HZOZLBCor4mBk= +github.com/cockroachdb/errors v1.11.1 h1:xSEW75zKaKCWzR3OfxXUxgrk/NtT4G1MiOv5lWZazG8= +github.com/cockroachdb/errors v1.11.1/go.mod h1:8MUxA3Gi6b25tYlFEBGLf+D8aISL+M4MIpiWMSNRfxw= github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI= github.com/cockroachdb/logtags v0.0.0-20211118104740-dabe8e521a4f/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE= @@ -214,8 +217,9 @@ github.com/cockroachdb/pebble v0.0.0-20230209160836-829675f94811/go.mod h1:Nb5lg github.com/cockroachdb/pebble v0.0.0-20230302152029-717cbce0c2e3 h1:S4re5MXHfznkOlgkgUfh9ptgaG2esdH95IuJWwP0fM0= github.com/cockroachdb/pebble v0.0.0-20230302152029-717cbce0c2e3/go.mod h1:9lRMC4XN3/BLPtIp6kAKwIaHu369NOf2rMucPzipz50= github.com/cockroachdb/redact v1.0.8/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= -github.com/cockroachdb/redact v1.1.3 h1:AKZds10rFSIj7qADf0g46UixK8NNLwWTNdCIGS5wfSQ= github.com/cockroachdb/redact v1.1.3/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= +github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwPJ30= +github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= github.com/cockroachdb/sentry-go v0.6.1-cockroachdb.2/go.mod h1:8BT+cPK6xvFOcRlk0R8eg+OTkcqI6baNH4xAkpiYVvQ= github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= github.com/coinbase/rosetta-sdk-go v0.7.0 h1:lmTO/JEpCvZgpbkOITL95rA80CPKb5CtMzLaqF2mCNg= @@ -258,13 +262,13 @@ github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c/go.mod h1:6Uh github.com/deckarep/golang-set v1.8.0 h1:sk9/l/KqpunDwP7pSjUg0keiOOLEnOBHzykLrsPppp4= github.com/deckarep/golang-set v1.8.0/go.mod h1:5nI87KwE7wgsBU1F4GKAw2Qod7p5kyS383rP6+o6qqo= github.com/deckarep/golang-set/v2 v2.1.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= -github.com/deckarep/golang-set/v2 v2.3.0 h1:qs18EKUfHm2X9fA50Mr/M5hccg2tNnVqsiBImnyDs0g= -github.com/deckarep/golang-set/v2 v2.3.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= -github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= +github.com/deckarep/golang-set/v2 v2.3.1 h1:vjmkvJt/IV27WXPyYQpAh4bRyWJc5Y435D17XQ9QU5A= +github.com/deckarep/golang-set/v2 v2.3.1/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= +github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 h1:HbphB4TFFXpv7MNrT52FGrrgVXF1owhMVTHFZIlnvd4= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0/go.mod h1:DZGJHZMqrU4JJqFAWUS2UO1+lbSKsdiOoYi9Zzey7Fc= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= github.com/deepmap/oapi-codegen v1.6.0/go.mod h1:ryDa9AgbELGeB+YEXE1dR53yAjHwFvE9iAUlWl9Al3M= github.com/deepmap/oapi-codegen v1.8.2/go.mod h1:YLgSKSDv/bZQB7N4ws6luhozi3cEdRktEqrX88CvjIw= @@ -352,8 +356,9 @@ github.com/gballet/go-verkle v0.0.0-20220902153445-097bd83b7732/go.mod h1:o/XfIX github.com/getkin/kin-openapi v0.53.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4= github.com/getkin/kin-openapi v0.61.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4= github.com/getsentry/sentry-go v0.12.0/go.mod h1:NSap0JBYWzHND8oMbyi0+XZhUalc1TBdRL1M71JZW2c= -github.com/getsentry/sentry-go v0.18.0 h1:MtBW5H9QgdcJabtZcuJG80BMOwaBpkRDZkxRkNC1sN0= github.com/getsentry/sentry-go v0.18.0/go.mod h1:Kgon4Mby+FJ7ZWHFUAZgVaIa8sxHtnRJRLTXZr51aKQ= +github.com/getsentry/sentry-go v0.25.0 h1:q6Eo+hS+yoJlTO3uu/azhQadsD8V+jQn2D8VvX1eOyI= +github.com/getsentry/sentry-go v0.25.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= github.com/ghemawat/stream v0.0.0-20171120220530-696b145b53b9/go.mod h1:106OIgooyS7OzLDOpUGgm9fA3bQENb/cFSyyBmMoJDs= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= @@ -393,8 +398,9 @@ github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KE github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= -github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= +github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= @@ -518,8 +524,9 @@ github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8l github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.2-0.20190904063534-ff6b7dc882cf/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= +github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2 h1:23T5iq8rbUYlhpt5DB4XJkc6BU31uODLD1o1gKvZmD0= github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2/go.mod h1:k9Qvh+8juN+UKMCS/3jFtGICgW8O96FVaZsaxdzDkR4= github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a h1:w8hkcTqaFpzKqonE9uMCefW1WDie15eSP/4MssdenaM= @@ -682,13 +689,13 @@ github.com/holiman/big v0.0.0-20221017200358-a027dc42d04e/go.mod h1:j9cQbcqHQujT github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= github.com/holiman/uint256 v1.2.0/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw= -github.com/holiman/uint256 v1.2.2 h1:TXKcSGc2WaxPD2+bmzAsVthL4+pEN0YwXcL5qED83vk= -github.com/holiman/uint256 v1.2.2/go.mod h1:SC8Ryt4n+UBbPbIBKaG9zbbDlp4jOru9xFZmPzLUTxw= +github.com/holiman/uint256 v1.2.3 h1:K8UWO1HUJpRMXBxbmaY1Y8IAMZC/RsKB+ArEnnK4l5o= +github.com/holiman/uint256 v1.2.3/go.mod h1:SC8Ryt4n+UBbPbIBKaG9zbbDlp4jOru9xFZmPzLUTxw= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= github.com/huin/goupnp v1.0.3/go.mod h1:ZxNlw5WqJj6wSsRK5+YfflQGXYfccj5VgQsMNixHM7Y= -github.com/huin/goupnp v1.1.0 h1:gEe0Dp/lZmPZiDFzJJaOfUpOvv2MKUkoBX8lDrn9vKU= -github.com/huin/goupnp v1.1.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= +github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= +github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= github.com/hydrogen18/memlistener v0.0.0-20141126152155-54553eb933fb/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= @@ -816,8 +823,8 @@ github.com/klauspost/compress v1.15.0/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47e github.com/klauspost/compress v1.15.10/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= github.com/klauspost/compress v1.15.11/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= github.com/klauspost/compress v1.15.15/go.mod h1:ZcK2JAFqKOpnBlxcLsJzYfrS9X1akm9fHZNnD9+Vo/4= -github.com/klauspost/compress v1.16.4 h1:91KN02FnsOYhuunwU4ssRe8lc2JosWmizWa91B5v1PU= -github.com/klauspost/compress v1.16.4/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/compress v1.17.1 h1:NE3C767s2ak2bweCZo3+rdP4U/HoyVXLv/X9f2gPS5g= +github.com/klauspost/compress v1.17.1/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid v0.0.0-20180405133222-e7e905edc00e/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= @@ -939,8 +946,8 @@ github.com/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp9 github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= -github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= -github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= +github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-tty v0.0.0-20180907095812-13ff1204f104/go.mod h1:XPvLUNfbS4fJH25nqRHfWLMa1ONC8Amw+mIA639KxkE= github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= @@ -1147,15 +1154,17 @@ github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= github.com/prometheus/client_golang v1.12.0/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= -github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= +github.com/prometheus/client_golang v1.17.0 h1:rl2sfwZMtSthVU752MqfjQozy7blglC+1SOtjMAMh+Q= +github.com/prometheus/client_golang v1.17.0/go.mod h1:VeL+gMmOAxkS2IqfCq0ZmHSL+LjWfWDUmp1mBz9JgUY= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.1-0.20210607210712-147c58e9608a/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= -github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= +github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= +github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= @@ -1166,8 +1175,8 @@ github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9 github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= github.com/prometheus/common v0.39.0/go.mod h1:6XBZ7lYdLCbkAVhwRsWTZn+IN5AB9F/NXd5w0BbEX0Y= -github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM= -github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= +github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY= +github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= @@ -1176,11 +1185,11 @@ github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4O github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= -github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= +github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= +github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= +github.com/prometheus/tsdb v0.7.1 h1:YZcsG11NqnK4czYLrWd9mpEuAJIHVQLwdrleYfszMAA= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= -github.com/prometheus/tsdb v0.10.0 h1:If5rVCMTp6W2SiRAQFlbpJNgVlgMEd+U2GZckwK38ic= -github.com/prometheus/tsdb v0.10.0/go.mod h1:oi49uRhEe9dPUTlS3JRZOwJuVi6tmh10QSgwXEyGCt4= github.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c/go.mod h1:5STLWrekHfjyYwxBRVRXNOSewLJ3PWfDJd1VyTS21fI= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= @@ -1209,8 +1218,9 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= -github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= +github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= @@ -1363,12 +1373,12 @@ github.com/timakin/bodyclose v0.0.0-20190930140734-f7f2e9bca95e/go.mod h1:Qimiff github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= github.com/tklauser/go-sysconf v0.3.5/go.mod h1:MkWzOF4RMCshBAMXuhXJs64Rte09mITnppBXY/rYEFI= github.com/tklauser/go-sysconf v0.3.10/go.mod h1:C8XykCvCb+Gn0oNCWPIlcb0RuglQTYaQ2hGm7jmxEFk= -github.com/tklauser/go-sysconf v0.3.11 h1:89WgdJhk5SNwJfu+GKyYveZ4IaJ7xAkecBo+KdJV0CM= -github.com/tklauser/go-sysconf v0.3.11/go.mod h1:GqXfhXY3kiPa0nAXPDIQIWzJbMCB7AmcWpGR8lSZfqI= +github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= +github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= github.com/tklauser/numcpus v0.2.2/go.mod h1:x3qojaO3uyYt0i56EW/VUYs7uBvdl2fkfZFu0T9wgjM= github.com/tklauser/numcpus v0.4.0/go.mod h1:1+UI3pD8NW14VMwdgJNJ1ESk2UnwhAnz5hMwiKKqXCQ= -github.com/tklauser/numcpus v0.6.0 h1:kebhY2Qt+3U6RNK7UqpYNA+tJ23IBEGKkB7JQBfDYms= -github.com/tklauser/numcpus v0.6.0/go.mod h1:FEZLMke0lhOUG6w2JadTzp0a+Nl8PF/GFkQ5UVIcaL4= +github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= +github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tommy-muehle/go-mnd v1.1.1 h1:4D0wuPKjOTiK2garzuPGGvm4zZ/wLYDOH8TJSABC7KU= github.com/tommy-muehle/go-mnd v1.1.1/go.mod h1:dSUh0FtTP8VhvkL1S+gUR1OKd9ZnSaozuI6r3m6wOig= @@ -1445,8 +1455,9 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg= github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= +github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw= +github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= @@ -1546,8 +1557,8 @@ golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220926161630-eccd6366d1be/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= -golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g= -golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= +golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= +golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1564,8 +1575,8 @@ golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMk golang.org/x/exp v0.0.0-20200513190911-00229845015e/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= golang.org/x/exp v0.0.0-20220426173459-3bcf042a4bf5/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE= golang.org/x/exp v0.0.0-20230206171751-46f607a40771/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= -golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 h1:k/i9J1pBpvlfR+9QsetwPyERsqu1GIbi967PQMq3Ivc= -golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= +golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI= +golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo= golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= @@ -1597,8 +1608,8 @@ golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.6.0-dev.0.20211013180041-c96bc1413d57/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= -golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk= -golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY= +golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1673,8 +1684,8 @@ golang.org/x/net v0.0.0-20221002022538-bcab6841153b/go.mod h1:YDH+HFinaLZZlnHAfS golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= -golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= -golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1707,8 +1718,8 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI= -golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ= +golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1826,15 +1837,17 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= -golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols= -golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= +golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1847,8 +1860,8 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1946,8 +1959,8 @@ golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.8-0.20211029000441-d6a9af8af023/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= -golang.org/x/tools v0.9.3 h1:Gn1I8+64MsuTb/HpH+LmQtNas23LhUVr3rYZ0eKuaMM= -golang.org/x/tools v0.9.3/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= +golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc= +golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -2093,8 +2106,8 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= -google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/hmy/downloader/adapter_test.go b/hmy/downloader/adapter_test.go index 692ed8ad7..4bc023b5c 100644 --- a/hmy/downloader/adapter_test.go +++ b/hmy/downloader/adapter_test.go @@ -8,11 +8,13 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/event" + "github.com/ethereum/go-ethereum/trie" "github.com/harmony-one/harmony/block" "github.com/harmony-one/harmony/consensus/engine" "github.com/harmony-one/harmony/consensus/reward" "github.com/harmony-one/harmony/core/state" + "github.com/harmony-one/harmony/core/state/snapshot" "github.com/harmony-one/harmony/core/types" "github.com/harmony-one/harmony/crypto/bls" "github.com/harmony-one/harmony/internal/params" @@ -88,7 +90,9 @@ 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) Snapshots() *snapshot.Tree { return nil } func (bc *testBlockChain) TrieNode(hash common.Hash) ([]byte, error) { return []byte{}, nil } +func (bc *testBlockChain) TrieDB() *trie.Database { return 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 } diff --git a/internal/chain/engine_test.go b/internal/chain/engine_test.go index 7654d9d6c..530cbdc01 100644 --- a/internal/chain/engine_test.go +++ b/internal/chain/engine_test.go @@ -5,6 +5,7 @@ import ( "math/big" "testing" + "github.com/ethereum/go-ethereum/trie" bls_core "github.com/harmony-one/bls/ffi/go/bls" "github.com/harmony-one/harmony/block" blockfactory "github.com/harmony-one/harmony/block/factory" @@ -21,6 +22,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/harmony-one/harmony/core/rawdb" "github.com/harmony-one/harmony/core/state" + "github.com/harmony-one/harmony/core/state/snapshot" "github.com/harmony-one/harmony/core/types" "github.com/harmony-one/harmony/internal/params" ) @@ -328,6 +330,7 @@ func (bc *fakeBlockChain) ContractCode(hash common.Hash) ([]byte, error) 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) TrieDB() *trie.Database { return 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 } @@ -353,6 +356,9 @@ func (bc *fakeBlockChain) Config() *params.ChainConfig { func (cr *fakeBlockChain) StateAt(root common.Hash) (*state.DB, error) { return nil, nil } +func (cr *fakeBlockChain) Snapshots() *snapshot.Tree { + return nil +} func (bc *fakeBlockChain) ReadValidatorSnapshot(addr common.Address) (*staking.ValidatorSnapshot, error) { return nil, nil } diff --git a/p2p/stream/protocols/sync/chain.go b/p2p/stream/protocols/sync/chain.go index a095fffc1..efabd9307 100644 --- a/p2p/stream/protocols/sync/chain.go +++ b/p2p/stream/protocols/sync/chain.go @@ -1,12 +1,21 @@ package sync import ( + Bytes "bytes" + "fmt" + "time" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/light" + "github.com/ethereum/go-ethereum/trie" "github.com/harmony-one/harmony/block" "github.com/harmony-one/harmony/consensus/engine" + "github.com/harmony-one/harmony/core/state" "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/harmony-one/harmony/p2p/stream/protocols/sync/message" "github.com/pkg/errors" ) @@ -18,6 +27,10 @@ type chainHelper interface { getBlocksByHashes(hs []common.Hash) ([]*types.Block, error) getNodeData(hs []common.Hash) ([][]byte, error) getReceipts(hs []common.Hash) ([]types.Receipts, error) + getAccountRange(root common.Hash, origin common.Hash, limit common.Hash, bytes uint64) ([]*message.AccountData, [][]byte, error) + getStorageRanges(root common.Hash, accounts []common.Hash, origin common.Hash, limit common.Hash, bytes uint64) ([]*message.StoragesData, [][]byte, error) + getByteCodes(hs []common.Hash, bytes uint64) ([][]byte, error) + getTrieNodes(root common.Hash, paths []*message.TrieNodePathSet, bytes uint64, start time.Time) ([][]byte, error) } type chainHelperImpl struct { @@ -182,3 +195,285 @@ func (ch *chainHelperImpl) getReceipts(hs []common.Hash) ([]types.Receipts, erro } return receipts, nil } + +// getAccountRangeRequest +func (ch *chainHelperImpl) getAccountRange(root common.Hash, origin common.Hash, limit common.Hash, bytes uint64) ([]*message.AccountData, [][]byte, error) { + if bytes > softResponseLimit { + bytes = softResponseLimit + } + // Retrieve the requested state and bail out if non existent + tr, err := trie.New(trie.StateTrieID(root), ch.chain.TrieDB()) + if err != nil { + return nil, nil, err + } + it, err := ch.chain.Snapshots().AccountIterator(root, origin) + if err != nil { + return nil, nil, err + } + // Iterate over the requested range and pile accounts up + var ( + accounts []*message.AccountData + size uint64 + last common.Hash + ) + for it.Next() { + hash, account := it.Hash(), common.CopyBytes(it.Account()) + + // Track the returned interval for the Merkle proofs + last = hash + + // Assemble the reply item + size += uint64(common.HashLength + len(account)) + accounts = append(accounts, &message.AccountData{ + Hash: hash[:], + Body: account, + }) + // If we've exceeded the request threshold, abort + if Bytes.Compare(hash[:], limit[:]) >= 0 { + break + } + if size > bytes { + break + } + } + it.Release() + + // Generate the Merkle proofs for the first and last account + proof := light.NewNodeSet() + if err := tr.Prove(origin[:], 0, proof); err != nil { + utils.Logger().Warn().Err(err).Interface("origin", origin).Msg("Failed to prove account range") + return nil, nil, err + } + if last != (common.Hash{}) { + if err := tr.Prove(last[:], 0, proof); err != nil { + utils.Logger().Warn().Err(err).Interface("last", last).Msg("Failed to prove account range") + return nil, nil, err + } + } + var proofs [][]byte + for _, blob := range proof.NodeList() { + proofs = append(proofs, blob) + } + return accounts, proofs, nil +} + +// getStorageRangesRequest +func (ch *chainHelperImpl) getStorageRanges(root common.Hash, accounts []common.Hash, origin common.Hash, limit common.Hash, bytes uint64) ([]*message.StoragesData, [][]byte, error) { + if bytes > softResponseLimit { + bytes = softResponseLimit + } + + // Calculate the hard limit at which to abort, even if mid storage trie + hardLimit := uint64(float64(bytes) * (1 + stateLookupSlack)) + + // Retrieve storage ranges until the packet limit is reached + var ( + slots []*message.StoragesData + proofs [][]byte + size uint64 + ) + for _, account := range accounts { + // If we've exceeded the requested data limit, abort without opening + // a new storage range (that we'd need to prove due to exceeded size) + if size >= bytes { + break + } + // The first account might start from a different origin and end sooner + // origin==nil or limit ==nil + // Retrieve the requested state and bail out if non existent + it, err := ch.chain.Snapshots().StorageIterator(root, account, origin) + if err != nil { + return nil, nil, err + } + // Iterate over the requested range and pile slots up + var ( + storage []*message.StorageData + last common.Hash + abort bool + ) + for it.Next() { + if size >= hardLimit { + abort = true + break + } + hash, slot := it.Hash(), common.CopyBytes(it.Slot()) + + // Track the returned interval for the Merkle proofs + last = hash + + // Assemble the reply item + size += uint64(common.HashLength + len(slot)) + storage = append(storage, &message.StorageData{ + Hash: hash[:], + Body: slot, + }) + // If we've exceeded the request threshold, abort + if Bytes.Compare(hash[:], limit[:]) >= 0 { + break + } + } + + if len(storage) > 0 { + storages := &message.StoragesData{ + Data: storage, + } + slots = append(slots, storages) + } + it.Release() + + // Generate the Merkle proofs for the first and last storage slot, but + // only if the response was capped. If the entire storage trie included + // in the response, no need for any proofs. + if origin != (common.Hash{}) || (abort && len(storage) > 0) { + // Request started at a non-zero hash or was capped prematurely, add + // the endpoint Merkle proofs + accTrie, err := trie.NewStateTrie(trie.StateTrieID(root), ch.chain.TrieDB()) + if err != nil { + return nil, nil, err + } + acc, err := accTrie.TryGetAccountByHash(account) + if err != nil || acc == nil { + return nil, nil, err + } + id := trie.StorageTrieID(root, account, acc.Root) + stTrie, err := trie.NewStateTrie(id, ch.chain.TrieDB()) + if err != nil { + return nil, nil, err + } + proof := light.NewNodeSet() + if err := stTrie.Prove(origin[:], 0, proof); err != nil { + utils.Logger().Warn().Interface("origin", origin).Msg("Failed to prove storage range") + return nil, nil, err + } + if last != (common.Hash{}) { + if err := stTrie.Prove(last[:], 0, proof); err != nil { + utils.Logger().Warn().Interface("last", last).Msg("Failed to prove storage range") + return nil, nil, err + } + } + for _, blob := range proof.NodeList() { + proofs = append(proofs, blob) + } + // Proof terminates the reply as proofs are only added if a node + // refuses to serve more data (exception when a contract fetch is + // finishing, but that's that). + break + } + } + return slots, proofs, nil +} + +// getByteCodesRequest +func (ch *chainHelperImpl) getByteCodes(hashes []common.Hash, bytes uint64) ([][]byte, error) { + if bytes > softResponseLimit { + bytes = softResponseLimit + } + if len(hashes) > maxCodeLookups { + hashes = hashes[:maxCodeLookups] + } + // Retrieve bytecodes until the packet size limit is reached + var ( + codes [][]byte + totalBytes uint64 + ) + for _, hash := range hashes { + if hash == state.EmptyCodeHash { + // Peers should not request the empty code, but if they do, at + // least sent them back a correct response without db lookups + codes = append(codes, []byte{}) + } else if blob, err := ch.chain.ContractCode(hash); err == nil { // Double Check: ContractCodeWithPrefix + codes = append(codes, blob) + totalBytes += uint64(len(blob)) + } + if totalBytes > bytes { + break + } + } + return codes, nil +} + +// getTrieNodesRequest +func (ch *chainHelperImpl) getTrieNodes(root common.Hash, paths []*message.TrieNodePathSet, bytes uint64, start time.Time) ([][]byte, error) { + if bytes > softResponseLimit { + bytes = softResponseLimit + } + // Make sure we have the state associated with the request + triedb := ch.chain.TrieDB() + + accTrie, err := trie.NewStateTrie(trie.StateTrieID(root), triedb) + if err != nil { + // We don't have the requested state available, bail out + return nil, nil + } + // The 'snap' might be nil, in which case we cannot serve storage slots. + snap := ch.chain.Snapshots().Snapshot(root) + // Retrieve trie nodes until the packet size limit is reached + var ( + nodes [][]byte + TotalBytes uint64 + loads int // Trie hash expansions to count database reads + ) + for _, p := range paths { + switch len(p.Pathset) { + case 0: + // Ensure we penalize invalid requests + return nil, fmt.Errorf("zero-item pathset requested") + + case 1: + // If we're only retrieving an account trie node, fetch it directly + blob, resolved, err := accTrie.TryGetNode(p.Pathset[0]) + loads += resolved // always account database reads, even for failures + if err != nil { + break + } + nodes = append(nodes, blob) + TotalBytes += uint64(len(blob)) + + default: + var stRoot common.Hash + // Storage slots requested, open the storage trie and retrieve from there + if snap == nil { + // We don't have the requested state snapshotted yet (or it is stale), + // but can look up the account via the trie instead. + account, err := accTrie.TryGetAccountByHash(common.BytesToHash(p.Pathset[0])) + loads += 8 // We don't know the exact cost of lookup, this is an estimate + if err != nil || account == nil { + break + } + stRoot = account.Root + } else { + account, err := snap.Account(common.BytesToHash(p.Pathset[0])) + loads++ // always account database reads, even for failures + if err != nil || account == nil { + break + } + stRoot = common.BytesToHash(account.Root) + } + id := trie.StorageTrieID(root, common.BytesToHash(p.Pathset[0]), stRoot) + stTrie, err := trie.NewStateTrie(id, triedb) + loads++ // always account database reads, even for failures + if err != nil { + break + } + for _, path := range p.Pathset[1:] { + blob, resolved, err := stTrie.TryGetNode(path) + loads += resolved // always account database reads, even for failures + if err != nil { + break + } + nodes = append(nodes, blob) + TotalBytes += uint64(len(blob)) + + // Sanity check limits to avoid DoS on the store trie loads + if TotalBytes > bytes || loads > maxTrieNodeLookups || time.Since(start) > maxTrieNodeTimeSpent { + break + } + } + } + // Abort request processing if we've exceeded our limits + if TotalBytes > bytes || loads > maxTrieNodeLookups || time.Since(start) > maxTrieNodeTimeSpent { + break + } + } + return nodes, nil +} diff --git a/p2p/stream/protocols/sync/chain_test.go b/p2p/stream/protocols/sync/chain_test.go index 8d478e2b3..414492054 100644 --- a/p2p/stream/protocols/sync/chain_test.go +++ b/p2p/stream/protocols/sync/chain_test.go @@ -6,12 +6,15 @@ import ( "errors" "fmt" "math/big" + "time" + "unsafe" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/rlp" protobuf "github.com/golang/protobuf/proto" "github.com/harmony-one/harmony/block" "github.com/harmony-one/harmony/core/types" + "github.com/harmony-one/harmony/p2p/stream/protocols/sync/message" syncpb "github.com/harmony-one/harmony/p2p/stream/protocols/sync/message" ) @@ -60,6 +63,26 @@ func (tch *testChainHelper) getReceipts(hs []common.Hash) ([]types.Receipts, err return receipts, nil } +func (ch *testChainHelper) getAccountRange(root common.Hash, origin common.Hash, limit common.Hash, bytes uint64) ([]*message.AccountData, [][]byte, error) { + testAccountRanges, testProofs := makeTestAccountRanges(2) + return testAccountRanges, testProofs, nil +} + +func (ch *testChainHelper) getStorageRanges(root common.Hash, accounts []common.Hash, origin common.Hash, limit common.Hash, bytes uint64) ([]*message.StoragesData, [][]byte, error) { + testSlots, testProofs := makeTestStorageRanges(2) + return testSlots, testProofs, nil +} + +func (ch *testChainHelper) getByteCodes(hs []common.Hash, bytes uint64) ([][]byte, error) { + testByteCodes := makeTestByteCodes(2) + return testByteCodes, nil +} + +func (ch *testChainHelper) getTrieNodes(root common.Hash, paths []*message.TrieNodePathSet, bytes uint64, start time.Time) ([][]byte, error) { + testTrieNodes := makeTestTrieNodes(2) + return testTrieNodes, nil +} + func checkGetReceiptsResult(b []byte, hs []common.Hash) error { var msg = &syncpb.Message{} if err := protobuf.Unmarshal(b, msg); err != nil { @@ -156,6 +179,57 @@ func makeTestReceipts(n int, nPerBlock int) []*types.Receipt { return receipts } +func makeTestAccountRanges(n int) ([]*message.AccountData, [][]byte) { + accounts := make([]*message.AccountData, n) + proofs := make([][]byte, n) + for i := 0; i < n; i++ { + accounts[i] = &message.AccountData{ + Hash: numberToHash(uint64(i * 2)).Bytes(), + Body: numberToHash(uint64(i*2 + 1)).Bytes(), + } + } + for i := 0; i < n; i++ { + proofs[i] = numberToHash(uint64(i)).Bytes() + } + return accounts, proofs +} + +func makeTestStorageRanges(n int) ([]*message.StoragesData, [][]byte) { + slots := make([]*message.StoragesData, n) + proofs := make([][]byte, n) + for i := 0; i < n; i++ { + slots[i] = &message.StoragesData{ + Data: make([]*syncpb.StorageData, 2), + } + for j := 0; j < 2; j++ { + slots[i].Data[j] = &message.StorageData{ + Hash: numberToHash(uint64(i * 2)).Bytes(), + Body: numberToHash(uint64(i*2 + 1)).Bytes(), + } + } + } + for i := 0; i < n; i++ { + proofs[i] = numberToHash(uint64(i)).Bytes() + } + return slots, proofs +} + +func makeTestByteCodes(n int) [][]byte { + byteCodes := make([][]byte, n) + for i := 0; i < n; i++ { + byteCodes[i] = numberToHash(uint64(i)).Bytes() + } + return byteCodes +} + +func makeTestTrieNodes(n int) [][]byte { + trieNodes := make([][]byte, n) + for i := 0; i < n; i++ { + trieNodes[i] = numberToHash(uint64(i)).Bytes() + } + return trieNodes +} + func decodeBlocksBytes(bbs [][]byte) ([]*types.Block, error) { blocks := make([]*types.Block, 0, len(bbs)) @@ -169,6 +243,19 @@ func decodeBlocksBytes(bbs [][]byte) ([]*types.Block, error) { return blocks, nil } +func decodeHashBytes(hs [][]byte) ([]common.Hash, error) { + hashes := make([]common.Hash, 0) + + for _, h := range hs { + var hash common.Hash + if err := rlp.DecodeBytes(h, &hash); err != nil { + return nil, err + } + hashes = append(hashes, hash) + } + return hashes, nil +} + func checkBlockNumberResult(b []byte) error { var msg = &syncpb.Message{} if err := protobuf.Unmarshal(b, msg); err != nil { @@ -230,3 +317,90 @@ func checkBlocksByHashesResult(b []byte, hs []common.Hash) error { } return nil } + +func checkAccountRangeResult(bytes uint64, b []byte) error { + var msg = &syncpb.Message{} + if err := protobuf.Unmarshal(b, msg); err != nil { + return err + } + gbResp, err := msg.GetAccountRangesResponse() + if err != nil { + return err + } + if len(gbResp.Accounts) == 0 { + return errors.New("nil response from GetAccountRanges") + } + if len(gbResp.Proof) != len(gbResp.Accounts) { + return errors.New("unexpected proofs") + } + if len(b) > int(bytes) { + return errors.New("unexpected data bytes") + } + return nil +} + +func checkStorageRangesResult(accounts []common.Hash, bytes uint64, b []byte) error { + var msg = &syncpb.Message{} + if err := protobuf.Unmarshal(b, msg); err != nil { + return err + } + gbResp, err := msg.GetStorageRangesResponse() + if err != nil { + return err + } + if len(gbResp.Slots) == 0 { + return errors.New("nil response from GetStorageRanges") + } + if len(gbResp.Slots) != len(gbResp.Proof) { + return errors.New("unexpected proofs") + } + sz := unsafe.Sizeof(gbResp.Slots) + if sz > uintptr(bytes) { + return errors.New("unexpected slot bytes") + } + return nil +} + +func checkByteCodesResult(hs []common.Hash, bytes uint64, b []byte) error { + var msg = &syncpb.Message{} + if err := protobuf.Unmarshal(b, msg); err != nil { + return err + } + gbResp, err := msg.GetByteCodesResponse() + if err != nil { + return err + } + if len(gbResp.Codes) == 0 { + return errors.New("nil response from GetByteCodes") + } + if len(gbResp.Codes) != len(hs) { + return errors.New("unexpected byte codes") + } + sz := len(hs) * common.HashLength + if sz > int(bytes) { + return errors.New("unexpected data bytes") + } + return nil +} + +func checkTrieNodesResult(hs []common.Hash, bytes uint64, b []byte) error { + var msg = &syncpb.Message{} + if err := protobuf.Unmarshal(b, msg); err != nil { + return err + } + gbResp, err := msg.GetTrieNodesResponse() + if err != nil { + return err + } + if len(gbResp.Nodes) == 0 { + return errors.New("nil response from checkGetTrieNodes") + } + if len(gbResp.Nodes) != len(hs) { + return errors.New("unexpected byte codes") + } + sz := len(hs) * common.HashLength + if sz > int(bytes) { + return errors.New("unexpected data bytes") + } + return nil +} diff --git a/p2p/stream/protocols/sync/client.go b/p2p/stream/protocols/sync/client.go index 0b8a2a2fd..9024142ce 100644 --- a/p2p/stream/protocols/sync/client.go +++ b/p2p/stream/protocols/sync/client.go @@ -10,6 +10,7 @@ import ( "github.com/ethereum/go-ethereum/rlp" protobuf "github.com/golang/protobuf/proto" "github.com/harmony-one/harmony/core/types" + "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" "github.com/pkg/errors" @@ -181,6 +182,120 @@ func (p *Protocol) GetNodeData(ctx context.Context, hs []common.Hash, opts ...Op return } +// GetAccountRange do getAccountRange through sync stream protocol. +// returns the accounts along with proofs as result, target stream id, and error +func (p *Protocol) GetAccountRange(ctx context.Context, root common.Hash, origin common.Hash, limit common.Hash, bytes uint64, opts ...Option) (accounts []*message.AccountData, proof []common.Hash, stid sttypes.StreamID, err error) { + timer := p.doMetricClientRequest("getAccountRange") + defer p.doMetricPostClientRequest("getAccountRange", err, timer) + + if bytes == 0 { + err = fmt.Errorf("zero account ranges bytes requested") + return + } + if bytes > softResponseLimit { + err = fmt.Errorf("requested bytes exceed limit") + return + } + req := newGetAccountRangeRequest(root, origin, limit, bytes) + resp, stid, err := p.rm.DoRequest(ctx, req, opts...) + if err != nil { + return + } + accounts, proof, err = req.getAccountRangeFromResponse(resp) + return +} + +// GetStorageRanges do getStorageRanges through sync stream protocol. +// returns the slots along with proofs as result, target stream id, and error +func (p *Protocol) GetStorageRanges(ctx context.Context, root common.Hash, accounts []common.Hash, origin common.Hash, limit common.Hash, bytes uint64, opts ...Option) (slots []*message.StorageData, proof []common.Hash, stid sttypes.StreamID, err error) { + timer := p.doMetricClientRequest("getStorageRanges") + defer p.doMetricPostClientRequest("getStorageRanges", err, timer) + + if bytes == 0 { + err = fmt.Errorf("zero storage ranges bytes requested") + return + } + if bytes > softResponseLimit { + err = fmt.Errorf("requested bytes exceed limit") + return + } + if len(accounts) > GetStorageRangesRequestCap { + err = fmt.Errorf("number of requested accounts exceed limit") + return + } + req := newGetStorageRangesRequest(root, accounts, origin, limit, bytes) + resp, stid, err := p.rm.DoRequest(ctx, req, opts...) + if err != nil { + return + } + var storages []*message.StoragesData + storages, proof, err = req.getStorageRangesFromResponse(resp) + if err != nil { + return + } + slots = make([]*message.StorageData, 0) + for _, storage := range storages { + for _, data := range storage.Data { + slots = append(slots, data) + } + } + return +} + +// GetByteCodes do getByteCodes through sync stream protocol. +// returns the codes as result, target stream id, and error +func (p *Protocol) GetByteCodes(ctx context.Context, hs []common.Hash, bytes uint64, opts ...Option) (codes [][]byte, stid sttypes.StreamID, err error) { + timer := p.doMetricClientRequest("getByteCodes") + defer p.doMetricPostClientRequest("getByteCodes", err, timer) + + if bytes == 0 { + err = fmt.Errorf("zero bytecode bytes requested") + return + } + if bytes > softResponseLimit { + err = fmt.Errorf("requested bytes exceed limit") + return + } + if len(hs) > GetByteCodesRequestCap { + err = fmt.Errorf("number of requested hashes exceed limit") + return + } + req := newGetByteCodesRequest(hs, bytes) + resp, stid, err := p.rm.DoRequest(ctx, req, opts...) + if err != nil { + return + } + codes, err = req.getByteCodesFromResponse(resp) + return +} + +// GetTrieNodes do getTrieNodes through sync stream protocol. +// returns the nodes as result, target stream id, and error +func (p *Protocol) GetTrieNodes(ctx context.Context, root common.Hash, paths []*message.TrieNodePathSet, bytes uint64, opts ...Option) (nodes [][]byte, stid sttypes.StreamID, err error) { + timer := p.doMetricClientRequest("getTrieNodes") + defer p.doMetricPostClientRequest("getTrieNodes", err, timer) + + if bytes == 0 { + err = fmt.Errorf("zero trie nodes bytes requested") + return + } + if bytes > softResponseLimit { + err = fmt.Errorf("requested bytes exceed limit") + return + } + if len(paths) > GetTrieNodesRequestCap { + err = fmt.Errorf("number of requested paths exceed limit") + return + } + req := newGetTrieNodesRequest(root, paths, bytes) + resp, stid, err := p.rm.DoRequest(ctx, req, opts...) + if err != nil { + return + } + nodes, err = req.getTrieNodesFromResponse(resp) + return +} + // getBlocksByNumberRequest is the request for get block by numbers which implements // sttypes.Request interface type getBlocksByNumberRequest struct { @@ -571,3 +686,305 @@ func (req *getReceiptsRequest) parseGetReceiptsBytes(resp *syncResponse) ([]type } return receipts, nil } + +// getAccountRangeRequest is the request for get account ranges which implements +// sttypes.Request interface +type getAccountRangeRequest struct { + root common.Hash + origin common.Hash + limit common.Hash + bytes uint64 + pbReq *syncpb.Request +} + +func newGetAccountRangeRequest(root common.Hash, origin common.Hash, limit common.Hash, bytes uint64) *getAccountRangeRequest { + pbReq := syncpb.MakeGetAccountRangeRequest(root, origin, limit, bytes) + return &getAccountRangeRequest{ + root: root, + origin: origin, + limit: limit, + bytes: bytes, + pbReq: pbReq, + } +} + +func (req *getAccountRangeRequest) ReqID() uint64 { + return req.pbReq.GetReqId() +} + +func (req *getAccountRangeRequest) SetReqID(val uint64) { + req.pbReq.ReqId = val +} + +func (req *getAccountRangeRequest) String() string { + ss := make([]string, 0, 4) + ss = append(ss, req.root.String()) + ss = append(ss, req.origin.String()) + ss = append(ss, req.limit.String()) + ss = append(ss, fmt.Sprint(req.bytes)) + rqStr := strings.Join(ss, ",") + return fmt.Sprintf("REQUEST [GetAccountRange: %s]", rqStr) +} + +func (req *getAccountRangeRequest) IsSupportedByProto(target sttypes.ProtoSpec) bool { + return target.Version.GreaterThanOrEqual(MinVersion) +} + +func (req *getAccountRangeRequest) Encode() ([]byte, error) { + msg := syncpb.MakeMessageFromRequest(req.pbReq) + return protobuf.Marshal(msg) +} + +// []*message.AccountData, []common.Hash +func (req *getAccountRangeRequest) getAccountRangeFromResponse(resp sttypes.Response) ([]*message.AccountData, []common.Hash, error) { + sResp, ok := resp.(*syncResponse) + if !ok || sResp == nil { + return nil, nil, errors.New("not sync response") + } + return req.parseGetAccountRangeResponse(sResp) +} + +func (req *getAccountRangeRequest) parseGetAccountRangeResponse(resp *syncResponse) ([]*message.AccountData, []common.Hash, error) { + if errResp := resp.pb.GetErrorResponse(); errResp != nil { + return nil, nil, errors.New(errResp.Error) + } + grResp := resp.pb.GetGetAccountRangeResponse() + if grResp == nil { + return nil, nil, errors.New("response not GetAccountRange") + } + proofs := make([]common.Hash, 0) + for _, proofBytes := range grResp.Proof { + var proof common.Hash + if err := rlp.DecodeBytes(proofBytes, &proof); err != nil { + return nil, nil, errors.Wrap(err, "[GetAccountRangeResponse]") + } + proofs = append(proofs, proof) + } + return grResp.Accounts, proofs, nil +} + +// getStorageRangesRequest is the request for get storage ranges which implements +// sttypes.Request interface +type getStorageRangesRequest struct { + root common.Hash + accounts []common.Hash + origin common.Hash + limit common.Hash + bytes uint64 + pbReq *syncpb.Request +} + +func newGetStorageRangesRequest(root common.Hash, accounts []common.Hash, origin common.Hash, limit common.Hash, bytes uint64) *getStorageRangesRequest { + pbReq := syncpb.MakeGetStorageRangesRequest(root, accounts, origin, limit, bytes) + return &getStorageRangesRequest{ + root: root, + accounts: accounts, + origin: origin, + limit: limit, + bytes: bytes, + pbReq: pbReq, + } +} + +func (req *getStorageRangesRequest) ReqID() uint64 { + return req.pbReq.GetReqId() +} + +func (req *getStorageRangesRequest) SetReqID(val uint64) { + req.pbReq.ReqId = val +} + +func (req *getStorageRangesRequest) String() string { + ss := make([]string, 0, 4) + ss = append(ss, req.root.String()) + for _, acc := range req.accounts { + ss = append(ss, acc.String()) + } + ss = append(ss, req.origin.String()) + ss = append(ss, req.limit.String()) + ss = append(ss, fmt.Sprint(req.bytes)) + rqStr := strings.Join(ss, ",") + return fmt.Sprintf("REQUEST [GetStorageRanges: %s]", rqStr) +} + +func (req *getStorageRangesRequest) IsSupportedByProto(target sttypes.ProtoSpec) bool { + return target.Version.GreaterThanOrEqual(MinVersion) +} + +func (req *getStorageRangesRequest) Encode() ([]byte, error) { + msg := syncpb.MakeMessageFromRequest(req.pbReq) + return protobuf.Marshal(msg) +} + +// []*message.AccountData, []common.Hash +func (req *getStorageRangesRequest) getStorageRangesFromResponse(resp sttypes.Response) ([]*message.StoragesData, []common.Hash, error) { + sResp, ok := resp.(*syncResponse) + if !ok || sResp == nil { + return nil, nil, errors.New("not sync response") + } + return req.parseGetStorageRangesResponse(sResp) +} + +func (req *getStorageRangesRequest) parseGetStorageRangesResponse(resp *syncResponse) ([]*message.StoragesData, []common.Hash, error) { + if errResp := resp.pb.GetErrorResponse(); errResp != nil { + return nil, nil, errors.New(errResp.Error) + } + grResp := resp.pb.GetGetStorageRangesResponse() + if grResp == nil { + return nil, nil, errors.New("response not GetStorageRanges") + } + proofs := make([]common.Hash, 0) + for _, proofBytes := range grResp.Proof { + var proof common.Hash + if err := rlp.DecodeBytes(proofBytes, &proof); err != nil { + return nil, nil, errors.Wrap(err, "[GetStorageRangesResponse]") + } + proofs = append(proofs, proof) + } + return grResp.Slots, proofs, nil +} + +// getByteCodesRequest is the request for get code bytes which implements +// sttypes.Request interface +type getByteCodesRequest struct { + hashes []common.Hash + bytes uint64 + pbReq *syncpb.Request +} + +func newGetByteCodesRequest(hashes []common.Hash, bytes uint64) *getByteCodesRequest { + pbReq := syncpb.MakeGetByteCodesRequest(hashes, bytes) + return &getByteCodesRequest{ + hashes: hashes, + bytes: bytes, + pbReq: pbReq, + } +} + +func (req *getByteCodesRequest) ReqID() uint64 { + return req.pbReq.GetReqId() +} + +func (req *getByteCodesRequest) SetReqID(val uint64) { + req.pbReq.ReqId = val +} + +func (req *getByteCodesRequest) String() string { + ss := make([]string, 0, 4) + for _, h := range req.hashes { + ss = append(ss, h.String()) + } + ss = append(ss, fmt.Sprint(req.bytes)) + rqStr := strings.Join(ss, ",") + return fmt.Sprintf("REQUEST [GetByteCodes: %s]", rqStr) +} + +func (req *getByteCodesRequest) IsSupportedByProto(target sttypes.ProtoSpec) bool { + return target.Version.GreaterThanOrEqual(MinVersion) +} + +func (req *getByteCodesRequest) Encode() ([]byte, error) { + msg := syncpb.MakeMessageFromRequest(req.pbReq) + return protobuf.Marshal(msg) +} + +func (req *getByteCodesRequest) getByteCodesFromResponse(resp sttypes.Response) ([][]byte, error) { + sResp, ok := resp.(*syncResponse) + if !ok || sResp == nil { + return nil, errors.New("not sync response") + } + return req.parseGetByteCodesResponse(sResp) +} + +func (req *getByteCodesRequest) parseGetByteCodesResponse(resp *syncResponse) ([][]byte, error) { + if errResp := resp.pb.GetErrorResponse(); errResp != nil { + return nil, errors.New(errResp.Error) + } + grResp := resp.pb.GetGetByteCodesResponse() + if grResp == nil { + return nil, errors.New("response not GetByteCodes") + } + codes := make([][]byte, 0) + for _, codeBytes := range grResp.Codes { + var code []byte + if err := rlp.DecodeBytes(codeBytes, &code); err != nil { + return nil, errors.Wrap(err, "[GetByteCodesResponse]") + } + codes = append(codes, code) + } + return codes, nil +} + +// getTrieNodesRequest is the request for get trie nodes which implements +// sttypes.Request interface +type getTrieNodesRequest struct { + root common.Hash + paths []*message.TrieNodePathSet + bytes uint64 + pbReq *syncpb.Request +} + +func newGetTrieNodesRequest(root common.Hash, paths []*message.TrieNodePathSet, bytes uint64) *getTrieNodesRequest { + pbReq := syncpb.MakeGetTrieNodesRequest(root, paths, bytes) + return &getTrieNodesRequest{ + root: root, + paths: paths, + bytes: bytes, + pbReq: pbReq, + } +} + +func (req *getTrieNodesRequest) ReqID() uint64 { + return req.pbReq.GetReqId() +} + +func (req *getTrieNodesRequest) SetReqID(val uint64) { + req.pbReq.ReqId = val +} + +func (req *getTrieNodesRequest) String() string { + ss := make([]string, 0, 4) + ss = append(ss, req.root.String()) + for _, p := range req.paths { + ss = append(ss, p.String()) + } + ss = append(ss, fmt.Sprint(req.bytes)) + rqStr := strings.Join(ss, ",") + return fmt.Sprintf("REQUEST [GetTrieNodes: %s]", rqStr) +} + +func (req *getTrieNodesRequest) IsSupportedByProto(target sttypes.ProtoSpec) bool { + return target.Version.GreaterThanOrEqual(MinVersion) +} + +func (req *getTrieNodesRequest) Encode() ([]byte, error) { + msg := syncpb.MakeMessageFromRequest(req.pbReq) + return protobuf.Marshal(msg) +} + +func (req *getTrieNodesRequest) getTrieNodesFromResponse(resp sttypes.Response) ([][]byte, error) { + sResp, ok := resp.(*syncResponse) + if !ok || sResp == nil { + return nil, errors.New("not sync response") + } + return req.parseGetTrieNodesResponse(sResp) +} + +func (req *getTrieNodesRequest) parseGetTrieNodesResponse(resp *syncResponse) ([][]byte, error) { + if errResp := resp.pb.GetErrorResponse(); errResp != nil { + return nil, errors.New(errResp.Error) + } + grResp := resp.pb.GetGetTrieNodesResponse() + if grResp == nil { + return nil, errors.New("response not GetTrieNodes") + } + nodes := make([][]byte, 0) + for _, codeBytes := range grResp.Nodes { + var code []byte + if err := rlp.DecodeBytes(codeBytes, &code); err != nil { + return nil, errors.Wrap(err, "[GetTrieNodesResponse]") + } + nodes = append(nodes, code) + } + return nodes, nil +} diff --git a/p2p/stream/protocols/sync/client_test.go b/p2p/stream/protocols/sync/client_test.go index edfa126d0..611afd761 100644 --- a/p2p/stream/protocols/sync/client_test.go +++ b/p2p/stream/protocols/sync/client_test.go @@ -25,6 +25,8 @@ var ( _ sttypes.Request = &getBlockNumberRequest{} _ sttypes.Request = &getReceiptsRequest{} _ sttypes.Response = &syncResponse{&syncpb.Response{}} + // MaxHash represents the maximum possible hash value. + MaxHash = common.HexToHash("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") ) var ( @@ -67,6 +69,69 @@ var ( testNodeDataResponse = syncpb.MakeGetNodeDataResponse(0, [][]byte{testNodeDataBytes}) + account1 = common.HexToHash("0xf493f79c43bd747129a226ad42529885a4b108aba6046b2d12071695a6627844") + account2 = common.HexToHash("0xf493f79c43bd747129a226ad42529885a4b108aba6046b2d12071695a6627844") + resAccounts = []common.Hash{account1, account2} + + accountsData = []*message.AccountData{ + &syncpb.AccountData{ + Hash: account1[:], + Body: common.HexToHash("0x00bf100000000000000000000000000000000000000000000000000000000000").Bytes(), + }, + &syncpb.AccountData{ + Hash: account2[:], + Body: common.HexToHash("0x00bf100000000000000000000000000000000000000000000000000000000000").Bytes(), + }, + } + + slots = []*syncpb.StoragesData{ + &syncpb.StoragesData{ + Data: []*syncpb.StorageData{ + &syncpb.StorageData{ + Hash: account1[:], + Body: common.HexToHash("0x00bf100000000000000000000000000000000000000000000000000000000000").Bytes(), + }, + }, + }, + &syncpb.StoragesData{ + Data: []*syncpb.StorageData{ + &syncpb.StorageData{ + Hash: account2[:], + Body: common.HexToHash("0x00bf100000000000000000000000000000000000000000000000000000000000").Bytes(), + }, + }, + }, + } + + proofBytes1, _ = rlp.EncodeToBytes(account1) + proofBytes2, _ = rlp.EncodeToBytes(account2) + proof = [][]byte{proofBytes1, proofBytes2} + + codeBytes1, _ = rlp.EncodeToBytes(account1) + codeBytes2, _ = rlp.EncodeToBytes(account2) + testByteCodes = [][]byte{codeBytes1, codeBytes2} + dataNodeBytes1, _ = rlp.EncodeToBytes(numberToHash(1).Bytes()) + dataNodeBytes2, _ = rlp.EncodeToBytes(numberToHash(2).Bytes()) + testTrieNodes = [][]byte{dataNodeBytes1, dataNodeBytes2} + testPathSet = [][]byte{numberToHash(19850928).Bytes(), numberToHash(13640607).Bytes()} + + testPaths = []*syncpb.TrieNodePathSet{ + &syncpb.TrieNodePathSet{ + Pathset: testPathSet, + }, + &syncpb.TrieNodePathSet{ + Pathset: testPathSet, + }, + } + + testAccountRangeResponse = syncpb.MakeGetAccountRangeResponse(0, accountsData, proof) + + testStorageRangesResponse = syncpb.MakeGetStorageRangesResponse(0, slots, proof) + + testByteCodesResponse = syncpb.MakeGetByteCodesResponse(0, testByteCodes) + + testTrieNodesResponse = syncpb.MakeGetTrieNodesResponse(0, testTrieNodes) + testErrorResponse = syncpb.MakeErrorResponse(0, errors.New("test error")) ) @@ -428,6 +493,267 @@ func TestProtocol_GetNodeData(t *testing.T) { } } +func TestProtocol_GetAccountRange(t *testing.T) { + var ( + root = numberToHash(1985082913640607) + ffHash = MaxHash + zero = common.Hash{} + ) + + tests := []struct { + getResponse getResponseFn + expErr error + expStID sttypes.StreamID + }{ + { + getResponse: func(request sttypes.Request) (sttypes.Response, sttypes.StreamID) { + return &syncResponse{ + pb: testAccountRangeResponse, + }, 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 GetAccountRange"), + 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) + accounts, proof, stid, err := protocol.GetAccountRange(context.Background(), root, zero, ffHash, uint64(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(accounts) != len(proof) { + t.Errorf("accounts: %v", test.getResponse) + t.Errorf("accounts: %v", accounts) + t.Errorf("proof: %v", proof) + t.Errorf("Test %v: accounts size (%d) not equal to proof size (%d)", i, len(accounts), len(proof)) + } + } + } +} + +func TestProtocol_GetStorageRanges(t *testing.T) { + var ( + root = numberToHash(1985082913640607) + firstKey = common.HexToHash("0x00bf49f440a1cd0527e4d06e2765654c0f56452257516d793a9b8d604dcfdf2a") + secondKey = common.HexToHash("0x09e47cd5056a689e708f22fe1f932709a320518e444f5f7d8d46a3da523d6606") + testAccounts = []common.Hash{secondKey, firstKey} + ffHash = MaxHash + zero = common.Hash{} + ) + + tests := []struct { + getResponse getResponseFn + expErr error + expStID sttypes.StreamID + }{ + { + getResponse: func(request sttypes.Request) (sttypes.Response, sttypes.StreamID) { + return &syncResponse{ + pb: testStorageRangesResponse, + }, 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 GetStorageRanges"), + 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) + slots, proof, stid, err := protocol.GetStorageRanges(context.Background(), root, testAccounts, zero, ffHash, uint64(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(slots) != len(testAccounts) { + t.Errorf("Test %v: slots size not equal to accounts size", i) + } + if len(slots) != len(proof) { + t.Errorf("Test %v: account size not equal to proof", i) + } + } + } +} + +func TestProtocol_GetByteCodes(t *testing.T) { + tests := []struct { + getResponse getResponseFn + expErr error + expStID sttypes.StreamID + }{ + { + getResponse: func(request sttypes.Request) (sttypes.Response, sttypes.StreamID) { + return &syncResponse{ + pb: testByteCodesResponse, + }, 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 GetByteCodes"), + 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) + codes, stid, err := protocol.GetByteCodes(context.Background(), []common.Hash{numberToHash(19850829)}, uint64(500)) + + 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(codes) != 2 { + t.Errorf("Test %v: size not 2", i) + } + } + } +} + +func TestProtocol_GetTrieNodes(t *testing.T) { + var ( + root = numberToHash(1985082913640607) + ) + + tests := []struct { + getResponse getResponseFn + expErr error + expStID sttypes.StreamID + }{ + { + getResponse: func(request sttypes.Request) (sttypes.Response, sttypes.StreamID) { + return &syncResponse{ + pb: testTrieNodesResponse, + }, 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 GetTrieNodes"), + 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) + nodes, stid, err := protocol.GetTrieNodes(context.Background(), root, testPaths, uint64(500)) + + 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(nodes) != 2 { + t.Errorf("Test %v: size not 2", i) + } + } + } +} + type getResponseFn func(request sttypes.Request) (sttypes.Response, sttypes.StreamID) type testHostRequestManager struct { diff --git a/p2p/stream/protocols/sync/const.go b/p2p/stream/protocols/sync/const.go index b4cf4410a..d606a4675 100644 --- a/p2p/stream/protocols/sync/const.go +++ b/p2p/stream/protocols/sync/const.go @@ -25,6 +25,39 @@ const ( // This number has an effect on maxMsgBytes as 20MB defined in github.com/harmony-one/harmony/p2p/stream/types. GetReceiptsCap = 128 + // GetStorageRangesRequestCap is the cap of request of single GetStorageRanges request + // This number has an effect on maxMsgBytes as 20MB defined in github.com/harmony-one/harmony/p2p/stream/types. + GetStorageRangesRequestCap = 256 + + // GetByteCodesRequestCap is the cap of request of single GetByteCodes request + // This number has an effect on maxMsgBytes as 20MB defined in github.com/harmony-one/harmony/p2p/stream/types. + GetByteCodesRequestCap = 128 + + // GetTrieNodesRequestCap is the cap of request of single GetTrieNodes request + // This number has an effect on maxMsgBytes as 20MB defined in github.com/harmony-one/harmony/p2p/stream/types. + GetTrieNodesRequestCap = 128 + + // stateLookupSlack defines the ratio by how much a state response can exceed + // the requested limit in order to try and avoid breaking up contracts into + // multiple packages and proving them. + stateLookupSlack = 0.1 + + // softResponseLimit is the target maximum size of replies to data retrievals. + softResponseLimit = 2 * 1024 * 1024 + + // maxCodeLookups is the maximum number of bytecodes to serve. This number is + // there to limit the number of disk lookups. + maxCodeLookups = 1024 + + // maxTrieNodeLookups is the maximum number of state trie nodes to serve. This + // number is there to limit the number of disk lookups. + maxTrieNodeLookups = 1024 + + // maxTrieNodeTimeSpent is the maximum time we should spend on looking up trie nodes. + // If we spend too much time, then it's a fairly high chance of timing out + // at the remote side, which means all the work is in vain. + maxTrieNodeTimeSpent = 5 * time.Second + // MaxStreamFailures is the maximum allowed failures before stream gets removed MaxStreamFailures = 5 diff --git a/p2p/stream/protocols/sync/message/compose.go b/p2p/stream/protocols/sync/message/compose.go index 2c0c36709..3be09da5b 100644 --- a/p2p/stream/protocols/sync/message/compose.go +++ b/p2p/stream/protocols/sync/message/compose.go @@ -68,6 +68,60 @@ func MakeGetReceiptsRequest(hashes []common.Hash) *Request { } } +// MakeGetAccountRangeRequest makes the GetAccountRange request +func MakeGetAccountRangeRequest(root common.Hash, origin common.Hash, limit common.Hash, bytes uint64) *Request { + return &Request{ + Request: &Request_GetAccountRangeRequest{ + GetAccountRangeRequest: &GetAccountRangeRequest{ + Root: root[:], + Origin: origin[:], + Limit: limit[:], + Bytes: bytes, + }, + }, + } +} + +// MakeGetStorageRangesRequest makes the GetStorageRanges request +func MakeGetStorageRangesRequest(root common.Hash, accounts []common.Hash, origin common.Hash, limit common.Hash, bytes uint64) *Request { + return &Request{ + Request: &Request_GetStorageRangesRequest{ + GetStorageRangesRequest: &GetStorageRangesRequest{ + Root: root[:], + Accounts: hashesToBytes(accounts), + Origin: origin[:], + Limit: limit[:], + Bytes: bytes, + }, + }, + } +} + +// MakeGetByteCodesRequest makes the GetByteCodes request +func MakeGetByteCodesRequest(hashes []common.Hash, bytes uint64) *Request { + return &Request{ + Request: &Request_GetByteCodesRequest{ + GetByteCodesRequest: &GetByteCodesRequest{ + Hashes: hashesToBytes(hashes), + Bytes: bytes, + }, + }, + } +} + +// MakeGetTrieNodesRequest makes the GetTrieNodes request +func MakeGetTrieNodesRequest(root common.Hash, paths []*TrieNodePathSet, bytes uint64) *Request { + return &Request{ + Request: &Request_GetTrieNodesRequest{ + GetTrieNodesRequest: &GetTrieNodesRequest{ + Root: root[:], + Paths: paths, + Bytes: bytes, + }, + }, + } +} + // MakeErrorResponse makes the error response func MakeErrorResponseMessage(rid uint64, err error) *Message { resp := MakeErrorResponse(rid, err) @@ -196,6 +250,80 @@ func MakeGetReceiptsResponse(rid uint64, receipts map[uint64]*Receipts) *Respons } } +// MakeGetAccountRangeResponseMessage makes the GetAccountRangeResponse of Message type +func MakeGetAccountRangeResponseMessage(rid uint64, accounts []*AccountData, proof [][]byte) *Message { + resp := MakeGetAccountRangeResponse(rid, accounts, proof) + return makeMessageFromResponse(resp) +} + +// MakeGetAccountRangeResponse make the GetAccountRangeResponse of Response type +func MakeGetAccountRangeResponse(rid uint64, accounts []*AccountData, proof [][]byte) *Response { + return &Response{ + ReqId: rid, + Response: &Response_GetAccountRangeResponse{ + GetAccountRangeResponse: &GetAccountRangeResponse{ + Accounts: accounts, + Proof: proof, + }, + }, + } +} + +// MakeGetStorageRangesResponseMessage makes the GetStorageRangesResponse of Message type +func MakeGetStorageRangesResponseMessage(rid uint64, slots []*StoragesData, proof [][]byte) *Message { + resp := MakeGetStorageRangesResponse(rid, slots, proof) + return makeMessageFromResponse(resp) +} + +// MakeGetStorageRangesResponse make the GetStorageRangesResponse of Response type +func MakeGetStorageRangesResponse(rid uint64, slots []*StoragesData, proof [][]byte) *Response { + return &Response{ + ReqId: rid, + Response: &Response_GetStorageRangesResponse{ + GetStorageRangesResponse: &GetStorageRangesResponse{ + Slots: slots, + Proof: proof, + }, + }, + } +} + +// MakeGetByteCodesResponseMessage makes the GetByteCodesResponse of Message type +func MakeGetByteCodesResponseMessage(rid uint64, codes [][]byte) *Message { + resp := MakeGetByteCodesResponse(rid, codes) + return makeMessageFromResponse(resp) +} + +// MakeGetByteCodesResponse make the GetByteCodesResponse of Response type +func MakeGetByteCodesResponse(rid uint64, codes [][]byte) *Response { + return &Response{ + ReqId: rid, + Response: &Response_GetByteCodesResponse{ + GetByteCodesResponse: &GetByteCodesResponse{ + Codes: codes, + }, + }, + } +} + +// MakeGetTrieNodesResponseMessage makes the GetTrieNodesResponse of Message type +func MakeGetTrieNodesResponseMessage(rid uint64, nodes [][]byte) *Message { + resp := MakeGetTrieNodesResponse(rid, nodes) + return makeMessageFromResponse(resp) +} + +// MakeGetTrieNodesResponse make the GetTrieNodesResponse of Response type +func MakeGetTrieNodesResponse(rid uint64, nodes [][]byte) *Response { + return &Response{ + ReqId: rid, + Response: &Response_GetTrieNodesResponse{ + GetTrieNodesResponse: &GetTrieNodesResponse{ + Nodes: nodes, + }, + }, + } +} + // 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 be7a95995..db37f7c7d 100644 --- a/p2p/stream/protocols/sync/message/msg.pb.go +++ b/p2p/stream/protocols/sync/message/msg.pb.go @@ -115,6 +115,10 @@ type Request struct { // *Request_GetBlocksByHashesRequest // *Request_GetNodeDataRequest // *Request_GetReceiptsRequest + // *Request_GetAccountRangeRequest + // *Request_GetStorageRangesRequest + // *Request_GetByteCodesRequest + // *Request_GetTrieNodesRequest Request isRequest_Request `protobuf_oneof:"request"` } @@ -206,6 +210,34 @@ func (x *Request) GetGetReceiptsRequest() *GetReceiptsRequest { return nil } +func (x *Request) GetGetAccountRangeRequest() *GetAccountRangeRequest { + if x, ok := x.GetRequest().(*Request_GetAccountRangeRequest); ok { + return x.GetAccountRangeRequest + } + return nil +} + +func (x *Request) GetGetStorageRangesRequest() *GetStorageRangesRequest { + if x, ok := x.GetRequest().(*Request_GetStorageRangesRequest); ok { + return x.GetStorageRangesRequest + } + return nil +} + +func (x *Request) GetGetByteCodesRequest() *GetByteCodesRequest { + if x, ok := x.GetRequest().(*Request_GetByteCodesRequest); ok { + return x.GetByteCodesRequest + } + return nil +} + +func (x *Request) GetGetTrieNodesRequest() *GetTrieNodesRequest { + if x, ok := x.GetRequest().(*Request_GetTrieNodesRequest); ok { + return x.GetTrieNodesRequest + } + return nil +} + type isRequest_Request interface { isRequest_Request() } @@ -234,6 +266,22 @@ type Request_GetReceiptsRequest struct { GetReceiptsRequest *GetReceiptsRequest `protobuf:"bytes,7,opt,name=get_receipts_request,json=getReceiptsRequest,proto3,oneof"` } +type Request_GetAccountRangeRequest struct { + GetAccountRangeRequest *GetAccountRangeRequest `protobuf:"bytes,8,opt,name=get_account_range_request,json=getAccountRangeRequest,proto3,oneof"` +} + +type Request_GetStorageRangesRequest struct { + GetStorageRangesRequest *GetStorageRangesRequest `protobuf:"bytes,9,opt,name=get_storage_ranges_request,json=getStorageRangesRequest,proto3,oneof"` +} + +type Request_GetByteCodesRequest struct { + GetByteCodesRequest *GetByteCodesRequest `protobuf:"bytes,10,opt,name=get_byte_codes_request,json=getByteCodesRequest,proto3,oneof"` +} + +type Request_GetTrieNodesRequest struct { + GetTrieNodesRequest *GetTrieNodesRequest `protobuf:"bytes,11,opt,name=get_trie_nodes_request,json=getTrieNodesRequest,proto3,oneof"` +} + func (*Request_GetBlockNumberRequest) isRequest_Request() {} func (*Request_GetBlockHashesRequest) isRequest_Request() {} @@ -246,6 +294,14 @@ func (*Request_GetNodeDataRequest) isRequest_Request() {} func (*Request_GetReceiptsRequest) isRequest_Request() {} +func (*Request_GetAccountRangeRequest) isRequest_Request() {} + +func (*Request_GetStorageRangesRequest) isRequest_Request() {} + +func (*Request_GetByteCodesRequest) isRequest_Request() {} + +func (*Request_GetTrieNodesRequest) isRequest_Request() {} + type GetBlockNumberRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -519,26 +575,19 @@ func (x *GetReceiptsRequest) GetBlockHashes() [][]byte { return nil } -type Response struct { +type GetAccountRangeRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - ReqId uint64 `protobuf:"varint,1,opt,name=req_id,json=reqId,proto3" json:"req_id,omitempty"` - // Types that are assignable to Response: - // - // *Response_ErrorResponse - // *Response_GetBlockNumberResponse - // *Response_GetBlockHashesResponse - // *Response_GetBlocksByNumResponse - // *Response_GetBlocksByHashesResponse - // *Response_GetNodeDataResponse - // *Response_GetReceiptsResponse - Response isResponse_Response `protobuf_oneof:"response"` + Root []byte `protobuf:"bytes,1,opt,name=root,proto3" json:"root,omitempty"` + Origin []byte `protobuf:"bytes,2,opt,name=origin,proto3" json:"origin,omitempty"` + Limit []byte `protobuf:"bytes,3,opt,name=limit,proto3" json:"limit,omitempty"` + Bytes uint64 `protobuf:"varint,4,opt,name=bytes,proto3" json:"bytes,omitempty"` } -func (x *Response) Reset() { - *x = Response{} +func (x *GetAccountRangeRequest) Reset() { + *x = GetAccountRangeRequest{} if protoimpl.UnsafeEnabled { mi := &file_msg_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -546,13 +595,13 @@ func (x *Response) Reset() { } } -func (x *Response) String() string { +func (x *GetAccountRangeRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*Response) ProtoMessage() {} +func (*GetAccountRangeRequest) ProtoMessage() {} -func (x *Response) ProtoReflect() protoreflect.Message { +func (x *GetAccountRangeRequest) ProtoReflect() protoreflect.Message { mi := &file_msg_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -564,130 +613,53 @@ func (x *Response) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use Response.ProtoReflect.Descriptor instead. -func (*Response) Descriptor() ([]byte, []int) { +// Deprecated: Use GetAccountRangeRequest.ProtoReflect.Descriptor instead. +func (*GetAccountRangeRequest) Descriptor() ([]byte, []int) { return file_msg_proto_rawDescGZIP(), []int{8} } -func (x *Response) GetReqId() uint64 { +func (x *GetAccountRangeRequest) GetRoot() []byte { if x != nil { - return x.ReqId - } - return 0 -} - -func (m *Response) GetResponse() isResponse_Response { - if m != nil { - return m.Response - } - return nil -} - -func (x *Response) GetErrorResponse() *ErrorResponse { - if x, ok := x.GetResponse().(*Response_ErrorResponse); ok { - return x.ErrorResponse - } - return nil -} - -func (x *Response) GetGetBlockNumberResponse() *GetBlockNumberResponse { - if x, ok := x.GetResponse().(*Response_GetBlockNumberResponse); ok { - return x.GetBlockNumberResponse - } - return nil -} - -func (x *Response) GetGetBlockHashesResponse() *GetBlockHashesResponse { - if x, ok := x.GetResponse().(*Response_GetBlockHashesResponse); ok { - return x.GetBlockHashesResponse - } - return nil -} - -func (x *Response) GetGetBlocksByNumResponse() *GetBlocksByNumResponse { - if x, ok := x.GetResponse().(*Response_GetBlocksByNumResponse); ok { - return x.GetBlocksByNumResponse + return x.Root } return nil } -func (x *Response) GetGetBlocksByHashesResponse() *GetBlocksByHashesResponse { - if x, ok := x.GetResponse().(*Response_GetBlocksByHashesResponse); ok { - return x.GetBlocksByHashesResponse +func (x *GetAccountRangeRequest) GetOrigin() []byte { + if x != nil { + return x.Origin } return nil } -func (x *Response) GetGetNodeDataResponse() *GetNodeDataResponse { - if x, ok := x.GetResponse().(*Response_GetNodeDataResponse); ok { - return x.GetNodeDataResponse +func (x *GetAccountRangeRequest) GetLimit() []byte { + if x != nil { + return x.Limit } return nil } -func (x *Response) GetGetReceiptsResponse() *GetReceiptsResponse { - if x, ok := x.GetResponse().(*Response_GetReceiptsResponse); ok { - return x.GetReceiptsResponse +func (x *GetAccountRangeRequest) GetBytes() uint64 { + if x != nil { + return x.Bytes } - return nil -} - -type isResponse_Response interface { - isResponse_Response() -} - -type Response_ErrorResponse struct { - ErrorResponse *ErrorResponse `protobuf:"bytes,2,opt,name=error_response,json=errorResponse,proto3,oneof"` -} - -type Response_GetBlockNumberResponse struct { - GetBlockNumberResponse *GetBlockNumberResponse `protobuf:"bytes,3,opt,name=get_block_number_response,json=getBlockNumberResponse,proto3,oneof"` -} - -type Response_GetBlockHashesResponse struct { - GetBlockHashesResponse *GetBlockHashesResponse `protobuf:"bytes,4,opt,name=get_block_hashes_response,json=getBlockHashesResponse,proto3,oneof"` -} - -type Response_GetBlocksByNumResponse struct { - GetBlocksByNumResponse *GetBlocksByNumResponse `protobuf:"bytes,5,opt,name=get_blocks_by_num_response,json=getBlocksByNumResponse,proto3,oneof"` -} - -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"` + return 0 } -func (*Response_ErrorResponse) isResponse_Response() {} - -func (*Response_GetBlockNumberResponse) isResponse_Response() {} - -func (*Response_GetBlockHashesResponse) isResponse_Response() {} - -func (*Response_GetBlocksByNumResponse) isResponse_Response() {} - -func (*Response_GetBlocksByHashesResponse) isResponse_Response() {} - -func (*Response_GetNodeDataResponse) isResponse_Response() {} - -func (*Response_GetReceiptsResponse) isResponse_Response() {} - -type ErrorResponse struct { +type GetStorageRangesRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Error string `protobuf:"bytes,1,opt,name=error,proto3" json:"error,omitempty"` + Root []byte `protobuf:"bytes,1,opt,name=root,proto3" json:"root,omitempty"` + Accounts [][]byte `protobuf:"bytes,2,rep,name=accounts,proto3" json:"accounts,omitempty"` + Origin []byte `protobuf:"bytes,3,opt,name=origin,proto3" json:"origin,omitempty"` + Limit []byte `protobuf:"bytes,4,opt,name=limit,proto3" json:"limit,omitempty"` + Bytes uint64 `protobuf:"varint,5,opt,name=bytes,proto3" json:"bytes,omitempty"` } -func (x *ErrorResponse) Reset() { - *x = ErrorResponse{} +func (x *GetStorageRangesRequest) Reset() { + *x = GetStorageRangesRequest{} if protoimpl.UnsafeEnabled { mi := &file_msg_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -695,13 +667,13 @@ func (x *ErrorResponse) Reset() { } } -func (x *ErrorResponse) String() string { +func (x *GetStorageRangesRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ErrorResponse) ProtoMessage() {} +func (*GetStorageRangesRequest) ProtoMessage() {} -func (x *ErrorResponse) ProtoReflect() protoreflect.Message { +func (x *GetStorageRangesRequest) ProtoReflect() protoreflect.Message { mi := &file_msg_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -713,28 +685,57 @@ func (x *ErrorResponse) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ErrorResponse.ProtoReflect.Descriptor instead. -func (*ErrorResponse) Descriptor() ([]byte, []int) { +// Deprecated: Use GetStorageRangesRequest.ProtoReflect.Descriptor instead. +func (*GetStorageRangesRequest) Descriptor() ([]byte, []int) { return file_msg_proto_rawDescGZIP(), []int{9} } -func (x *ErrorResponse) GetError() string { +func (x *GetStorageRangesRequest) GetRoot() []byte { if x != nil { - return x.Error + return x.Root } - return "" + return nil } -type GetBlockNumberResponse struct { +func (x *GetStorageRangesRequest) GetAccounts() [][]byte { + if x != nil { + return x.Accounts + } + return nil +} + +func (x *GetStorageRangesRequest) GetOrigin() []byte { + if x != nil { + return x.Origin + } + return nil +} + +func (x *GetStorageRangesRequest) GetLimit() []byte { + if x != nil { + return x.Limit + } + return nil +} + +func (x *GetStorageRangesRequest) GetBytes() uint64 { + if x != nil { + return x.Bytes + } + return 0 +} + +type GetByteCodesRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Number uint64 `protobuf:"varint,1,opt,name=number,proto3" json:"number,omitempty"` + Hashes [][]byte `protobuf:"bytes,1,rep,name=hashes,proto3" json:"hashes,omitempty"` + Bytes uint64 `protobuf:"varint,2,opt,name=bytes,proto3" json:"bytes,omitempty"` } -func (x *GetBlockNumberResponse) Reset() { - *x = GetBlockNumberResponse{} +func (x *GetByteCodesRequest) Reset() { + *x = GetByteCodesRequest{} if protoimpl.UnsafeEnabled { mi := &file_msg_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -742,13 +743,13 @@ func (x *GetBlockNumberResponse) Reset() { } } -func (x *GetBlockNumberResponse) String() string { +func (x *GetByteCodesRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*GetBlockNumberResponse) ProtoMessage() {} +func (*GetByteCodesRequest) ProtoMessage() {} -func (x *GetBlockNumberResponse) ProtoReflect() protoreflect.Message { +func (x *GetByteCodesRequest) ProtoReflect() protoreflect.Message { mi := &file_msg_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -760,28 +761,35 @@ func (x *GetBlockNumberResponse) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use GetBlockNumberResponse.ProtoReflect.Descriptor instead. -func (*GetBlockNumberResponse) Descriptor() ([]byte, []int) { +// Deprecated: Use GetByteCodesRequest.ProtoReflect.Descriptor instead. +func (*GetByteCodesRequest) Descriptor() ([]byte, []int) { return file_msg_proto_rawDescGZIP(), []int{10} } -func (x *GetBlockNumberResponse) GetNumber() uint64 { +func (x *GetByteCodesRequest) GetHashes() [][]byte { if x != nil { - return x.Number + return x.Hashes + } + return nil +} + +func (x *GetByteCodesRequest) GetBytes() uint64 { + if x != nil { + return x.Bytes } return 0 } -type GetBlockHashesResponse struct { +type TrieNodePathSet struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Hashes [][]byte `protobuf:"bytes,1,rep,name=hashes,proto3" json:"hashes,omitempty"` + Pathset [][]byte `protobuf:"bytes,1,rep,name=pathset,proto3" json:"pathset,omitempty"` } -func (x *GetBlockHashesResponse) Reset() { - *x = GetBlockHashesResponse{} +func (x *TrieNodePathSet) Reset() { + *x = TrieNodePathSet{} if protoimpl.UnsafeEnabled { mi := &file_msg_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -789,13 +797,13 @@ func (x *GetBlockHashesResponse) Reset() { } } -func (x *GetBlockHashesResponse) String() string { +func (x *TrieNodePathSet) String() string { return protoimpl.X.MessageStringOf(x) } -func (*GetBlockHashesResponse) ProtoMessage() {} +func (*TrieNodePathSet) ProtoMessage() {} -func (x *GetBlockHashesResponse) ProtoReflect() protoreflect.Message { +func (x *TrieNodePathSet) ProtoReflect() protoreflect.Message { mi := &file_msg_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -807,29 +815,30 @@ func (x *GetBlockHashesResponse) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use GetBlockHashesResponse.ProtoReflect.Descriptor instead. -func (*GetBlockHashesResponse) Descriptor() ([]byte, []int) { +// Deprecated: Use TrieNodePathSet.ProtoReflect.Descriptor instead. +func (*TrieNodePathSet) Descriptor() ([]byte, []int) { return file_msg_proto_rawDescGZIP(), []int{11} } -func (x *GetBlockHashesResponse) GetHashes() [][]byte { +func (x *TrieNodePathSet) GetPathset() [][]byte { if x != nil { - return x.Hashes + return x.Pathset } return nil } -type GetBlocksByNumResponse struct { +type GetTrieNodesRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - BlocksBytes [][]byte `protobuf:"bytes,1,rep,name=blocks_bytes,json=blocksBytes,proto3" json:"blocks_bytes,omitempty"` - CommitSig [][]byte `protobuf:"bytes,2,rep,name=commit_sig,json=commitSig,proto3" json:"commit_sig,omitempty"` + Root []byte `protobuf:"bytes,1,opt,name=root,proto3" json:"root,omitempty"` + Paths []*TrieNodePathSet `protobuf:"bytes,2,rep,name=paths,proto3" json:"paths,omitempty"` + Bytes uint64 `protobuf:"varint,3,opt,name=bytes,proto3" json:"bytes,omitempty"` } -func (x *GetBlocksByNumResponse) Reset() { - *x = GetBlocksByNumResponse{} +func (x *GetTrieNodesRequest) Reset() { + *x = GetTrieNodesRequest{} if protoimpl.UnsafeEnabled { mi := &file_msg_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -837,13 +846,13 @@ func (x *GetBlocksByNumResponse) Reset() { } } -func (x *GetBlocksByNumResponse) String() string { +func (x *GetTrieNodesRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*GetBlocksByNumResponse) ProtoMessage() {} +func (*GetTrieNodesRequest) ProtoMessage() {} -func (x *GetBlocksByNumResponse) ProtoReflect() protoreflect.Message { +func (x *GetTrieNodesRequest) ProtoReflect() protoreflect.Message { mi := &file_msg_proto_msgTypes[12] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -855,36 +864,56 @@ func (x *GetBlocksByNumResponse) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use GetBlocksByNumResponse.ProtoReflect.Descriptor instead. -func (*GetBlocksByNumResponse) Descriptor() ([]byte, []int) { +// Deprecated: Use GetTrieNodesRequest.ProtoReflect.Descriptor instead. +func (*GetTrieNodesRequest) Descriptor() ([]byte, []int) { return file_msg_proto_rawDescGZIP(), []int{12} } -func (x *GetBlocksByNumResponse) GetBlocksBytes() [][]byte { +func (x *GetTrieNodesRequest) GetRoot() []byte { if x != nil { - return x.BlocksBytes + return x.Root } return nil } -func (x *GetBlocksByNumResponse) GetCommitSig() [][]byte { +func (x *GetTrieNodesRequest) GetPaths() []*TrieNodePathSet { if x != nil { - return x.CommitSig + return x.Paths } return nil } -type GetBlocksByHashesResponse struct { +func (x *GetTrieNodesRequest) GetBytes() uint64 { + if x != nil { + return x.Bytes + } + return 0 +} + +type Response struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - BlocksBytes [][]byte `protobuf:"bytes,1,rep,name=blocks_bytes,json=blocksBytes,proto3" json:"blocks_bytes,omitempty"` - CommitSig [][]byte `protobuf:"bytes,2,rep,name=commit_sig,json=commitSig,proto3" json:"commit_sig,omitempty"` + ReqId uint64 `protobuf:"varint,1,opt,name=req_id,json=reqId,proto3" json:"req_id,omitempty"` + // Types that are assignable to Response: + // + // *Response_ErrorResponse + // *Response_GetBlockNumberResponse + // *Response_GetBlockHashesResponse + // *Response_GetBlocksByNumResponse + // *Response_GetBlocksByHashesResponse + // *Response_GetNodeDataResponse + // *Response_GetReceiptsResponse + // *Response_GetAccountRangeResponse + // *Response_GetStorageRangesResponse + // *Response_GetByteCodesResponse + // *Response_GetTrieNodesResponse + Response isResponse_Response `protobuf_oneof:"response"` } -func (x *GetBlocksByHashesResponse) Reset() { - *x = GetBlocksByHashesResponse{} +func (x *Response) Reset() { + *x = Response{} if protoimpl.UnsafeEnabled { mi := &file_msg_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -892,13 +921,13 @@ func (x *GetBlocksByHashesResponse) Reset() { } } -func (x *GetBlocksByHashesResponse) String() string { +func (x *Response) String() string { return protoimpl.X.MessageStringOf(x) } -func (*GetBlocksByHashesResponse) ProtoMessage() {} +func (*Response) ProtoMessage() {} -func (x *GetBlocksByHashesResponse) ProtoReflect() protoreflect.Message { +func (x *Response) ProtoReflect() protoreflect.Message { mi := &file_msg_proto_msgTypes[13] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -910,50 +939,754 @@ func (x *GetBlocksByHashesResponse) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use GetBlocksByHashesResponse.ProtoReflect.Descriptor instead. -func (*GetBlocksByHashesResponse) Descriptor() ([]byte, []int) { +// Deprecated: Use Response.ProtoReflect.Descriptor instead. +func (*Response) Descriptor() ([]byte, []int) { return file_msg_proto_rawDescGZIP(), []int{13} } -func (x *GetBlocksByHashesResponse) GetBlocksBytes() [][]byte { +func (x *Response) GetReqId() uint64 { + if x != nil { + return x.ReqId + } + return 0 +} + +func (m *Response) GetResponse() isResponse_Response { + if m != nil { + return m.Response + } + return nil +} + +func (x *Response) GetErrorResponse() *ErrorResponse { + if x, ok := x.GetResponse().(*Response_ErrorResponse); ok { + return x.ErrorResponse + } + return nil +} + +func (x *Response) GetGetBlockNumberResponse() *GetBlockNumberResponse { + if x, ok := x.GetResponse().(*Response_GetBlockNumberResponse); ok { + return x.GetBlockNumberResponse + } + return nil +} + +func (x *Response) GetGetBlockHashesResponse() *GetBlockHashesResponse { + if x, ok := x.GetResponse().(*Response_GetBlockHashesResponse); ok { + return x.GetBlockHashesResponse + } + return nil +} + +func (x *Response) GetGetBlocksByNumResponse() *GetBlocksByNumResponse { + if x, ok := x.GetResponse().(*Response_GetBlocksByNumResponse); ok { + return x.GetBlocksByNumResponse + } + return nil +} + +func (x *Response) GetGetBlocksByHashesResponse() *GetBlocksByHashesResponse { + if x, ok := x.GetResponse().(*Response_GetBlocksByHashesResponse); ok { + return x.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 +} + +func (x *Response) GetGetAccountRangeResponse() *GetAccountRangeResponse { + if x, ok := x.GetResponse().(*Response_GetAccountRangeResponse); ok { + return x.GetAccountRangeResponse + } + return nil +} + +func (x *Response) GetGetStorageRangesResponse() *GetStorageRangesResponse { + if x, ok := x.GetResponse().(*Response_GetStorageRangesResponse); ok { + return x.GetStorageRangesResponse + } + return nil +} + +func (x *Response) GetGetByteCodesResponse() *GetByteCodesResponse { + if x, ok := x.GetResponse().(*Response_GetByteCodesResponse); ok { + return x.GetByteCodesResponse + } + return nil +} + +func (x *Response) GetGetTrieNodesResponse() *GetTrieNodesResponse { + if x, ok := x.GetResponse().(*Response_GetTrieNodesResponse); ok { + return x.GetTrieNodesResponse + } + return nil +} + +type isResponse_Response interface { + isResponse_Response() +} + +type Response_ErrorResponse struct { + ErrorResponse *ErrorResponse `protobuf:"bytes,2,opt,name=error_response,json=errorResponse,proto3,oneof"` +} + +type Response_GetBlockNumberResponse struct { + GetBlockNumberResponse *GetBlockNumberResponse `protobuf:"bytes,3,opt,name=get_block_number_response,json=getBlockNumberResponse,proto3,oneof"` +} + +type Response_GetBlockHashesResponse struct { + GetBlockHashesResponse *GetBlockHashesResponse `protobuf:"bytes,4,opt,name=get_block_hashes_response,json=getBlockHashesResponse,proto3,oneof"` +} + +type Response_GetBlocksByNumResponse struct { + GetBlocksByNumResponse *GetBlocksByNumResponse `protobuf:"bytes,5,opt,name=get_blocks_by_num_response,json=getBlocksByNumResponse,proto3,oneof"` +} + +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"` +} + +type Response_GetAccountRangeResponse struct { + GetAccountRangeResponse *GetAccountRangeResponse `protobuf:"bytes,9,opt,name=get_account_range_response,json=getAccountRangeResponse,proto3,oneof"` +} + +type Response_GetStorageRangesResponse struct { + GetStorageRangesResponse *GetStorageRangesResponse `protobuf:"bytes,10,opt,name=get_storage_ranges_response,json=getStorageRangesResponse,proto3,oneof"` +} + +type Response_GetByteCodesResponse struct { + GetByteCodesResponse *GetByteCodesResponse `protobuf:"bytes,11,opt,name=get_byte_codes_response,json=getByteCodesResponse,proto3,oneof"` +} + +type Response_GetTrieNodesResponse struct { + GetTrieNodesResponse *GetTrieNodesResponse `protobuf:"bytes,12,opt,name=get_trie_nodes_response,json=getTrieNodesResponse,proto3,oneof"` +} + +func (*Response_ErrorResponse) isResponse_Response() {} + +func (*Response_GetBlockNumberResponse) isResponse_Response() {} + +func (*Response_GetBlockHashesResponse) isResponse_Response() {} + +func (*Response_GetBlocksByNumResponse) isResponse_Response() {} + +func (*Response_GetBlocksByHashesResponse) isResponse_Response() {} + +func (*Response_GetNodeDataResponse) isResponse_Response() {} + +func (*Response_GetReceiptsResponse) isResponse_Response() {} + +func (*Response_GetAccountRangeResponse) isResponse_Response() {} + +func (*Response_GetStorageRangesResponse) isResponse_Response() {} + +func (*Response_GetByteCodesResponse) isResponse_Response() {} + +func (*Response_GetTrieNodesResponse) isResponse_Response() {} + +type ErrorResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Error string `protobuf:"bytes,1,opt,name=error,proto3" json:"error,omitempty"` +} + +func (x *ErrorResponse) Reset() { + *x = ErrorResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_msg_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ErrorResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ErrorResponse) ProtoMessage() {} + +func (x *ErrorResponse) 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 ErrorResponse.ProtoReflect.Descriptor instead. +func (*ErrorResponse) Descriptor() ([]byte, []int) { + return file_msg_proto_rawDescGZIP(), []int{14} +} + +func (x *ErrorResponse) GetError() string { + if x != nil { + return x.Error + } + return "" +} + +type GetBlockNumberResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Number uint64 `protobuf:"varint,1,opt,name=number,proto3" json:"number,omitempty"` +} + +func (x *GetBlockNumberResponse) Reset() { + *x = GetBlockNumberResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_msg_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetBlockNumberResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetBlockNumberResponse) ProtoMessage() {} + +func (x *GetBlockNumberResponse) 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 GetBlockNumberResponse.ProtoReflect.Descriptor instead. +func (*GetBlockNumberResponse) Descriptor() ([]byte, []int) { + return file_msg_proto_rawDescGZIP(), []int{15} +} + +func (x *GetBlockNumberResponse) GetNumber() uint64 { + if x != nil { + return x.Number + } + return 0 +} + +type GetBlockHashesResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Hashes [][]byte `protobuf:"bytes,1,rep,name=hashes,proto3" json:"hashes,omitempty"` +} + +func (x *GetBlockHashesResponse) Reset() { + *x = GetBlockHashesResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_msg_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetBlockHashesResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetBlockHashesResponse) ProtoMessage() {} + +func (x *GetBlockHashesResponse) ProtoReflect() protoreflect.Message { + mi := &file_msg_proto_msgTypes[16] + 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 GetBlockHashesResponse.ProtoReflect.Descriptor instead. +func (*GetBlockHashesResponse) Descriptor() ([]byte, []int) { + return file_msg_proto_rawDescGZIP(), []int{16} +} + +func (x *GetBlockHashesResponse) GetHashes() [][]byte { + if x != nil { + return x.Hashes + } + return nil +} + +type GetBlocksByNumResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + BlocksBytes [][]byte `protobuf:"bytes,1,rep,name=blocks_bytes,json=blocksBytes,proto3" json:"blocks_bytes,omitempty"` + CommitSig [][]byte `protobuf:"bytes,2,rep,name=commit_sig,json=commitSig,proto3" json:"commit_sig,omitempty"` +} + +func (x *GetBlocksByNumResponse) Reset() { + *x = GetBlocksByNumResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_msg_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetBlocksByNumResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetBlocksByNumResponse) ProtoMessage() {} + +func (x *GetBlocksByNumResponse) ProtoReflect() protoreflect.Message { + mi := &file_msg_proto_msgTypes[17] + 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 GetBlocksByNumResponse.ProtoReflect.Descriptor instead. +func (*GetBlocksByNumResponse) Descriptor() ([]byte, []int) { + return file_msg_proto_rawDescGZIP(), []int{17} +} + +func (x *GetBlocksByNumResponse) GetBlocksBytes() [][]byte { + if x != nil { + return x.BlocksBytes + } + return nil +} + +func (x *GetBlocksByNumResponse) GetCommitSig() [][]byte { + if x != nil { + return x.CommitSig + } + return nil +} + +type GetBlocksByHashesResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + BlocksBytes [][]byte `protobuf:"bytes,1,rep,name=blocks_bytes,json=blocksBytes,proto3" json:"blocks_bytes,omitempty"` + CommitSig [][]byte `protobuf:"bytes,2,rep,name=commit_sig,json=commitSig,proto3" json:"commit_sig,omitempty"` +} + +func (x *GetBlocksByHashesResponse) Reset() { + *x = GetBlocksByHashesResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_msg_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetBlocksByHashesResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetBlocksByHashesResponse) ProtoMessage() {} + +func (x *GetBlocksByHashesResponse) ProtoReflect() protoreflect.Message { + mi := &file_msg_proto_msgTypes[18] + 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 GetBlocksByHashesResponse.ProtoReflect.Descriptor instead. +func (*GetBlocksByHashesResponse) Descriptor() ([]byte, []int) { + return file_msg_proto_rawDescGZIP(), []int{18} +} + +func (x *GetBlocksByHashesResponse) GetBlocksBytes() [][]byte { if x != nil { return x.BlocksBytes } return nil } -func (x *GetBlocksByHashesResponse) GetCommitSig() [][]byte { +func (x *GetBlocksByHashesResponse) GetCommitSig() [][]byte { + if x != nil { + return x.CommitSig + } + 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[19] + 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[19] + 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{19} +} + +func (x *GetNodeDataResponse) GetDataBytes() [][]byte { + if x != nil { + return x.DataBytes + } + 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[20] + 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[20] + 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{20} +} + +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 + + 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[21] + 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[21] + 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{21} +} + +func (x *GetReceiptsResponse) GetReceipts() map[uint64]*Receipts { + if x != nil { + return x.Receipts + } + return nil +} + +type AccountData struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Hash []byte `protobuf:"bytes,1,opt,name=hash,proto3" json:"hash,omitempty"` + Body []byte `protobuf:"bytes,2,opt,name=body,proto3" json:"body,omitempty"` +} + +func (x *AccountData) Reset() { + *x = AccountData{} + if protoimpl.UnsafeEnabled { + mi := &file_msg_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AccountData) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AccountData) ProtoMessage() {} + +func (x *AccountData) ProtoReflect() protoreflect.Message { + mi := &file_msg_proto_msgTypes[22] + 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 AccountData.ProtoReflect.Descriptor instead. +func (*AccountData) Descriptor() ([]byte, []int) { + return file_msg_proto_rawDescGZIP(), []int{22} +} + +func (x *AccountData) GetHash() []byte { + if x != nil { + return x.Hash + } + return nil +} + +func (x *AccountData) GetBody() []byte { + if x != nil { + return x.Body + } + return nil +} + +type GetAccountRangeResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Accounts []*AccountData `protobuf:"bytes,1,rep,name=accounts,proto3" json:"accounts,omitempty"` + Proof [][]byte `protobuf:"bytes,2,rep,name=proof,proto3" json:"proof,omitempty"` +} + +func (x *GetAccountRangeResponse) Reset() { + *x = GetAccountRangeResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_msg_proto_msgTypes[23] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetAccountRangeResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetAccountRangeResponse) ProtoMessage() {} + +func (x *GetAccountRangeResponse) ProtoReflect() protoreflect.Message { + mi := &file_msg_proto_msgTypes[23] + 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 GetAccountRangeResponse.ProtoReflect.Descriptor instead. +func (*GetAccountRangeResponse) Descriptor() ([]byte, []int) { + return file_msg_proto_rawDescGZIP(), []int{23} +} + +func (x *GetAccountRangeResponse) GetAccounts() []*AccountData { + if x != nil { + return x.Accounts + } + return nil +} + +func (x *GetAccountRangeResponse) GetProof() [][]byte { + if x != nil { + return x.Proof + } + return nil +} + +type StorageData struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Hash []byte `protobuf:"bytes,1,opt,name=hash,proto3" json:"hash,omitempty"` + Body []byte `protobuf:"bytes,2,opt,name=body,proto3" json:"body,omitempty"` +} + +func (x *StorageData) Reset() { + *x = StorageData{} + if protoimpl.UnsafeEnabled { + mi := &file_msg_proto_msgTypes[24] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *StorageData) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StorageData) ProtoMessage() {} + +func (x *StorageData) ProtoReflect() protoreflect.Message { + mi := &file_msg_proto_msgTypes[24] + 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 StorageData.ProtoReflect.Descriptor instead. +func (*StorageData) Descriptor() ([]byte, []int) { + return file_msg_proto_rawDescGZIP(), []int{24} +} + +func (x *StorageData) GetHash() []byte { + if x != nil { + return x.Hash + } + return nil +} + +func (x *StorageData) GetBody() []byte { if x != nil { - return x.CommitSig + return x.Body } return nil } -type GetNodeDataResponse struct { +type StoragesData 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"` + Data []*StorageData `protobuf:"bytes,1,rep,name=data,proto3" json:"data,omitempty"` } -func (x *GetNodeDataResponse) Reset() { - *x = GetNodeDataResponse{} +func (x *StoragesData) Reset() { + *x = StoragesData{} if protoimpl.UnsafeEnabled { - mi := &file_msg_proto_msgTypes[14] + mi := &file_msg_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *GetNodeDataResponse) String() string { +func (x *StoragesData) String() string { return protoimpl.X.MessageStringOf(x) } -func (*GetNodeDataResponse) ProtoMessage() {} +func (*StoragesData) ProtoMessage() {} -func (x *GetNodeDataResponse) ProtoReflect() protoreflect.Message { - mi := &file_msg_proto_msgTypes[14] +func (x *StoragesData) ProtoReflect() protoreflect.Message { + mi := &file_msg_proto_msgTypes[25] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -964,43 +1697,44 @@ func (x *GetNodeDataResponse) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use GetNodeDataResponse.ProtoReflect.Descriptor instead. -func (*GetNodeDataResponse) Descriptor() ([]byte, []int) { - return file_msg_proto_rawDescGZIP(), []int{14} +// Deprecated: Use StoragesData.ProtoReflect.Descriptor instead. +func (*StoragesData) Descriptor() ([]byte, []int) { + return file_msg_proto_rawDescGZIP(), []int{25} } -func (x *GetNodeDataResponse) GetDataBytes() [][]byte { +func (x *StoragesData) GetData() []*StorageData { if x != nil { - return x.DataBytes + return x.Data } return nil } -type Receipts struct { +type GetStorageRangesResponse 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"` + Slots []*StoragesData `protobuf:"bytes,1,rep,name=slots,proto3" json:"slots,omitempty"` + Proof [][]byte `protobuf:"bytes,2,rep,name=proof,proto3" json:"proof,omitempty"` } -func (x *Receipts) Reset() { - *x = Receipts{} +func (x *GetStorageRangesResponse) Reset() { + *x = GetStorageRangesResponse{} if protoimpl.UnsafeEnabled { - mi := &file_msg_proto_msgTypes[15] + mi := &file_msg_proto_msgTypes[26] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *Receipts) String() string { +func (x *GetStorageRangesResponse) String() string { return protoimpl.X.MessageStringOf(x) } -func (*Receipts) ProtoMessage() {} +func (*GetStorageRangesResponse) ProtoMessage() {} -func (x *Receipts) ProtoReflect() protoreflect.Message { - mi := &file_msg_proto_msgTypes[15] +func (x *GetStorageRangesResponse) ProtoReflect() protoreflect.Message { + mi := &file_msg_proto_msgTypes[26] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1011,43 +1745,50 @@ func (x *Receipts) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use Receipts.ProtoReflect.Descriptor instead. -func (*Receipts) Descriptor() ([]byte, []int) { - return file_msg_proto_rawDescGZIP(), []int{15} +// Deprecated: Use GetStorageRangesResponse.ProtoReflect.Descriptor instead. +func (*GetStorageRangesResponse) Descriptor() ([]byte, []int) { + return file_msg_proto_rawDescGZIP(), []int{26} } -func (x *Receipts) GetReceiptBytes() [][]byte { +func (x *GetStorageRangesResponse) GetSlots() []*StoragesData { if x != nil { - return x.ReceiptBytes + return x.Slots } return nil } -type GetReceiptsResponse struct { +func (x *GetStorageRangesResponse) GetProof() [][]byte { + if x != nil { + return x.Proof + } + return nil +} + +type GetByteCodesResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - 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"` + Codes [][]byte `protobuf:"bytes,1,rep,name=codes,proto3" json:"codes,omitempty"` } -func (x *GetReceiptsResponse) Reset() { - *x = GetReceiptsResponse{} +func (x *GetByteCodesResponse) Reset() { + *x = GetByteCodesResponse{} if protoimpl.UnsafeEnabled { - mi := &file_msg_proto_msgTypes[16] + mi := &file_msg_proto_msgTypes[27] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *GetReceiptsResponse) String() string { +func (x *GetByteCodesResponse) String() string { return protoimpl.X.MessageStringOf(x) } -func (*GetReceiptsResponse) ProtoMessage() {} +func (*GetByteCodesResponse) ProtoMessage() {} -func (x *GetReceiptsResponse) ProtoReflect() protoreflect.Message { - mi := &file_msg_proto_msgTypes[16] +func (x *GetByteCodesResponse) ProtoReflect() protoreflect.Message { + mi := &file_msg_proto_msgTypes[27] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1058,14 +1799,61 @@ func (x *GetReceiptsResponse) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use GetReceiptsResponse.ProtoReflect.Descriptor instead. -func (*GetReceiptsResponse) Descriptor() ([]byte, []int) { - return file_msg_proto_rawDescGZIP(), []int{16} +// Deprecated: Use GetByteCodesResponse.ProtoReflect.Descriptor instead. +func (*GetByteCodesResponse) Descriptor() ([]byte, []int) { + return file_msg_proto_rawDescGZIP(), []int{27} } -func (x *GetReceiptsResponse) GetReceipts() map[uint64]*Receipts { +func (x *GetByteCodesResponse) GetCodes() [][]byte { if x != nil { - return x.Receipts + return x.Codes + } + return nil +} + +type GetTrieNodesResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Nodes [][]byte `protobuf:"bytes,1,rep,name=nodes,proto3" json:"nodes,omitempty"` +} + +func (x *GetTrieNodesResponse) Reset() { + *x = GetTrieNodesResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_msg_proto_msgTypes[28] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetTrieNodesResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetTrieNodesResponse) ProtoMessage() {} + +func (x *GetTrieNodesResponse) ProtoReflect() protoreflect.Message { + mi := &file_msg_proto_msgTypes[28] + 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 GetTrieNodesResponse.ProtoReflect.Descriptor instead. +func (*GetTrieNodesResponse) Descriptor() ([]byte, []int) { + return file_msg_proto_rawDescGZIP(), []int{28} +} + +func (x *GetTrieNodesResponse) GetNodes() [][]byte { + if x != nil { + return x.Nodes } return nil } @@ -1084,7 +1872,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, 0xbd, 0x05, 0x0a, 0x07, 0x52, + 0x65, 0x71, 0x5f, 0x6f, 0x72, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x22, 0xf6, 0x08, 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, @@ -1127,119 +1915,239 @@ var file_msg_proto_rawDesc = []byte{ 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, + 0x52, 0x65, 0x63, 0x65, 0x69, 0x70, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x70, 0x0a, 0x19, 0x67, 0x65, 0x74, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x72, + 0x61, 0x6e, 0x67, 0x65, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x08, 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, + 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x61, 0x6e, 0x67, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x16, 0x67, 0x65, 0x74, 0x41, 0x63, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x73, 0x0a, 0x1a, 0x67, 0x65, 0x74, 0x5f, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, + 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, + 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, 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, 0x6d, 0x2e, 0x73, 0x79, 0x6e, - 0x63, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, + 0x61, 0x67, 0x65, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x52, 0x61, + 0x6e, 0x67, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x17, 0x67, + 0x65, 0x74, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x67, 0x0a, 0x16, 0x67, 0x65, 0x74, 0x5f, 0x62, 0x79, + 0x74, 0x65, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x18, 0x0a, 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, 0x79, 0x74, 0x65, 0x43, 0x6f, 0x64, 0x65, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x13, 0x67, 0x65, 0x74, 0x42, + 0x79, 0x74, 0x65, 0x43, 0x6f, 0x64, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x67, 0x0a, 0x16, 0x67, 0x65, 0x74, 0x5f, 0x74, 0x72, 0x69, 0x65, 0x5f, 0x6e, 0x6f, 0x64, 0x65, + 0x73, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x0b, 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, 0x54, 0x72, 0x69, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x48, 0x00, 0x52, 0x13, 0x67, 0x65, 0x74, 0x54, 0x72, 0x69, 0x65, 0x4e, 0x6f, 0x64, 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, 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, 0x70, 0x0a, + 0x16, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x61, 0x6e, 0x67, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x6f, 0x6f, 0x74, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x72, 0x6f, 0x6f, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6f, + 0x72, 0x69, 0x67, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6f, 0x72, 0x69, + 0x67, 0x69, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x79, 0x74, + 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x22, + 0x8d, 0x01, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x52, 0x61, + 0x6e, 0x67, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x72, + 0x6f, 0x6f, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x72, 0x6f, 0x6f, 0x74, 0x12, + 0x1a, 0x0a, 0x08, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, + 0x0c, 0x52, 0x08, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x6f, + 0x72, 0x69, 0x67, 0x69, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6f, 0x72, 0x69, + 0x67, 0x69, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x79, 0x74, + 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x22, + 0x43, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x42, 0x79, 0x74, 0x65, 0x43, 0x6f, 0x64, 0x65, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x06, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, 0x12, 0x14, + 0x0a, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x62, + 0x79, 0x74, 0x65, 0x73, 0x22, 0x2b, 0x0a, 0x0f, 0x54, 0x72, 0x69, 0x65, 0x4e, 0x6f, 0x64, 0x65, + 0x50, 0x61, 0x74, 0x68, 0x53, 0x65, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x74, 0x68, 0x73, + 0x65, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x07, 0x70, 0x61, 0x74, 0x68, 0x73, 0x65, + 0x74, 0x22, 0x83, 0x01, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x54, 0x72, 0x69, 0x65, 0x4e, 0x6f, 0x64, + 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x6f, 0x6f, + 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x72, 0x6f, 0x6f, 0x74, 0x12, 0x42, 0x0a, + 0x05, 0x70, 0x61, 0x74, 0x68, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 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, 0x54, 0x72, 0x69, 0x65, 0x4e, + 0x6f, 0x64, 0x65, 0x50, 0x61, 0x74, 0x68, 0x53, 0x65, 0x74, 0x52, 0x05, 0x70, 0x61, 0x74, 0x68, + 0x73, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x22, 0xeb, 0x09, 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, 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, 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, + 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, 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, 0x12, 0x73, 0x0a, 0x1a, 0x67, 0x65, 0x74, 0x5f, 0x61, 0x63, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, 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, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, + 0x52, 0x17, 0x67, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x61, 0x6e, 0x67, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x76, 0x0a, 0x1b, 0x67, 0x65, 0x74, + 0x5f, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x5f, + 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, + 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, + 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, 0x18, 0x67, 0x65, 0x74, 0x53, 0x74, 0x6f, 0x72, + 0x61, 0x67, 0x65, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x6a, 0x0a, 0x17, 0x67, 0x65, 0x74, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x5f, 0x63, 0x6f, + 0x64, 0x65, 0x73, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x0b, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x31, 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, 0x79, 0x74, 0x65, 0x43, 0x6f, 0x64, 0x65, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, 0x14, 0x67, 0x65, 0x74, 0x42, 0x79, 0x74, 0x65, + 0x43, 0x6f, 0x64, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6a, 0x0a, + 0x17, 0x67, 0x65, 0x74, 0x5f, 0x74, 0x72, 0x69, 0x65, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x5f, + 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, + 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, + 0x54, 0x72, 0x69, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x48, 0x00, 0x52, 0x14, 0x67, 0x65, 0x74, 0x54, 0x72, 0x69, 0x65, 0x4e, 0x6f, 0x64, 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, 0x22, 0x34, 0x0a, 0x13, 0x47, 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, + 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, 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, 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, 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, + 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, 0x22, 0x35, 0x0a, 0x0b, 0x41, 0x63, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x44, 0x61, 0x74, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, + 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x12, 0x0a, + 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x62, 0x6f, 0x64, + 0x79, 0x22, 0x75, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, + 0x61, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x44, 0x0a, 0x08, + 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, + 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, 0x41, 0x63, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x44, 0x61, 0x74, 0x61, 0x52, 0x08, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x18, 0x02, 0x20, 0x03, 0x28, + 0x0c, 0x52, 0x05, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x22, 0x35, 0x0a, 0x0b, 0x53, 0x74, 0x6f, 0x72, + 0x61, 0x67, 0x65, 0x44, 0x61, 0x74, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x62, + 0x6f, 0x64, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x22, + 0x4c, 0x0a, 0x0c, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x73, 0x44, 0x61, 0x74, 0x61, 0x12, + 0x3c, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 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, 0x53, 0x74, 0x6f, 0x72, + 0x61, 0x67, 0x65, 0x44, 0x61, 0x74, 0x61, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x71, 0x0a, + 0x18, 0x47, 0x65, 0x74, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x52, 0x61, 0x6e, 0x67, 0x65, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3f, 0x0a, 0x05, 0x73, 0x6c, 0x6f, + 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 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, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x73, 0x44, + 0x61, 0x74, 0x61, 0x52, 0x05, 0x73, 0x6c, 0x6f, 0x74, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x72, + 0x6f, 0x6f, 0x66, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x05, 0x70, 0x72, 0x6f, 0x6f, 0x66, + 0x22, 0x2c, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x42, 0x79, 0x74, 0x65, 0x43, 0x6f, 0x64, 0x65, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x64, 0x65, + 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x05, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x22, 0x2c, + 0x0a, 0x14, 0x47, 0x65, 0x74, 0x54, 0x72, 0x69, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x05, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x42, 0x0c, 0x5a, 0x0a, + 0x2e, 0x2f, 0x3b, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, } var ( @@ -1254,7 +2162,7 @@ func file_msg_proto_rawDescGZIP() []byte { return file_msg_proto_rawDescData } -var file_msg_proto_msgTypes = make([]protoimpl.MessageInfo, 18) +var file_msg_proto_msgTypes = make([]protoimpl.MessageInfo, 30) var file_msg_proto_goTypes = []interface{}{ (*Message)(nil), // 0: harmony.stream.sync.message.Message (*Request)(nil), // 1: harmony.stream.sync.message.Request @@ -1264,40 +2172,64 @@ var file_msg_proto_goTypes = []interface{}{ (*GetBlocksByHashesRequest)(nil), // 5: harmony.stream.sync.message.GetBlocksByHashesRequest (*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 - (*Receipts)(nil), // 15: harmony.stream.sync.message.Receipts - (*GetReceiptsResponse)(nil), // 16: harmony.stream.sync.message.GetReceiptsResponse - nil, // 17: harmony.stream.sync.message.GetReceiptsResponse.ReceiptsEntry + (*GetAccountRangeRequest)(nil), // 8: harmony.stream.sync.message.GetAccountRangeRequest + (*GetStorageRangesRequest)(nil), // 9: harmony.stream.sync.message.GetStorageRangesRequest + (*GetByteCodesRequest)(nil), // 10: harmony.stream.sync.message.GetByteCodesRequest + (*TrieNodePathSet)(nil), // 11: harmony.stream.sync.message.TrieNodePathSet + (*GetTrieNodesRequest)(nil), // 12: harmony.stream.sync.message.GetTrieNodesRequest + (*Response)(nil), // 13: harmony.stream.sync.message.Response + (*ErrorResponse)(nil), // 14: harmony.stream.sync.message.ErrorResponse + (*GetBlockNumberResponse)(nil), // 15: harmony.stream.sync.message.GetBlockNumberResponse + (*GetBlockHashesResponse)(nil), // 16: harmony.stream.sync.message.GetBlockHashesResponse + (*GetBlocksByNumResponse)(nil), // 17: harmony.stream.sync.message.GetBlocksByNumResponse + (*GetBlocksByHashesResponse)(nil), // 18: harmony.stream.sync.message.GetBlocksByHashesResponse + (*GetNodeDataResponse)(nil), // 19: harmony.stream.sync.message.GetNodeDataResponse + (*Receipts)(nil), // 20: harmony.stream.sync.message.Receipts + (*GetReceiptsResponse)(nil), // 21: harmony.stream.sync.message.GetReceiptsResponse + (*AccountData)(nil), // 22: harmony.stream.sync.message.AccountData + (*GetAccountRangeResponse)(nil), // 23: harmony.stream.sync.message.GetAccountRangeResponse + (*StorageData)(nil), // 24: harmony.stream.sync.message.StorageData + (*StoragesData)(nil), // 25: harmony.stream.sync.message.StoragesData + (*GetStorageRangesResponse)(nil), // 26: harmony.stream.sync.message.GetStorageRangesResponse + (*GetByteCodesResponse)(nil), // 27: harmony.stream.sync.message.GetByteCodesResponse + (*GetTrieNodesResponse)(nil), // 28: harmony.stream.sync.message.GetTrieNodesResponse + nil, // 29: 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 - 8, // 1: harmony.stream.sync.message.Message.resp:type_name -> harmony.stream.sync.message.Response + 13, // 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 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 - 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 + 8, // 8: harmony.stream.sync.message.Request.get_account_range_request:type_name -> harmony.stream.sync.message.GetAccountRangeRequest + 9, // 9: harmony.stream.sync.message.Request.get_storage_ranges_request:type_name -> harmony.stream.sync.message.GetStorageRangesRequest + 10, // 10: harmony.stream.sync.message.Request.get_byte_codes_request:type_name -> harmony.stream.sync.message.GetByteCodesRequest + 12, // 11: harmony.stream.sync.message.Request.get_trie_nodes_request:type_name -> harmony.stream.sync.message.GetTrieNodesRequest + 11, // 12: harmony.stream.sync.message.GetTrieNodesRequest.paths:type_name -> harmony.stream.sync.message.TrieNodePathSet + 14, // 13: harmony.stream.sync.message.Response.error_response:type_name -> harmony.stream.sync.message.ErrorResponse + 15, // 14: harmony.stream.sync.message.Response.get_block_number_response:type_name -> harmony.stream.sync.message.GetBlockNumberResponse + 16, // 15: harmony.stream.sync.message.Response.get_block_hashes_response:type_name -> harmony.stream.sync.message.GetBlockHashesResponse + 17, // 16: harmony.stream.sync.message.Response.get_blocks_by_num_response:type_name -> harmony.stream.sync.message.GetBlocksByNumResponse + 18, // 17: harmony.stream.sync.message.Response.get_blocks_by_hashes_response:type_name -> harmony.stream.sync.message.GetBlocksByHashesResponse + 19, // 18: harmony.stream.sync.message.Response.get_node_data_response:type_name -> harmony.stream.sync.message.GetNodeDataResponse + 21, // 19: harmony.stream.sync.message.Response.get_receipts_response:type_name -> harmony.stream.sync.message.GetReceiptsResponse + 23, // 20: harmony.stream.sync.message.Response.get_account_range_response:type_name -> harmony.stream.sync.message.GetAccountRangeResponse + 26, // 21: harmony.stream.sync.message.Response.get_storage_ranges_response:type_name -> harmony.stream.sync.message.GetStorageRangesResponse + 27, // 22: harmony.stream.sync.message.Response.get_byte_codes_response:type_name -> harmony.stream.sync.message.GetByteCodesResponse + 28, // 23: harmony.stream.sync.message.Response.get_trie_nodes_response:type_name -> harmony.stream.sync.message.GetTrieNodesResponse + 29, // 24: harmony.stream.sync.message.GetReceiptsResponse.receipts:type_name -> harmony.stream.sync.message.GetReceiptsResponse.ReceiptsEntry + 22, // 25: harmony.stream.sync.message.GetAccountRangeResponse.accounts:type_name -> harmony.stream.sync.message.AccountData + 24, // 26: harmony.stream.sync.message.StoragesData.data:type_name -> harmony.stream.sync.message.StorageData + 25, // 27: harmony.stream.sync.message.GetStorageRangesResponse.slots:type_name -> harmony.stream.sync.message.StoragesData + 20, // 28: harmony.stream.sync.message.GetReceiptsResponse.ReceiptsEntry.value:type_name -> harmony.stream.sync.message.Receipts + 29, // [29:29] is the sub-list for method output_type + 29, // [29:29] is the sub-list for method input_type + 29, // [29:29] is the sub-list for extension type_name + 29, // [29:29] is the sub-list for extension extendee + 0, // [0:29] is the sub-list for field type_name } func init() { file_msg_proto_init() } @@ -1403,7 +2335,7 @@ func file_msg_proto_init() { } } file_msg_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Response); i { + switch v := v.(*GetAccountRangeRequest); i { case 0: return &v.state case 1: @@ -1415,7 +2347,7 @@ func file_msg_proto_init() { } } file_msg_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ErrorResponse); i { + switch v := v.(*GetStorageRangesRequest); i { case 0: return &v.state case 1: @@ -1427,7 +2359,7 @@ func file_msg_proto_init() { } } file_msg_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetBlockNumberResponse); i { + switch v := v.(*GetByteCodesRequest); i { case 0: return &v.state case 1: @@ -1439,7 +2371,7 @@ func file_msg_proto_init() { } } file_msg_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetBlockHashesResponse); i { + switch v := v.(*TrieNodePathSet); i { case 0: return &v.state case 1: @@ -1451,7 +2383,7 @@ func file_msg_proto_init() { } } file_msg_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetBlocksByNumResponse); i { + switch v := v.(*GetTrieNodesRequest); i { case 0: return &v.state case 1: @@ -1463,7 +2395,7 @@ func file_msg_proto_init() { } } file_msg_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetBlocksByHashesResponse); i { + switch v := v.(*Response); i { case 0: return &v.state case 1: @@ -1475,7 +2407,7 @@ func file_msg_proto_init() { } } file_msg_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetNodeDataResponse); i { + switch v := v.(*ErrorResponse); i { case 0: return &v.state case 1: @@ -1487,7 +2419,7 @@ func file_msg_proto_init() { } } file_msg_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Receipts); i { + switch v := v.(*GetBlockNumberResponse); i { case 0: return &v.state case 1: @@ -1499,6 +2431,66 @@ func file_msg_proto_init() { } } file_msg_proto_msgTypes[16].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[17].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[18].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetBlocksByHashesResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_msg_proto_msgTypes[19].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[20].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[21].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetReceiptsResponse); i { case 0: return &v.state @@ -1510,6 +2502,90 @@ func file_msg_proto_init() { return nil } } + file_msg_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AccountData); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_msg_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetAccountRangeResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_msg_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*StorageData); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_msg_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*StoragesData); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_msg_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetStorageRangesResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_msg_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetByteCodesResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_msg_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetTrieNodesResponse); 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), @@ -1522,8 +2598,12 @@ func file_msg_proto_init() { (*Request_GetBlocksByHashesRequest)(nil), (*Request_GetNodeDataRequest)(nil), (*Request_GetReceiptsRequest)(nil), + (*Request_GetAccountRangeRequest)(nil), + (*Request_GetStorageRangesRequest)(nil), + (*Request_GetByteCodesRequest)(nil), + (*Request_GetTrieNodesRequest)(nil), } - file_msg_proto_msgTypes[8].OneofWrappers = []interface{}{ + file_msg_proto_msgTypes[13].OneofWrappers = []interface{}{ (*Response_ErrorResponse)(nil), (*Response_GetBlockNumberResponse)(nil), (*Response_GetBlockHashesResponse)(nil), @@ -1531,6 +2611,10 @@ func file_msg_proto_init() { (*Response_GetBlocksByHashesResponse)(nil), (*Response_GetNodeDataResponse)(nil), (*Response_GetReceiptsResponse)(nil), + (*Response_GetAccountRangeResponse)(nil), + (*Response_GetStorageRangesResponse)(nil), + (*Response_GetByteCodesResponse)(nil), + (*Response_GetTrieNodesResponse)(nil), } type x struct{} out := protoimpl.TypeBuilder{ @@ -1538,7 +2622,7 @@ func file_msg_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_msg_proto_rawDesc, NumEnums: 0, - NumMessages: 18, + NumMessages: 30, NumExtensions: 0, NumServices: 0, }, diff --git a/p2p/stream/protocols/sync/message/msg.proto b/p2p/stream/protocols/sync/message/msg.proto index f48341868..85fa67460 100644 --- a/p2p/stream/protocols/sync/message/msg.proto +++ b/p2p/stream/protocols/sync/message/msg.proto @@ -19,6 +19,10 @@ message Request { GetBlocksByHashesRequest get_blocks_by_hashes_request = 5; GetNodeDataRequest get_node_data_request = 6; GetReceiptsRequest get_receipts_request = 7; + GetAccountRangeRequest get_account_range_request = 8; + GetStorageRangesRequest get_storage_ranges_request = 9; + GetByteCodesRequest get_byte_codes_request = 10; + GetTrieNodesRequest get_trie_nodes_request = 11; } } @@ -44,6 +48,36 @@ message GetReceiptsRequest { repeated bytes block_hashes = 1; } +message GetAccountRangeRequest { + bytes root = 1; + bytes origin = 2; + bytes limit = 3; + uint64 bytes = 4; +} + +message GetStorageRangesRequest { + bytes root = 1; + repeated bytes accounts = 2; + bytes origin = 3; + bytes limit = 4; + uint64 bytes = 5; +} + +message GetByteCodesRequest { + repeated bytes hashes = 1; + uint64 bytes = 2; +} + +message TrieNodePathSet { + repeated bytes pathset = 1; +} + +message GetTrieNodesRequest { + bytes root = 1; + repeated TrieNodePathSet paths = 2; + uint64 bytes = 3; +} + message Response { uint64 req_id = 1; oneof response { @@ -54,6 +88,10 @@ message Response { GetBlocksByHashesResponse get_blocks_by_hashes_response = 6; GetNodeDataResponse get_node_data_response = 7; GetReceiptsResponse get_receipts_response = 8; + GetAccountRangeResponse get_account_range_response = 9; + GetStorageRangesResponse get_storage_ranges_response = 10; + GetByteCodesResponse get_byte_codes_response = 11; + GetTrieNodesResponse get_trie_nodes_response = 12; } } @@ -90,3 +128,35 @@ message Receipts { message GetReceiptsResponse { map receipts = 1; } + +message AccountData { + bytes hash = 1; + bytes body = 2; +} + +message GetAccountRangeResponse { + repeated AccountData accounts = 1; + repeated bytes proof = 2; +} + +message StorageData { + bytes hash = 1; + bytes body = 2; +} + +message StoragesData { + repeated StorageData data = 1; +} + +message GetStorageRangesResponse { + repeated StoragesData slots = 1; + repeated bytes proof = 2; +} + +message GetByteCodesResponse { + repeated bytes codes = 1; +} + +message GetTrieNodesResponse { + repeated bytes nodes = 1; +} \ No newline at end of file diff --git a/p2p/stream/protocols/sync/message/parse.go b/p2p/stream/protocols/sync/message/parse.go index b0bf360a8..4c9849c06 100644 --- a/p2p/stream/protocols/sync/message/parse.go +++ b/p2p/stream/protocols/sync/message/parse.go @@ -111,3 +111,67 @@ func (msg *Message) GetNodeDataResponse() (*GetNodeDataResponse, error) { } return gnResp, nil } + +// GetAccountRangesResponse parse the message to GetAccountRangesResponse +func (msg *Message) GetAccountRangesResponse() (*GetAccountRangeResponse, error) { + resp := msg.GetResp() + if resp == nil { + return nil, errors.New("not response message") + } + if errResp := resp.GetErrorResponse(); errResp != nil { + return nil, &ResponseError{errResp.Error} + } + gnResp := resp.GetGetAccountRangeResponse() + if gnResp == nil { + return nil, errors.New("not GetGetAccountRangeResponse") + } + return gnResp, nil +} + +// GetStorageRangesResponse parse the message to GetStorageRangesResponse +func (msg *Message) GetStorageRangesResponse() (*GetStorageRangesResponse, error) { + resp := msg.GetResp() + if resp == nil { + return nil, errors.New("not response message") + } + if errResp := resp.GetErrorResponse(); errResp != nil { + return nil, &ResponseError{errResp.Error} + } + gnResp := resp.GetGetStorageRangesResponse() + if gnResp == nil { + return nil, errors.New("not GetGetStorageRangesResponse") + } + return gnResp, nil +} + +// GetByteCodesResponse parse the message to GetByteCodesResponse +func (msg *Message) GetByteCodesResponse() (*GetByteCodesResponse, error) { + resp := msg.GetResp() + if resp == nil { + return nil, errors.New("not response message") + } + if errResp := resp.GetErrorResponse(); errResp != nil { + return nil, &ResponseError{errResp.Error} + } + gnResp := resp.GetGetByteCodesResponse() + if gnResp == nil { + return nil, errors.New("not GetByteCodesResponse") + } + return gnResp, nil +} + +// GetTrieNodesResponse parse the message to GetTrieNodesResponse +func (msg *Message) GetTrieNodesResponse() (*GetTrieNodesResponse, error) { + resp := msg.GetResp() + if resp == nil { + return nil, errors.New("not response message") + } + if errResp := resp.GetErrorResponse(); errResp != nil { + return nil, &ResponseError{errResp.Error} + } + gnResp := resp.GetGetTrieNodesResponse() + if gnResp == nil { + return nil, errors.New("not GetTrieNodesResponse") + } + return gnResp, nil +} diff --git a/p2p/stream/protocols/sync/stream.go b/p2p/stream/protocols/sync/stream.go index 56419767f..3077a8a13 100644 --- a/p2p/stream/protocols/sync/stream.go +++ b/p2p/stream/protocols/sync/stream.go @@ -10,6 +10,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/rlp" protobuf "github.com/golang/protobuf/proto" + "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" libp2p_network "github.com/libp2p/go-libp2p/core/network" @@ -188,6 +189,18 @@ func (st *syncStream) handleReq(req *syncpb.Request) error { if rReq := req.GetGetReceiptsRequest(); rReq != nil { return st.handleGetReceiptsRequest(req.ReqId, rReq) } + if ndReq := req.GetGetAccountRangeRequest(); ndReq != nil { + return st.handleGetAccountRangeRequest(req.ReqId, ndReq) + } + if ndReq := req.GetGetStorageRangesRequest(); ndReq != nil { + return st.handleGetStorageRangesRequest(req.ReqId, ndReq) + } + if ndReq := req.GetGetByteCodesRequest(); ndReq != nil { + return st.handleGetByteCodesRequest(req.ReqId, ndReq) + } + if ndReq := req.GetGetTrieNodesRequest(); ndReq != nil { + return st.handleGetTrieNodesRequest(req.ReqId, ndReq) + } // unsupported request type return st.handleUnknownRequest(req.ReqId) } @@ -308,6 +321,95 @@ func (st *syncStream) handleGetReceiptsRequest(rid uint64, req *syncpb.GetReceip return errors.Wrap(err, "[GetReceipts]") } +func (st *syncStream) handleGetAccountRangeRequest(rid uint64, req *syncpb.GetAccountRangeRequest) error { + serverRequestCounterVec.With(prometheus.Labels{ + "topic": string(st.ProtoID()), + "request_type": "getAccountRangeRequest", + }).Inc() + + root := common.BytesToHash(req.Root) + origin := common.BytesToHash(req.Origin) + limit := common.BytesToHash(req.Limit) + resp, err := st.computeGetAccountRangeRequest(rid, root, origin, limit, req.Bytes) + 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, "[GetAccountRange]") +} + +func (st *syncStream) handleGetStorageRangesRequest(rid uint64, req *syncpb.GetStorageRangesRequest) error { + serverRequestCounterVec.With(prometheus.Labels{ + "topic": string(st.ProtoID()), + "request_type": "getStorageRangesRequest", + }).Inc() + + root := common.BytesToHash(req.Root) + accounts := bytesToHashes(req.Accounts) + origin := common.BytesToHash(req.Origin) + limit := common.BytesToHash(req.Limit) + resp, err := st.computeGetStorageRangesRequest(rid, root, accounts, origin, limit, req.Bytes) + 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, "[GetStorageRanges]") +} + +func (st *syncStream) handleGetByteCodesRequest(rid uint64, req *syncpb.GetByteCodesRequest) error { + serverRequestCounterVec.With(prometheus.Labels{ + "topic": string(st.ProtoID()), + "request_type": "getByteCodesRequest", + }).Inc() + + hashes := bytesToHashes(req.Hashes) + resp, err := st.computeGetByteCodesRequest(rid, hashes, req.Bytes) + 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, "[GetByteCodes]") +} + +func (st *syncStream) handleGetTrieNodesRequest(rid uint64, req *syncpb.GetTrieNodesRequest) error { + serverRequestCounterVec.With(prometheus.Labels{ + "topic": string(st.ProtoID()), + "request_type": "getTrieNodesRequest", + }).Inc() + + root := common.BytesToHash(req.Root) + resp, err := st.computeGetTrieNodesRequest(rid, root, req.Paths, req.Bytes) + 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, "[GetTrieNodes]") +} + func (st *syncStream) handleUnknownRequest(rid uint64) error { serverRequestCounterVec.With(prometheus.Labels{ "topic": string(st.ProtoID()), @@ -453,6 +555,74 @@ func (st *syncStream) computeGetReceipts(rid uint64, hs []common.Hash) (*syncpb. return syncpb.MakeGetReceiptsResponseMessage(rid, normalizedReceipts), nil } +func (st *syncStream) computeGetAccountRangeRequest(rid uint64, root common.Hash, origin common.Hash, limit common.Hash, bytes uint64) (*syncpb.Message, error) { + if bytes == 0 { + return nil, fmt.Errorf("zero account ranges bytes requested") + } + if bytes > softResponseLimit { + return nil, fmt.Errorf("requested bytes exceed limit") + } + accounts, proof, err := st.chain.getAccountRange(root, origin, limit, bytes) + if err != nil { + return nil, err + } + return syncpb.MakeGetAccountRangeResponseMessage(rid, accounts, proof), nil +} + +func (st *syncStream) computeGetStorageRangesRequest(rid uint64, root common.Hash, accounts []common.Hash, origin common.Hash, limit common.Hash, bytes uint64) (*syncpb.Message, error) { + if bytes == 0 { + return nil, fmt.Errorf("zero storage ranges bytes requested") + } + if bytes > softResponseLimit { + return nil, fmt.Errorf("requested bytes exceed limit") + } + if len(accounts) > GetStorageRangesRequestCap { + err := fmt.Errorf("GetStorageRangesRequest amount exceed cap: %v > %v", len(accounts), GetStorageRangesRequestCap) + return nil, err + } + slots, proofs, err := st.chain.getStorageRanges(root, accounts, origin, limit, bytes) + if err != nil { + return nil, err + } + return syncpb.MakeGetStorageRangesResponseMessage(rid, slots, proofs), nil +} + +func (st *syncStream) computeGetByteCodesRequest(rid uint64, hs []common.Hash, bytes uint64) (*syncpb.Message, error) { + if bytes == 0 { + return nil, fmt.Errorf("zero byte code bytes requested") + } + if bytes > softResponseLimit { + return nil, fmt.Errorf("requested bytes exceed limit") + } + if len(hs) > GetByteCodesRequestCap { + err := fmt.Errorf("GetByteCodesRequest amount exceed cap: %v > %v", len(hs), GetByteCodesRequestCap) + return nil, err + } + codes, err := st.chain.getByteCodes(hs, bytes) + if err != nil { + return nil, err + } + return syncpb.MakeGetByteCodesResponseMessage(rid, codes), nil +} + +func (st *syncStream) computeGetTrieNodesRequest(rid uint64, root common.Hash, paths []*message.TrieNodePathSet, bytes uint64) (*syncpb.Message, error) { + if bytes == 0 { + return nil, fmt.Errorf("zero trie node bytes requested") + } + if bytes > softResponseLimit { + return nil, fmt.Errorf("requested bytes exceed limit") + } + if len(paths) > GetTrieNodesRequestCap { + err := fmt.Errorf("GetTrieNodesRequest amount exceed cap: %v > %v", len(paths), GetTrieNodesRequestCap) + return nil, err + } + nodes, err := st.chain.getTrieNodes(root, paths, bytes, time.Now()) + if err != nil { + return nil, err + } + return syncpb.MakeGetTrieNodesResponseMessage(rid, nodes), nil +} + func bytesToHashes(bs [][]byte) []common.Hash { hs := make([]common.Hash, 0, len(bs)) for _, b := range bs { diff --git a/p2p/stream/protocols/sync/stream_test.go b/p2p/stream/protocols/sync/stream_test.go index f33bc3eb9..3b538c14b 100644 --- a/p2p/stream/protocols/sync/stream_test.go +++ b/p2p/stream/protocols/sync/stream_test.go @@ -60,6 +60,30 @@ var ( } testGetNodeDataRequest = syncpb.MakeGetNodeDataRequest(testGetNodeData) testGetNodeDataRequestMsg = syncpb.MakeMessageFromRequest(testGetNodeDataRequest) + + maxBytes = uint64(500) + root = numberToHash(1) + origin = numberToHash(2) + limit = numberToHash(3) + + testHashes = []common.Hash{ + numberToHash(1), + numberToHash(2), + } + + testAccounts = []common.Hash{account1, account2} + + testGetAccountRangesRequest = syncpb.MakeGetAccountRangeRequest(root, origin, limit, maxBytes) + testGetAccountRangesRequestMsg = syncpb.MakeMessageFromRequest(testGetAccountRangesRequest) + + testGetStorageRangesRequest = syncpb.MakeGetStorageRangesRequest(root, testAccounts, origin, limit, maxBytes) + testGetStorageRangesRequestMsg = syncpb.MakeMessageFromRequest(testGetStorageRangesRequest) + + testGetByteCodesRequest = syncpb.MakeGetByteCodesRequest(testHashes, maxBytes) + testGetByteCodesRequestMsg = syncpb.MakeMessageFromRequest(testGetByteCodesRequest) + + testGetTrieNodesRequest = syncpb.MakeGetTrieNodesRequest(root, testPaths, maxBytes) + testGetTrieNodesRequestMsg = syncpb.MakeMessageFromRequest(testGetTrieNodesRequest) ) func TestSyncStream_HandleGetBlocksByRequest(t *testing.T) { @@ -188,6 +212,90 @@ func TestSyncStream_HandleGetNodeData(t *testing.T) { } } +func TestSyncStream_HandleGetAccountRanges(t *testing.T) { + st, remoteSt := makeTestSyncStream() + + go st.run() + defer close(st.closeC) + + req := testGetAccountRangesRequestMsg + b, _ := protobuf.Marshal(req) + err := remoteSt.WriteBytes(b) + if err != nil { + t.Fatal(err) + } + + time.Sleep(200 * time.Millisecond) + receivedBytes, _ := remoteSt.ReadBytes() + + if err := checkAccountRangeResult(maxBytes, receivedBytes); err != nil { + t.Fatal(err) + } +} + +func TestSyncStream_HandleGetStorageRanges(t *testing.T) { + st, remoteSt := makeTestSyncStream() + + go st.run() + defer close(st.closeC) + + req := testGetStorageRangesRequestMsg + b, _ := protobuf.Marshal(req) + err := remoteSt.WriteBytes(b) + if err != nil { + t.Fatal(err) + } + + time.Sleep(200 * time.Millisecond) + receivedBytes, _ := remoteSt.ReadBytes() + + if err := checkStorageRangesResult(testAccounts, maxBytes, receivedBytes); err != nil { + t.Fatal(err) + } +} + +func TestSyncStream_HandleGetByteCodesResult(t *testing.T) { + st, remoteSt := makeTestSyncStream() + + go st.run() + defer close(st.closeC) + + req := testGetByteCodesRequestMsg + b, _ := protobuf.Marshal(req) + err := remoteSt.WriteBytes(b) + if err != nil { + t.Fatal(err) + } + + time.Sleep(200 * time.Millisecond) + receivedBytes, _ := remoteSt.ReadBytes() + + if err := checkByteCodesResult(testHashes, maxBytes, receivedBytes); err != nil { + t.Fatal(err) + } +} + +func TestSyncStream_HandleGetTrieNodes(t *testing.T) { + st, remoteSt := makeTestSyncStream() + + go st.run() + defer close(st.closeC) + + req := testGetTrieNodesRequestMsg + b, _ := protobuf.Marshal(req) + err := remoteSt.WriteBytes(b) + if err != nil { + t.Fatal(err) + } + + time.Sleep(200 * time.Millisecond) + receivedBytes, _ := remoteSt.ReadBytes() + + if err := checkTrieNodesResult(testHashes, maxBytes, receivedBytes); err != nil { + t.Fatal(err) + } +} + func makeTestSyncStream() (*syncStream, *testRemoteBaseStream) { localRaw, remoteRaw := makePairP2PStreams() remote := newTestRemoteBaseStream(remoteRaw) diff --git a/test/chain/chain/chain_makers.go b/test/chain/chain/chain_makers.go index 2b82beb57..122540038 100644 --- a/test/chain/chain/chain_makers.go +++ b/test/chain/chain/chain_makers.go @@ -22,12 +22,14 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/trie" "github.com/harmony-one/harmony/core" "github.com/harmony-one/harmony/block" blockfactory "github.com/harmony-one/harmony/block/factory" consensus_engine "github.com/harmony-one/harmony/consensus/engine" "github.com/harmony-one/harmony/core/state" + "github.com/harmony-one/harmony/core/state/snapshot" "github.com/harmony-one/harmony/core/types" "github.com/harmony-one/harmony/core/vm" "github.com/harmony-one/harmony/internal/params" @@ -252,6 +254,7 @@ func (cr *fakeChainReader) GetReceiptsByHash(hash common.Hash) types.Receipts 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) TrieDB() *trie.Database { return 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 } @@ -273,6 +276,9 @@ func (cr *fakeChainReader) ReadValidatorInformationAtState( func (cr *fakeChainReader) StateAt(root common.Hash) (*state.DB, error) { return nil, nil } +func (cr *fakeChainReader) Snapshots() *snapshot.Tree { + return nil +} func (cr *fakeChainReader) ReadValidatorSnapshot( addr common.Address, ) (*staking.ValidatorSnapshot, error) { From 57dd5f26783deab49cf4ec37e6bd9c772106dfda Mon Sep 17 00:00:00 2001 From: Konstantin <355847+Frozen@users.noreply.github.com> Date: Thu, 26 Oct 2023 07:35:32 -0800 Subject: [PATCH 04/19] Fixed. (#4543) --- shard/committee/assignment.go | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/shard/committee/assignment.go b/shard/committee/assignment.go index 85162e671..4978b6155 100644 --- a/shard/committee/assignment.go +++ b/shard/committee/assignment.go @@ -25,19 +25,6 @@ import ( "github.com/pkg/errors" ) -// ValidatorListProvider .. -type ValidatorListProvider interface { - Compute( - epoch *big.Int, reader DataProvider, - ) (*shard.State, error) - ReadFromDB(epoch *big.Int, reader DataProvider) (*shard.State, error) -} - -// Reader is committee.Reader and it is the API that committee membership assignment needs -type Reader interface { - ValidatorListProvider -} - // StakingCandidatesReader .. type StakingCandidatesReader interface { CurrentBlock() *types.Block @@ -272,7 +259,7 @@ type partialStakingEnabled struct{} var ( // WithStakingEnabled .. - WithStakingEnabled Reader = partialStakingEnabled{} + WithStakingEnabled = partialStakingEnabled{} // ErrComputeForEpochInPast .. ErrComputeForEpochInPast = errors.New("cannot compute for epoch in past") ) From b1389dacc452688584199958b58544c688e62e17 Mon Sep 17 00:00:00 2001 From: Konstantin <355847+Frozen@users.noreply.github.com> Date: Thu, 26 Oct 2023 07:36:13 -0800 Subject: [PATCH 05/19] Fixed data race. (#4544) * Fixed data race. * Additional error checking for InsertChain. --- api/service/legacysync/epoch_syncing.go | 14 ++- api/service/stagedstreamsync/beacon_helper.go | 5 +- api/service/stagedstreamsync/sig_verify.go | 9 +- api/service/stagedstreamsync/stage_epoch.go | 20 +++-- .../stagedstreamsync/staged_stream_sync.go | 8 +- api/service/stagedsync/stage_state.go | 2 +- api/service/stagedsync/stagedsync.go | 7 +- consensus/consensus_v2.go | 3 +- consensus/downloader.go | 3 +- node/node_explorer.go | 2 +- p2p/host.go | 2 +- p2p/security/security.go | 88 ++++++++----------- p2p/security/security_test.go | 24 +++-- 13 files changed, 105 insertions(+), 82 deletions(-) diff --git a/api/service/legacysync/epoch_syncing.go b/api/service/legacysync/epoch_syncing.go index e4453cb69..5d9b4dab1 100644 --- a/api/service/legacysync/epoch_syncing.go +++ b/api/service/legacysync/epoch_syncing.go @@ -199,8 +199,18 @@ func processWithPayload(payload [][]byte, bc core.BlockChain) error { decoded = append(decoded, block) } - _, err := bc.InsertChain(decoded, true) - return err + for _, block := range decoded { + _, err := bc.InsertChain([]*types.Block{block}, true) + switch { + case errors.Is(err, core.ErrKnownBlock): + continue + case err != nil: + return err + default: + } + } + + return nil } // CreateSyncConfig creates SyncConfig for StateSync object. diff --git a/api/service/stagedstreamsync/beacon_helper.go b/api/service/stagedstreamsync/beacon_helper.go index a996f368b..4fe70dc23 100644 --- a/api/service/stagedstreamsync/beacon_helper.go +++ b/api/service/stagedstreamsync/beacon_helper.go @@ -1,8 +1,10 @@ package stagedstreamsync import ( + "errors" "time" + "github.com/harmony-one/harmony/core" "github.com/harmony-one/harmony/core/types" "github.com/harmony-one/harmony/internal/utils" "github.com/rs/zerolog" @@ -126,7 +128,8 @@ func (bh *beaconHelper) insertLastMileBlocks() (inserted int, bn uint64, err err } // TODO: Instruct the beacon helper to verify signatures. This may require some forks // in pub-sub message (add commit sigs in node.block.sync messages) - if _, err = bh.bc.InsertChain(types.Blocks{b}, true); err != nil { + _, err = bh.bc.InsertChain(types.Blocks{b}, true) + if err != nil && !errors.Is(err, core.ErrKnownBlock) { bn-- return } diff --git a/api/service/stagedstreamsync/sig_verify.go b/api/service/stagedstreamsync/sig_verify.go index 649c6eaec..8de71effc 100644 --- a/api/service/stagedstreamsync/sig_verify.go +++ b/api/service/stagedstreamsync/sig_verify.go @@ -3,6 +3,7 @@ package stagedstreamsync import ( "fmt" + "github.com/harmony-one/harmony/core" "github.com/harmony-one/harmony/core/types" "github.com/harmony-one/harmony/crypto/bls" "github.com/harmony-one/harmony/internal/chain" @@ -53,8 +54,14 @@ func verifyAndInsertBlock(bc blockChain, block *types.Block, nextBlocks ...*type if err := bc.Engine().VerifyHeader(bc, block.Header(), true); err != nil { return errors.Wrap(err, "[VerifyHeader]") } - if _, err := bc.InsertChain(types.Blocks{block}, false); err != nil { + _, err = bc.InsertChain(types.Blocks{block}, false) + switch { + case errors.Is(err, core.ErrKnownBlock): + return nil + case err != nil: return errors.Wrap(err, "[InsertChain]") + default: + } return nil } diff --git a/api/service/stagedstreamsync/stage_epoch.go b/api/service/stagedstreamsync/stage_epoch.go index e84b74f34..8129ce0db 100644 --- a/api/service/stagedstreamsync/stage_epoch.go +++ b/api/service/stagedstreamsync/stage_epoch.go @@ -4,6 +4,7 @@ import ( "context" "github.com/harmony-one/harmony/core" + "github.com/harmony-one/harmony/core/types" "github.com/harmony-one/harmony/internal/utils" sttypes "github.com/harmony-one/harmony/p2p/stream/types" "github.com/harmony-one/harmony/shard" @@ -129,13 +130,20 @@ func (sr *StageEpoch) doShortRangeSyncForEpochSync(ctx context.Context, s *Stage return 0, nil } - n, err := s.state.bc.InsertChain(blocks, true) - numBlocksInsertedShortRangeHistogramVec.With(s.state.promLabels()).Observe(float64(n)) - if err != nil { - utils.Logger().Info().Err(err).Int("blocks inserted", n).Msg("Insert block failed") - sh.streamsFailed([]sttypes.StreamID{streamID}, "corrupted data") - return n, err + n := 0 + for _, block := range blocks { + _, err := s.state.bc.InsertChain([]*types.Block{block}, true) + switch { + case errors.Is(err, core.ErrKnownBlock): + case err != nil: + utils.Logger().Info().Err(err).Int("blocks inserted", n).Msg("Insert block failed") + sh.streamsFailed([]sttypes.StreamID{streamID}, "corrupted data") + return n, err + default: + } + n++ } + numBlocksInsertedShortRangeHistogramVec.With(s.state.promLabels()).Observe(float64(n)) return n, nil } diff --git a/api/service/stagedstreamsync/staged_stream_sync.go b/api/service/stagedstreamsync/staged_stream_sync.go index 1592186b5..fc5929047 100644 --- a/api/service/stagedstreamsync/staged_stream_sync.go +++ b/api/service/stagedstreamsync/staged_stream_sync.go @@ -636,7 +636,8 @@ func (ss *StagedStreamSync) addConsensusLastMile(bc core.BlockChain, cs *consens if block == nil { break } - if _, err := bc.InsertChain(types.Blocks{block}, true); err != nil { + _, err := bc.InsertChain(types.Blocks{block}, true) + if err != nil && !errors.Is(err, core.ErrKnownBlock) { return errors.Wrap(err, "failed to InsertChain") } hashes = append(hashes, block.Header().Hash()) @@ -704,13 +705,16 @@ func (ss *StagedStreamSync) UpdateBlockAndStatus(block *types.Block, bc core.Blo } _, err := bc.InsertChain([]*types.Block{block}, false /* verifyHeaders */) - if err != nil { + switch { + case errors.Is(err, core.ErrKnownBlock): + case err != nil: utils.Logger().Error(). Err(err). Uint64("block number", block.NumberU64()). Uint32("shard", block.ShardID()). Msgf("[STAGED_STREAM_SYNC] UpdateBlockAndStatus: Error adding new block to blockchain") return err + default: } utils.Logger().Info(). Uint64("blockHeight", block.NumberU64()). diff --git a/api/service/stagedsync/stage_state.go b/api/service/stagedsync/stage_state.go index 7086acec1..1e2b38bd9 100644 --- a/api/service/stagedsync/stage_state.go +++ b/api/service/stagedsync/stage_state.go @@ -178,7 +178,7 @@ func (stg *StageStates) Exec(firstCycle bool, invalidBlockRevert bool, s *StageS headBeforeNewBlocks := stg.configs.bc.CurrentBlock().NumberU64() headHashBeforeNewBlocks := stg.configs.bc.CurrentBlock().Hash() _, err = stg.configs.bc.InsertChain(newBlocks, false) //TODO: verifyHeaders can be done here - if err != nil { + if err != nil && !errors.Is(err, core.ErrKnownBlock) { // TODO: handle chain rollback because of bad block utils.Logger().Error(). Err(err). diff --git a/api/service/stagedsync/stagedsync.go b/api/service/stagedsync/stagedsync.go index f1de66f9f..4cc2a98ea 100644 --- a/api/service/stagedsync/stagedsync.go +++ b/api/service/stagedsync/stagedsync.go @@ -1091,13 +1091,16 @@ func (ss *StagedSync) UpdateBlockAndStatus(block *types.Block, bc core.BlockChai } _, err := bc.InsertChain([]*types.Block{block}, false /* verifyHeaders */) - if err != nil { + switch { + case errors.Is(err, core.ErrKnownBlock): + case err != nil: utils.Logger().Error(). Err(err). Uint64("block number", block.NumberU64()). Uint32("shard", block.ShardID()). Msgf("[STAGED_SYNC] UpdateBlockAndStatus: Error adding new block to blockchain") return err + default: } utils.Logger().Info(). Uint64("blockHeight", block.NumberU64()). @@ -1218,7 +1221,7 @@ func (ss *StagedSync) addConsensusLastMile(bc core.BlockChain, cs *consensus.Con if block == nil { break } - if _, err := bc.InsertChain(types.Blocks{block}, true); err != nil { + if _, err := bc.InsertChain(types.Blocks{block}, true); err != nil && !errors.Is(err, core.ErrKnownBlock) { return errors.Wrap(err, "failed to InsertChain") } } diff --git a/consensus/consensus_v2.go b/consensus/consensus_v2.go index 5beb54ed7..04c590b2e 100644 --- a/consensus/consensus_v2.go +++ b/consensus/consensus_v2.go @@ -661,7 +661,8 @@ 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 { + _, err := consensus.Blockchain().InsertChain([]*types.Block{blk}, !consensus.fBFTLog.IsBlockVerified(blk.Hash())) + if err != nil && !errors.Is(err, core.ErrKnownBlock) { consensus.getLogger().Error().Err(err).Msg("[commitBlock] Failed to add block to chain") return err } diff --git a/consensus/downloader.go b/consensus/downloader.go index 1fdc131e7..84414aa80 100644 --- a/consensus/downloader.go +++ b/consensus/downloader.go @@ -2,6 +2,7 @@ package consensus import ( "github.com/ethereum/go-ethereum/event" + "github.com/harmony-one/harmony/core" "github.com/harmony-one/harmony/core/types" "github.com/pkg/errors" ) @@ -93,7 +94,7 @@ func (consensus *Consensus) AddConsensusLastMile() error { if block == nil { break } - if _, err := consensus.Blockchain().InsertChain(types.Blocks{block}, true); err != nil { + if _, err := consensus.Blockchain().InsertChain(types.Blocks{block}, true); err != nil && !errors.Is(err, core.ErrKnownBlock) { return errors.Wrap(err, "failed to InsertChain") } } diff --git a/node/node_explorer.go b/node/node_explorer.go index fbb5b8898..ce1b0a244 100644 --- a/node/node_explorer.go +++ b/node/node_explorer.go @@ -154,7 +154,7 @@ func (node *Node) AddNewBlockForExplorer(block *types.Block) { utils.Logger().Info().Uint64("blockHeight", block.NumberU64()).Msg("[Explorer] Adding new block for explorer node") - if _, err := node.Blockchain().InsertChain([]*types.Block{block}, false); err == nil { + if _, err := node.Blockchain().InsertChain([]*types.Block{block}, false); err == nil || errors.Is(err, core.ErrKnownBlock) { if block.IsLastBlockInEpoch() { node.Consensus.UpdateConsensusInformation() } diff --git a/p2p/host.go b/p2p/host.go index 31c9c2c44..62015fc8c 100644 --- a/p2p/host.go +++ b/p2p/host.go @@ -254,7 +254,7 @@ func NewHost(cfg HostConfig) (Host, error) { self.PeerID = p2pHost.ID() subLogger := utils.Logger().With().Str("hostID", p2pHost.ID().Pretty()).Logger() - security := security.NewManager(cfg.MaxConnPerIP, cfg.MaxPeers) + security := security.NewManager(cfg.MaxConnPerIP, int(cfg.MaxPeers)) // has to save the private key for host h := &HostV2{ h: p2pHost, diff --git a/p2p/security/security.go b/p2p/security/security.go index 932f8b6e9..7c8825ffb 100644 --- a/p2p/security/security.go +++ b/p2p/security/security.go @@ -3,7 +3,6 @@ package security import ( "fmt" "sync" - "sync/atomic" "github.com/harmony-one/harmony/internal/utils" libp2p_network "github.com/libp2p/go-libp2p/core/network" @@ -18,56 +17,53 @@ type Security interface { type Manager struct { maxConnPerIP int - maxPeers int64 + maxPeers int mutex sync.Mutex - peers peerMap // All the connected nodes, key is the Peer's IP, value is the peer's ID array + peers *peerMap // All the connected nodes, key is the Peer's IP, value is the peer's ID array } type peerMap struct { - count int64 - peers sync.Map + peers map[string][]string } -func (peerMap *peerMap) Len() int64 { - return atomic.LoadInt64(&peerMap.count) +func newPeersMap() *peerMap { + return &peerMap{ + peers: make(map[string][]string), + } } -func (peerMap *peerMap) Store(key, value interface{}) { - // only increment if you didn't have this key - hasKey := peerMap.HasKey(key) - peerMap.peers.Store(key, value) - if !hasKey { - atomic.AddInt64(&peerMap.count, 1) - } +func (peerMap *peerMap) Len() int { + return len(peerMap.peers) } -func (peerMap *peerMap) HasKey(key interface{}) bool { - hasKey := false - peerMap.peers.Range(func(k, v interface{}) bool { - if k == key { - hasKey = true - return false - } - return true - }) - return hasKey +func (peerMap *peerMap) Store(key string, value []string) { + peerMap.peers[key] = value +} + +func (peerMap *peerMap) HasKey(key string) bool { + _, ok := peerMap.peers[key] + return ok } -func (peerMap *peerMap) Delete(key interface{}) { - peerMap.peers.Delete(key) - atomic.AddInt64(&peerMap.count, -1) +func (peerMap *peerMap) Delete(key string) { + delete(peerMap.peers, key) } -func (peerMap *peerMap) Load(key interface{}) (value interface{}, ok bool) { - return peerMap.peers.Load(key) +func (peerMap *peerMap) Load(key string) (value []string, ok bool) { + value, ok = peerMap.peers[key] + return value, ok } -func (peerMap *peerMap) Range(f func(key, value any) bool) { - peerMap.peers.Range(f) +func (peerMap *peerMap) Range(f func(key string, value []string) bool) { + for key, value := range peerMap.peers { + if !f(key, value) { + break + } + } } -func NewManager(maxConnPerIP int, maxPeers int64) *Manager { +func NewManager(maxConnPerIP int, maxPeers int) *Manager { if maxConnPerIP < 0 { panic("maximum connections per IP must not be negative") } @@ -77,9 +73,16 @@ func NewManager(maxConnPerIP int, maxPeers int64) *Manager { return &Manager{ maxConnPerIP: maxConnPerIP, maxPeers: maxPeers, + peers: newPeersMap(), } } +func (m *Manager) RangePeers(f func(key string, value []string) bool) { + m.mutex.Lock() + defer m.mutex.Unlock() + m.peers.Range(f) +} + func (m *Manager) OnConnectCheck(net libp2p_network.Network, conn libp2p_network.Conn) error { m.mutex.Lock() defer m.mutex.Unlock() @@ -89,19 +92,11 @@ func (m *Manager) OnConnectCheck(net libp2p_network.Network, conn libp2p_network return errors.Wrap(err, "failed on get remote ip") } - value, ok := m.peers.Load(remoteIp) - if !ok { - value = []string{} - } - - peers, ok := value.([]string) - if !ok { - return errors.New("peers info type err") - } + peers, _ := m.peers.Load(remoteIp) // avoid add repeatedly peerID := conn.RemotePeer().String() - _, ok = find(peers, peerID) + _, ok := find(peers, peerID) if !ok { peers = append(peers, peerID) } @@ -118,7 +113,7 @@ func (m *Manager) OnConnectCheck(net libp2p_network.Network, conn libp2p_network // only limit addition if it's a new peer and not an existing peer with new connection if m.maxPeers > 0 && currentPeerCount >= m.maxPeers && !m.peers.HasKey(remoteIp) { utils.Logger().Warn(). - Int64("connected peers", currentPeerCount). + Int("connected peers", currentPeerCount). Str("new peer", remoteIp). Msg("too many peers, closing") return net.ClosePeer(conn.RemotePeer()) @@ -136,16 +131,11 @@ func (m *Manager) OnDisconnectCheck(conn libp2p_network.Conn) error { return errors.Wrap(err, "failed on get ip") } - value, ok := m.peers.Load(ip) + peers, ok := m.peers.Load(ip) if !ok { return nil } - peers, ok := value.([]string) - if !ok { - return errors.New("peers info type err") - } - peerID := conn.RemotePeer().String() index, ok := find(peers, peerID) if ok { diff --git a/p2p/security/security_test.go b/p2p/security/security_test.go index 73ce4741e..cdaa99f93 100644 --- a/p2p/security/security_test.go +++ b/p2p/security/security_test.go @@ -13,6 +13,7 @@ import ( "github.com/libp2p/go-libp2p/core/peer" ma "github.com/multiformats/go-multiaddr" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) type ConnectCallback func(net libp2p_network.Network, conn libp2p_network.Conn) error @@ -53,7 +54,7 @@ func (mh *fakeHost) SetDisconnectCallback(callback DisconnectCallback) { func TestManager_OnConnectCheck(t *testing.T) { h1, err := newPeer(50550) - assert.Nil(t, err) + require.NoError(t, err) defer h1.Close() fakeHost := &fakeHost{} @@ -65,10 +66,9 @@ func TestManager_OnConnectCheck(t *testing.T) { assert.Nil(t, err) defer h2.Close() err = h2.Connect(context.Background(), peer.AddrInfo{ID: h1.ID(), Addrs: h1.Network().ListenAddresses()}) - assert.Nil(t, err) + require.NoError(t, err) - security.peers.Range(func(k, v interface{}) bool { - peers := v.([]string) + security.RangePeers(func(k string, peers []string) bool { assert.Equal(t, 1, len(peers)) return true }) @@ -78,9 +78,8 @@ func TestManager_OnConnectCheck(t *testing.T) { defer h3.Close() err = h3.Connect(context.Background(), peer.AddrInfo{ID: h1.ID(), Addrs: h1.Network().ListenAddresses()}) assert.Nil(t, err) - security.peers.Range(func(k, v interface{}) bool { - peers := v.([]string) - assert.Equal(t, 2, len(peers)) + security.RangePeers(func(k string, peers []string) bool { + require.Equal(t, 2, len(peers)) return true }) @@ -89,9 +88,8 @@ func TestManager_OnConnectCheck(t *testing.T) { defer h4.Close() err = h4.Connect(context.Background(), peer.AddrInfo{ID: h1.ID(), Addrs: h1.Network().ListenAddresses()}) assert.Nil(t, err) - security.peers.Range(func(k, v interface{}) bool { - peers := v.([]string) - assert.Equal(t, 2, len(peers)) + security.RangePeers(func(k string, peers []string) bool { + require.Equal(t, 2, len(peers)) return true }) } @@ -112,8 +110,7 @@ func TestManager_OnDisconnectCheck(t *testing.T) { err = h2.Connect(context.Background(), peer.AddrInfo{ID: h1.ID(), Addrs: h1.Network().ListenAddresses()}) assert.Nil(t, err) - security.peers.Range(func(k, v interface{}) bool { - peers := v.([]string) + security.RangePeers(func(k string, peers []string) bool { assert.Equal(t, 1, len(peers)) return true }) @@ -121,8 +118,7 @@ func TestManager_OnDisconnectCheck(t *testing.T) { err = h2.Network().ClosePeer(h1.ID()) assert.Nil(t, err) time.Sleep(200 * time.Millisecond) - security.peers.Range(func(k, v interface{}) bool { - peers := v.([]string) + security.RangePeers(func(k string, peers []string) bool { assert.Equal(t, 0, len(peers)) return true }) From 2f23d81879455e55cdb30f3079a7870cf30e48fe Mon Sep 17 00:00:00 2001 From: frozen <355847+Frozen@users.noreply.github.com> Date: Tue, 13 Jun 2023 17:13:40 -0400 Subject: [PATCH 06/19] Last mile blocks insert. --- api/service/stagedstreamsync/downloader.go | 3 +- api/service/stagedstreamsync/downloaders.go | 4 +-- api/service/stagedstreamsync/service.go | 4 +-- .../stagedstreamsync/stage_short_range.go | 34 ++++++++++++++++--- api/service/stagedstreamsync/syncing.go | 6 ++-- cmd/harmony/main.go | 5 +-- core/blockchain.go | 8 ----- core/blockchain_impl.go | 5 +-- core/blockchain_stub.go | 4 --- node/node.go | 4 +++ node/node_handler.go | 19 ++++++----- 11 files changed, 60 insertions(+), 36 deletions(-) diff --git a/api/service/stagedstreamsync/downloader.go b/api/service/stagedstreamsync/downloader.go index 371104895..156722a14 100644 --- a/api/service/stagedstreamsync/downloader.go +++ b/api/service/stagedstreamsync/downloader.go @@ -6,6 +6,7 @@ import ( "time" "github.com/ethereum/go-ethereum/event" + "github.com/harmony-one/harmony/consensus" "github.com/rs/zerolog" "github.com/harmony-one/harmony/consensus" @@ -38,7 +39,7 @@ type ( ) // NewDownloader creates a new downloader -func NewDownloader(host p2p.Host, bc core.BlockChain, consensus *consensus.Consensus, dbDir string, isBeaconNode bool, config Config) *Downloader { +func NewDownloader(host p2p.Host, bc core.BlockChain, consensus *consensus.Consensus, dbDir string, isBeaconNode bool, config Config, c *consensus.Consensus) *Downloader { config.fixValues() sp := sync.NewProtocol(sync.Config{ diff --git a/api/service/stagedstreamsync/downloaders.go b/api/service/stagedstreamsync/downloaders.go index 583f3e152..08a8e40de 100644 --- a/api/service/stagedstreamsync/downloaders.go +++ b/api/service/stagedstreamsync/downloaders.go @@ -16,7 +16,7 @@ type Downloaders struct { } // NewDownloaders creates Downloaders for sync of multiple blockchains -func NewDownloaders(host p2p.Host, bcs []core.BlockChain, consensus *consensus.Consensus, dbDir string, config Config) *Downloaders { +func NewDownloaders(host p2p.Host, bcs []core.BlockChain, consensus *consensus.Consensus, dbDir string, config Config, c *consensus.Consensus) *Downloaders { ds := make(map[uint32]*Downloader) isBeaconNode := len(bcs) == 1 for _, bc := range bcs { @@ -26,7 +26,7 @@ func NewDownloaders(host p2p.Host, bcs []core.BlockChain, consensus *consensus.C if _, ok := ds[bc.ShardID()]; ok { continue } - ds[bc.ShardID()] = NewDownloader(host, bc, consensus, dbDir, isBeaconNode, config) + ds[bc.ShardID()] = NewDownloader(host, bc, consensus, dbDir, isBeaconNode, config, c) } return &Downloaders{ ds: ds, diff --git a/api/service/stagedstreamsync/service.go b/api/service/stagedstreamsync/service.go index f7ffd7f2d..90db7eada 100644 --- a/api/service/stagedstreamsync/service.go +++ b/api/service/stagedstreamsync/service.go @@ -12,9 +12,9 @@ type StagedStreamSyncService struct { } // NewService creates a new downloader service -func NewService(host p2p.Host, bcs []core.BlockChain, consensus *consensus.Consensus, config Config, dbDir string) *StagedStreamSyncService { +func NewService(host p2p.Host, bcs []core.BlockChain, consensus *consensus.Consensus, config Config, dbDir string, c *consensus.Consensus) *StagedStreamSyncService { return &StagedStreamSyncService{ - Downloaders: NewDownloaders(host, bcs, consensus, dbDir, config), + Downloaders: NewDownloaders(host, bcs, consensus, dbDir, config, c), } } diff --git a/api/service/stagedstreamsync/stage_short_range.go b/api/service/stagedstreamsync/stage_short_range.go index ce6cdf36b..f3037869a 100644 --- a/api/service/stagedstreamsync/stage_short_range.go +++ b/api/service/stagedstreamsync/stage_short_range.go @@ -3,7 +3,9 @@ package stagedstreamsync import ( "context" + "github.com/harmony-one/harmony/consensus" "github.com/harmony-one/harmony/core" + "github.com/harmony-one/harmony/core/types" "github.com/harmony-one/harmony/internal/utils" sttypes "github.com/harmony-one/harmony/p2p/stream/types" "github.com/harmony-one/harmony/shard" @@ -18,6 +20,7 @@ type StageShortRange struct { type StageShortRangeCfg struct { bc core.BlockChain db kv.RwDB + c *consensus.Consensus } func NewStageShortRange(cfg StageShortRangeCfg) *StageShortRange { @@ -26,10 +29,11 @@ func NewStageShortRange(cfg StageShortRangeCfg) *StageShortRange { } } -func NewStageShortRangeCfg(bc core.BlockChain, db kv.RwDB) StageShortRangeCfg { +func NewStageShortRangeCfg(bc core.BlockChain, db kv.RwDB, c *consensus.Consensus) StageShortRangeCfg { return StageShortRangeCfg{ bc: bc, db: db, + c: c, } } @@ -104,9 +108,12 @@ func (sr *StageShortRange) doShortRangeSync(ctx context.Context, s *StageState) return 0, errors.Wrap(err, "prerequisite") } } - curBN := sr.configs.bc.CurrentBlock().NumberU64() - blkNums := sh.prepareBlockHashNumbers(curBN) - hashChain, whitelist, err := sh.getHashChain(ctx, blkNums) + var ( + bc = sr.configs.bc + curBN = bc.CurrentHeader().NumberU64() + blkNums = sh.prepareBlockHashNumbers(curBN) + hashChain, whitelist, err = sh.getHashChain(ctx, blkNums) + ) if err != nil { if errors.Is(err, context.DeadlineExceeded) || errors.Is(err, context.Canceled) { return 0, nil @@ -156,6 +163,25 @@ func (sr *StageShortRange) doShortRangeSync(ctx context.Context, s *StageState) return 0, err } + numInserted := 0 + err = sr.configs.c.GetLastMileBlockIter(sr.configs.bc.CurrentHeader().NumberU64()+1, func(blockIter *consensus.LastMileBlockIter) error { + for { + block := blockIter.Next() + if block == nil { + break + } + if _, err := bc.InsertChain(types.Blocks{block}, true); err != nil { + return errors.Wrap(err, "failed to InsertChain") + } + numInserted++ + } + return nil + }) + if err != nil { + return 0, errors.WithMessage(err, "failed to InsertChain for last mile blocks") + } + utils.Logger().Info().Int("last mile blocks inserted", numInserted).Msg("Insert last mile blocks success") + return n, nil } diff --git a/api/service/stagedstreamsync/syncing.go b/api/service/stagedstreamsync/syncing.go index 738f2f920..adf52ae9f 100644 --- a/api/service/stagedstreamsync/syncing.go +++ b/api/service/stagedstreamsync/syncing.go @@ -46,8 +46,9 @@ func CreateStagedSync(ctx context.Context, protocol syncProtocol, config Config, logger zerolog.Logger, + logProgress bool, + c *consensus.Consensus, ) (*StagedStreamSync, error) { - logger.Info(). Uint32("shard", bc.ShardID()). Bool("beaconNode", isBeaconNode). @@ -56,7 +57,6 @@ func CreateStagedSync(ctx context.Context, Bool("serverOnly", config.ServerOnly). Int("minStreams", config.MinStreams). Msg(WrapStagedSyncMsg("creating staged sync")) - var mainDB kv.RwDB dbs := make([]kv.RwDB, config.Concurrency) if config.UseMemDB { @@ -82,7 +82,7 @@ func CreateStagedSync(ctx context.Context, } stageHeadsCfg := NewStageHeadersCfg(bc, mainDB) - stageShortRangeCfg := NewStageShortRangeCfg(bc, mainDB) + stageShortRangeCfg := NewStageShortRangeCfg(bc, mainDB, c) stageSyncEpochCfg := NewStageEpochCfg(bc, mainDB) stageBodiesCfg := NewStageBodiesCfg(bc, mainDB, dbs, config.Concurrency, protocol, isBeaconNode, config.LogProgress) stageStatesCfg := NewStageStatesCfg(bc, mainDB, dbs, config.Concurrency, logger, config.LogProgress) diff --git a/cmd/harmony/main.go b/cmd/harmony/main.go index 9fc89d45d..b1afbe6bf 100644 --- a/cmd/harmony/main.go +++ b/cmd/harmony/main.go @@ -1,6 +1,7 @@ package main import ( + "context" "fmt" "math/big" "math/rand" @@ -521,7 +522,7 @@ func setupNodeAndRun(hc harmonyconfig.HarmonyConfig) { Msg("Start p2p host failed") } - if err := currentNode.BootstrapConsensus(); err != nil { + if err := node.BootstrapConsensus(context.TODO(), currentNode.Consensus, currentNode.Host()); err != nil { fmt.Fprint(os.Stderr, "could not bootstrap consensus", err.Error()) if !currentNode.NodeConfig.IsOffline { os.Exit(-1) @@ -1032,7 +1033,7 @@ func setupStagedSyncService(node *node.Node, host p2p.Host, hc harmonyconfig.Har } } //Setup stream sync service - s := stagedstreamsync.NewService(host, blockchains, node.Consensus, sConfig, hc.General.DataDir) + s := stagedstreamsync.NewService(host, blockchains, node.Consensus, sConfig, hc.General.DataDir, node.Consensus) node.RegisterService(service.StagedStreamSync, s) diff --git a/core/blockchain.go b/core/blockchain.go index 0adc96925..40d33100a 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -109,14 +109,6 @@ type BlockChain interface { // but does not write any state. This is used to construct competing side forks // up to the point where they exceed the canonical total difficulty. WriteBlockWithoutState(block *types.Block, td *big.Int) (err error) - // WriteBlockWithState writes the block and all associated state to the database. - WriteBlockWithState( - block *types.Block, receipts []*types.Receipt, - cxReceipts []*types.CXReceipt, - stakeMsgs []types2.StakeMsg, - paid reward.Reader, - state *state.DB, - ) (status WriteStatus, err error) // GetMaxGarbageCollectedBlockNumber .. GetMaxGarbageCollectedBlockNumber() int64 // InsertChain attempts to insert the given batch of blocks in to the canonical diff --git a/core/blockchain_impl.go b/core/blockchain_impl.go index e9eca1f4c..9e7f1134b 100644 --- a/core/blockchain_impl.go +++ b/core/blockchain_impl.go @@ -1473,7 +1473,8 @@ func (bc *BlockChainImpl) WriteBlockWithoutState(block *types.Block, td *big.Int return nil } -func (bc *BlockChainImpl) WriteBlockWithState( +// writeBlockWithState writes the block and all associated state to the database. +func (bc *BlockChainImpl) writeBlockWithState( block *types.Block, receipts []*types.Receipt, cxReceipts []*types.CXReceipt, stakeMsgs []staking.StakeMsg, @@ -1880,7 +1881,7 @@ func (bc *BlockChainImpl) insertChain(chain types.Blocks, verifyHeaders bool) (i // Write the block to the chain and get the status. substart = time.Now() - status, err := bc.WriteBlockWithState( + status, err := bc.writeBlockWithState( block, receipts, cxReceipts, stakeMsgs, payout, state, ) if err != nil { diff --git a/core/blockchain_stub.go b/core/blockchain_stub.go index e9ef10ce9..e42a12b10 100644 --- a/core/blockchain_stub.go +++ b/core/blockchain_stub.go @@ -124,10 +124,6 @@ func (a Stub) WriteBlockWithoutState(block *types.Block, td *big.Int) (err error return errors.Errorf("method WriteBlockWithoutState not implemented for %s", a.Name) } -func (a Stub) WriteBlockWithState(block *types.Block, receipts []*types.Receipt, cxReceipts []*types.CXReceipt, stakeMsgs []staking.StakeMsg, paid reward.Reader, state *state.DB) (status WriteStatus, err error) { - return 0, errors.Errorf("method WriteBlockWithState not implemented for %s", a.Name) -} - func (a Stub) GetMaxGarbageCollectedBlockNumber() int64 { return 0 } diff --git a/node/node.go b/node/node.go index e4d567066..41373e1b5 100644 --- a/node/node.go +++ b/node/node.go @@ -149,6 +149,10 @@ type Node struct { registry *registry.Registry } +func (node *Node) Host() p2p.Host { + return node.host +} + // Blockchain returns the blockchain for the node's current shard. func (node *Node) Blockchain() core.BlockChain { return node.registry.GetBlockchain() diff --git a/node/node_handler.go b/node/node_handler.go index eeaf90f2d..89464d3c0 100644 --- a/node/node_handler.go +++ b/node/node_handler.go @@ -404,16 +404,21 @@ func (node *Node) PostConsensusProcessing(newBlock *types.Block) error { } // BootstrapConsensus is a goroutine to check number of peers and start the consensus -func (node *Node) BootstrapConsensus() error { - ctx, cancel := context.WithTimeout(context.Background(), time.Minute) +func BootstrapConsensus(ctx context.Context, consensus *consensus.Consensus, host p2p.Host) error { + ctx, cancel := context.WithTimeout(ctx, time.Minute) defer cancel() - min := node.Consensus.MinPeers + min := consensus.MinPeers enoughMinPeers := make(chan struct{}) const checkEvery = 3 * time.Second go func() { for { - <-time.After(checkEvery) - numPeersNow := node.host.GetPeerCount() + select { + case <-ctx.Done(): + return + case <-time.After(checkEvery): + } + + numPeersNow := host.GetPeerCount() if numPeersNow >= min { utils.Logger().Info().Msg("[bootstrap] StartConsensus") enoughMinPeers <- struct{}{} @@ -432,9 +437,7 @@ func (node *Node) BootstrapConsensus() error { case <-ctx.Done(): return ctx.Err() case <-enoughMinPeers: - go func() { - node.Consensus.StartChannel() - }() + go consensus.StartChannel() return nil } } From fad17fe5393f308a362a9c912b90e6ae72d906ef Mon Sep 17 00:00:00 2001 From: frozen <355847+Frozen@users.noreply.github.com> Date: Tue, 13 Jun 2023 20:26:17 -0400 Subject: [PATCH 07/19] Added logs. --- api/service/stagedstreamsync/syncing.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/api/service/stagedstreamsync/syncing.go b/api/service/stagedstreamsync/syncing.go index adf52ae9f..416c5c1a1 100644 --- a/api/service/stagedstreamsync/syncing.go +++ b/api/service/stagedstreamsync/syncing.go @@ -248,8 +248,14 @@ func (s *StagedStreamSync) doSync(downloaderContext context.Context, initSync bo for { ctx, cancel := context.WithCancel(downloaderContext) - + started := s.bc.CurrentHeader().NumberU64() n, err := s.doSyncCycle(ctx, initSync) + finished := s.bc.CurrentHeader().NumberU64() + utils.Logger().Info(). + Uint64("from", started). + Int("returned", n). + Uint64("to", finished). + Msg(WrapStagedSyncMsg("synced blocks")) if err != nil { utils.Logger().Error(). Err(err). From c63818480c0c2a808331afadbad2185520f38579 Mon Sep 17 00:00:00 2001 From: frozen <355847+Frozen@users.noreply.github.com> Date: Tue, 13 Jun 2023 20:47:55 -0400 Subject: [PATCH 08/19] Added logs. --- api/service/stagedstreamsync/syncing.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/api/service/stagedstreamsync/syncing.go b/api/service/stagedstreamsync/syncing.go index 416c5c1a1..18a1d79d8 100644 --- a/api/service/stagedstreamsync/syncing.go +++ b/api/service/stagedstreamsync/syncing.go @@ -246,7 +246,9 @@ func (s *StagedStreamSync) doSync(downloaderContext context.Context, initSync bo s.startSyncing() defer s.finishSyncing() + i := 0 for { + i++ ctx, cancel := context.WithCancel(downloaderContext) started := s.bc.CurrentHeader().NumberU64() n, err := s.doSyncCycle(ctx, initSync) @@ -255,6 +257,8 @@ func (s *StagedStreamSync) doSync(downloaderContext context.Context, initSync bo Uint64("from", started). Int("returned", n). Uint64("to", finished). + Bool("initSync", initSync). + Int("cycle", i). Msg(WrapStagedSyncMsg("synced blocks")) if err != nil { utils.Logger().Error(). From b6987ec68fadcab6a1fb1ef42b6a651178cc916e Mon Sep 17 00:00:00 2001 From: frozen <355847+Frozen@users.noreply.github.com> Date: Tue, 13 Jun 2023 20:51:01 -0400 Subject: [PATCH 09/19] Added logs. --- api/service/stagedstreamsync/syncing.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/api/service/stagedstreamsync/syncing.go b/api/service/stagedstreamsync/syncing.go index 18a1d79d8..bf5b59526 100644 --- a/api/service/stagedstreamsync/syncing.go +++ b/api/service/stagedstreamsync/syncing.go @@ -379,6 +379,9 @@ func (s *StagedStreamSync) finishSyncing() { if s.evtDownloadFinishedSubscribed { s.evtDownloadFinished.Send(struct{}{}) } + utils.Logger().Info(). + Bool("evtDownloadFinishedSubscribed", s.evtDownloadFinishedSubscribed). + Msg(WrapStagedSyncMsg("finished syncing")) } func (s *StagedStreamSync) checkPrerequisites() error { From 525b20ae20a8d503cd3932cc2b7053627e9758cf Mon Sep 17 00:00:00 2001 From: frozen <355847+Frozen@users.noreply.github.com> Date: Tue, 13 Jun 2023 21:14:34 -0400 Subject: [PATCH 10/19] Start and finish syncing. --- api/service/stagedstreamsync/syncing.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/api/service/stagedstreamsync/syncing.go b/api/service/stagedstreamsync/syncing.go index bf5b59526..3ebb4f21b 100644 --- a/api/service/stagedstreamsync/syncing.go +++ b/api/service/stagedstreamsync/syncing.go @@ -227,6 +227,9 @@ func (s *StagedStreamSync) doSync(downloaderContext context.Context, initSync bo return 0, 0, err } + s.startSyncing() + defer s.finishSyncing() + var estimatedHeight uint64 if initSync { if h, err := s.estimateCurrentNumber(downloaderContext); err != nil { @@ -243,9 +246,6 @@ func (s *StagedStreamSync) doSync(downloaderContext context.Context, initSync bo } } - s.startSyncing() - defer s.finishSyncing() - i := 0 for { i++ From 0e4568253a5e027ddedffaf9191d143f23593892 Mon Sep 17 00:00:00 2001 From: frozen <355847+Frozen@users.noreply.github.com> Date: Sun, 25 Jun 2023 00:24:26 -0400 Subject: [PATCH 11/19] Passed peerID to handlers. --- api/service/stagedstreamsync/stage_heads.go | 2 +- consensus/consensus.go | 17 ++++------- consensus/consensus_test.go | 5 ++++ consensus/consensus_v2.go | 26 +++++++--------- consensus/fbft_log.go | 8 ++++- consensus/fbft_log_test.go | 4 +-- consensus/validator.go | 13 ++++---- consensus/view_change_construct.go | 4 ++- consensus/view_change_msg.go | 2 +- internal/utils/blockedpeers/manager.go | 33 +++++++++++++++++++++ internal/utils/blockedpeers/manager_test.go | 26 ++++++++++++++++ internal/utils/lrucache/lrucache.go | 6 ++++ internal/utils/timer.go | 4 ++- node/node.go | 10 +++++-- p2p/host.go | 20 +++++++------ p2p/security/security.go | 29 +++++++++++------- p2p/security/security_test.go | 5 ++-- 17 files changed, 149 insertions(+), 65 deletions(-) create mode 100644 internal/utils/blockedpeers/manager.go create mode 100644 internal/utils/blockedpeers/manager_test.go diff --git a/api/service/stagedstreamsync/stage_heads.go b/api/service/stagedstreamsync/stage_heads.go index c917884a3..d05543c06 100644 --- a/api/service/stagedstreamsync/stage_heads.go +++ b/api/service/stagedstreamsync/stage_heads.go @@ -53,7 +53,7 @@ func (heads *StageHeads) Exec(ctx context.Context, firstCycle bool, invalidBlock maxHeight := s.state.status.targetBN maxBlocksPerSyncCycle := uint64(1024) // TODO: should be in config -> s.state.MaxBlocksPerSyncCycle - currentHeight := heads.configs.bc.CurrentBlock().NumberU64() + currentHeight := heads.configs.bc.CurrentHeader().NumberU64() s.state.currentCycle.TargetHeight = maxHeight targetHeight := uint64(0) if errV := CreateView(ctx, heads.configs.db, tx, func(etx kv.Tx) (err error) { diff --git a/consensus/consensus.go b/consensus/consensus.go index b396f6ead..bdb4803bb 100644 --- a/consensus/consensus.go +++ b/consensus/consensus.go @@ -94,8 +94,6 @@ type Consensus struct { // The post-consensus job func passed from Node object // Called when consensus on a new block is done PostConsensusJob func(*types.Block) error - // The verifier func passed from Node object - BlockVerifier VerifyBlockFunc // verified block to state sync broadcast VerifiedNewBlock chan *types.Block // will trigger state syncing when blockNum is low @@ -171,12 +169,12 @@ 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 err := consensus.BlockVerifier(block); err != nil { +func (FBFTLog *FBFTLog) verifyBlock(block *types.Block) error { + if !FBFTLog.IsBlockVerified(block.Hash()) { + if err := FBFTLog.BlockVerify(block); err != nil { return errors.Errorf("Block verification failed: %s", err) } - consensus.fBFTLog.MarkBlockVerified(block) + FBFTLog.MarkBlockVerified(block) } return nil } @@ -304,12 +302,7 @@ func New( consensus.RndChannel = make(chan [vdfAndSeedSize]byte) consensus.IgnoreViewIDCheck = abool.NewBool(false) // Make Sure Verifier is not null - consensus.vc = newViewChange() - // TODO: reference to blockchain/beaconchain should be removed. - verifier := VerifyNewBlock(registry.GetWebHooks(), consensus.Blockchain(), consensus.Beaconchain()) - consensus.BlockVerifier = verifier - consensus.vc.verifyBlock = consensus.verifyBlock - + consensus.vc = newViewChange(consensus.FBFTLog.BlockVerify) // init prometheus metrics initMetrics() consensus.AddPubkeyMetrics() diff --git a/consensus/consensus_test.go b/consensus/consensus_test.go index 697ba4952..83d2021e3 100644 --- a/consensus/consensus_test.go +++ b/consensus/consensus_test.go @@ -22,6 +22,7 @@ func TestConsensusInitialization(t *testing.T) { assert.NoError(t, err) messageSender := &MessageSender{host: host, retryTimes: int(phaseDuration.Seconds()) / RetryIntervalInSec} + fbtLog := NewFBFTLog(consensus.FBFTLog.verifyNewBlock) state := State{mode: Normal} timeouts := createTimeout() @@ -36,6 +37,10 @@ func TestConsensusInitialization(t *testing.T) { assert.IsType(t, make(chan struct{}), consensus.BlockNumLowChan) // FBFTLog + assert.Equal(t, fbtLog.blocks, consensus.FBFTLog.blocks) + assert.Equal(t, fbtLog.messages, consensus.FBFTLog.messages) + assert.Equal(t, len(fbtLog.verifiedBlocks), 0) + assert.Equal(t, fbtLog.verifiedBlocks, consensus.FBFTLog.verifiedBlocks) assert.NotNil(t, consensus.FBFTLog()) assert.Equal(t, FBFTAnnounce, consensus.phase) diff --git a/consensus/consensus_v2.go b/consensus/consensus_v2.go index 04c590b2e..27c9b15bf 100644 --- a/consensus/consensus_v2.go +++ b/consensus/consensus_v2.go @@ -4,6 +4,7 @@ import ( "bytes" "context" "encoding/hex" + libp2p_peer "github.com/libp2p/go-libp2p/core/peer" "math/big" "sync/atomic" "time" @@ -55,7 +56,7 @@ func (consensus *Consensus) isViewChangingMode() bool { } // HandleMessageUpdate will update the consensus state according to received message -func (consensus *Consensus) HandleMessageUpdate(ctx context.Context, msg *msg_pb.Message, senderKey *bls.SerializedPublicKey) error { +func (consensus *Consensus) HandleMessageUpdate(ctx context.Context, peer libp2p_peer.ID, msg *msg_pb.Message, senderKey *bls.SerializedPublicKey) error { consensus.mutex.Lock() defer consensus.mutex.Unlock() // when node is in ViewChanging mode, it still accepts normal messages into FBFTLog @@ -393,11 +394,12 @@ func (consensus *Consensus) tick() { // the bootstrap timer will be stopped once consensus is reached or view change // is succeeded if k != timeoutBootstrap { - consensus.getLogger().Debug(). - Str("k", k.String()). - Str("Mode", consensus.current.Mode().String()). - Msg("[ConsensusMainLoop] consensusTimeout stopped!!!") - v.Stop() + if v.Stop() { // prevent useless logs + consensus.getLogger().Debug(). + Str("k", k.String()). + Str("Mode", consensus.current.Mode().String()). + Msg("[ConsensusMainLoop] consensusTimeout stopped!!!") + } continue } } @@ -453,7 +455,6 @@ func (consensus *Consensus) BlockChannel(newBlock *types.Block) { type LastMileBlockIter struct { blockCandidates []*types.Block fbftLog *FBFTLog - verify func(*types.Block) error curIndex int logger *zerolog.Logger } @@ -468,9 +469,6 @@ func (consensus *Consensus) GetLastMileBlockIter(bnStart uint64, cb func(iter *L // GetLastMileBlockIter get the iterator of the last mile blocks starting from number bnStart func (consensus *Consensus) getLastMileBlockIter(bnStart uint64, cb func(iter *LastMileBlockIter) error) error { - if consensus.BlockVerifier == nil { - return errors.New("consensus haven't initialized yet") - } blocks, _, err := consensus.getLastMileBlocksAndMsg(bnStart) if err != nil { return err @@ -478,7 +476,6 @@ func (consensus *Consensus) getLastMileBlockIter(bnStart uint64, cb func(iter *L return cb(&LastMileBlockIter{ blockCandidates: blocks, fbftLog: consensus.fBFTLog, - verify: consensus.BlockVerifier, curIndex: 0, logger: consensus.getLogger(), }) @@ -493,7 +490,7 @@ func (iter *LastMileBlockIter) Next() *types.Block { iter.curIndex++ if !iter.fbftLog.IsBlockVerified(block.Hash()) { - if err := iter.verify(block); err != nil { + if err := iter.fbftLog.BlockVerify(block); err != nil { iter.logger.Debug().Err(err).Msg("block verification failed in consensus last mile block") return nil } @@ -620,9 +617,6 @@ func (consensus *Consensus) verifyLastCommitSig(lastCommitSig []byte, blk *types // tryCatchup add the last mile block in PBFT log memory cache to blockchain. func (consensus *Consensus) tryCatchup() error { // TODO: change this to a more systematic symbol - if consensus.BlockVerifier == nil { - return errors.New("consensus haven't finished initialization") - } initBN := consensus.getBlockNum() defer consensus.postCatchup(initBN) @@ -637,7 +631,7 @@ func (consensus *Consensus) tryCatchup() error { } blk.SetCurrentCommitSig(msg.Payload) - if err := consensus.verifyBlock(blk); err != nil { + if err := consensus.FBFTLog.verifyBlock(blk); err != nil { consensus.getLogger().Err(err).Msg("[TryCatchup] failed block verifier") return err } diff --git a/consensus/fbft_log.go b/consensus/fbft_log.go index 982aecab7..7ffa2ff9e 100644 --- a/consensus/fbft_log.go +++ b/consensus/fbft_log.go @@ -113,14 +113,16 @@ type FBFTLog struct { blocks map[common.Hash]*types.Block // store blocks received in FBFT verifiedBlocks map[common.Hash]struct{} // store block hashes for blocks that has already been verified messages map[fbftMsgID]*FBFTMessage // store messages received in FBFT + verifyNewBlock func(*types.Block) error // block verification function } // NewFBFTLog returns new instance of FBFTLog -func NewFBFTLog() *FBFTLog { +func NewFBFTLog(verifyNewBlock func(*types.Block) error) *FBFTLog { pbftLog := FBFTLog{ blocks: make(map[common.Hash]*types.Block), messages: make(map[fbftMsgID]*FBFTMessage), verifiedBlocks: make(map[common.Hash]struct{}), + verifyNewBlock: verifyNewBlock, } return &pbftLog } @@ -130,6 +132,10 @@ func (log *FBFTLog) AddBlock(block *types.Block) { log.blocks[block.Hash()] = block } +func (log *FBFTLog) BlockVerify(block *types.Block) error { + return log.verifyNewBlock(block) +} + // MarkBlockVerified marks the block as verified func (log *FBFTLog) MarkBlockVerified(block *types.Block) { log.verifiedBlocks[block.Hash()] = struct{}{} diff --git a/consensus/fbft_log_test.go b/consensus/fbft_log_test.go index 420effff4..c22c70b3e 100644 --- a/consensus/fbft_log_test.go +++ b/consensus/fbft_log_test.go @@ -65,7 +65,7 @@ func TestGetMessagesByTypeSeqViewHash(t *testing.T) { ViewID: 3, BlockHash: [32]byte{01, 02}, } - log := NewFBFTLog() + log := NewFBFTLog(nil) log.AddVerifiedMessage(&pbftMsg) found := log.GetMessagesByTypeSeqViewHash( @@ -90,7 +90,7 @@ func TestHasMatchingAnnounce(t *testing.T) { ViewID: 3, BlockHash: [32]byte{01, 02}, } - log := NewFBFTLog() + log := NewFBFTLog(nil) log.AddVerifiedMessage(&pbftMsg) found := log.HasMatchingViewAnnounce(2, 3, [32]byte{01, 02}) if !found { diff --git a/consensus/validator.go b/consensus/validator.go index 0506f4359..02f92cd50 100644 --- a/consensus/validator.go +++ b/consensus/validator.go @@ -63,6 +63,11 @@ func (consensus *Consensus) onAnnounce(msg *msg_pb.Message) { go func() { // Best effort check, no need to error out. _, err := consensus.ValidateNewBlock(recvMsg) + if err != nil { + // maybe ban sender + consensus.getLogger().Error(). + Err(err).Msgf("[Announce] Failed to validate block") + } if err == nil { consensus.GetLogger().Info(). Msg("[Announce] Block verified") @@ -76,6 +81,7 @@ func (consensus *Consensus) ValidateNewBlock(recvMsg *FBFTMessage) (*types.Block defer consensus.mutex.Unlock() return consensus.validateNewBlock(recvMsg) } + func (consensus *Consensus) validateNewBlock(recvMsg *FBFTMessage) (*types.Block, error) { if consensus.fBFTLog.IsBlockVerified(recvMsg.BlockHash) { var blockObj *types.Block @@ -125,12 +131,7 @@ func (consensus *Consensus) validateNewBlock(recvMsg *FBFTMessage) (*types.Block Hex("blockHash", recvMsg.BlockHash[:]). Msg("[validateNewBlock] Prepared message and block added") - if consensus.BlockVerifier == nil { - consensus.getLogger().Debug().Msg("[validateNewBlock] consensus received message before init. Ignoring") - return nil, errors.New("nil block verifier") - } - - if err := consensus.verifyBlock(&blockObj); err != nil { + if err := consensus.FBFTLog.verifyBlock(&blockObj); err != nil { consensus.getLogger().Error().Err(err).Msg("[validateNewBlock] Block verification failed") return nil, errors.Errorf("Block verification failed: %s", err.Error()) } diff --git a/consensus/view_change_construct.go b/consensus/view_change_construct.go index 061d2a795..0c3aa1e60 100644 --- a/consensus/view_change_construct.go +++ b/consensus/view_change_construct.go @@ -51,9 +51,11 @@ type viewChange struct { } // newViewChange returns a new viewChange object -func newViewChange() *viewChange { +func newViewChange(verifyBlock VerifyBlockFunc) *viewChange { vc := viewChange{} vc.Reset() + vc.verifyBlock = verifyBlock + return &vc } diff --git a/consensus/view_change_msg.go b/consensus/view_change_msg.go index 6c4b08005..21ec801aa 100644 --- a/consensus/view_change_msg.go +++ b/consensus/view_change_msg.go @@ -45,7 +45,7 @@ func (consensus *Consensus) constructViewChangeMessage(priKey *bls.PrivateKeyWra Interface("preparedMsg", preparedMsg). Msg("[constructViewChangeMessage] found prepared msg") if block != nil { - if err := consensus.verifyBlock(block); err == nil { + if err := consensus.FBFTLog.verifyBlock(block); err == nil { tmpEncoded, err := rlp.EncodeToBytes(block) if err != nil { consensus.getLogger().Err(err).Msg("[constructViewChangeMessage] Failed encoding block") diff --git a/internal/utils/blockedpeers/manager.go b/internal/utils/blockedpeers/manager.go new file mode 100644 index 000000000..04f50225d --- /dev/null +++ b/internal/utils/blockedpeers/manager.go @@ -0,0 +1,33 @@ +package blockedpeers + +import ( + "github.com/harmony-one/harmony/internal/utils/lrucache" + libp2p_peer "github.com/libp2p/go-libp2p/core/peer" + "time" +) + +type Manager struct { + internal *lrucache.Cache[libp2p_peer.ID, time.Time] +} + +func NewManager(size int) *Manager { + return &Manager{ + internal: lrucache.NewCache[libp2p_peer.ID, time.Time](size), + } +} + +func (m *Manager) IsBanned(key libp2p_peer.ID, now time.Time) bool { + future, ok := m.internal.Get(key) + if ok { + return future.After(now) // future > now + } + return ok +} + +func (m *Manager) Ban(key libp2p_peer.ID, future time.Time) { + m.internal.Set(key, future) +} + +func (m *Manager) Contains(key libp2p_peer.ID) bool { + return m.internal.Contains(key) +} diff --git a/internal/utils/blockedpeers/manager_test.go b/internal/utils/blockedpeers/manager_test.go new file mode 100644 index 000000000..31d0b680d --- /dev/null +++ b/internal/utils/blockedpeers/manager_test.go @@ -0,0 +1,26 @@ +package blockedpeers + +import ( + libp2p_peer "github.com/libp2p/go-libp2p/core/peer" + "github.com/stretchr/testify/require" + "testing" + "time" +) + +func TestNewManager(t *testing.T) { + var ( + peer1 libp2p_peer.ID = "peer1" + now = time.Now() + m = NewManager(4) + ) + + t.Run("check_empty", func(t *testing.T) { + require.False(t, m.IsBanned(peer1, now), "peer1 should not be banned") + }) + t.Run("ban_peer1", func(t *testing.T) { + m.Ban(peer1, now.Add(2*time.Second)) + require.True(t, m.IsBanned(peer1, now), "peer1 should be banned") + require.False(t, m.IsBanned(peer1, now.Add(3*time.Second)), "peer1 should not be banned after 3 seconds") + }) + +} diff --git a/internal/utils/lrucache/lrucache.go b/internal/utils/lrucache/lrucache.go index 4859811b5..95d9b88bb 100644 --- a/internal/utils/lrucache/lrucache.go +++ b/internal/utils/lrucache/lrucache.go @@ -25,3 +25,9 @@ func (c *Cache[K, V]) Get(key K) (V, bool) { func (c *Cache[K, V]) Set(key K, value V) { c.cache.Add(key, value) } + +// Contains checks if a key is in the cache, without updating the +// recent-ness or deleting it for being stale. +func (c *Cache[K, V]) Contains(key K) bool { + return c.cache.Contains(key) +} diff --git a/internal/utils/timer.go b/internal/utils/timer.go index d355d5c71..176732fca 100644 --- a/internal/utils/timer.go +++ b/internal/utils/timer.go @@ -34,9 +34,11 @@ func (timeout *Timeout) Start() { } // Stop stops the timeout clock -func (timeout *Timeout) Stop() { +func (timeout *Timeout) Stop() (stopped bool) { + stopped = timeout.state != Inactive timeout.state = Inactive timeout.start = time.Now() + return stopped } // Expired checks whether the timeout is reached/expired diff --git a/node/node.go b/node/node.go index 41373e1b5..8d9665854 100644 --- a/node/node.go +++ b/node/node.go @@ -559,7 +559,7 @@ func (node *Node) validateNodeMessage(ctx context.Context, payload []byte) ( // validate shardID // validate public key size // verify message signature -func validateShardBoundMessage(consensus *consensus.Consensus, nodeConfig *nodeconfig.ConfigType, payload []byte, +func validateShardBoundMessage(consensus *consensus.Consensus, peer libp2p_peer.ID, nodeConfig *nodeconfig.ConfigType, payload []byte, ) (*msg_pb.Message, *bls.SerializedPublicKey, bool, error) { var ( m msg_pb.Message @@ -740,6 +740,7 @@ func (node *Node) StartPubSub() error { // p2p consensus message handler function type p2pHandlerConsensus func( ctx context.Context, + peer libp2p_peer.ID, msg *msg_pb.Message, key *bls.SerializedPublicKey, ) error @@ -753,6 +754,7 @@ func (node *Node) StartPubSub() error { // interface pass to p2p message validator type validated struct { + peerID libp2p_peer.ID consensusBound bool handleC p2pHandlerConsensus handleCArg *msg_pb.Message @@ -810,7 +812,7 @@ func (node *Node) StartPubSub() error { // validate consensus message validMsg, senderPubKey, ignore, err := validateShardBoundMessage( - node.Consensus, node.NodeConfig, openBox[proto.MessageCategoryBytes:], + node.Consensus, peer, node.NodeConfig, openBox[proto.MessageCategoryBytes:], ) if err != nil { @@ -824,6 +826,7 @@ func (node *Node) StartPubSub() error { } msg.ValidatorData = validated{ + peerID: peer, consensusBound: true, handleC: node.Consensus.HandleMessageUpdate, handleCArg: validMsg, @@ -854,6 +857,7 @@ func (node *Node) StartPubSub() error { } } msg.ValidatorData = validated{ + peerID: peer, consensusBound: false, handleE: node.HandleNodeMessage, handleEArg: validMsg, @@ -905,7 +909,7 @@ func (node *Node) StartPubSub() error { errChan <- withError{err, nil} } } else { - if err := msg.handleC(ctx, msg.handleCArg, msg.senderPubKey); err != nil { + if err := msg.handleC(ctx, msg.peerID, msg.handleCArg, msg.senderPubKey); err != nil { errChan <- withError{err, msg.senderPubKey} } } diff --git a/p2p/host.go b/p2p/host.go index 62015fc8c..745e9cef3 100644 --- a/p2p/host.go +++ b/p2p/host.go @@ -11,6 +11,13 @@ import ( "sync" "time" + "github.com/harmony-one/bls/ffi/go/bls" + nodeconfig "github.com/harmony-one/harmony/internal/configs/node" + "github.com/harmony-one/harmony/internal/utils" + "github.com/harmony-one/harmony/internal/utils/blockedpeers" + "github.com/harmony-one/harmony/p2p/discovery" + "github.com/harmony-one/harmony/p2p/security" + sttypes "github.com/harmony-one/harmony/p2p/stream/types" "github.com/libp2p/go-libp2p" dht "github.com/libp2p/go-libp2p-kad-dht" libp2p_pubsub "github.com/libp2p/go-libp2p-pubsub" @@ -24,19 +31,11 @@ import ( "github.com/libp2p/go-libp2p/core/protocol" "github.com/libp2p/go-libp2p/core/routing" "github.com/libp2p/go-libp2p/p2p/net/connmgr" - "github.com/libp2p/go-libp2p/p2p/security/noise" libp2ptls "github.com/libp2p/go-libp2p/p2p/security/tls" ma "github.com/multiformats/go-multiaddr" "github.com/pkg/errors" "github.com/rs/zerolog" - - "github.com/harmony-one/bls/ffi/go/bls" - nodeconfig "github.com/harmony-one/harmony/internal/configs/node" - "github.com/harmony-one/harmony/internal/utils" - "github.com/harmony-one/harmony/p2p/discovery" - "github.com/harmony-one/harmony/p2p/security" - sttypes "github.com/harmony-one/harmony/p2p/stream/types" ) type ConnectCallback func(net libp2p_network.Network, conn libp2p_network.Conn) error @@ -254,7 +253,8 @@ func NewHost(cfg HostConfig) (Host, error) { self.PeerID = p2pHost.ID() subLogger := utils.Logger().With().Str("hostID", p2pHost.ID().Pretty()).Logger() - security := security.NewManager(cfg.MaxConnPerIP, int(cfg.MaxPeers)) + banned := blockedpeers.NewManager(1024) + security := security.NewManager(cfg.MaxConnPerIP, int(cfg.MaxPeers, banned)) // has to save the private key for host h := &HostV2{ h: p2pHost, @@ -269,6 +269,7 @@ func NewHost(cfg HostConfig) (Host, error) { logger: &subLogger, ctx: ctx, cancel: cancel, + banned: banned, } utils.Logger().Info(). @@ -323,6 +324,7 @@ type HostV2 struct { onDisconnects DisconnectCallbacks ctx context.Context cancel func() + banned *blockedpeers.Manager } // PubSub .. diff --git a/p2p/security/security.go b/p2p/security/security.go index 7c8825ffb..e9523cd02 100644 --- a/p2p/security/security.go +++ b/p2p/security/security.go @@ -4,7 +4,7 @@ import ( "fmt" "sync" - "github.com/harmony-one/harmony/internal/utils" + "github.com/harmony-one/harmony/internal/utils/blockedpeers" libp2p_network "github.com/libp2p/go-libp2p/core/network" ma "github.com/multiformats/go-multiaddr" "github.com/pkg/errors" @@ -15,14 +15,6 @@ type Security interface { OnDisconnectCheck(conn libp2p_network.Conn) error } -type Manager struct { - maxConnPerIP int - maxPeers int - - mutex sync.Mutex - peers *peerMap // All the connected nodes, key is the Peer's IP, value is the peer's ID array -} - type peerMap struct { peers map[string][]string } @@ -63,7 +55,16 @@ func (peerMap *peerMap) Range(f func(key string, value []string) bool) { } } -func NewManager(maxConnPerIP int, maxPeers int) *Manager { +type Manager struct { + maxConnPerIP int + maxPeers int64 + + mutex sync.Mutex + peers peerMap // All the connected nodes, key is the Peer's IP, value is the peer's ID array + banned *blockedpeers.Manager +} + +func NewManager(maxConnPerIP int, maxPeers int64, banned *blockedpeers.Manager) *Manager { if maxConnPerIP < 0 { panic("maximum connections per IP must not be negative") } @@ -74,6 +75,7 @@ func NewManager(maxConnPerIP int, maxPeers int) *Manager { maxConnPerIP: maxConnPerIP, maxPeers: maxPeers, peers: newPeersMap(), + banned: banned, } } @@ -118,6 +120,13 @@ func (m *Manager) OnConnectCheck(net libp2p_network.Network, conn libp2p_network Msg("too many peers, closing") return net.ClosePeer(conn.RemotePeer()) } + if m.banned.IsBanned(conn.RemotePeer(), time.Now()) { + utils.Logger().Warn(). + Str("new peer", remoteIp). + Msg("peer is banned, closing") + return net.ClosePeer(conn.RemotePeer()) + } + m.peers.Store(remoteIp, peers) return nil } diff --git a/p2p/security/security_test.go b/p2p/security/security_test.go index cdaa99f93..79a2dac28 100644 --- a/p2p/security/security_test.go +++ b/p2p/security/security_test.go @@ -3,6 +3,7 @@ package security import ( "context" "fmt" + "github.com/harmony-one/harmony/internal/utils/blockedpeers" "testing" "time" @@ -58,7 +59,7 @@ func TestManager_OnConnectCheck(t *testing.T) { defer h1.Close() fakeHost := &fakeHost{} - security := NewManager(2, 1) + security := NewManager(2, 1, blockedpeers.NewManager(4)) h1.Network().Notify(fakeHost) fakeHost.SetConnectCallback(security.OnConnectCheck) fakeHost.SetDisconnectCallback(security.OnDisconnectCheck) @@ -100,7 +101,7 @@ func TestManager_OnDisconnectCheck(t *testing.T) { defer h1.Close() fakeHost := &fakeHost{} - security := NewManager(2, 0) + security := NewManager(2, 0, blockedpeers.NewManager(4)) h1.Network().Notify(fakeHost) fakeHost.SetConnectCallback(security.OnConnectCheck) fakeHost.SetDisconnectCallback(security.OnDisconnectCheck) From a6ddc19fedbc54716041ebaedf684a023ed48d59 Mon Sep 17 00:00:00 2001 From: frozen <355847+Frozen@users.noreply.github.com> Date: Sun, 25 Jun 2023 00:42:04 -0400 Subject: [PATCH 12/19] Implemented method for interface. --- internal/utils/blockedpeers/manager.go | 9 ++++++++ internal/utils/lrucache/lrucache.go | 12 +++++++++++ internal/utils/lrucache/lrucache_test.go | 27 ++++++++++++++++++++++++ p2p/host.go | 4 +--- 4 files changed, 49 insertions(+), 3 deletions(-) create mode 100644 internal/utils/lrucache/lrucache_test.go diff --git a/internal/utils/blockedpeers/manager.go b/internal/utils/blockedpeers/manager.go index 04f50225d..021199f7b 100644 --- a/internal/utils/blockedpeers/manager.go +++ b/internal/utils/blockedpeers/manager.go @@ -18,6 +18,7 @@ func NewManager(size int) *Manager { func (m *Manager) IsBanned(key libp2p_peer.ID, now time.Time) bool { future, ok := m.internal.Get(key) + if ok { return future.After(now) // future > now } @@ -31,3 +32,11 @@ func (m *Manager) Ban(key libp2p_peer.ID, future time.Time) { func (m *Manager) Contains(key libp2p_peer.ID) bool { return m.internal.Contains(key) } + +func (m *Manager) Len() int { + return m.internal.Len() +} + +func (m *Manager) Keys() []libp2p_peer.ID { + return m.internal.Keys() +} diff --git a/internal/utils/lrucache/lrucache.go b/internal/utils/lrucache/lrucache.go index 95d9b88bb..e20424a10 100644 --- a/internal/utils/lrucache/lrucache.go +++ b/internal/utils/lrucache/lrucache.go @@ -31,3 +31,15 @@ func (c *Cache[K, V]) Set(key K, value V) { func (c *Cache[K, V]) Contains(key K) bool { return c.cache.Contains(key) } + +func (c *Cache[K, V]) Len() int { + return c.cache.Len() +} + +func (c *Cache[K, V]) Keys() []K { + out := make([]K, 0, c.cache.Len()) + for _, v := range c.cache.Keys() { + out = append(out, v.(K)) + } + return out +} diff --git a/internal/utils/lrucache/lrucache_test.go b/internal/utils/lrucache/lrucache_test.go new file mode 100644 index 000000000..67f16ff39 --- /dev/null +++ b/internal/utils/lrucache/lrucache_test.go @@ -0,0 +1,27 @@ +package lrucache + +import ( + "github.com/stretchr/testify/require" + "testing" +) + +func TestKeys(t *testing.T) { + c := NewCache[int, int](10) + + for i := 0; i < 3; i++ { + c.Set(i, i) + } + m := map[int]int{ + 0: 0, + 1: 1, + 2: 2, + } + keys := c.Keys() + + m2 := map[int]int{} + for _, k := range keys { + m2[k] = k + } + + require.Equal(t, m, m2) +} diff --git a/p2p/host.go b/p2p/host.go index 745e9cef3..aeafea7dc 100644 --- a/p2p/host.go +++ b/p2p/host.go @@ -494,9 +494,7 @@ func (host *HostV2) ListPeer(topic string) []libp2p_peer.ID { // ListBlockedPeer returns list of blocked peer func (host *HostV2) ListBlockedPeer() []libp2p_peer.ID { - // TODO: this is a place holder for now - peers := make([]libp2p_peer.ID, 0) - return peers + return host.banned.Keys() } // GetPeerCount ... From 82b3f0cedaf76290a123f419bf6fef6aed742592 Mon Sep 17 00:00:00 2001 From: frozen <355847+Frozen@users.noreply.github.com> Date: Sun, 23 Jul 2023 12:41:04 -0400 Subject: [PATCH 13/19] Updated. --- consensus/consensus.go | 4 ++-- consensus/consensus_test.go | 8 ++++---- consensus/consensus_v2.go | 5 +++-- consensus/validator.go | 2 +- consensus/view_change_msg.go | 2 +- 5 files changed, 11 insertions(+), 10 deletions(-) diff --git a/consensus/consensus.go b/consensus/consensus.go index bdb4803bb..1e35773ef 100644 --- a/consensus/consensus.go +++ b/consensus/consensus.go @@ -268,7 +268,7 @@ func New( consensus := Consensus{ mutex: &sync.RWMutex{}, ShardID: shard, - fBFTLog: NewFBFTLog(), + fBFTLog: NewFBFTLog(VerifyNewBlock(registry.GetWebHooks(), registry.GetBlockchain(), registry.GetBeaconchain())), phase: FBFTAnnounce, current: State{mode: Normal}, Decider: Decider, @@ -302,7 +302,7 @@ func New( consensus.RndChannel = make(chan [vdfAndSeedSize]byte) consensus.IgnoreViewIDCheck = abool.NewBool(false) // Make Sure Verifier is not null - consensus.vc = newViewChange(consensus.FBFTLog.BlockVerify) + consensus.vc = newViewChange(consensus.fBFTLog.BlockVerify) // init prometheus metrics initMetrics() consensus.AddPubkeyMetrics() diff --git a/consensus/consensus_test.go b/consensus/consensus_test.go index 83d2021e3..725e70c3f 100644 --- a/consensus/consensus_test.go +++ b/consensus/consensus_test.go @@ -22,7 +22,7 @@ func TestConsensusInitialization(t *testing.T) { assert.NoError(t, err) messageSender := &MessageSender{host: host, retryTimes: int(phaseDuration.Seconds()) / RetryIntervalInSec} - fbtLog := NewFBFTLog(consensus.FBFTLog.verifyNewBlock) + fbtLog := NewFBFTLog(nil) state := State{mode: Normal} timeouts := createTimeout() @@ -37,10 +37,10 @@ func TestConsensusInitialization(t *testing.T) { assert.IsType(t, make(chan struct{}), consensus.BlockNumLowChan) // FBFTLog - assert.Equal(t, fbtLog.blocks, consensus.FBFTLog.blocks) - assert.Equal(t, fbtLog.messages, consensus.FBFTLog.messages) + assert.Equal(t, fbtLog.blocks, consensus.fBFTLog.blocks) + assert.Equal(t, fbtLog.messages, consensus.fBFTLog.messages) assert.Equal(t, len(fbtLog.verifiedBlocks), 0) - assert.Equal(t, fbtLog.verifiedBlocks, consensus.FBFTLog.verifiedBlocks) + assert.Equal(t, fbtLog.verifiedBlocks, consensus.fBFTLog.verifiedBlocks) assert.NotNil(t, consensus.FBFTLog()) assert.Equal(t, FBFTAnnounce, consensus.phase) diff --git a/consensus/consensus_v2.go b/consensus/consensus_v2.go index 27c9b15bf..258d82a8f 100644 --- a/consensus/consensus_v2.go +++ b/consensus/consensus_v2.go @@ -4,11 +4,12 @@ import ( "bytes" "context" "encoding/hex" - libp2p_peer "github.com/libp2p/go-libp2p/core/peer" "math/big" "sync/atomic" "time" + libp2p_peer "github.com/libp2p/go-libp2p/core/peer" + "github.com/ethereum/go-ethereum/common" bls2 "github.com/harmony-one/bls/ffi/go/bls" "github.com/harmony-one/harmony/consensus/signature" @@ -631,7 +632,7 @@ func (consensus *Consensus) tryCatchup() error { } blk.SetCurrentCommitSig(msg.Payload) - if err := consensus.FBFTLog.verifyBlock(blk); err != nil { + if err := consensus.fBFTLog.verifyBlock(blk); err != nil { consensus.getLogger().Err(err).Msg("[TryCatchup] failed block verifier") return err } diff --git a/consensus/validator.go b/consensus/validator.go index 02f92cd50..6a1f21e1a 100644 --- a/consensus/validator.go +++ b/consensus/validator.go @@ -131,7 +131,7 @@ func (consensus *Consensus) validateNewBlock(recvMsg *FBFTMessage) (*types.Block Hex("blockHash", recvMsg.BlockHash[:]). Msg("[validateNewBlock] Prepared message and block added") - if err := consensus.FBFTLog.verifyBlock(&blockObj); err != nil { + if err := consensus.fBFTLog.verifyBlock(&blockObj); err != nil { consensus.getLogger().Error().Err(err).Msg("[validateNewBlock] Block verification failed") return nil, errors.Errorf("Block verification failed: %s", err.Error()) } diff --git a/consensus/view_change_msg.go b/consensus/view_change_msg.go index 21ec801aa..c0a9863dd 100644 --- a/consensus/view_change_msg.go +++ b/consensus/view_change_msg.go @@ -45,7 +45,7 @@ func (consensus *Consensus) constructViewChangeMessage(priKey *bls.PrivateKeyWra Interface("preparedMsg", preparedMsg). Msg("[constructViewChangeMessage] found prepared msg") if block != nil { - if err := consensus.FBFTLog.verifyBlock(block); err == nil { + if err := consensus.fBFTLog.verifyBlock(block); err == nil { tmpEncoded, err := rlp.EncodeToBytes(block) if err != nil { consensus.getLogger().Err(err).Msg("[constructViewChangeMessage] Failed encoding block") From 41900b0400824d268f346af854236f91615341f6 Mon Sep 17 00:00:00 2001 From: frozen <355847+Frozen@users.noreply.github.com> Date: Mon, 16 Oct 2023 22:15:13 -0400 Subject: [PATCH 14/19] Rebased onto dev. --- api/service/stagedstreamsync/downloader.go | 4 +--- api/service/stagedstreamsync/syncing.go | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/api/service/stagedstreamsync/downloader.go b/api/service/stagedstreamsync/downloader.go index 156722a14..2b112bbac 100644 --- a/api/service/stagedstreamsync/downloader.go +++ b/api/service/stagedstreamsync/downloader.go @@ -6,9 +6,6 @@ import ( "time" "github.com/ethereum/go-ethereum/event" - "github.com/harmony-one/harmony/consensus" - "github.com/rs/zerolog" - "github.com/harmony-one/harmony/consensus" "github.com/harmony-one/harmony/core" nodeconfig "github.com/harmony-one/harmony/internal/configs/node" @@ -17,6 +14,7 @@ import ( "github.com/harmony-one/harmony/p2p/stream/common/streammanager" "github.com/harmony-one/harmony/p2p/stream/protocols/sync" "github.com/harmony-one/harmony/shard" + "github.com/rs/zerolog" ) type ( diff --git a/api/service/stagedstreamsync/syncing.go b/api/service/stagedstreamsync/syncing.go index 3ebb4f21b..0be19902a 100644 --- a/api/service/stagedstreamsync/syncing.go +++ b/api/service/stagedstreamsync/syncing.go @@ -46,8 +46,6 @@ func CreateStagedSync(ctx context.Context, protocol syncProtocol, config Config, logger zerolog.Logger, - logProgress bool, - c *consensus.Consensus, ) (*StagedStreamSync, error) { logger.Info(). Uint32("shard", bc.ShardID()). @@ -82,7 +80,7 @@ func CreateStagedSync(ctx context.Context, } stageHeadsCfg := NewStageHeadersCfg(bc, mainDB) - stageShortRangeCfg := NewStageShortRangeCfg(bc, mainDB, c) + stageShortRangeCfg := NewStageShortRangeCfg(bc, mainDB, consensus) stageSyncEpochCfg := NewStageEpochCfg(bc, mainDB) stageBodiesCfg := NewStageBodiesCfg(bc, mainDB, dbs, config.Concurrency, protocol, isBeaconNode, config.LogProgress) stageStatesCfg := NewStageStatesCfg(bc, mainDB, dbs, config.Concurrency, logger, config.LogProgress) From f0b70d9f7162c8d70c878f0f076651a8be89449c Mon Sep 17 00:00:00 2001 From: frozen <355847+Frozen@users.noreply.github.com> Date: Fri, 20 Oct 2023 15:40:10 -0400 Subject: [PATCH 15/19] Fixed imports. --- internal/utils/blockedpeers/manager.go | 17 +++++++++-------- internal/utils/blockedpeers/manager_test.go | 11 ++++++----- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/internal/utils/blockedpeers/manager.go b/internal/utils/blockedpeers/manager.go index 021199f7b..a56fe29e6 100644 --- a/internal/utils/blockedpeers/manager.go +++ b/internal/utils/blockedpeers/manager.go @@ -1,22 +1,23 @@ package blockedpeers import ( - "github.com/harmony-one/harmony/internal/utils/lrucache" - libp2p_peer "github.com/libp2p/go-libp2p/core/peer" "time" + + "github.com/harmony-one/harmony/internal/utils/lrucache" + "github.com/libp2p/go-libp2p/core/peer" ) type Manager struct { - internal *lrucache.Cache[libp2p_peer.ID, time.Time] + internal *lrucache.Cache[peer.ID, time.Time] } func NewManager(size int) *Manager { return &Manager{ - internal: lrucache.NewCache[libp2p_peer.ID, time.Time](size), + internal: lrucache.NewCache[peer.ID, time.Time](size), } } -func (m *Manager) IsBanned(key libp2p_peer.ID, now time.Time) bool { +func (m *Manager) IsBanned(key peer.ID, now time.Time) bool { future, ok := m.internal.Get(key) if ok { @@ -25,11 +26,11 @@ func (m *Manager) IsBanned(key libp2p_peer.ID, now time.Time) bool { return ok } -func (m *Manager) Ban(key libp2p_peer.ID, future time.Time) { +func (m *Manager) Ban(key peer.ID, future time.Time) { m.internal.Set(key, future) } -func (m *Manager) Contains(key libp2p_peer.ID) bool { +func (m *Manager) Contains(key peer.ID) bool { return m.internal.Contains(key) } @@ -37,6 +38,6 @@ func (m *Manager) Len() int { return m.internal.Len() } -func (m *Manager) Keys() []libp2p_peer.ID { +func (m *Manager) Keys() []peer.ID { return m.internal.Keys() } diff --git a/internal/utils/blockedpeers/manager_test.go b/internal/utils/blockedpeers/manager_test.go index 31d0b680d..b1bccb54a 100644 --- a/internal/utils/blockedpeers/manager_test.go +++ b/internal/utils/blockedpeers/manager_test.go @@ -1,17 +1,18 @@ package blockedpeers import ( - libp2p_peer "github.com/libp2p/go-libp2p/core/peer" - "github.com/stretchr/testify/require" "testing" "time" + + "github.com/libp2p/go-libp2p/core/peer" + "github.com/stretchr/testify/require" ) func TestNewManager(t *testing.T) { var ( - peer1 libp2p_peer.ID = "peer1" - now = time.Now() - m = NewManager(4) + peer1 peer.ID = "peer1" + now = time.Now() + m = NewManager(4) ) t.Run("check_empty", func(t *testing.T) { From 61794505074dfbdf8c65715c0887749dd7a4057a Mon Sep 17 00:00:00 2001 From: frozen <355847+Frozen@users.noreply.github.com> Date: Mon, 23 Oct 2023 01:16:54 -0400 Subject: [PATCH 16/19] Fixed imports. --- internal/utils/lrucache/lrucache_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/internal/utils/lrucache/lrucache_test.go b/internal/utils/lrucache/lrucache_test.go index 67f16ff39..005603b9d 100644 --- a/internal/utils/lrucache/lrucache_test.go +++ b/internal/utils/lrucache/lrucache_test.go @@ -1,8 +1,9 @@ package lrucache import ( - "github.com/stretchr/testify/require" "testing" + + "github.com/stretchr/testify/require" ) func TestKeys(t *testing.T) { From 96e03868aeed121aa03dd09116b5be430f142969 Mon Sep 17 00:00:00 2001 From: frozen <355847+Frozen@users.noreply.github.com> Date: Mon, 23 Oct 2023 02:06:09 -0400 Subject: [PATCH 17/19] Fixed imports. --- p2p/host.go | 7 ------- p2p/security/security.go | 14 ++++++++------ p2p/security/security_test.go | 2 +- 3 files changed, 9 insertions(+), 14 deletions(-) diff --git a/p2p/host.go b/p2p/host.go index aeafea7dc..18dce6a46 100644 --- a/p2p/host.go +++ b/p2p/host.go @@ -11,13 +11,6 @@ import ( "sync" "time" - "github.com/harmony-one/bls/ffi/go/bls" - nodeconfig "github.com/harmony-one/harmony/internal/configs/node" - "github.com/harmony-one/harmony/internal/utils" - "github.com/harmony-one/harmony/internal/utils/blockedpeers" - "github.com/harmony-one/harmony/p2p/discovery" - "github.com/harmony-one/harmony/p2p/security" - sttypes "github.com/harmony-one/harmony/p2p/stream/types" "github.com/libp2p/go-libp2p" dht "github.com/libp2p/go-libp2p-kad-dht" libp2p_pubsub "github.com/libp2p/go-libp2p-pubsub" diff --git a/p2p/security/security.go b/p2p/security/security.go index e9523cd02..f8d032253 100644 --- a/p2p/security/security.go +++ b/p2p/security/security.go @@ -3,16 +3,18 @@ package security import ( "fmt" "sync" + "time" + "github.com/harmony-one/harmony/internal/utils" "github.com/harmony-one/harmony/internal/utils/blockedpeers" - libp2p_network "github.com/libp2p/go-libp2p/core/network" + libp2pnetwork "github.com/libp2p/go-libp2p/core/network" ma "github.com/multiformats/go-multiaddr" "github.com/pkg/errors" ) type Security interface { - OnConnectCheck(net libp2p_network.Network, conn libp2p_network.Conn) error - OnDisconnectCheck(conn libp2p_network.Conn) error + OnConnectCheck(net libp2pnetwork.Network, conn libp2pnetwork.Conn) error + OnDisconnectCheck(conn libp2pnetwork.Conn) error } type peerMap struct { @@ -85,7 +87,7 @@ func (m *Manager) RangePeers(f func(key string, value []string) bool) { m.peers.Range(f) } -func (m *Manager) OnConnectCheck(net libp2p_network.Network, conn libp2p_network.Conn) error { +func (m *Manager) OnConnectCheck(net libp2pnetwork.Network, conn libp2pnetwork.Conn) error { m.mutex.Lock() defer m.mutex.Unlock() @@ -131,7 +133,7 @@ func (m *Manager) OnConnectCheck(net libp2p_network.Network, conn libp2p_network return nil } -func (m *Manager) OnDisconnectCheck(conn libp2p_network.Conn) error { +func (m *Manager) OnDisconnectCheck(conn libp2pnetwork.Conn) error { m.mutex.Lock() defer m.mutex.Unlock() @@ -169,7 +171,7 @@ func find(slice []string, val string) (int, bool) { return -1, false } -func getRemoteIP(conn libp2p_network.Conn) (string, error) { +func getRemoteIP(conn libp2pnetwork.Conn) (string, error) { for _, protocol := range conn.RemoteMultiaddr().Protocols() { switch protocol.Code { case ma.P_IP4: diff --git a/p2p/security/security_test.go b/p2p/security/security_test.go index 79a2dac28..7d610707e 100644 --- a/p2p/security/security_test.go +++ b/p2p/security/security_test.go @@ -3,10 +3,10 @@ package security import ( "context" "fmt" - "github.com/harmony-one/harmony/internal/utils/blockedpeers" "testing" "time" + "github.com/harmony-one/harmony/internal/utils/blockedpeers" "github.com/libp2p/go-libp2p" ic "github.com/libp2p/go-libp2p/core/crypto" "github.com/libp2p/go-libp2p/core/host" From 64d7392c3b57c7db9e3d4bc5c0fbece1c546ae7b Mon Sep 17 00:00:00 2001 From: frozen <355847+Frozen@users.noreply.github.com> Date: Tue, 24 Oct 2023 20:42:27 -0400 Subject: [PATCH 18/19] Clean up. --- Makefile | 5 ++- api/service/stagedstreamsync/downloader.go | 5 +-- api/service/stagedstreamsync/downloaders.go | 4 +-- api/service/stagedstreamsync/service.go | 4 +-- api/service/stagedstreamsync/stage_heads.go | 2 +- .../stagedstreamsync/stage_short_range.go | 34 +++---------------- api/service/stagedstreamsync/syncing.go | 25 ++++---------- cmd/harmony/main.go | 5 ++- consensus/consensus.go | 19 +++++++---- consensus/consensus_test.go | 5 --- consensus/consensus_v2.go | 26 ++++++++------ consensus/fbft_log.go | 8 +---- consensus/fbft_log_test.go | 4 +-- consensus/validator.go | 13 ++++--- consensus/view_change_construct.go | 4 +-- consensus/view_change_msg.go | 2 +- core/blockchain.go | 8 +++++ core/blockchain_impl.go | 7 ++-- core/blockchain_stub.go | 4 +++ internal/utils/timer.go | 4 +-- node/node.go | 4 --- node/node_handler.go | 19 +++++------ p2p/security/security.go | 12 +++---- 23 files changed, 96 insertions(+), 127 deletions(-) diff --git a/Makefile b/Makefile index deb990bf5..6fc8f2607 100644 --- a/Makefile +++ b/Makefile @@ -179,4 +179,7 @@ debug_external: clean bash test/debug-external.sh build_localnet_validator: - bash test/build-localnet-validator.sh \ No newline at end of file + bash test/build-localnet-validator.sh + +tt: + go test -v -test.run OnDisconnectCheck ./p2p/security \ No newline at end of file diff --git a/api/service/stagedstreamsync/downloader.go b/api/service/stagedstreamsync/downloader.go index 2b112bbac..371104895 100644 --- a/api/service/stagedstreamsync/downloader.go +++ b/api/service/stagedstreamsync/downloader.go @@ -6,6 +6,8 @@ import ( "time" "github.com/ethereum/go-ethereum/event" + "github.com/rs/zerolog" + "github.com/harmony-one/harmony/consensus" "github.com/harmony-one/harmony/core" nodeconfig "github.com/harmony-one/harmony/internal/configs/node" @@ -14,7 +16,6 @@ import ( "github.com/harmony-one/harmony/p2p/stream/common/streammanager" "github.com/harmony-one/harmony/p2p/stream/protocols/sync" "github.com/harmony-one/harmony/shard" - "github.com/rs/zerolog" ) type ( @@ -37,7 +38,7 @@ type ( ) // NewDownloader creates a new downloader -func NewDownloader(host p2p.Host, bc core.BlockChain, consensus *consensus.Consensus, dbDir string, isBeaconNode bool, config Config, c *consensus.Consensus) *Downloader { +func NewDownloader(host p2p.Host, bc core.BlockChain, consensus *consensus.Consensus, dbDir string, isBeaconNode bool, config Config) *Downloader { config.fixValues() sp := sync.NewProtocol(sync.Config{ diff --git a/api/service/stagedstreamsync/downloaders.go b/api/service/stagedstreamsync/downloaders.go index 08a8e40de..583f3e152 100644 --- a/api/service/stagedstreamsync/downloaders.go +++ b/api/service/stagedstreamsync/downloaders.go @@ -16,7 +16,7 @@ type Downloaders struct { } // NewDownloaders creates Downloaders for sync of multiple blockchains -func NewDownloaders(host p2p.Host, bcs []core.BlockChain, consensus *consensus.Consensus, dbDir string, config Config, c *consensus.Consensus) *Downloaders { +func NewDownloaders(host p2p.Host, bcs []core.BlockChain, consensus *consensus.Consensus, dbDir string, config Config) *Downloaders { ds := make(map[uint32]*Downloader) isBeaconNode := len(bcs) == 1 for _, bc := range bcs { @@ -26,7 +26,7 @@ func NewDownloaders(host p2p.Host, bcs []core.BlockChain, consensus *consensus.C if _, ok := ds[bc.ShardID()]; ok { continue } - ds[bc.ShardID()] = NewDownloader(host, bc, consensus, dbDir, isBeaconNode, config, c) + ds[bc.ShardID()] = NewDownloader(host, bc, consensus, dbDir, isBeaconNode, config) } return &Downloaders{ ds: ds, diff --git a/api/service/stagedstreamsync/service.go b/api/service/stagedstreamsync/service.go index 90db7eada..f7ffd7f2d 100644 --- a/api/service/stagedstreamsync/service.go +++ b/api/service/stagedstreamsync/service.go @@ -12,9 +12,9 @@ type StagedStreamSyncService struct { } // NewService creates a new downloader service -func NewService(host p2p.Host, bcs []core.BlockChain, consensus *consensus.Consensus, config Config, dbDir string, c *consensus.Consensus) *StagedStreamSyncService { +func NewService(host p2p.Host, bcs []core.BlockChain, consensus *consensus.Consensus, config Config, dbDir string) *StagedStreamSyncService { return &StagedStreamSyncService{ - Downloaders: NewDownloaders(host, bcs, consensus, dbDir, config, c), + Downloaders: NewDownloaders(host, bcs, consensus, dbDir, config), } } diff --git a/api/service/stagedstreamsync/stage_heads.go b/api/service/stagedstreamsync/stage_heads.go index d05543c06..c917884a3 100644 --- a/api/service/stagedstreamsync/stage_heads.go +++ b/api/service/stagedstreamsync/stage_heads.go @@ -53,7 +53,7 @@ func (heads *StageHeads) Exec(ctx context.Context, firstCycle bool, invalidBlock maxHeight := s.state.status.targetBN maxBlocksPerSyncCycle := uint64(1024) // TODO: should be in config -> s.state.MaxBlocksPerSyncCycle - currentHeight := heads.configs.bc.CurrentHeader().NumberU64() + currentHeight := heads.configs.bc.CurrentBlock().NumberU64() s.state.currentCycle.TargetHeight = maxHeight targetHeight := uint64(0) if errV := CreateView(ctx, heads.configs.db, tx, func(etx kv.Tx) (err error) { diff --git a/api/service/stagedstreamsync/stage_short_range.go b/api/service/stagedstreamsync/stage_short_range.go index f3037869a..ce6cdf36b 100644 --- a/api/service/stagedstreamsync/stage_short_range.go +++ b/api/service/stagedstreamsync/stage_short_range.go @@ -3,9 +3,7 @@ package stagedstreamsync import ( "context" - "github.com/harmony-one/harmony/consensus" "github.com/harmony-one/harmony/core" - "github.com/harmony-one/harmony/core/types" "github.com/harmony-one/harmony/internal/utils" sttypes "github.com/harmony-one/harmony/p2p/stream/types" "github.com/harmony-one/harmony/shard" @@ -20,7 +18,6 @@ type StageShortRange struct { type StageShortRangeCfg struct { bc core.BlockChain db kv.RwDB - c *consensus.Consensus } func NewStageShortRange(cfg StageShortRangeCfg) *StageShortRange { @@ -29,11 +26,10 @@ func NewStageShortRange(cfg StageShortRangeCfg) *StageShortRange { } } -func NewStageShortRangeCfg(bc core.BlockChain, db kv.RwDB, c *consensus.Consensus) StageShortRangeCfg { +func NewStageShortRangeCfg(bc core.BlockChain, db kv.RwDB) StageShortRangeCfg { return StageShortRangeCfg{ bc: bc, db: db, - c: c, } } @@ -108,12 +104,9 @@ func (sr *StageShortRange) doShortRangeSync(ctx context.Context, s *StageState) return 0, errors.Wrap(err, "prerequisite") } } - var ( - bc = sr.configs.bc - curBN = bc.CurrentHeader().NumberU64() - blkNums = sh.prepareBlockHashNumbers(curBN) - hashChain, whitelist, err = sh.getHashChain(ctx, blkNums) - ) + curBN := sr.configs.bc.CurrentBlock().NumberU64() + blkNums := sh.prepareBlockHashNumbers(curBN) + hashChain, whitelist, err := sh.getHashChain(ctx, blkNums) if err != nil { if errors.Is(err, context.DeadlineExceeded) || errors.Is(err, context.Canceled) { return 0, nil @@ -163,25 +156,6 @@ func (sr *StageShortRange) doShortRangeSync(ctx context.Context, s *StageState) return 0, err } - numInserted := 0 - err = sr.configs.c.GetLastMileBlockIter(sr.configs.bc.CurrentHeader().NumberU64()+1, func(blockIter *consensus.LastMileBlockIter) error { - for { - block := blockIter.Next() - if block == nil { - break - } - if _, err := bc.InsertChain(types.Blocks{block}, true); err != nil { - return errors.Wrap(err, "failed to InsertChain") - } - numInserted++ - } - return nil - }) - if err != nil { - return 0, errors.WithMessage(err, "failed to InsertChain for last mile blocks") - } - utils.Logger().Info().Int("last mile blocks inserted", numInserted).Msg("Insert last mile blocks success") - return n, nil } diff --git a/api/service/stagedstreamsync/syncing.go b/api/service/stagedstreamsync/syncing.go index 0be19902a..738f2f920 100644 --- a/api/service/stagedstreamsync/syncing.go +++ b/api/service/stagedstreamsync/syncing.go @@ -47,6 +47,7 @@ func CreateStagedSync(ctx context.Context, config Config, logger zerolog.Logger, ) (*StagedStreamSync, error) { + logger.Info(). Uint32("shard", bc.ShardID()). Bool("beaconNode", isBeaconNode). @@ -55,6 +56,7 @@ func CreateStagedSync(ctx context.Context, Bool("serverOnly", config.ServerOnly). Int("minStreams", config.MinStreams). Msg(WrapStagedSyncMsg("creating staged sync")) + var mainDB kv.RwDB dbs := make([]kv.RwDB, config.Concurrency) if config.UseMemDB { @@ -80,7 +82,7 @@ func CreateStagedSync(ctx context.Context, } stageHeadsCfg := NewStageHeadersCfg(bc, mainDB) - stageShortRangeCfg := NewStageShortRangeCfg(bc, mainDB, consensus) + stageShortRangeCfg := NewStageShortRangeCfg(bc, mainDB) stageSyncEpochCfg := NewStageEpochCfg(bc, mainDB) stageBodiesCfg := NewStageBodiesCfg(bc, mainDB, dbs, config.Concurrency, protocol, isBeaconNode, config.LogProgress) stageStatesCfg := NewStageStatesCfg(bc, mainDB, dbs, config.Concurrency, logger, config.LogProgress) @@ -225,9 +227,6 @@ func (s *StagedStreamSync) doSync(downloaderContext context.Context, initSync bo return 0, 0, err } - s.startSyncing() - defer s.finishSyncing() - var estimatedHeight uint64 if initSync { if h, err := s.estimateCurrentNumber(downloaderContext); err != nil { @@ -244,20 +243,13 @@ func (s *StagedStreamSync) doSync(downloaderContext context.Context, initSync bo } } - i := 0 + s.startSyncing() + defer s.finishSyncing() + for { - i++ ctx, cancel := context.WithCancel(downloaderContext) - started := s.bc.CurrentHeader().NumberU64() + n, err := s.doSyncCycle(ctx, initSync) - finished := s.bc.CurrentHeader().NumberU64() - utils.Logger().Info(). - Uint64("from", started). - Int("returned", n). - Uint64("to", finished). - Bool("initSync", initSync). - Int("cycle", i). - Msg(WrapStagedSyncMsg("synced blocks")) if err != nil { utils.Logger().Error(). Err(err). @@ -377,9 +369,6 @@ func (s *StagedStreamSync) finishSyncing() { if s.evtDownloadFinishedSubscribed { s.evtDownloadFinished.Send(struct{}{}) } - utils.Logger().Info(). - Bool("evtDownloadFinishedSubscribed", s.evtDownloadFinishedSubscribed). - Msg(WrapStagedSyncMsg("finished syncing")) } func (s *StagedStreamSync) checkPrerequisites() error { diff --git a/cmd/harmony/main.go b/cmd/harmony/main.go index b1afbe6bf..9fc89d45d 100644 --- a/cmd/harmony/main.go +++ b/cmd/harmony/main.go @@ -1,7 +1,6 @@ package main import ( - "context" "fmt" "math/big" "math/rand" @@ -522,7 +521,7 @@ func setupNodeAndRun(hc harmonyconfig.HarmonyConfig) { Msg("Start p2p host failed") } - if err := node.BootstrapConsensus(context.TODO(), currentNode.Consensus, currentNode.Host()); err != nil { + if err := currentNode.BootstrapConsensus(); err != nil { fmt.Fprint(os.Stderr, "could not bootstrap consensus", err.Error()) if !currentNode.NodeConfig.IsOffline { os.Exit(-1) @@ -1033,7 +1032,7 @@ func setupStagedSyncService(node *node.Node, host p2p.Host, hc harmonyconfig.Har } } //Setup stream sync service - s := stagedstreamsync.NewService(host, blockchains, node.Consensus, sConfig, hc.General.DataDir, node.Consensus) + s := stagedstreamsync.NewService(host, blockchains, node.Consensus, sConfig, hc.General.DataDir) node.RegisterService(service.StagedStreamSync, s) diff --git a/consensus/consensus.go b/consensus/consensus.go index 1e35773ef..b396f6ead 100644 --- a/consensus/consensus.go +++ b/consensus/consensus.go @@ -94,6 +94,8 @@ type Consensus struct { // The post-consensus job func passed from Node object // Called when consensus on a new block is done PostConsensusJob func(*types.Block) error + // The verifier func passed from Node object + BlockVerifier VerifyBlockFunc // verified block to state sync broadcast VerifiedNewBlock chan *types.Block // will trigger state syncing when blockNum is low @@ -169,12 +171,12 @@ func (consensus *Consensus) Beaconchain() core.BlockChain { } // VerifyBlock is a function used to verify the block and keep trace of verified blocks. -func (FBFTLog *FBFTLog) verifyBlock(block *types.Block) error { - if !FBFTLog.IsBlockVerified(block.Hash()) { - if err := FBFTLog.BlockVerify(block); err != nil { +func (consensus *Consensus) verifyBlock(block *types.Block) error { + if !consensus.fBFTLog.IsBlockVerified(block.Hash()) { + if err := consensus.BlockVerifier(block); err != nil { return errors.Errorf("Block verification failed: %s", err) } - FBFTLog.MarkBlockVerified(block) + consensus.fBFTLog.MarkBlockVerified(block) } return nil } @@ -268,7 +270,7 @@ func New( consensus := Consensus{ mutex: &sync.RWMutex{}, ShardID: shard, - fBFTLog: NewFBFTLog(VerifyNewBlock(registry.GetWebHooks(), registry.GetBlockchain(), registry.GetBeaconchain())), + fBFTLog: NewFBFTLog(), phase: FBFTAnnounce, current: State{mode: Normal}, Decider: Decider, @@ -302,7 +304,12 @@ func New( consensus.RndChannel = make(chan [vdfAndSeedSize]byte) consensus.IgnoreViewIDCheck = abool.NewBool(false) // Make Sure Verifier is not null - consensus.vc = newViewChange(consensus.fBFTLog.BlockVerify) + consensus.vc = newViewChange() + // TODO: reference to blockchain/beaconchain should be removed. + verifier := VerifyNewBlock(registry.GetWebHooks(), consensus.Blockchain(), consensus.Beaconchain()) + consensus.BlockVerifier = verifier + consensus.vc.verifyBlock = consensus.verifyBlock + // init prometheus metrics initMetrics() consensus.AddPubkeyMetrics() diff --git a/consensus/consensus_test.go b/consensus/consensus_test.go index 725e70c3f..697ba4952 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(nil) state := State{mode: Normal} timeouts := createTimeout() @@ -37,10 +36,6 @@ func TestConsensusInitialization(t *testing.T) { assert.IsType(t, make(chan struct{}), consensus.BlockNumLowChan) // FBFTLog - assert.Equal(t, fbtLog.blocks, consensus.fBFTLog.blocks) - assert.Equal(t, fbtLog.messages, consensus.fBFTLog.messages) - assert.Equal(t, len(fbtLog.verifiedBlocks), 0) - assert.Equal(t, fbtLog.verifiedBlocks, consensus.fBFTLog.verifiedBlocks) assert.NotNil(t, consensus.FBFTLog()) assert.Equal(t, FBFTAnnounce, consensus.phase) diff --git a/consensus/consensus_v2.go b/consensus/consensus_v2.go index 258d82a8f..6d3ef5b47 100644 --- a/consensus/consensus_v2.go +++ b/consensus/consensus_v2.go @@ -8,14 +8,13 @@ import ( "sync/atomic" "time" - libp2p_peer "github.com/libp2p/go-libp2p/core/peer" - "github.com/ethereum/go-ethereum/common" bls2 "github.com/harmony-one/bls/ffi/go/bls" "github.com/harmony-one/harmony/consensus/signature" "github.com/harmony-one/harmony/core" nodeconfig "github.com/harmony-one/harmony/internal/configs/node" "github.com/harmony-one/harmony/internal/utils" + libp2p_peer "github.com/libp2p/go-libp2p/core/peer" "github.com/rs/zerolog" msg_pb "github.com/harmony-one/harmony/api/proto/message" @@ -395,12 +394,11 @@ func (consensus *Consensus) tick() { // the bootstrap timer will be stopped once consensus is reached or view change // is succeeded if k != timeoutBootstrap { - if v.Stop() { // prevent useless logs - consensus.getLogger().Debug(). - Str("k", k.String()). - Str("Mode", consensus.current.Mode().String()). - Msg("[ConsensusMainLoop] consensusTimeout stopped!!!") - } + consensus.getLogger().Debug(). + Str("k", k.String()). + Str("Mode", consensus.current.Mode().String()). + Msg("[ConsensusMainLoop] consensusTimeout stopped!!!") + v.Stop() continue } } @@ -456,6 +454,7 @@ func (consensus *Consensus) BlockChannel(newBlock *types.Block) { type LastMileBlockIter struct { blockCandidates []*types.Block fbftLog *FBFTLog + verify func(*types.Block) error curIndex int logger *zerolog.Logger } @@ -470,6 +469,9 @@ func (consensus *Consensus) GetLastMileBlockIter(bnStart uint64, cb func(iter *L // GetLastMileBlockIter get the iterator of the last mile blocks starting from number bnStart func (consensus *Consensus) getLastMileBlockIter(bnStart uint64, cb func(iter *LastMileBlockIter) error) error { + if consensus.BlockVerifier == nil { + return errors.New("consensus haven't initialized yet") + } blocks, _, err := consensus.getLastMileBlocksAndMsg(bnStart) if err != nil { return err @@ -477,6 +479,7 @@ func (consensus *Consensus) getLastMileBlockIter(bnStart uint64, cb func(iter *L return cb(&LastMileBlockIter{ blockCandidates: blocks, fbftLog: consensus.fBFTLog, + verify: consensus.BlockVerifier, curIndex: 0, logger: consensus.getLogger(), }) @@ -491,7 +494,7 @@ func (iter *LastMileBlockIter) Next() *types.Block { iter.curIndex++ if !iter.fbftLog.IsBlockVerified(block.Hash()) { - if err := iter.fbftLog.BlockVerify(block); err != nil { + if err := iter.verify(block); err != nil { iter.logger.Debug().Err(err).Msg("block verification failed in consensus last mile block") return nil } @@ -618,6 +621,9 @@ func (consensus *Consensus) verifyLastCommitSig(lastCommitSig []byte, blk *types // tryCatchup add the last mile block in PBFT log memory cache to blockchain. func (consensus *Consensus) tryCatchup() error { // TODO: change this to a more systematic symbol + if consensus.BlockVerifier == nil { + return errors.New("consensus haven't finished initialization") + } initBN := consensus.getBlockNum() defer consensus.postCatchup(initBN) @@ -632,7 +638,7 @@ func (consensus *Consensus) tryCatchup() error { } blk.SetCurrentCommitSig(msg.Payload) - if err := consensus.fBFTLog.verifyBlock(blk); err != nil { + if err := consensus.verifyBlock(blk); err != nil { consensus.getLogger().Err(err).Msg("[TryCatchup] failed block verifier") return err } diff --git a/consensus/fbft_log.go b/consensus/fbft_log.go index 7ffa2ff9e..982aecab7 100644 --- a/consensus/fbft_log.go +++ b/consensus/fbft_log.go @@ -113,16 +113,14 @@ type FBFTLog struct { blocks map[common.Hash]*types.Block // store blocks received in FBFT verifiedBlocks map[common.Hash]struct{} // store block hashes for blocks that has already been verified messages map[fbftMsgID]*FBFTMessage // store messages received in FBFT - verifyNewBlock func(*types.Block) error // block verification function } // NewFBFTLog returns new instance of FBFTLog -func NewFBFTLog(verifyNewBlock func(*types.Block) error) *FBFTLog { +func NewFBFTLog() *FBFTLog { pbftLog := FBFTLog{ blocks: make(map[common.Hash]*types.Block), messages: make(map[fbftMsgID]*FBFTMessage), verifiedBlocks: make(map[common.Hash]struct{}), - verifyNewBlock: verifyNewBlock, } return &pbftLog } @@ -132,10 +130,6 @@ func (log *FBFTLog) AddBlock(block *types.Block) { log.blocks[block.Hash()] = block } -func (log *FBFTLog) BlockVerify(block *types.Block) error { - return log.verifyNewBlock(block) -} - // MarkBlockVerified marks the block as verified func (log *FBFTLog) MarkBlockVerified(block *types.Block) { log.verifiedBlocks[block.Hash()] = struct{}{} diff --git a/consensus/fbft_log_test.go b/consensus/fbft_log_test.go index c22c70b3e..420effff4 100644 --- a/consensus/fbft_log_test.go +++ b/consensus/fbft_log_test.go @@ -65,7 +65,7 @@ func TestGetMessagesByTypeSeqViewHash(t *testing.T) { ViewID: 3, BlockHash: [32]byte{01, 02}, } - log := NewFBFTLog(nil) + log := NewFBFTLog() log.AddVerifiedMessage(&pbftMsg) found := log.GetMessagesByTypeSeqViewHash( @@ -90,7 +90,7 @@ func TestHasMatchingAnnounce(t *testing.T) { ViewID: 3, BlockHash: [32]byte{01, 02}, } - log := NewFBFTLog(nil) + log := NewFBFTLog() log.AddVerifiedMessage(&pbftMsg) found := log.HasMatchingViewAnnounce(2, 3, [32]byte{01, 02}) if !found { diff --git a/consensus/validator.go b/consensus/validator.go index 6a1f21e1a..0506f4359 100644 --- a/consensus/validator.go +++ b/consensus/validator.go @@ -63,11 +63,6 @@ func (consensus *Consensus) onAnnounce(msg *msg_pb.Message) { go func() { // Best effort check, no need to error out. _, err := consensus.ValidateNewBlock(recvMsg) - if err != nil { - // maybe ban sender - consensus.getLogger().Error(). - Err(err).Msgf("[Announce] Failed to validate block") - } if err == nil { consensus.GetLogger().Info(). Msg("[Announce] Block verified") @@ -81,7 +76,6 @@ func (consensus *Consensus) ValidateNewBlock(recvMsg *FBFTMessage) (*types.Block defer consensus.mutex.Unlock() return consensus.validateNewBlock(recvMsg) } - func (consensus *Consensus) validateNewBlock(recvMsg *FBFTMessage) (*types.Block, error) { if consensus.fBFTLog.IsBlockVerified(recvMsg.BlockHash) { var blockObj *types.Block @@ -131,7 +125,12 @@ func (consensus *Consensus) validateNewBlock(recvMsg *FBFTMessage) (*types.Block Hex("blockHash", recvMsg.BlockHash[:]). Msg("[validateNewBlock] Prepared message and block added") - if err := consensus.fBFTLog.verifyBlock(&blockObj); err != nil { + if consensus.BlockVerifier == nil { + consensus.getLogger().Debug().Msg("[validateNewBlock] consensus received message before init. Ignoring") + return nil, errors.New("nil block verifier") + } + + if err := consensus.verifyBlock(&blockObj); err != nil { consensus.getLogger().Error().Err(err).Msg("[validateNewBlock] Block verification failed") return nil, errors.Errorf("Block verification failed: %s", err.Error()) } diff --git a/consensus/view_change_construct.go b/consensus/view_change_construct.go index 0c3aa1e60..061d2a795 100644 --- a/consensus/view_change_construct.go +++ b/consensus/view_change_construct.go @@ -51,11 +51,9 @@ type viewChange struct { } // newViewChange returns a new viewChange object -func newViewChange(verifyBlock VerifyBlockFunc) *viewChange { +func newViewChange() *viewChange { vc := viewChange{} vc.Reset() - vc.verifyBlock = verifyBlock - return &vc } diff --git a/consensus/view_change_msg.go b/consensus/view_change_msg.go index c0a9863dd..6c4b08005 100644 --- a/consensus/view_change_msg.go +++ b/consensus/view_change_msg.go @@ -45,7 +45,7 @@ func (consensus *Consensus) constructViewChangeMessage(priKey *bls.PrivateKeyWra Interface("preparedMsg", preparedMsg). Msg("[constructViewChangeMessage] found prepared msg") if block != nil { - if err := consensus.fBFTLog.verifyBlock(block); err == nil { + if err := consensus.verifyBlock(block); err == nil { tmpEncoded, err := rlp.EncodeToBytes(block) if err != nil { consensus.getLogger().Err(err).Msg("[constructViewChangeMessage] Failed encoding block") diff --git a/core/blockchain.go b/core/blockchain.go index 40d33100a..0adc96925 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -109,6 +109,14 @@ type BlockChain interface { // but does not write any state. This is used to construct competing side forks // up to the point where they exceed the canonical total difficulty. WriteBlockWithoutState(block *types.Block, td *big.Int) (err error) + // WriteBlockWithState writes the block and all associated state to the database. + WriteBlockWithState( + block *types.Block, receipts []*types.Receipt, + cxReceipts []*types.CXReceipt, + stakeMsgs []types2.StakeMsg, + paid reward.Reader, + state *state.DB, + ) (status WriteStatus, err error) // GetMaxGarbageCollectedBlockNumber .. GetMaxGarbageCollectedBlockNumber() int64 // InsertChain attempts to insert the given batch of blocks in to the canonical diff --git a/core/blockchain_impl.go b/core/blockchain_impl.go index 9e7f1134b..b12de5637 100644 --- a/core/blockchain_impl.go +++ b/core/blockchain_impl.go @@ -1473,8 +1473,7 @@ func (bc *BlockChainImpl) WriteBlockWithoutState(block *types.Block, td *big.Int return nil } -// writeBlockWithState writes the block and all associated state to the database. -func (bc *BlockChainImpl) writeBlockWithState( +func (bc *BlockChainImpl) WriteBlockWithState( block *types.Block, receipts []*types.Receipt, cxReceipts []*types.CXReceipt, stakeMsgs []staking.StakeMsg, @@ -1683,6 +1682,8 @@ func (bc *BlockChainImpl) insertChain(chain types.Blocks, verifyHeaders bool) (i if len(chain) == 0 { return 0, nil, nil, ErrEmptyChain } + first := chain[0] + fmt.Println("insertChain", utils.GetPort(), first.ShardID(), first.Epoch().Uint64(), first.NumberU64()) // Do a sanity check that the provided chain is actually ordered and linked for i := 1; i < len(chain); i++ { if chain[i].NumberU64() != chain[i-1].NumberU64()+1 || chain[i].ParentHash() != chain[i-1].Hash() { @@ -1881,7 +1882,7 @@ func (bc *BlockChainImpl) insertChain(chain types.Blocks, verifyHeaders bool) (i // Write the block to the chain and get the status. substart = time.Now() - status, err := bc.writeBlockWithState( + status, err := bc.WriteBlockWithState( block, receipts, cxReceipts, stakeMsgs, payout, state, ) if err != nil { diff --git a/core/blockchain_stub.go b/core/blockchain_stub.go index e42a12b10..e9ef10ce9 100644 --- a/core/blockchain_stub.go +++ b/core/blockchain_stub.go @@ -124,6 +124,10 @@ func (a Stub) WriteBlockWithoutState(block *types.Block, td *big.Int) (err error return errors.Errorf("method WriteBlockWithoutState not implemented for %s", a.Name) } +func (a Stub) WriteBlockWithState(block *types.Block, receipts []*types.Receipt, cxReceipts []*types.CXReceipt, stakeMsgs []staking.StakeMsg, paid reward.Reader, state *state.DB) (status WriteStatus, err error) { + return 0, errors.Errorf("method WriteBlockWithState not implemented for %s", a.Name) +} + func (a Stub) GetMaxGarbageCollectedBlockNumber() int64 { return 0 } diff --git a/internal/utils/timer.go b/internal/utils/timer.go index 176732fca..d355d5c71 100644 --- a/internal/utils/timer.go +++ b/internal/utils/timer.go @@ -34,11 +34,9 @@ func (timeout *Timeout) Start() { } // Stop stops the timeout clock -func (timeout *Timeout) Stop() (stopped bool) { - stopped = timeout.state != Inactive +func (timeout *Timeout) Stop() { timeout.state = Inactive timeout.start = time.Now() - return stopped } // Expired checks whether the timeout is reached/expired diff --git a/node/node.go b/node/node.go index 8d9665854..f035bf491 100644 --- a/node/node.go +++ b/node/node.go @@ -149,10 +149,6 @@ type Node struct { registry *registry.Registry } -func (node *Node) Host() p2p.Host { - return node.host -} - // Blockchain returns the blockchain for the node's current shard. func (node *Node) Blockchain() core.BlockChain { return node.registry.GetBlockchain() diff --git a/node/node_handler.go b/node/node_handler.go index 89464d3c0..eeaf90f2d 100644 --- a/node/node_handler.go +++ b/node/node_handler.go @@ -404,21 +404,16 @@ func (node *Node) PostConsensusProcessing(newBlock *types.Block) error { } // BootstrapConsensus is a goroutine to check number of peers and start the consensus -func BootstrapConsensus(ctx context.Context, consensus *consensus.Consensus, host p2p.Host) error { - ctx, cancel := context.WithTimeout(ctx, time.Minute) +func (node *Node) BootstrapConsensus() error { + ctx, cancel := context.WithTimeout(context.Background(), time.Minute) defer cancel() - min := consensus.MinPeers + min := node.Consensus.MinPeers enoughMinPeers := make(chan struct{}) const checkEvery = 3 * time.Second go func() { for { - select { - case <-ctx.Done(): - return - case <-time.After(checkEvery): - } - - numPeersNow := host.GetPeerCount() + <-time.After(checkEvery) + numPeersNow := node.host.GetPeerCount() if numPeersNow >= min { utils.Logger().Info().Msg("[bootstrap] StartConsensus") enoughMinPeers <- struct{}{} @@ -437,7 +432,9 @@ func BootstrapConsensus(ctx context.Context, consensus *consensus.Consensus, hos case <-ctx.Done(): return ctx.Err() case <-enoughMinPeers: - go consensus.StartChannel() + go func() { + node.Consensus.StartChannel() + }() return nil } } diff --git a/p2p/security/security.go b/p2p/security/security.go index f8d032253..db70c76d4 100644 --- a/p2p/security/security.go +++ b/p2p/security/security.go @@ -7,14 +7,14 @@ import ( "github.com/harmony-one/harmony/internal/utils" "github.com/harmony-one/harmony/internal/utils/blockedpeers" - libp2pnetwork "github.com/libp2p/go-libp2p/core/network" + libp2p_network "github.com/libp2p/go-libp2p/core/network" ma "github.com/multiformats/go-multiaddr" "github.com/pkg/errors" ) type Security interface { - OnConnectCheck(net libp2pnetwork.Network, conn libp2pnetwork.Conn) error - OnDisconnectCheck(conn libp2pnetwork.Conn) error + OnConnectCheck(net libp2p_network.Network, conn libp2p_network.Conn) error + OnDisconnectCheck(conn libp2p_network.Conn) error } type peerMap struct { @@ -87,7 +87,7 @@ func (m *Manager) RangePeers(f func(key string, value []string) bool) { m.peers.Range(f) } -func (m *Manager) OnConnectCheck(net libp2pnetwork.Network, conn libp2pnetwork.Conn) error { +func (m *Manager) OnConnectCheck(net libp2p_network.Network, conn libp2p_network.Conn) error { m.mutex.Lock() defer m.mutex.Unlock() @@ -133,7 +133,7 @@ func (m *Manager) OnConnectCheck(net libp2pnetwork.Network, conn libp2pnetwork.C return nil } -func (m *Manager) OnDisconnectCheck(conn libp2pnetwork.Conn) error { +func (m *Manager) OnDisconnectCheck(conn libp2p_network.Conn) error { m.mutex.Lock() defer m.mutex.Unlock() @@ -171,7 +171,7 @@ func find(slice []string, val string) (int, bool) { return -1, false } -func getRemoteIP(conn libp2pnetwork.Conn) (string, error) { +func getRemoteIP(conn libp2p_network.Conn) (string, error) { for _, protocol := range conn.RemoteMultiaddr().Protocols() { switch protocol.Code { case ma.P_IP4: From dc326f6fb249379ae3eda97ed1806d109802fb0e Mon Sep 17 00:00:00 2001 From: frozen <355847+Frozen@users.noreply.github.com> Date: Thu, 26 Oct 2023 11:58:16 -0400 Subject: [PATCH 19/19] Rebased. --- p2p/host.go | 9 ++++++++- p2p/security/security.go | 6 +++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/p2p/host.go b/p2p/host.go index 18dce6a46..4a4240c56 100644 --- a/p2p/host.go +++ b/p2p/host.go @@ -11,6 +11,13 @@ import ( "sync" "time" + "github.com/harmony-one/bls/ffi/go/bls" + nodeconfig "github.com/harmony-one/harmony/internal/configs/node" + "github.com/harmony-one/harmony/internal/utils" + "github.com/harmony-one/harmony/internal/utils/blockedpeers" + "github.com/harmony-one/harmony/p2p/discovery" + "github.com/harmony-one/harmony/p2p/security" + sttypes "github.com/harmony-one/harmony/p2p/stream/types" "github.com/libp2p/go-libp2p" dht "github.com/libp2p/go-libp2p-kad-dht" libp2p_pubsub "github.com/libp2p/go-libp2p-pubsub" @@ -247,7 +254,7 @@ func NewHost(cfg HostConfig) (Host, error) { subLogger := utils.Logger().With().Str("hostID", p2pHost.ID().Pretty()).Logger() banned := blockedpeers.NewManager(1024) - security := security.NewManager(cfg.MaxConnPerIP, int(cfg.MaxPeers, banned)) + security := security.NewManager(cfg.MaxConnPerIP, int(cfg.MaxPeers), banned) // has to save the private key for host h := &HostV2{ h: p2pHost, diff --git a/p2p/security/security.go b/p2p/security/security.go index db70c76d4..d363a9647 100644 --- a/p2p/security/security.go +++ b/p2p/security/security.go @@ -59,14 +59,14 @@ func (peerMap *peerMap) Range(f func(key string, value []string) bool) { type Manager struct { maxConnPerIP int - maxPeers int64 + maxPeers int mutex sync.Mutex - peers peerMap // All the connected nodes, key is the Peer's IP, value is the peer's ID array + peers *peerMap // All the connected nodes, key is the Peer's IP, value is the peer's ID array banned *blockedpeers.Manager } -func NewManager(maxConnPerIP int, maxPeers int64, banned *blockedpeers.Manager) *Manager { +func NewManager(maxConnPerIP int, maxPeers int, banned *blockedpeers.Manager) *Manager { if maxConnPerIP < 0 { panic("maximum connections per IP must not be negative") }