From 362d09404074a7c92a56f50cb466922cf985990b Mon Sep 17 00:00:00 2001 From: Ceyhun Onur Date: Mon, 25 Dec 2023 12:29:33 +0300 Subject: [PATCH 01/26] rename tx handlers --- plugin/evm/block_builder.go | 4 ++-- plugin/evm/message/codec.go | 2 +- plugin/evm/message/handler.go | 6 +++--- plugin/evm/message/handler_test.go | 12 ++++++------ plugin/evm/message/message.go | 18 +++++++++--------- plugin/evm/message/message_test.go | 6 +++--- 6 files changed, 24 insertions(+), 24 deletions(-) diff --git a/plugin/evm/block_builder.go b/plugin/evm/block_builder.go index ac78237670..68cdbf8083 100644 --- a/plugin/evm/block_builder.go +++ b/plugin/evm/block_builder.go @@ -157,9 +157,9 @@ func (b *blockBuilder) awaitSubmittedTxs() { b.signalTxsReady() if b.gossiper != nil && len(ethTxsEvent.Txs) > 0 { - // [GossipTxs] will block unless [gossiper.txsToGossipChan] (an + // [GossipEthTxs] will block unless [gossiper.ethTxsToGossipChan] (an // unbuffered channel) is listened on - if err := b.gossiper.GossipTxs(ethTxsEvent.Txs); err != nil { + if err := b.gossiper.GossipEthTxs(ethTxsEvent.Txs); err != nil { log.Warn( "failed to gossip new eth transactions", "err", err, diff --git a/plugin/evm/message/codec.go b/plugin/evm/message/codec.go index 91db9633ab..e49838cd56 100644 --- a/plugin/evm/message/codec.go +++ b/plugin/evm/message/codec.go @@ -27,7 +27,7 @@ func init() { errs := wrappers.Errs{} errs.Add( // Gossip types - c.RegisterType(TxsGossip{}), + c.RegisterType(EthTxsGossip{}), // Types for state sync frontier consensus c.RegisterType(SyncSummary{}), diff --git a/plugin/evm/message/handler.go b/plugin/evm/message/handler.go index b5933f28f3..c0617b0312 100644 --- a/plugin/evm/message/handler.go +++ b/plugin/evm/message/handler.go @@ -19,13 +19,13 @@ var ( // GossipHandler handles incoming gossip messages type GossipHandler interface { - HandleTxs(nodeID ids.NodeID, msg TxsGossip) error + HandleEthTxs(nodeID ids.NodeID, msg EthTxsGossip) error } type NoopMempoolGossipHandler struct{} -func (NoopMempoolGossipHandler) HandleTxs(nodeID ids.NodeID, _ TxsGossip) error { - log.Debug("dropping unexpected Txs message", "peerID", nodeID) +func (NoopMempoolGossipHandler) HandleEthTxs(nodeID ids.NodeID, msg EthTxsGossip) error { + log.Debug("dropping unexpected EthTxsGossip message", "peerID", nodeID) return nil } diff --git a/plugin/evm/message/handler_test.go b/plugin/evm/message/handler_test.go index 37ca82ea4a..dad0ec2b90 100644 --- a/plugin/evm/message/handler_test.go +++ b/plugin/evm/message/handler_test.go @@ -12,11 +12,11 @@ import ( ) type CounterHandler struct { - Txs int + EthTxs int } -func (h *CounterHandler) HandleTxs(ids.NodeID, TxsGossip) error { - h.Txs++ +func (h *CounterHandler) HandleEthTxs(ids.NodeID, EthTxsGossip) error { + h.EthTxs++ return nil } @@ -24,11 +24,11 @@ func TestHandleTxs(t *testing.T) { assert := assert.New(t) handler := CounterHandler{} - msg := TxsGossip{} + msg := EthTxsGossip{} err := msg.Handle(&handler, ids.EmptyNodeID) assert.NoError(err) - assert.Equal(1, handler.Txs) + assert.Equal(1, handler.EthTxs) } func TestNoopHandler(t *testing.T) { @@ -36,6 +36,6 @@ func TestNoopHandler(t *testing.T) { handler := NoopMempoolGossipHandler{} - err := handler.HandleTxs(ids.EmptyNodeID, TxsGossip{}) + err := handler.HandleEthTxs(ids.EmptyNodeID, EthTxsGossip{}) assert.NoError(err) } diff --git a/plugin/evm/message/message.go b/plugin/evm/message/message.go index 89e584179f..35887911c9 100644 --- a/plugin/evm/message/message.go +++ b/plugin/evm/message/message.go @@ -14,15 +14,15 @@ import ( ) const ( - // TxMsgSoftCapSize is the ideal size of encoded transaction bytes we send in - // any [Txs] message. We do not limit inbound messages to + // EthMsgSoftCapSize is the ideal size of encoded transaction bytes we send in + // any [EthTxsGossip] or [AtomicTxGossip] message. We do not limit inbound messages to // this size, however. Max inbound message size is enforced by the codec // (512KB). - TxMsgSoftCapSize = 64 * units.KiB + EthMsgSoftCapSize = 64 * units.KiB ) var ( - _ GossipMessage = TxsGossip{} + _ GossipMessage = EthTxsGossip{} errUnexpectedCodecVersion = errors.New("unexpected codec version") ) @@ -35,16 +35,16 @@ type GossipMessage interface { Handle(handler GossipHandler, nodeID ids.NodeID) error } -type TxsGossip struct { +type EthTxsGossip struct { Txs []byte `serialize:"true"` } -func (msg TxsGossip) Handle(handler GossipHandler, nodeID ids.NodeID) error { - return handler.HandleTxs(nodeID, msg) +func (msg EthTxsGossip) Handle(handler GossipHandler, nodeID ids.NodeID) error { + return handler.HandleEthTxs(nodeID, msg) } -func (msg TxsGossip) String() string { - return fmt.Sprintf("TxsGossip(Len=%d)", len(msg.Txs)) +func (msg EthTxsGossip) String() string { + return fmt.Sprintf("EthTxsGossip(Len=%d)", len(msg.Txs)) } func ParseGossipMessage(codec codec.Manager, bytes []byte) (GossipMessage, error) { diff --git a/plugin/evm/message/message_test.go b/plugin/evm/message/message_test.go index 29f47f226d..0a18fde784 100644 --- a/plugin/evm/message/message_test.go +++ b/plugin/evm/message/message_test.go @@ -20,7 +20,7 @@ func TestMarshalTxs(t *testing.T) { base64EthTxGossip := "AAAAAAAAAAAABGJsYWg=" msg := []byte("blah") - builtMsg := TxsGossip{ + builtMsg := EthTxsGossip{ Txs: msg, } builtMsgBytes, err := BuildGossipMessage(Codec, builtMsg) @@ -30,7 +30,7 @@ func TestMarshalTxs(t *testing.T) { parsedMsgIntf, err := ParseGossipMessage(Codec, builtMsgBytes) assert.NoError(err) - parsedMsg, ok := parsedMsgIntf.(TxsGossip) + parsedMsg, ok := parsedMsgIntf.(EthTxsGossip) assert.True(ok) assert.Equal(msg, parsedMsg.Txs) @@ -39,7 +39,7 @@ func TestMarshalTxs(t *testing.T) { func TestTxsTooLarge(t *testing.T) { assert := assert.New(t) - builtMsg := TxsGossip{ + builtMsg := EthTxsGossip{ Txs: utils.RandomBytes(1024 * units.KiB), } _, err := BuildGossipMessage(Codec, builtMsg) From 30598a9cd850a6bc71ab8888aadf9dc2078fdd93 Mon Sep 17 00:00:00 2001 From: Ceyhun Onur Date: Mon, 25 Dec 2023 12:29:42 +0300 Subject: [PATCH 02/26] add p2p sdk handlers --- go.mod | 30 ++--- go.sum | 61 +++++----- peer/network.go | 89 ++++++++------- peer/network_test.go | 78 +++++++++---- plugin/evm/gossip.go | 177 +++++++++++++++++++++++++++++ plugin/evm/gossip_mempool.go | 117 -------------------- plugin/evm/gossip_test.go | 26 +++++ plugin/evm/gossiper.go | 137 ++++++++++++++--------- plugin/evm/gossipper_test.go | 72 ++++++------ plugin/evm/syncervm_test.go | 2 +- plugin/evm/tx_gossip_test.go | 208 ++++++++++++++++++++++++++++------- plugin/evm/vm.go | 125 ++++++++++++--------- scripts/versions.sh | 2 +- sync/client/client.go | 2 +- x/warp/predicate_test.go | 4 +- 15 files changed, 720 insertions(+), 410 deletions(-) create mode 100644 plugin/evm/gossip.go delete mode 100644 plugin/evm/gossip_mempool.go create mode 100644 plugin/evm/gossip_test.go diff --git a/go.mod b/go.mod index d04b55474e..db5a1f4daf 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,8 @@ go 1.20 require ( github.com/VictoriaMetrics/fastcache v1.10.0 github.com/ava-labs/avalanche-network-runner v1.7.4-0.20231127162258-2f3ceed8ae4b - github.com/ava-labs/avalanchego v1.10.17 + github.com/ava-labs/avalanchego v1.10.18-rc.8 + github.com/ava-labs/coreth v0.12.9-rc.9.0.20231222191417-2e3f762373e9 github.com/cespare/cp v0.1.0 github.com/cockroachdb/pebble v0.0.0-20230209160836-829675f94811 github.com/davecgh/go-spew v1.1.1 @@ -29,8 +30,8 @@ require ( github.com/mattn/go-colorable v0.1.13 github.com/mattn/go-isatty v0.0.16 github.com/olekukonko/tablewriter v0.0.5 - github.com/onsi/ginkgo/v2 v2.8.1 - github.com/onsi/gomega v1.26.0 + github.com/onsi/ginkgo/v2 v2.13.1 + github.com/onsi/gomega v1.29.0 github.com/prometheus/client_golang v1.16.0 github.com/prometheus/client_model v0.3.0 github.com/shirou/gopsutil v3.21.11+incompatible @@ -44,10 +45,10 @@ require ( github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa go.uber.org/goleak v1.2.1 go.uber.org/mock v0.2.0 - golang.org/x/crypto v0.14.0 - golang.org/x/sync v0.3.0 - golang.org/x/sys v0.13.0 - golang.org/x/text v0.13.0 + golang.org/x/crypto v0.17.0 + golang.org/x/sync v0.5.0 + golang.org/x/sys v0.15.0 + golang.org/x/text v0.14.0 golang.org/x/time v0.1.0 google.golang.org/protobuf v1.31.0 gopkg.in/natefinch/lumberjack.v2 v2.0.0 @@ -57,7 +58,6 @@ require ( github.com/DataDog/zstd v1.5.2 // indirect github.com/Microsoft/go-winio v0.5.2 // indirect github.com/NYTimes/gziphandler v1.1.1 // indirect - github.com/ava-labs/coreth v0.12.9-rc.9 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bits-and-blooms/bitset v1.7.0 // indirect github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect @@ -76,18 +76,19 @@ require ( github.com/dlclark/regexp2 v1.7.0 // indirect github.com/ethereum/c-kzg-4844 v0.2.0 // indirect github.com/getsentry/sentry-go v0.18.0 // indirect - github.com/go-logr/logr v1.2.3 // indirect + github.com/go-logr/logr v1.3.0 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.2.6 // indirect github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect github.com/go-stack/stack v1.8.1 // indirect + github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/gofrs/flock v0.8.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang-jwt/jwt/v4 v4.3.0 // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect github.com/google/btree v1.1.2 // indirect - github.com/google/go-cmp v0.5.9 // indirect + github.com/google/go-cmp v0.6.0 // indirect github.com/google/pprof v0.0.0-20230207041349-798e818bf904 // indirect github.com/google/renameio/v2 v2.0.0 // indirect github.com/gorilla/mux v1.8.0 // indirect @@ -144,10 +145,11 @@ require ( go.opentelemetry.io/proto/otlp v0.19.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.26.0 // indirect - golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df // indirect - golang.org/x/mod v0.11.0 // indirect - golang.org/x/net v0.17.0 // indirect - golang.org/x/term v0.13.0 // indirect + golang.org/x/exp v0.0.0-20231127185646-65229373498e // indirect + golang.org/x/mod v0.14.0 // indirect + golang.org/x/net v0.19.0 // indirect + golang.org/x/term v0.15.0 // indirect + golang.org/x/tools v0.16.0 // indirect gonum.org/v1/gonum v0.11.0 // indirect google.golang.org/genproto v0.0.0-20230711160842-782d3b101e98 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98 // indirect diff --git a/go.sum b/go.sum index 5ac902dae5..161e2a63a7 100644 --- a/go.sum +++ b/go.sum @@ -61,10 +61,10 @@ github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kd github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/ava-labs/avalanche-network-runner v1.7.4-0.20231127162258-2f3ceed8ae4b h1:iH6q+S7dmBOYCXrZx+nNlS1HBp72L2msiVCLs39Ls5A= github.com/ava-labs/avalanche-network-runner v1.7.4-0.20231127162258-2f3ceed8ae4b/go.mod h1:aeAm8dgJ1xucQKlYoRDMgYjA0UWGwmaICG9wL0WvseU= -github.com/ava-labs/avalanchego v1.10.17 h1:Ri01nU5ukKC38ZCkCh3namaMZtJkSuv1X/vC13uJguc= -github.com/ava-labs/avalanchego v1.10.17/go.mod h1:A6f3877qlq7bePjCU4T0D60bZGecRMCk15pMpJGOb4Q= -github.com/ava-labs/coreth v0.12.9-rc.9 h1:mvYxABdyPByXwwwIxnTBCiNO23dsE1Kfnd5H106lric= -github.com/ava-labs/coreth v0.12.9-rc.9/go.mod h1:yrf2vEah4Fgj6sJ4UpHewo4DLolwdpf2bJuLRT80PGw= +github.com/ava-labs/avalanchego v1.10.18-rc.8 h1:IBGS1psMY+HNm3w9kQHaHF1+SIssv7qdNV8H50mAGY4= +github.com/ava-labs/avalanchego v1.10.18-rc.8/go.mod h1:duoSU6Xb1HoVhQThAXqcCY7ik7LPWwQHb/YgdauXrfc= +github.com/ava-labs/coreth v0.12.9-rc.9.0.20231222191417-2e3f762373e9 h1:DiJBkm2IJ/My4u5DP4gq2wIbdflFRuZJbDm8DbgNDdg= +github.com/ava-labs/coreth v0.12.9-rc.9.0.20231222191417-2e3f762373e9/go.mod h1:Xftjgk8T46k5/pWSQWcmdPanNl68kTcufd9S4kB58bM= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= @@ -220,8 +220,8 @@ github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= -github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY= +github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= @@ -234,6 +234,8 @@ github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5Nq github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/go-test/deep v1.0.7 h1:/VSMRlnY/JSyqxQUzQLKVMAskpY/NZKFA5j2P+0pP2M= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= @@ -300,8 +302,8 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= @@ -490,16 +492,16 @@ github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vv github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= -github.com/onsi/ginkgo/v2 v2.8.1 h1:xFTEVwOFa1D/Ty24Ws1npBWkDYEV9BqZrsDxVrVkrrU= -github.com/onsi/ginkgo/v2 v2.8.1/go.mod h1:N1/NbDngAFcSLdyZ+/aYTYGSlq9qMCS/cNKGJjy+csc= +github.com/onsi/ginkgo/v2 v2.13.1 h1:LNGfMbR2OVGBfXjvRZIZ2YCTQdGKtPLvuI1rMCCj3OU= +github.com/onsi/ginkgo/v2 v2.13.1/go.mod h1:XStQ8QcGwLyF4HdfcZB8SFOS/MWCgDuXMSBe6zrvLgM= github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= -github.com/onsi/gomega v1.26.0 h1:03cDLK28U6hWvCAns6NeydX3zIm4SF3ci69ulidS32Q= -github.com/onsi/gomega v1.26.0/go.mod h1:r+zV744Re+DiYCIPRlYOTxn0YkOLcAnW8k1xXdMPGhM= +github.com/onsi/gomega v1.29.0 h1:KIA/t2t5UBzoirT4H9tsML45GEbo3ouUnBHsCfD2tVg= +github.com/onsi/gomega v1.29.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/otiai10/copy v1.11.0 h1:OKBD80J/mLBrwnzXqGtFCzprFSGioo30JcmR4APsNwc= @@ -582,6 +584,7 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= @@ -678,8 +681,8 @@ golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= -golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= +golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= +golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -690,8 +693,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df h1:UA2aFVmmsIlefxMk29Dp2juaUSth8Pyn3Tq5Y5mJGME= -golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= +golang.org/x/exp v0.0.0-20231127185646-65229373498e h1:Gvh4YaCaXNs6dKTlfgismwWZKyjVZXwOPfIyUaqU3No= +golang.org/x/exp v0.0.0-20231127185646-65229373498e/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI= 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= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -718,8 +721,8 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.11.0 h1:bUO06HqtnRcc/7l71XBe4WcqTZ+3AH1J59zWDDwLKgU= -golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= +golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= 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= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -765,8 +768,8 @@ golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= -golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= +golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -789,8 +792,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/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.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= -golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= +golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -858,13 +861,13 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/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/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= +golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 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.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= -golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= +golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4= +golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= 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= @@ -875,8 +878,8 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -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/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= 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= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -939,6 +942,8 @@ golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.16.0 h1:GO788SKMRunPIBCXiQyo2AaexLstOrVhuAL5YwsckQM= +golang.org/x/tools v0.16.0/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= 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= diff --git a/peer/network.go b/peer/network.go index e10ab73654..3011356093 100644 --- a/peer/network.go +++ b/peer/network.go @@ -78,9 +78,10 @@ type Network interface { // (length of response divided by request time), and with 0 if the response is invalid. TrackBandwidth(nodeID ids.NodeID, bandwidth float64) - // NewAppProtocol reserves a protocol identifier and returns a corresponding - // client to send messages with - NewAppProtocol(protocol uint64, handler p2p.Handler, options ...p2p.ClientOption) (*p2p.Client, error) + // NewClient returns a client to send messages with for the given protocol + NewClient(protocol uint64, options ...p2p.ClientOption) *p2p.Client + // AddHandler registers a server handler for an application protocol + AddHandler(protocol uint64, handler p2p.Handler) error } // network is an implementation of Network that processes message requests for @@ -92,7 +93,7 @@ type network struct { outstandingRequestHandlers map[uint32]message.ResponseHandler // maps avalanchego requestID => message.ResponseHandler activeAppRequests *semaphore.Weighted // controls maximum number of active outbound requests activeCrossChainRequests *semaphore.Weighted // controls maximum number of active outbound cross chain requests - network *p2p.Network + p2pNetwork *p2p.Network appSender common.AppSender // avalanchego AppSender for sending messages codec codec.Manager // Codec used for parsing messages crossChainCodec codec.Manager // Codec used for parsing cross chain messages @@ -123,7 +124,7 @@ func NewNetwork(p2pNetwork *p2p.Network, appSender common.AppSender, codec codec outstandingRequestHandlers: make(map[uint32]message.ResponseHandler), activeAppRequests: semaphore.NewWeighted(maxActiveAppRequests), activeCrossChainRequests: semaphore.NewWeighted(maxActiveCrossChainRequests), - network: p2pNetwork, + p2pNetwork: p2pNetwork, gossipHandler: message.NoopMempoolGossipHandler{}, appRequestHandler: message.NoopRequestHandler{}, crossChainRequestHandler: message.NoopCrossChainRequestHandler{}, @@ -183,7 +184,7 @@ func (n *network) sendAppRequest(ctx context.Context, nodeID ids.NodeID, request return nil } - log.Trace("sending request to peer", "nodeID", nodeID, "requestLen", len(request)) + log.Debug("sending request to peer", "nodeID", nodeID, "requestLen", len(request)) n.peers.TrackPeer(nodeID) requestID := n.nextRequestID() @@ -200,7 +201,7 @@ func (n *network) sendAppRequest(ctx context.Context, nodeID ids.NodeID, request return err } - log.Trace("sent request message to peer", "nodeID", nodeID, "requestID", requestID) + log.Debug("sent request message to peer", "nodeID", nodeID, "requestID", requestID) return nil } @@ -232,7 +233,7 @@ func (n *network) SendCrossChainRequest(ctx context.Context, chainID ids.ID, req return err } - log.Trace("sent request message to chain", "chainID", chainID, "crossChainRequestID", requestID) + log.Debug("sent request message to chain", "chainID", chainID, "crossChainRequestID", requestID) return nil } @@ -244,21 +245,21 @@ func (n *network) CrossChainAppRequest(ctx context.Context, requestingChainID id return nil } - log.Trace("received CrossChainAppRequest from chain", "requestingChainID", requestingChainID, "requestID", requestID, "requestLen", len(request)) + log.Debug("received CrossChainAppRequest from chain", "requestingChainID", requestingChainID, "requestID", requestID, "requestLen", len(request)) var req message.CrossChainRequest if _, err := n.crossChainCodec.Unmarshal(request, &req); err != nil { - log.Trace("failed to unmarshal CrossChainAppRequest", "requestingChainID", requestingChainID, "requestID", requestID, "requestLen", len(request), "err", err) + log.Debug("failed to unmarshal CrossChainAppRequest", "requestingChainID", requestingChainID, "requestID", requestID, "requestLen", len(request), "err", err) return nil } bufferedDeadline, err := calculateTimeUntilDeadline(deadline, n.crossChainStats) if err != nil { - log.Trace("deadline to process CrossChainAppRequest has expired, skipping", "requestingChainID", requestingChainID, "requestID", requestID, "err", err) + log.Debug("deadline to process CrossChainAppRequest has expired, skipping", "requestingChainID", requestingChainID, "requestID", requestID, "err", err) return nil } - log.Trace("processing incoming CrossChainAppRequest", "requestingChainID", requestingChainID, "requestID", requestID, "req", req) + log.Debug("processing incoming CrossChainAppRequest", "requestingChainID", requestingChainID, "requestID", requestID, "req", req) handleCtx, cancel := context.WithDeadline(context.Background(), bufferedDeadline) defer cancel() @@ -280,13 +281,13 @@ func (n *network) CrossChainAppRequest(ctx context.Context, requestingChainID id // - request times out before a response is provided // If [requestID] is not known, this function will emit a log and return a nil error. // If the response handler returns an error it is propagated as a fatal error. -func (n *network) CrossChainAppRequestFailed(ctx context.Context, respondingChainID ids.ID, requestID uint32) error { - log.Trace("received CrossChainAppRequestFailed from chain", "respondingChainID", respondingChainID, "requestID", requestID) +func (n *network) CrossChainAppRequestFailed(ctx context.Context, respondingChainID ids.ID, requestID uint32, _ *common.AppError) error { + log.Debug("received CrossChainAppRequestFailed from chain", "respondingChainID", respondingChainID, "requestID", requestID) handler, exists := n.markRequestFulfilled(requestID) if !exists { // Can happen after the network has been closed. - log.Trace("received CrossChainAppRequestFailed to unknown request", "respondingChainID", respondingChainID, "requestID", requestID) + log.Debug("received CrossChainAppRequestFailed to unknown request", "respondingChainID", respondingChainID, "requestID", requestID) return nil } @@ -301,12 +302,12 @@ func (n *network) CrossChainAppRequestFailed(ctx context.Context, respondingChai // If [requestID] is not known, this function will emit a log and return a nil error. // If the response handler returns an error it is propagated as a fatal error. func (n *network) CrossChainAppResponse(ctx context.Context, respondingChainID ids.ID, requestID uint32, response []byte) error { - log.Trace("received CrossChainAppResponse from responding chain", "respondingChainID", respondingChainID, "requestID", requestID) + log.Debug("received CrossChainAppResponse from responding chain", "respondingChainID", respondingChainID, "requestID", requestID) handler, exists := n.markRequestFulfilled(requestID) if !exists { // Can happen after the network has been closed. - log.Trace("received CrossChainAppResponse to unknown request", "respondingChainID", respondingChainID, "requestID", requestID, "responseLen", len(response)) + log.Debug("received CrossChainAppResponse to unknown request", "respondingChainID", respondingChainID, "requestID", requestID, "responseLen", len(response)) return nil } @@ -326,21 +327,21 @@ func (n *network) AppRequest(ctx context.Context, nodeID ids.NodeID, requestID u return nil } - log.Trace("received AppRequest from node", "nodeID", nodeID, "requestID", requestID, "requestLen", len(request)) + log.Debug("received AppRequest from node", "nodeID", nodeID, "requestID", requestID, "requestLen", len(request)) var req message.Request if _, err := n.codec.Unmarshal(request, &req); err != nil { - log.Trace("forwarding AppRequest to SDK network", "nodeID", nodeID, "requestID", requestID, "requestLen", len(request), "err", err) - return n.network.AppRequest(ctx, nodeID, requestID, deadline, request) + log.Debug("forwarding AppRequest to SDK network", "nodeID", nodeID, "requestID", requestID, "requestLen", len(request), "err", err) + return n.p2pNetwork.AppRequest(ctx, nodeID, requestID, deadline, request) } bufferedDeadline, err := calculateTimeUntilDeadline(deadline, n.appStats) if err != nil { - log.Trace("deadline to process AppRequest has expired, skipping", "nodeID", nodeID, "requestID", requestID, "err", err) + log.Debug("deadline to process AppRequest has expired, skipping", "nodeID", nodeID, "requestID", requestID, "err", err) return nil } - log.Trace("processing incoming request", "nodeID", nodeID, "requestID", requestID, "req", req) + log.Debug("processing incoming request", "nodeID", nodeID, "requestID", requestID, "req", req) // We make a new context here because we don't want to cancel the context // passed into n.AppSender.SendAppResponse below handleCtx, cancel := context.WithDeadline(context.Background(), bufferedDeadline) @@ -362,12 +363,12 @@ func (n *network) AppRequest(ctx context.Context, nodeID ids.NodeID, requestID u // If [requestID] is not known, this function will emit a log and return a nil error. // If the response handler returns an error it is propagated as a fatal error. func (n *network) AppResponse(ctx context.Context, nodeID ids.NodeID, requestID uint32, response []byte) error { - log.Trace("received AppResponse from peer", "nodeID", nodeID, "requestID", requestID) + log.Debug("received AppResponse from peer", "nodeID", nodeID, "requestID", requestID) handler, exists := n.markRequestFulfilled(requestID) if !exists { - log.Trace("forwarding AppResponse to SDK network", "nodeID", nodeID, "requestID", requestID, "responseLen", len(response)) - return n.network.AppResponse(ctx, nodeID, requestID, response) + log.Debug("forwarding AppResponse to SDK network", "nodeID", nodeID, "requestID", requestID, "responseLen", len(response)) + return n.p2pNetwork.AppResponse(ctx, nodeID, requestID, response) } // We must release the slot @@ -382,13 +383,13 @@ func (n *network) AppResponse(ctx context.Context, nodeID ids.NodeID, requestID // - request times out before a response is provided // error returned by this function is expected to be treated as fatal by the engine // returns error only when the response handler returns an error -func (n *network) AppRequestFailed(ctx context.Context, nodeID ids.NodeID, requestID uint32) error { - log.Trace("received AppRequestFailed from peer", "nodeID", nodeID, "requestID", requestID) +func (n *network) AppRequestFailed(ctx context.Context, nodeID ids.NodeID, requestID uint32, appErr *common.AppError) error { + log.Debug("received AppRequestFailed from peer", "nodeID", nodeID, "requestID", requestID) handler, exists := n.markRequestFulfilled(requestID) if !exists { - log.Trace("forwarding AppRequestFailed to SDK network", "nodeID", nodeID, "requestID", requestID) - return n.network.AppRequestFailed(ctx, nodeID, requestID) + log.Debug("forwarding AppRequestFailed to SDK network", "nodeID", nodeID, "requestID", requestID) + return n.p2pNetwork.AppRequestFailed(ctx, nodeID, requestID, appErr) } // We must release the slot @@ -445,22 +446,24 @@ func (n *network) Gossip(gossip []byte) error { return n.appSender.SendAppGossip(context.TODO(), gossip) } -// AppGossip is called by avalanchego -> VM when there is an incoming AppGossip from a peer -// error returned by this function is expected to be treated as fatal by the engine -// returns error if request could not be parsed as message.Request or when the requestHandler returns an error -func (n *network) AppGossip(_ context.Context, nodeID ids.NodeID, gossipBytes []byte) error { +// AppGossip is called by avalanchego -> VM when there is an incoming AppGossip +// from a peer. An error returned by this function is treated as fatal by the +// engine. +func (n *network) AppGossip(ctx context.Context, nodeID ids.NodeID, gossipBytes []byte) error { var gossipMsg message.GossipMessage if _, err := n.codec.Unmarshal(gossipBytes, &gossipMsg); err != nil { - log.Trace("could not parse app gossip", "nodeID", nodeID, "gossipLen", len(gossipBytes), "err", err) - return nil + log.Debug("forwarding AppGossip to SDK network", "nodeID", nodeID, "gossipLen", len(gossipBytes), "err", err) + return n.p2pNetwork.AppGossip(ctx, nodeID, gossipBytes) } - log.Trace("processing AppGossip from node", "nodeID", nodeID, "msg", gossipMsg) + log.Debug("processing AppGossip from node", "nodeID", nodeID, "msg", gossipMsg) return gossipMsg.Handle(n.gossipHandler, nodeID) } // Connected adds the given nodeID to the peer list so that it can receive messages func (n *network) Connected(ctx context.Context, nodeID ids.NodeID, nodeVersion *version.Application) error { + log.Debug("adding new peer", "nodeID", nodeID) + n.lock.Lock() defer n.lock.Unlock() @@ -469,15 +472,17 @@ func (n *network) Connected(ctx context.Context, nodeID ids.NodeID, nodeVersion } if nodeID == n.self { + log.Debug("skipping registering self as peer") return nil } n.peers.Connected(nodeID, nodeVersion) - return n.network.Connected(ctx, nodeID, nodeVersion) + return n.p2pNetwork.Connected(ctx, nodeID, nodeVersion) } // Disconnected removes given [nodeID] from the peer list func (n *network) Disconnected(ctx context.Context, nodeID ids.NodeID) error { + log.Debug("disconnecting peer", "nodeID", nodeID) n.lock.Lock() defer n.lock.Unlock() @@ -486,7 +491,7 @@ func (n *network) Disconnected(ctx context.Context, nodeID ids.NodeID) error { } n.peers.Disconnected(nodeID) - return n.network.Disconnected(ctx, nodeID) + return n.p2pNetwork.Disconnected(ctx, nodeID) } // Shutdown disconnects all peers @@ -539,8 +544,12 @@ func (n *network) TrackBandwidth(nodeID ids.NodeID, bandwidth float64) { n.peers.TrackBandwidth(nodeID, bandwidth) } -func (n *network) NewAppProtocol(protocol uint64, handler p2p.Handler, options ...p2p.ClientOption) (*p2p.Client, error) { - return n.network.NewAppProtocol(protocol, handler, options...) +func (n *network) NewClient(protocol uint64, options ...p2p.ClientOption) *p2p.Client { + return n.p2pNetwork.NewClient(protocol, options...) +} + +func (n *network) AddHandler(protocol uint64, handler p2p.Handler) error { + return n.p2pNetwork.AddHandler(protocol, handler) } // invariant: peer/network must use explicitly even request ids. diff --git a/peer/network_test.go b/peer/network_test.go index 260d54b492..e8d61fff1f 100644 --- a/peer/network_test.go +++ b/peer/network_test.go @@ -57,7 +57,9 @@ var ( func TestNetworkDoesNotConnectToItself(t *testing.T) { selfNodeID := ids.GenerateTestNodeID() - n := NewNetwork(p2p.NewNetwork(logging.NoLog{}, nil, prometheus.NewRegistry(), ""), nil, nil, nil, selfNodeID, 1, 1) + p2pNetwork, err := p2p.NewNetwork(logging.NoLog{}, nil, prometheus.NewRegistry(), "") + require.NoError(t, err) + n := NewNetwork(p2pNetwork, nil, nil, nil, selfNodeID, 1, 1) assert.NoError(t, n.Connected(context.Background(), selfNodeID, defaultPeerVersion)) assert.EqualValues(t, 0, n.Size()) } @@ -93,7 +95,9 @@ func TestRequestAnyRequestsRoutingAndResponse(t *testing.T) { codecManager := buildCodec(t, HelloRequest{}, HelloResponse{}) crossChainCodecManager := buildCodec(t, ExampleCrossChainRequest{}, ExampleCrossChainResponse{}) - net = NewNetwork(p2p.NewNetwork(logging.NoLog{}, nil, prometheus.NewRegistry(), ""), sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 16, 16) + p2pNetwork, err := p2p.NewNetwork(logging.NoLog{}, nil, prometheus.NewRegistry(), "") + require.NoError(t, err) + net = NewNetwork(p2pNetwork, sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 16, 16) net.SetRequestHandler(&HelloGreetingRequestHandler{codec: codecManager}) client := NewNetworkClient(net) nodeID := ids.GenerateTestNodeID() @@ -145,7 +149,9 @@ func TestAppRequestOnCtxCancellation(t *testing.T) { }, } - net := NewNetwork(p2p.NewNetwork(logging.NoLog{}, nil, prometheus.NewRegistry(), ""), sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 1) + p2pNetwork, err := p2p.NewNetwork(logging.NoLog{}, nil, prometheus.NewRegistry(), "") + require.NoError(t, err) + net := NewNetwork(p2pNetwork, sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 1) net.SetRequestHandler(&HelloGreetingRequestHandler{codec: codecManager}) requestMessage := HelloRequest{Message: "this is a request"} @@ -197,7 +203,9 @@ func TestRequestRequestsRoutingAndResponse(t *testing.T) { codecManager := buildCodec(t, HelloRequest{}, HelloResponse{}) crossChainCodecManager := buildCodec(t, ExampleCrossChainRequest{}, ExampleCrossChainResponse{}) - net = NewNetwork(p2p.NewNetwork(logging.NoLog{}, nil, prometheus.NewRegistry(), ""), sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 16, 16) + p2pNetwork, err := p2p.NewNetwork(logging.NoLog{}, nil, prometheus.NewRegistry(), "") + require.NoError(t, err) + net = NewNetwork(p2pNetwork, sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 16, 16) net.SetRequestHandler(&HelloGreetingRequestHandler{codec: codecManager}) client := NewNetworkClient(net) @@ -251,7 +259,7 @@ func TestRequestRequestsRoutingAndResponse(t *testing.T) { } // ensure empty nodeID is not allowed - _, err := client.SendAppRequest(context.Background(), ids.EmptyNodeID, []byte("hello there")) + _, err = client.SendAppRequest(context.Background(), ids.EmptyNodeID, []byte("hello there")) assert.Error(t, err) assert.Contains(t, err.Error(), "cannot send request to empty nodeID") } @@ -277,7 +285,9 @@ func TestAppRequestOnShutdown(t *testing.T) { codecManager := buildCodec(t, HelloRequest{}, HelloResponse{}) crossChainCodecManager := buildCodec(t, ExampleCrossChainRequest{}, ExampleCrossChainResponse{}) - net = NewNetwork(p2p.NewNetwork(logging.NoLog{}, nil, prometheus.NewRegistry(), ""), sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 1) + p2pNetwork, err := p2p.NewNetwork(logging.NoLog{}, nil, prometheus.NewRegistry(), "") + require.NoError(t, err) + net = NewNetwork(p2pNetwork, sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 1) client := NewNetworkClient(net) nodeID := ids.GenerateTestNodeID() require.NoError(t, net.Connected(context.Background(), nodeID, defaultPeerVersion)) @@ -326,7 +336,9 @@ func TestAppRequestAnyOnCtxCancellation(t *testing.T) { }, } - net := NewNetwork(p2p.NewNetwork(logging.NoLog{}, nil, prometheus.NewRegistry(), ""), sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 1) + p2pNetwork, err := p2p.NewNetwork(logging.NoLog{}, nil, prometheus.NewRegistry(), "") + require.NoError(t, err) + net := NewNetwork(p2pNetwork, sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 1) net.SetRequestHandler(&HelloGreetingRequestHandler{codec: codecManager}) assert.NoError(t, net.Connected( @@ -379,6 +391,7 @@ func TestRequestMinVersion(t *testing.T) { callNum := uint32(0) nodeID := ids.GenerateTestNodeID() codecManager := buildCodec(t, TestMessage{}) + crossChainCodecManager := buildCodec(t, ExampleCrossChainRequest{}, ExampleCrossChainResponse{}) var net Network sender := testAppSender{ @@ -402,8 +415,9 @@ func TestRequestMinVersion(t *testing.T) { } // passing nil as codec works because the net.AppRequest is never called - crossChainCodecManager := buildCodec(t, ExampleCrossChainRequest{}, ExampleCrossChainResponse{}) - net = NewNetwork(p2p.NewNetwork(logging.NoLog{}, nil, prometheus.NewRegistry(), ""), sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 16) + p2pNetwork, err := p2p.NewNetwork(logging.NoLog{}, nil, prometheus.NewRegistry(), "") + require.NoError(t, err) + net = NewNetwork(p2pNetwork, sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 16) client := NewNetworkClient(net) requestMessage := TestMessage{Message: "this is a request"} requestBytes, err := message.RequestToBytes(codecManager, requestMessage) @@ -413,6 +427,7 @@ func TestRequestMinVersion(t *testing.T) { context.Background(), nodeID, &version.Application{ + Name: version.Client, Major: 1, Minor: 7, Patch: 1, @@ -424,13 +439,14 @@ func TestRequestMinVersion(t *testing.T) { responseBytes, _, err := client.SendAppRequestAny( context.Background(), &version.Application{ + Name: version.Client, Major: 2, Minor: 0, Patch: 0, }, requestBytes, ) - assert.Equal(t, err.Error(), "no peers found matching version avalanche/2.0.0 out of 1 peers") + assert.Equal(t, err.Error(), "no peers found matching version avalanchego/2.0.0 out of 1 peers") assert.Nil(t, responseBytes) // ensure version matches and the request goes through @@ -467,7 +483,9 @@ func TestOnRequestHonoursDeadline(t *testing.T) { processingDuration: 500 * time.Millisecond, } - net = NewNetwork(p2p.NewNetwork(logging.NoLog{}, nil, prometheus.NewRegistry(), ""), sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 1) + p2pNetwork, err := p2p.NewNetwork(logging.NoLog{}, nil, prometheus.NewRegistry(), "") + require.NoError(t, err) + net = NewNetwork(p2pNetwork, sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 1) net.SetRequestHandler(requestHandler) nodeID := ids.GenerateTestNodeID() @@ -507,7 +525,9 @@ func TestGossip(t *testing.T) { } gossipHandler := &testGossipHandler{} - clientNetwork = NewNetwork(p2p.NewNetwork(logging.NoLog{}, nil, prometheus.NewRegistry(), ""), sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 1) + p2pNetwork, err := p2p.NewNetwork(logging.NoLog{}, nil, prometheus.NewRegistry(), "") + require.NoError(t, err) + clientNetwork = NewNetwork(p2pNetwork, sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 1) clientNetwork.SetGossipHandler(gossipHandler) assert.NoError(t, clientNetwork.Connected(context.Background(), nodeID, defaultPeerVersion)) @@ -534,7 +554,9 @@ func TestHandleInvalidMessages(t *testing.T) { requestID := uint32(1) sender := testAppSender{} - clientNetwork := NewNetwork(p2p.NewNetwork(logging.NoLog{}, nil, prometheus.NewRegistry(), ""), sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 1) + p2pNetwork, err := p2p.NewNetwork(logging.NoLog{}, nil, prometheus.NewRegistry(), "") + require.NoError(t, err) + clientNetwork := NewNetwork(p2pNetwork, sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 1) clientNetwork.SetGossipHandler(message.NoopMempoolGossipHandler{}) clientNetwork.SetRequestHandler(&testRequestHandler{}) @@ -583,7 +605,9 @@ func TestNetworkPropagatesRequestHandlerError(t *testing.T) { requestID := uint32(1) sender := testAppSender{} - clientNetwork := NewNetwork(p2p.NewNetwork(logging.NoLog{}, nil, prometheus.NewRegistry(), ""), sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 1) + p2pNetwork, err := p2p.NewNetwork(logging.NoLog{}, nil, prometheus.NewRegistry(), "") + require.NoError(t, err) + clientNetwork := NewNetwork(p2pNetwork, sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 1) clientNetwork.SetGossipHandler(message.NoopMempoolGossipHandler{}) clientNetwork.SetRequestHandler(&testRequestHandler{err: errors.New("fail")}) // Return an error from the request handler @@ -623,7 +647,9 @@ func TestCrossChainAppRequest(t *testing.T) { }, } - net = NewNetwork(p2p.NewNetwork(logging.NoLog{}, nil, prometheus.NewRegistry(), ""), sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 1) + p2pNetwork, err := p2p.NewNetwork(logging.NoLog{}, nil, prometheus.NewRegistry(), "") + require.NoError(t, err) + net = NewNetwork(p2pNetwork, sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 1) net.SetCrossChainRequestHandler(&testCrossChainHandler{codec: crossChainCodecManager}) client := NewNetworkClient(net) @@ -658,7 +684,9 @@ func TestCrossChainAppRequestOnCtxCancellation(t *testing.T) { }, } - net := NewNetwork(p2p.NewNetwork(logging.NoLog{}, nil, prometheus.NewRegistry(), ""), sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 1) + p2pNetwork, err := p2p.NewNetwork(logging.NoLog{}, nil, prometheus.NewRegistry(), "") + require.NoError(t, err) + net := NewNetwork(p2pNetwork, sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 1) net.SetCrossChainRequestHandler(&testCrossChainHandler{codec: crossChainCodecManager}) exampleCrossChainRequest := ExampleCrossChainRequest{ @@ -710,7 +738,9 @@ func TestCrossChainRequestRequestsRoutingAndResponse(t *testing.T) { codecManager := buildCodec(t, TestMessage{}) crossChainCodecManager := buildCodec(t, ExampleCrossChainRequest{}, ExampleCrossChainResponse{}) - net = NewNetwork(p2p.NewNetwork(logging.NoLog{}, nil, prometheus.NewRegistry(), ""), sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 1) + p2pNetwork, err := p2p.NewNetwork(logging.NoLog{}, nil, prometheus.NewRegistry(), "") + require.NoError(t, err) + net = NewNetwork(p2pNetwork, sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 1) net.SetCrossChainRequestHandler(&testCrossChainHandler{codec: crossChainCodecManager}) client := NewNetworkClient(net) @@ -770,7 +800,9 @@ func TestCrossChainRequestOnShutdown(t *testing.T) { } codecManager := buildCodec(t, TestMessage{}) crossChainCodecManager := buildCodec(t, ExampleCrossChainRequest{}, ExampleCrossChainResponse{}) - net = NewNetwork(p2p.NewNetwork(logging.NoLog{}, nil, prometheus.NewRegistry(), ""), sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 1) + p2pNetwork, err := p2p.NewNetwork(logging.NoLog{}, nil, prometheus.NewRegistry(), "") + require.NoError(t, err) + net = NewNetwork(p2pNetwork, sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 1) client := NewNetworkClient(net) exampleCrossChainRequest := ExampleCrossChainRequest{ @@ -823,9 +855,9 @@ func TestNetworkRouting(t *testing.T) { } protocol := 0 handler := &testSDKHandler{} - p2pNetwork := p2p.NewNetwork(logging.NoLog{}, sender, prometheus.NewRegistry(), "") - _, err := p2pNetwork.NewAppProtocol(uint64(protocol), handler) + p2pNetwork, err := p2p.NewNetwork(logging.NoLog{}, sender, prometheus.NewRegistry(), "") require.NoError(err) + require.NoError(p2pNetwork.AddHandler(uint64(protocol), handler)) networkCodec := codec.NewManager(0) crossChainCodec := codec.NewManager(0) @@ -849,7 +881,7 @@ func TestNetworkRouting(t *testing.T) { err = network.AppResponse(context.Background(), ids.GenerateTestNodeID(), 0, foobar) require.ErrorIs(err, p2p.ErrUnrequestedResponse) - err = network.AppRequestFailed(context.Background(), nodeID, 0) + err = network.AppRequestFailed(context.Background(), nodeID, 0, common.ErrTimeout) require.ErrorIs(err, p2p.ErrUnrequestedResponse) } @@ -978,7 +1010,7 @@ type HelloGossip struct { } func (h HelloGossip) Handle(handler message.GossipHandler, nodeID ids.NodeID) error { - return handler.HandleTxs(nodeID, message.TxsGossip{}) + return handler.HandleEthTxs(nodeID, message.EthTxsGossip{}) } func (h HelloGossip) String() string { @@ -995,7 +1027,7 @@ type testGossipHandler struct { nodeID ids.NodeID } -func (t *testGossipHandler) HandleTxs(nodeID ids.NodeID, msg message.TxsGossip) error { +func (t *testGossipHandler) HandleEthTxs(nodeID ids.NodeID, msg message.EthTxsGossip) error { t.received = true t.nodeID = nodeID return nil diff --git a/plugin/evm/gossip.go b/plugin/evm/gossip.go new file mode 100644 index 0000000000..41cea7df1a --- /dev/null +++ b/plugin/evm/gossip.go @@ -0,0 +1,177 @@ +// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package evm + +import ( + "context" + "fmt" + "sync" + "time" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/logging" + "github.com/ethereum/go-ethereum/log" + + "github.com/ava-labs/avalanchego/network/p2p" + "github.com/ava-labs/avalanchego/network/p2p/gossip" + + "github.com/ava-labs/subnet-evm/core" + "github.com/ava-labs/subnet-evm/core/txpool" + "github.com/ava-labs/subnet-evm/core/types" +) + +var ( + _ p2p.Handler = (*txGossipHandler)(nil) + + _ gossip.Gossipable = (*GossipEthTx)(nil) + _ gossip.Marshaller[*GossipEthTx] = (*GossipEthTxMarshaller)(nil) + _ gossip.Set[*GossipEthTx] = (*GossipEthTxPool)(nil) +) + +func newTxGossipHandler[T gossip.Gossipable]( + log logging.Logger, + marshaller gossip.Marshaller[T], + mempool gossip.Set[T], + metrics gossip.Metrics, + maxMessageSize int, + throttlingPeriod time.Duration, + throttlingLimit int, + validators *p2p.Validators, +) txGossipHandler { + // push gossip messages can be handled from any peer + handler := gossip.NewHandler[T]( + log, + marshaller, + // Don't forward gossip to avoid double-forwarding + gossip.NoOpAccumulator[T]{}, + mempool, + metrics, + maxMessageSize, + ) + + // pull gossip requests are filtered by validators and are throttled + // to prevent spamming + validatorHandler := p2p.NewValidatorHandler( + p2p.NewThrottlerHandler( + handler, + p2p.NewSlidingWindowThrottler(throttlingPeriod, throttlingLimit), + log, + ), + validators, + log, + ) + + return txGossipHandler{ + appGossipHandler: handler, + appRequestHandler: validatorHandler, + } +} + +type txGossipHandler struct { + p2p.NoOpHandler + appGossipHandler p2p.Handler + appRequestHandler p2p.Handler +} + +func (t txGossipHandler) AppGossip(ctx context.Context, nodeID ids.NodeID, gossipBytes []byte) { + t.appGossipHandler.AppGossip(ctx, nodeID, gossipBytes) +} + +func NewGossipEthTxPool(mempool *txpool.TxPool) (*GossipEthTxPool, error) { + bloom, err := gossip.NewBloomFilter(txGossipBloomMaxItems, txGossipBloomFalsePositiveRate) + if err != nil { + return nil, fmt.Errorf("failed to initialize bloom filter: %w", err) + } + + return &GossipEthTxPool{ + mempool: mempool, + pendingTxs: make(chan core.NewTxsEvent), + bloom: bloom, + }, nil +} + +type GossipEthTxPool struct { + mempool *txpool.TxPool + pendingTxs chan core.NewTxsEvent + + bloom *gossip.BloomFilter + lock sync.RWMutex +} + +func (g *GossipEthTxPool) Subscribe(ctx context.Context) { + g.mempool.SubscribeNewTxsEvent(g.pendingTxs) + + for { + select { + case <-ctx.Done(): + log.Debug("shutting down subscription") + return + case pendingTxs := <-g.pendingTxs: + g.lock.Lock() + for _, pendingTx := range pendingTxs.Txs { + tx := &GossipEthTx{Tx: pendingTx} + g.bloom.Add(tx) + reset, err := gossip.ResetBloomFilterIfNeeded(g.bloom, txGossipMaxFalsePositiveRate) + if err != nil { + log.Error("failed to reset bloom filter", "err", err) + continue + } + + if reset { + log.Debug("resetting bloom filter", "reason", "reached max filled ratio") + + g.mempool.IteratePending(func(tx *types.Transaction) bool { + g.bloom.Add(&GossipEthTx{Tx: pendingTx}) + return true + }) + } + } + g.lock.Unlock() + } + } +} + +// Add enqueues the transaction to the mempool. Subscribe should be called +// to receive an event if tx is actually added to the mempool or not. +func (g *GossipEthTxPool) Add(tx *GossipEthTx) error { + return g.mempool.AddRemotes([]*types.Transaction{tx.Tx})[0] +} + +func (g *GossipEthTxPool) Iterate(f func(tx *GossipEthTx) bool) { + g.mempool.IteratePending(func(tx *types.Transaction) bool { + return f(&GossipEthTx{Tx: tx}) + }) +} + +func (g *GossipEthTxPool) GetFilter() ([]byte, []byte, error) { + g.lock.RLock() + defer g.lock.RUnlock() + + bloom, err := g.bloom.Bloom.MarshalBinary() + salt := g.bloom.Salt + + return bloom, salt[:], err +} + +type GossipEthTxMarshaller struct{} + +func (g GossipEthTxMarshaller) MarshalGossip(tx *GossipEthTx) ([]byte, error) { + return tx.Tx.MarshalBinary() +} + +func (g GossipEthTxMarshaller) UnmarshalGossip(bytes []byte) (*GossipEthTx, error) { + tx := &GossipEthTx{ + Tx: &types.Transaction{}, + } + + return tx, tx.Tx.UnmarshalBinary(bytes) +} + +type GossipEthTx struct { + Tx *types.Transaction +} + +func (tx *GossipEthTx) GossipID() ids.ID { + return ids.ID(tx.Tx.Hash()) +} diff --git a/plugin/evm/gossip_mempool.go b/plugin/evm/gossip_mempool.go deleted file mode 100644 index 49c649e2bd..0000000000 --- a/plugin/evm/gossip_mempool.go +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package evm - -import ( - "context" - "fmt" - "sync" - - "github.com/ava-labs/avalanchego/ids" - "github.com/ethereum/go-ethereum/log" - - "github.com/ava-labs/avalanchego/network/p2p/gossip" - - "github.com/ava-labs/subnet-evm/core" - "github.com/ava-labs/subnet-evm/core/txpool" - "github.com/ava-labs/subnet-evm/core/types" -) - -var ( - _ gossip.Gossipable = (*GossipTx)(nil) - _ gossip.Set[*GossipTx] = (*GossipTxPool)(nil) -) - -func NewGossipTxPool(mempool *txpool.TxPool) (*GossipTxPool, error) { - bloom, err := gossip.NewBloomFilter(txGossipBloomMaxItems, txGossipBloomFalsePositiveRate) - if err != nil { - return nil, fmt.Errorf("failed to initialize bloom filter: %w", err) - } - - return &GossipTxPool{ - mempool: mempool, - pendingTxs: make(chan core.NewTxsEvent), - bloom: bloom, - }, nil -} - -type GossipTxPool struct { - mempool *txpool.TxPool - pendingTxs chan core.NewTxsEvent - - bloom *gossip.BloomFilter - lock sync.RWMutex -} - -func (g *GossipTxPool) Subscribe(ctx context.Context) { - g.mempool.SubscribeNewTxsEvent(g.pendingTxs) - - for { - select { - case <-ctx.Done(): - log.Debug("shutting down subscription") - return - case pendingTxs := <-g.pendingTxs: - g.lock.Lock() - for _, pendingTx := range pendingTxs.Txs { - tx := &GossipTx{Tx: pendingTx} - g.bloom.Add(tx) - reset, err := gossip.ResetBloomFilterIfNeeded(g.bloom, txGossipMaxFalsePositiveRate) - if err != nil { - log.Error("failed to reset bloom filter", "err", err) - continue - } - - if reset { - log.Debug("resetting bloom filter", "reason", "reached max filled ratio") - - g.mempool.IteratePending(func(tx *types.Transaction) bool { - g.bloom.Add(&GossipTx{Tx: pendingTx}) - return true - }) - } - } - g.lock.Unlock() - } - } -} - -// Add enqueues the transaction to the mempool. Subscribe should be called -// to receive an event if tx is actually added to the mempool or not. -func (g *GossipTxPool) Add(tx *GossipTx) error { - return g.mempool.AddRemotes([]*types.Transaction{tx.Tx})[0] -} - -func (g *GossipTxPool) Iterate(f func(tx *GossipTx) bool) { - g.mempool.IteratePending(func(tx *types.Transaction) bool { - return f(&GossipTx{Tx: tx}) - }) -} - -func (g *GossipTxPool) GetFilter() ([]byte, []byte, error) { - g.lock.RLock() - defer g.lock.RUnlock() - - bloom, err := g.bloom.Bloom.MarshalBinary() - salt := g.bloom.Salt - - return bloom, salt[:], err -} - -type GossipTx struct { - Tx *types.Transaction -} - -func (tx *GossipTx) GetID() ids.ID { - return ids.ID(tx.Tx.Hash()) -} - -func (tx *GossipTx) Marshal() ([]byte, error) { - return tx.Tx.MarshalBinary() -} - -func (tx *GossipTx) Unmarshal(bytes []byte) error { - tx.Tx = &types.Transaction{} - return tx.Tx.UnmarshalBinary(bytes) -} diff --git a/plugin/evm/gossip_test.go b/plugin/evm/gossip_test.go new file mode 100644 index 0000000000..153507c19b --- /dev/null +++ b/plugin/evm/gossip_test.go @@ -0,0 +1,26 @@ +// (c) 2019-2021, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package evm + +import ( + "testing" + + "github.com/ava-labs/subnet-evm/core/types" + "github.com/stretchr/testify/require" +) + +func TestGossipEthTxMarshaller(t *testing.T) { + require := require.New(t) + + blobTx := &types.BlobTx{} + want := &GossipEthTx{Tx: types.NewTx(blobTx)} + marshaller := GossipEthTxMarshaller{} + + bytes, err := marshaller.MarshalGossip(want) + require.NoError(err) + + got, err := marshaller.UnmarshalGossip(bytes) + require.NoError(err) + require.Equal(want.GossipID(), got.GossipID()) +} diff --git a/plugin/evm/gossiper.go b/plugin/evm/gossiper.go index 8f179d0ce5..578ed1d3ad 100644 --- a/plugin/evm/gossiper.go +++ b/plugin/evm/gossiper.go @@ -4,11 +4,13 @@ package evm import ( + "context" "math/big" "sync" "time" "github.com/ava-labs/avalanchego/codec" + "github.com/ava-labs/avalanchego/network/p2p/gossip" "github.com/ava-labs/subnet-evm/peer" @@ -32,9 +34,9 @@ const ( // in the cache, not entire transactions. recentCacheSize = 512 - // [txsGossipInterval] is how often we attempt to gossip newly seen + // [ethTxsGossipInterval] is how often we attempt to gossip newly seen // transactions to other nodes. - txsGossipInterval = 500 * time.Millisecond + ethTxsGossipInterval = 500 * time.Millisecond // [minGossipBatchInterval] is the minimum amount of time that must pass // before our last gossip to peers. @@ -43,8 +45,8 @@ const ( // Gossiper handles outgoing gossip of transactions type Gossiper interface { - // GossipTxs sends AppGossip message containing the given [txs] - GossipTxs(txs []*types.Transaction) error + // GossipEthTxs sends AppGossip message containing the given [txs] + GossipEthTxs(txs []*types.Transaction) error } // pushGossiper is used to gossip transactions to the network @@ -52,21 +54,22 @@ type pushGossiper struct { ctx *snow.Context config Config - client peer.NetworkClient - blockchain *core.BlockChain - txPool *txpool.TxPool + client peer.NetworkClient + blockchain *core.BlockChain + txPool *txpool.TxPool + ethTxGossiper gossip.Accumulator[*GossipEthTx] // We attempt to batch transactions we need to gossip to avoid runaway // amplification of mempol chatter. - txsToGossipChan chan []*types.Transaction - txsToGossip map[common.Hash]*types.Transaction - lastGossiped time.Time - shutdownChan chan struct{} - shutdownWg *sync.WaitGroup + ethTxsToGossipChan chan []*types.Transaction + ethTxsToGossip map[common.Hash]*types.Transaction + lastGossiped time.Time + shutdownChan chan struct{} + shutdownWg *sync.WaitGroup // [recentTxs] prevent us from over-gossiping the // same transaction in a short period of time. - recentTxs *cache.LRU[common.Hash, interface{}] + recentEthTxs *cache.LRU[common.Hash, interface{}] codec codec.Manager signer types.Signer @@ -75,22 +78,25 @@ type pushGossiper struct { // createGossiper constructs and returns a pushGossiper or noopGossiper // based on whether vm.chainConfig.SubnetEVMTimestamp is set -func (vm *VM) createGossiper(stats GossipStats) Gossiper { +func (vm *VM) createGossiper(stats GossipStats, ethTxGossiper gossip.Accumulator[*GossipEthTx], +) Gossiper { net := &pushGossiper{ - ctx: vm.ctx, - config: vm.config, - client: vm.client, - blockchain: vm.blockChain, - txPool: vm.txPool, - txsToGossipChan: make(chan []*types.Transaction), - txsToGossip: make(map[common.Hash]*types.Transaction), - shutdownChan: vm.shutdownChan, - shutdownWg: &vm.shutdownWg, - recentTxs: &cache.LRU[common.Hash, interface{}]{Size: recentCacheSize}, - codec: vm.networkCodec, - signer: types.LatestSigner(vm.blockChain.Config()), - stats: stats, + ctx: vm.ctx, + config: vm.config, + client: vm.client, + blockchain: vm.blockChain, + txPool: vm.txPool, + ethTxsToGossipChan: make(chan []*types.Transaction), + ethTxsToGossip: make(map[common.Hash]*types.Transaction), + shutdownChan: vm.shutdownChan, + shutdownWg: &vm.shutdownWg, + recentEthTxs: &cache.LRU[common.Hash, interface{}]{Size: recentCacheSize}, + codec: vm.networkCodec, + signer: types.LatestSigner(vm.blockChain.Config()), + stats: stats, + ethTxGossiper: ethTxGossiper, } + net.awaitEthTxGossip() return net } @@ -231,12 +237,12 @@ func (n *pushGossiper) queuePriorityRegossipTxs() types.Transactions { } // awaitEthTxGossip periodically gossips transactions that have been queued for -// gossip at least once every [txsGossipInterval]. +// gossip at least once every [ethTxsGossipInterval]. func (n *pushGossiper) awaitEthTxGossip() { n.shutdownWg.Add(1) go n.ctx.Log.RecoverAndPanic(func() { var ( - gossipTicker = time.NewTicker(txsGossipInterval) + gossipTicker = time.NewTicker(ethTxsGossipInterval) regossipTicker = time.NewTicker(n.config.RegossipFrequency.Duration) priorityRegossipTicker = time.NewTicker(n.config.PriorityRegossipFrequency.Duration) ) @@ -250,18 +256,24 @@ func (n *pushGossiper) awaitEthTxGossip() { for { select { case <-gossipTicker.C: - if attempted, err := n.gossipTxs(false); err != nil { + if attempted, err := n.gossipEthTxs(false); err != nil { log.Warn( "failed to send eth transactions", "len(txs)", attempted, "err", err, ) } + if err := n.ethTxGossiper.Gossip(context.TODO()); err != nil { + log.Warn( + "failed to send eth transactions", + "err", err, + ) + } case <-regossipTicker.C: for _, tx := range n.queueRegossipTxs() { - n.txsToGossip[tx.Hash()] = tx + n.ethTxsToGossip[tx.Hash()] = tx } - if attempted, err := n.gossipTxs(true); err != nil { + if attempted, err := n.gossipEthTxs(true); err != nil { log.Warn( "failed to regossip eth transactions", "len(txs)", attempted, @@ -270,26 +282,41 @@ func (n *pushGossiper) awaitEthTxGossip() { } case <-priorityRegossipTicker.C: for _, tx := range n.queuePriorityRegossipTxs() { - n.txsToGossip[tx.Hash()] = tx + n.ethTxsToGossip[tx.Hash()] = tx } - if attempted, err := n.gossipTxs(true); err != nil { + if attempted, err := n.gossipEthTxs(true); err != nil { log.Warn( "failed to regossip priority eth transactions", "len(txs)", attempted, "err", err, ) } - case txs := <-n.txsToGossipChan: + case txs := <-n.ethTxsToGossipChan: for _, tx := range txs { - n.txsToGossip[tx.Hash()] = tx + n.ethTxsToGossip[tx.Hash()] = tx } - if attempted, err := n.gossipTxs(false); err != nil { + if attempted, err := n.gossipEthTxs(false); err != nil { log.Warn( "failed to send eth transactions", "len(txs)", attempted, "err", err, ) } + + gossipTxs := make([]*GossipEthTx, 0, len(txs)) + for _, tx := range txs { + gossipTxs = append(gossipTxs, &GossipEthTx{Tx: tx}) + } + + n.ethTxGossiper.Add(gossipTxs...) + if err := n.ethTxGossiper.Gossip(context.TODO()); err != nil { + log.Warn( + "failed to send eth transactions", + "len(txs)", len(txs), + "err", err, + ) + } + case <-n.shutdownChan: return } @@ -297,7 +324,7 @@ func (n *pushGossiper) awaitEthTxGossip() { }) } -func (n *pushGossiper) sendTxs(txs []*types.Transaction) error { +func (n *pushGossiper) sendEthTxs(txs []*types.Transaction) error { if len(txs) == 0 { return nil } @@ -306,7 +333,7 @@ func (n *pushGossiper) sendTxs(txs []*types.Transaction) error { if err != nil { return err } - msg := message.TxsGossip{ + msg := message.EthTxsGossip{ Txs: txBytes, } msgBytes, err := message.BuildGossipMessage(n.codec, msg) @@ -323,15 +350,15 @@ func (n *pushGossiper) sendTxs(txs []*types.Transaction) error { return n.client.Gossip(msgBytes) } -func (n *pushGossiper) gossipTxs(force bool) (int, error) { - if (!force && time.Since(n.lastGossiped) < minGossipBatchInterval) || len(n.txsToGossip) == 0 { +func (n *pushGossiper) gossipEthTxs(force bool) (int, error) { + if (!force && time.Since(n.lastGossiped) < minGossipBatchInterval) || len(n.ethTxsToGossip) == 0 { return 0, nil } n.lastGossiped = time.Now() - txs := make([]*types.Transaction, 0, len(n.txsToGossip)) - for txHash, tx := range n.txsToGossip { + txs := make([]*types.Transaction, 0, len(n.ethTxsToGossip)) + for _, tx := range n.ethTxsToGossip { txs = append(txs, tx) - delete(n.txsToGossip, txHash) + delete(n.ethTxsToGossip, tx.Hash()) } selectedTxs := make([]*types.Transaction, 0) @@ -349,11 +376,11 @@ func (n *pushGossiper) gossipTxs(force bool) (int, error) { // We check [force] outside of the if statement to avoid an unnecessary // cache lookup. if !force { - if _, has := n.recentTxs.Get(txHash); has { + if _, has := n.recentEthTxs.Get(txHash); has { continue } } - n.recentTxs.Put(txHash, nil) + n.recentEthTxs.Put(txHash, nil) selectedTxs = append(selectedTxs, tx) } @@ -367,8 +394,8 @@ func (n *pushGossiper) gossipTxs(force bool) (int, error) { msgTxsSize := uint64(0) for _, tx := range selectedTxs { size := tx.Size() - if msgTxsSize+size > message.TxMsgSoftCapSize { - if err := n.sendTxs(msgTxs); err != nil { + if msgTxsSize+size > message.EthMsgSoftCapSize { + if err := n.sendEthTxs(msgTxs); err != nil { return len(selectedTxs), err } msgTxs = msgTxs[:0] @@ -379,18 +406,18 @@ func (n *pushGossiper) gossipTxs(force bool) (int, error) { } // Send any remaining [msgTxs] - return len(selectedTxs), n.sendTxs(msgTxs) + return len(selectedTxs), n.sendEthTxs(msgTxs) } -// GossipTxs enqueues the provided [txs] for gossiping. At some point, the +// GossipEthTxs enqueues the provided [txs] for gossiping. At some point, the // [pushGossiper] will attempt to gossip the provided txs to other nodes // (usually right away if not under load). // // NOTE: We never return a non-nil error from this function but retain the // option to do so in case it becomes useful. -func (n *pushGossiper) GossipTxs(txs []*types.Transaction) error { +func (n *pushGossiper) GossipEthTxs(txs []*types.Transaction) error { select { - case n.txsToGossipChan <- txs: + case n.ethTxsToGossipChan <- txs: case <-n.shutdownChan: } return nil @@ -411,16 +438,16 @@ func NewGossipHandler(vm *VM, stats GossipReceivedStats) *GossipHandler { } } -func (h *GossipHandler) HandleTxs(nodeID ids.NodeID, msg message.TxsGossip) error { +func (h *GossipHandler) HandleEthTxs(nodeID ids.NodeID, msg message.EthTxsGossip) error { log.Trace( - "AppGossip called with TxsGossip", + "AppGossip called with EthTxsGossip", "peerID", nodeID, "size(txs)", len(msg.Txs), ) if len(msg.Txs) == 0 { log.Trace( - "AppGossip received empty TxsGossip Message", + "AppGossip received empty EthTxsGossip Message", "peerID", nodeID, ) return nil diff --git a/plugin/evm/gossipper_test.go b/plugin/evm/gossipper_test.go index c2978db73f..d18163f998 100644 --- a/plugin/evm/gossipper_test.go +++ b/plugin/evm/gossipper_test.go @@ -49,7 +49,7 @@ func fundAddressByGenesis(addrs []common.Address) (string, error) { return string(bytes), err } -func getValidTxs(key *ecdsa.PrivateKey, count int, gasPrice *big.Int) []*types.Transaction { +func getValidEthTxs(key *ecdsa.PrivateKey, count int, gasPrice *big.Int) []*types.Transaction { res := make([]*types.Transaction, count) to := common.Address{} @@ -73,10 +73,10 @@ func getValidTxs(key *ecdsa.PrivateKey, count int, gasPrice *big.Int) []*types.T } // show that locally issued eth txs are gossiped -// Note: channel through which subnet-evm mempool push txs to vm is injected here +// Note: channel through which coreth mempool push txs to vm is injected here // to ease up UT, which target only VM behaviors in response to subnet-evm mempool // signals -func TestMempoolTxsAddedTxsGossipedAfterActivation(t *testing.T) { +func TestMempoolEthTxsAddedTxsGossipedAfterActivation(t *testing.T) { if os.Getenv("RUN_FLAKY_TESTS") != "true" { t.Skip("FLAKY") } @@ -86,10 +86,11 @@ func TestMempoolTxsAddedTxsGossipedAfterActivation(t *testing.T) { assert.NoError(err) addr := crypto.PubkeyToAddress(key.PublicKey) - cfgJson, err := fundAddressByGenesis([]common.Address{addr}) + + genesisJSON, err := fundAddressByGenesis([]common.Address{addr}) assert.NoError(err) - _, vm, _, sender := GenesisVM(t, true, cfgJson, "", "") + _, vm, _, sender := GenesisVM(t, true, genesisJSON, "", "") defer func() { err := vm.Shutdown(context.Background()) assert.NoError(err) @@ -98,20 +99,19 @@ func TestMempoolTxsAddedTxsGossipedAfterActivation(t *testing.T) { vm.txPool.SetMinFee(common.Big0) // create eth txes - ethTxs := getValidTxs(key, 3, common.Big1) + ethTxs := getValidEthTxs(key, 3, common.Big1) var wg sync.WaitGroup - var wg2 sync.WaitGroup wg.Add(2) - wg2.Add(1) sender.CantSendAppGossip = false + signal1 := make(chan struct{}) seen := 0 sender.SendAppGossipF = func(_ context.Context, gossipedBytes []byte) error { if seen == 0 { notifyMsgIntf, err := message.ParseGossipMessage(vm.networkCodec, gossipedBytes) assert.NoError(err) - requestMsg, ok := notifyMsgIntf.(message.TxsGossip) + requestMsg, ok := notifyMsgIntf.(message.EthTxsGossip) assert.True(ok) assert.NotEmpty(requestMsg.Txs) @@ -123,12 +123,12 @@ func TestMempoolTxsAddedTxsGossipedAfterActivation(t *testing.T) { []common.Hash{txs[0].Hash(), txs[1].Hash()}, ) seen++ - wg2.Done() + close(signal1) } else if seen == 1 { notifyMsgIntf, err := message.ParseGossipMessage(vm.networkCodec, gossipedBytes) assert.NoError(err) - requestMsg, ok := notifyMsgIntf.(message.TxsGossip) + requestMsg, ok := notifyMsgIntf.(message.EthTxsGossip) assert.True(ok) assert.NotEmpty(requestMsg.Txs) @@ -152,19 +152,19 @@ func TestMempoolTxsAddedTxsGossipedAfterActivation(t *testing.T) { } // Gossip txs again (shouldn't gossip hashes) - attemptAwait(t, &wg2, 5*time.Second) // wait until reorg processed - assert.NoError(vm.gossiper.GossipTxs(ethTxs[:2])) + <-signal1 // wait until reorg processed + assert.NoError(vm.gossiper.GossipEthTxs(ethTxs[:2])) errs = vm.txPool.AddRemotesSync(ethTxs) assert.Contains(errs[0].Error(), "already known") assert.Contains(errs[1].Error(), "already known") - assert.NoError(errs[2], "failed adding subnet-evm tx to mempool") + assert.NoError(errs[2], "failed adding coreth tx to mempool") attemptAwait(t, &wg, 5*time.Second) } // show that locally issued eth txs are chunked correctly -func TestMempoolTxsAddedTxsGossipedAfterActivationChunking(t *testing.T) { +func TestMempoolEthTxsAddedTxsGossipedAfterActivationChunking(t *testing.T) { if os.Getenv("RUN_FLAKY_TESTS") != "true" { t.Skip("FLAKY") } @@ -175,10 +175,10 @@ func TestMempoolTxsAddedTxsGossipedAfterActivationChunking(t *testing.T) { addr := crypto.PubkeyToAddress(key.PublicKey) - cfgJson, err := fundAddressByGenesis([]common.Address{addr}) + genesisJSON, err := fundAddressByGenesis([]common.Address{addr}) assert.NoError(err) - _, vm, _, sender := GenesisVM(t, true, cfgJson, "", "") + _, vm, _, sender := GenesisVM(t, true, genesisJSON, "", "") defer func() { err := vm.Shutdown(context.Background()) assert.NoError(err) @@ -187,7 +187,7 @@ func TestMempoolTxsAddedTxsGossipedAfterActivationChunking(t *testing.T) { vm.txPool.SetMinFee(common.Big0) // create eth txes - txs := getValidTxs(key, 100, common.Big1) + ethTxs := getValidEthTxs(key, 100, common.Big1) var wg sync.WaitGroup wg.Add(2) @@ -197,7 +197,7 @@ func TestMempoolTxsAddedTxsGossipedAfterActivationChunking(t *testing.T) { notifyMsgIntf, err := message.ParseGossipMessage(vm.networkCodec, gossipedBytes) assert.NoError(err) - requestMsg, ok := notifyMsgIntf.(message.TxsGossip) + requestMsg, ok := notifyMsgIntf.(message.EthTxsGossip) assert.True(ok) assert.NotEmpty(requestMsg.Txs) @@ -211,14 +211,14 @@ func TestMempoolTxsAddedTxsGossipedAfterActivationChunking(t *testing.T) { } // Notify VM about eth txs - errs := vm.txPool.AddRemotesSync(txs) + errs := vm.txPool.AddRemotesSync(ethTxs) for _, err := range errs { assert.NoError(err, "failed adding subnet-evm tx to mempool") } attemptAwait(t, &wg, 5*time.Second) - for _, tx := range txs { + for _, tx := range ethTxs { _, ok := seen[tx.Hash()] assert.True(ok, "missing hash: %v", tx.Hash()) } @@ -226,7 +226,7 @@ func TestMempoolTxsAddedTxsGossipedAfterActivationChunking(t *testing.T) { // show that a geth tx discovered from gossip is requested to the same node that // gossiped it -func TestMempoolTxsAppGossipHandling(t *testing.T) { +func TestMempoolEthTxsAppGossipHandling(t *testing.T) { if os.Getenv("RUN_FLAKY_TESTS") != "true" { t.Skip("FLAKY") } @@ -237,10 +237,10 @@ func TestMempoolTxsAppGossipHandling(t *testing.T) { addr := crypto.PubkeyToAddress(key.PublicKey) - cfgJson, err := fundAddressByGenesis([]common.Address{addr}) + genesisJSON, err := fundAddressByGenesis([]common.Address{addr}) assert.NoError(err) - _, vm, _, sender := GenesisVM(t, true, cfgJson, "", "") + _, vm, _, sender := GenesisVM(t, true, genesisJSON, "", "") defer func() { err := vm.Shutdown(context.Background()) assert.NoError(err) @@ -264,12 +264,12 @@ func TestMempoolTxsAppGossipHandling(t *testing.T) { } // prepare a tx - tx := getValidTxs(key, 1, common.Big1)[0] + tx := getValidEthTxs(key, 1, common.Big1)[0] // show that unknown subnet-evm hashes is requested txBytes, err := rlp.EncodeToBytes([]*types.Transaction{tx}) assert.NoError(err) - msg := message.TxsGossip{ + msg := message.EthTxsGossip{ Txs: txBytes, } msgBytes, err := message.BuildGossipMessage(vm.networkCodec, msg) @@ -284,7 +284,7 @@ func TestMempoolTxsAppGossipHandling(t *testing.T) { attemptAwait(t, &wg, 5*time.Second) } -func TestMempoolTxsRegossipSingleAccount(t *testing.T) { +func TestMempoolEthTxsRegossipSingleAccount(t *testing.T) { assert := assert.New(t) key, err := crypto.GenerateKey() @@ -304,10 +304,10 @@ func TestMempoolTxsRegossipSingleAccount(t *testing.T) { vm.txPool.SetMinFee(common.Big0) // create eth txes - txs := getValidTxs(key, 10, big.NewInt(226*params.GWei)) + ethTxs := getValidEthTxs(key, 10, big.NewInt(226*params.GWei)) // Notify VM about eth txs - errs := vm.txPool.AddRemotesSync(txs) + errs := vm.txPool.AddRemotesSync(ethTxs) for _, err := range errs { assert.NoError(err, "failed adding subnet-evm tx to remote mempool") } @@ -317,10 +317,10 @@ func TestMempoolTxsRegossipSingleAccount(t *testing.T) { pushNetwork := vm.gossiper.(*pushGossiper) queued := pushNetwork.queueRegossipTxs() assert.Len(queued, 1, "unexpected length of queued txs") - assert.Equal(txs[0].Hash(), queued[0].Hash()) + assert.Equal(ethTxs[0].Hash(), queued[0].Hash()) } -func TestMempoolTxsRegossip(t *testing.T) { +func TestMempoolEthTxsRegossip(t *testing.T) { assert := assert.New(t) keys := make([]*ecdsa.PrivateKey, 20) @@ -332,10 +332,10 @@ func TestMempoolTxsRegossip(t *testing.T) { addrs[i] = crypto.PubkeyToAddress(key.PublicKey) } - cfgJson, err := fundAddressByGenesis(addrs) + genesisJSON, err := fundAddressByGenesis(addrs) assert.NoError(err) - _, vm, _, _ := GenesisVM(t, true, cfgJson, `{"local-txs-enabled":true}`, "") + _, vm, _, _ := GenesisVM(t, true, genesisJSON, `{"local-txs-enabled":true}`, "") defer func() { err := vm.Shutdown(context.Background()) assert.NoError(err) @@ -347,7 +347,7 @@ func TestMempoolTxsRegossip(t *testing.T) { ethTxs := make([]*types.Transaction, 20) ethTxHashes := make([]common.Hash, 20) for i := 0; i < 20; i++ { - txs := getValidTxs(keys[i], 1, big.NewInt(226*params.GWei)) + txs := getValidEthTxs(keys[i], 1, big.NewInt(226*params.GWei)) tx := txs[0] ethTxs[i] = tx ethTxHashes[i] = tx.Hash() @@ -407,8 +407,8 @@ func TestMempoolTxsPriorityRegossip(t *testing.T) { vm.txPool.SetMinFee(common.Big0) // create eth txes - txs := getValidTxs(key, 10, big.NewInt(226*params.GWei)) - txs2 := getValidTxs(key2, 10, big.NewInt(226*params.GWei)) + txs := getValidEthTxs(key, 10, big.NewInt(226*params.GWei)) + txs2 := getValidEthTxs(key2, 10, big.NewInt(226*params.GWei)) // Notify VM about eth txs for _, err := range vm.txPool.AddRemotesSync(txs) { diff --git a/plugin/evm/syncervm_test.go b/plugin/evm/syncervm_test.go index a51b3e22e1..09c8155c6b 100644 --- a/plugin/evm/syncervm_test.go +++ b/plugin/evm/syncervm_test.go @@ -87,7 +87,7 @@ func TestStateSyncToggleEnabledToDisabled(t *testing.T) { reqCount++ // Fail all requests after number 50 to interrupt the sync if reqCount > 50 { - if err := syncerVM.AppRequestFailed(context.Background(), nodeID, requestID); err != nil { + if err := syncerVM.AppRequestFailed(context.Background(), nodeID, requestID, commonEng.ErrTimeout); err != nil { panic(err) } cancel := syncerVM.StateSyncClient.(*stateSyncerClient).cancel diff --git a/plugin/evm/tx_gossip_test.go b/plugin/evm/tx_gossip_test.go index b4815359a3..cf0df24779 100644 --- a/plugin/evm/tx_gossip_test.go +++ b/plugin/evm/tx_gossip_test.go @@ -5,20 +5,24 @@ package evm import ( "context" + "encoding/binary" "math/big" "sync" "testing" "time" + "github.com/ava-labs/avalanchego/database/memdb" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/network/p2p" "github.com/ava-labs/avalanchego/network/p2p/gossip" "github.com/ava-labs/avalanchego/proto/pb/sdk" + "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/snow/engine/common" "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/utils" "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/utils/set" + "github.com/ava-labs/coreth/params" "github.com/prometheus/client_golang/prometheus" "github.com/stretchr/testify/require" @@ -27,23 +31,57 @@ import ( "github.com/ava-labs/subnet-evm/core/types" ) -func TestTxGossip(t *testing.T) { +func TestEthTxGossip(t *testing.T) { require := require.New(t) + ctx := context.Background() + snowCtx := snow.DefaultContextTest() + validatorState := &validators.TestState{} + snowCtx.ValidatorState = validatorState + + responseSender := &common.FakeSender{ + SentAppResponse: make(chan []byte, 1), + } + vm := &VM{ + p2pSender: responseSender, + } + + require.NoError(vm.Initialize( + ctx, + snowCtx, + memdb.New(), + []byte(genesisJSONLatest), + nil, + nil, + make(chan common.Message), + nil, + &common.SenderTest{}, + )) + require.NoError(vm.SetState(ctx, snow.NormalOp)) - // set up prefunded address - _, vm, _, sender := GenesisVM(t, true, genesisJSONLatest, "", "") defer func() { - require.NoError(vm.Shutdown(context.Background())) + require.NoError(vm.Shutdown(ctx)) }() // sender for the peer requesting gossip from [vm] - peerSender := &common.SenderTest{} - router := p2p.NewNetwork(logging.NoLog{}, peerSender, prometheus.NewRegistry(), "") + peerSender := &common.FakeSender{ + SentAppRequest: make(chan []byte, 1), + } - // we're only making client requests, so we don't need a server handler - client, err := router.NewAppProtocol(txGossipProtocol, nil) + network, err := p2p.NewNetwork(logging.NoLog{}, peerSender, prometheus.NewRegistry(), "") require.NoError(err) + client := network.NewClient(ethTxGossipProtocol) + // we only accept gossip requests from validators + requestingNodeID := ids.GenerateTestNodeID() + require.NoError(vm.Network.Connected(ctx, requestingNodeID, nil)) + validatorState.GetCurrentHeightF = func(context.Context) (uint64, error) { + return 0, nil + } + validatorState.GetValidatorSetF = func(context.Context, uint64, ids.ID) (map[ids.NodeID]*validators.GetValidatorOutput, error) { + return map[ids.NodeID]*validators.GetValidatorOutput{requestingNodeID: nil}, nil + } + + // Ask the VM for any new transactions. We should get nothing at first. emptyBloomFilter, err := gossip.NewBloomFilter(txGossipBloomMaxItems, txGossipBloomFalsePositiveRate) require.NoError(err) emptyBloomFilterBytes, err := emptyBloomFilter.Bloom.MarshalBinary() @@ -57,34 +95,6 @@ func TestTxGossip(t *testing.T) { require.NoError(err) wg := &sync.WaitGroup{} - - requestingNodeID := ids.GenerateTestNodeID() - peerSender.SendAppRequestF = func(ctx context.Context, nodeIDs set.Set[ids.NodeID], requestID uint32, appRequestBytes []byte) error { - go func() { - require.NoError(vm.AppRequest(ctx, requestingNodeID, requestID, time.Time{}, appRequestBytes)) - }() - return nil - } - - sender.SendAppResponseF = func(ctx context.Context, nodeID ids.NodeID, requestID uint32, appResponseBytes []byte) error { - go func() { - require.NoError(router.AppResponse(ctx, nodeID, requestID, appResponseBytes)) - }() - return nil - } - - // we only accept gossip requests from validators - require.NoError(vm.Network.Connected(context.Background(), requestingNodeID, nil)) - mockValidatorSet, ok := vm.ctx.ValidatorState.(*validators.TestState) - require.True(ok) - mockValidatorSet.GetCurrentHeightF = func(context.Context) (uint64, error) { - return 0, nil - } - mockValidatorSet.GetValidatorSetF = func(context.Context, uint64, ids.ID) (map[ids.NodeID]*validators.GetValidatorOutput, error) { - return map[ids.NodeID]*validators.GetValidatorOutput{requestingNodeID: nil}, nil - } - - // Ask the VM for any new transactions. We should get nothing at first. wg.Add(1) onResponse := func(_ context.Context, nodeID ids.NodeID, responseBytes []byte, err error) { require.NoError(err) @@ -94,7 +104,9 @@ func TestTxGossip(t *testing.T) { require.Empty(response.Gossip) wg.Done() } - require.NoError(client.AppRequest(context.Background(), set.Set[ids.NodeID]{vm.ctx.NodeID: struct{}{}}, requestBytes, onResponse)) + require.NoError(client.AppRequest(ctx, set.Of(vm.ctx.NodeID), requestBytes, onResponse)) + require.NoError(vm.AppRequest(ctx, requestingNodeID, 1, time.Time{}, <-peerSender.SentAppRequest)) + require.NoError(network.AppResponse(ctx, snowCtx.NodeID, 1, <-responseSender.SentAppResponse)) wg.Wait() // Issue a tx to the VM @@ -111,6 +123,7 @@ func TestTxGossip(t *testing.T) { // wait so we aren't throttled by the vm time.Sleep(5 * time.Second) + marshaller := GossipEthTxMarshaller{} // Ask the VM for new transactions. We should get the newly issued tx. wg.Add(1) onResponse = func(_ context.Context, nodeID ids.NodeID, responseBytes []byte, err error) { @@ -120,12 +133,127 @@ func TestTxGossip(t *testing.T) { require.NoError(proto.Unmarshal(responseBytes, response)) require.Len(response.Gossip, 1) - gotTx := &GossipTx{} - require.NoError(gotTx.Unmarshal(response.Gossip[0])) + gotTx, err := marshaller.UnmarshalGossip(response.Gossip[0]) + require.NoError(err) require.Equal(signedTx.Hash(), gotTx.Tx.Hash()) wg.Done() } - require.NoError(client.AppRequest(context.Background(), set.Set[ids.NodeID]{vm.ctx.NodeID: struct{}{}}, requestBytes, onResponse)) + require.NoError(client.AppRequest(ctx, set.Of(vm.ctx.NodeID), requestBytes, onResponse)) + require.NoError(vm.AppRequest(ctx, requestingNodeID, 3, time.Time{}, <-peerSender.SentAppRequest)) + require.NoError(network.AppResponse(ctx, snowCtx.NodeID, 3, <-responseSender.SentAppResponse)) wg.Wait() } + +func TestEthTxPushGossipOutbound(t *testing.T) { + require := require.New(t) + ctx := context.Background() + snowCtx := snow.DefaultContextTest() + sender := &common.FakeSender{ + SentAppGossip: make(chan []byte, 1), + } + + vm := &VM{ + p2pSender: sender, + ethTxPullGossiper: gossip.NoOpGossiper{}, + } + + require.NoError(vm.Initialize( + ctx, + snowCtx, + memdb.New(), + []byte(genesisJSONLatest), + nil, + nil, + make(chan common.Message), + nil, + &common.FakeSender{}, + )) + require.NoError(vm.SetState(ctx, snow.NormalOp)) + + address := testEthAddrs[0] + key := testKeys[0] + tx := types.NewTransaction(0, address, big.NewInt(10), 100_000, big.NewInt(params.LaunchMinGasPrice), nil) + signedTx, err := types.SignTx(tx, types.NewEIP155Signer(vm.chainConfig.ChainID), key) + require.NoError(err) + + // issue a tx + require.NoError(vm.txPool.AddLocal(signedTx)) + + sent := <-sender.SentAppGossip + got := &sdk.PushGossip{} + + // we should get a message that has the protocol prefix and the gossip + // message + require.Equal(byte(ethTxGossipProtocol), sent[0]) + require.NoError(proto.Unmarshal(sent[1:], got)) + + marshaller := GossipEthTxMarshaller{} + require.Len(got.Gossip, 1) + gossipedTx, err := marshaller.UnmarshalGossip(got.Gossip[0]) + require.NoError(err) + require.Equal(ids.ID(signedTx.Hash()), gossipedTx.GossipID()) +} + +// Tests that a gossiped tx is added to the mempool and forwarded +func TestEthTxPushGossipInbound(t *testing.T) { + require := require.New(t) + ctx := context.Background() + snowCtx := snow.DefaultContextTest() + + sender := &common.FakeSender{ + SentAppGossip: make(chan []byte, 1), + } + vm := &VM{ + p2pSender: sender, + ethTxPullGossiper: gossip.NoOpGossiper{}, + } + + require.NoError(vm.Initialize( + ctx, + snowCtx, + memdb.New(), + []byte(genesisJSONLatest), + nil, + nil, + make(chan common.Message), + nil, + &common.FakeSender{}, + )) + require.NoError(vm.SetState(ctx, snow.NormalOp)) + + address := testEthAddrs[0] + key := testKeys[0] + tx := types.NewTransaction(0, address, big.NewInt(10), 100_000, big.NewInt(params.LaunchMinGasPrice), nil) + signedTx, err := types.SignTx(tx, types.NewEIP155Signer(vm.chainConfig.ChainID), key) + require.NoError(err) + + marshaller := GossipEthTxMarshaller{} + gossipedTx := &GossipEthTx{ + Tx: signedTx, + } + gossipedTxBytes, err := marshaller.MarshalGossip(gossipedTx) + require.NoError(err) + + inboundGossip := &sdk.PushGossip{ + Gossip: [][]byte{gossipedTxBytes}, + } + + inboundGossipBytes, err := proto.Marshal(inboundGossip) + require.NoError(err) + + inboundGossipMsg := append(binary.AppendUvarint(nil, ethTxGossipProtocol), inboundGossipBytes...) + require.NoError(vm.AppGossip(ctx, ids.EmptyNodeID, inboundGossipMsg)) + + forwardedMsg := &sdk.PushGossip{} + outboundGossipBytes := <-sender.SentAppGossip + + require.Equal(byte(ethTxGossipProtocol), outboundGossipBytes[0]) + require.NoError(proto.Unmarshal(outboundGossipBytes[1:], forwardedMsg)) + require.Len(forwardedMsg.Gossip, 1) + + forwardedTx, err := marshaller.UnmarshalGossip(forwardedMsg.Gossip[0]) + require.NoError(err) + require.Equal(gossipedTx.GossipID(), forwardedTx.GossipID()) + require.True(vm.txPool.Has(signedTx.Hash())) +} diff --git a/plugin/evm/vm.go b/plugin/evm/vm.go index cc8ba2cfb3..4abd15a008 100644 --- a/plugin/evm/vm.go +++ b/plugin/evm/vm.go @@ -103,35 +103,26 @@ const ( chainStateMetricsPrefix = "chain_state" // p2p app protocols - txGossipProtocol = 0x0 + ethTxGossipProtocol = 0x0 // gossip constants txGossipBloomMaxItems = 8 * 1024 txGossipBloomFalsePositiveRate = 0.01 txGossipMaxFalsePositiveRate = 0.05 - txGossipTargetResponseSize = 20 * units.KiB + txGossipTargetMessageSize = 20 * units.KiB maxValidatorSetStaleness = time.Minute - throttlingPeriod = 10 * time.Second - throttlingLimit = 2 + txGossipThrottlingPeriod = 10 * time.Second + txGossipThrottlingLimit = 2 gossipFrequency = 10 * time.Second -) - -var ( - txGossipConfig = gossip.Config{ - Namespace: "eth_tx_gossip", - PollSize: 10, - } - txGossipHandlerConfig = gossip.HandlerConfig{ - Namespace: "eth_tx_gossip", - TargetResponseSize: txGossipTargetResponseSize, - } + txGossipPollSize = 10 ) // Define the API endpoints for the VM const ( - adminEndpoint = "/admin" - ethRPCEndpoint = "/rpc" - ethWSEndpoint = "/ws" + adminEndpoint = "/admin" + ethRPCEndpoint = "/rpc" + ethWSEndpoint = "/ws" + ethTxGossipNamespace = "eth_tx_gossip" ) var ( @@ -248,6 +239,11 @@ type VM struct { // Avalanche Warp Messaging backend // Used to serve BLS signatures of warp messages over RPC warpBackend warp.Backend + // Initialize only sets these if nil so they can be overridden in tests + p2pSender commonEng.AppSender + ethTxGossipHandler p2p.Handler + ethTxPullGossiper gossip.Gossiper + ethTxPushGossiper gossip.Accumulator[*GossipEthTx] } // Initialize implements the snowman.ChainVM interface @@ -459,7 +455,14 @@ func (vm *VM) Initialize( } // initialize peer network - p2pNetwork := p2p.NewNetwork(vm.ctx.Log, appSender, vm.sdkMetrics, "p2p") + if vm.p2pSender == nil { + vm.p2pSender = appSender + } + + p2pNetwork, err := p2p.NewNetwork(vm.ctx.Log, vm.p2pSender, vm.sdkMetrics, "p2p") + if err != nil { + return fmt.Errorf("failed to initialize p2p network: %w", err) + } vm.validators = p2p.NewValidators(p2pNetwork.Peers, vm.ctx.Log, vm.ctx.SubnetID, vm.ctx.ValidatorState, maxValidatorSetStaleness) vm.networkCodec = message.Codec vm.Network = peer.NewNetwork(p2pNetwork, appSender, vm.networkCodec, message.CrossChainCodec, chainCtx.NodeID, vm.config.MaxOutboundActiveRequests, vm.config.MaxOutboundActiveCrossChainRequests) @@ -656,60 +659,78 @@ func (vm *VM) initBlockBuilding() error { ctx, cancel := context.WithCancel(context.TODO()) vm.cancel = cancel + ethTxGossipMarshaller := GossipEthTxMarshaller{} + + ethTxGossipClient := vm.Network.NewClient(ethTxGossipProtocol, p2p.WithValidatorSampling(vm.validators)) + + ethTxGossipMetrics, err := gossip.NewMetrics(vm.sdkMetrics, ethTxGossipNamespace) + if err != nil { + return fmt.Errorf("failed to initialize eth tx gossip metrics: %w", err) + } + + if vm.ethTxPushGossiper == nil { + vm.ethTxPushGossiper = gossip.NewPushGossiper[*GossipEthTx]( + ethTxGossipMarshaller, + ethTxGossipClient, + ethTxGossipMetrics, + txGossipTargetMessageSize, + ) + } + // NOTE: gossip network must be initialized first otherwise ETH tx gossip will not work. gossipStats := NewGossipStats() - vm.gossiper = vm.createGossiper(gossipStats) + vm.gossiper = vm.createGossiper(gossipStats, vm.ethTxPushGossiper) vm.builder = vm.NewBlockBuilder(vm.toEngine) vm.builder.awaitSubmittedTxs() vm.Network.SetGossipHandler(NewGossipHandler(vm, gossipStats)) - txPool, err := NewGossipTxPool(vm.txPool) + ethTxPool, err := NewGossipEthTxPool(vm.txPool) if err != nil { return err } vm.shutdownWg.Add(1) go func() { - txPool.Subscribe(ctx) + ethTxPool.Subscribe(ctx) vm.shutdownWg.Done() }() - var txGossipHandler p2p.Handler - - txGossipHandler, err = gossip.NewHandler[*GossipTx](txPool, txGossipHandlerConfig, vm.sdkMetrics) - if err != nil { - return err - } - txGossipHandler = &p2p.ValidatorHandler{ - ValidatorSet: vm.validators, - Handler: &p2p.ThrottlerHandler{ - Throttler: p2p.NewSlidingWindowThrottler(throttlingPeriod, throttlingLimit), - Handler: txGossipHandler, - }, - } - txGossipClient, err := vm.Network.NewAppProtocol(txGossipProtocol, txGossipHandler, p2p.WithValidatorSampling(vm.validators)) - if err != nil { - return err + if vm.ethTxGossipHandler == nil { + vm.ethTxGossipHandler = newTxGossipHandler[*GossipEthTx]( + vm.ctx.Log, + ethTxGossipMarshaller, + ethTxPool, + ethTxGossipMetrics, + txGossipTargetMessageSize, + txGossipThrottlingPeriod, + txGossipThrottlingLimit, + vm.validators, + ) } - var ethTxGossiper gossip.Gossiper - ethTxGossiper, err = gossip.NewPullGossiper[GossipTx, *GossipTx]( - txGossipConfig, - vm.ctx.Log, - txPool, - txGossipClient, - vm.sdkMetrics, - ) - if err != nil { + + if err := vm.Network.AddHandler(ethTxGossipProtocol, vm.ethTxGossipHandler); err != nil { return err } - txGossiper := gossip.ValidatorGossiper{ - Gossiper: ethTxGossiper, - NodeID: vm.ctx.NodeID, - Validators: vm.validators, + + if vm.ethTxPullGossiper == nil { + ethTxPullGossiper := gossip.NewPullGossiper[*GossipEthTx]( + vm.ctx.Log, + ethTxGossipMarshaller, + ethTxPool, + ethTxGossipClient, + ethTxGossipMetrics, + txGossipPollSize, + ) + + vm.ethTxPullGossiper = gossip.ValidatorGossiper{ + Gossiper: ethTxPullGossiper, + NodeID: vm.ctx.NodeID, + Validators: vm.validators, + } } vm.shutdownWg.Add(1) go func() { - gossip.Every(ctx, vm.ctx.Log, txGossiper, gossipFrequency) + gossip.Every(ctx, vm.ctx.Log, vm.ethTxPullGossiper, gossipFrequency) vm.shutdownWg.Done() }() diff --git a/scripts/versions.sh b/scripts/versions.sh index f9125a2baf..d7d978e229 100644 --- a/scripts/versions.sh +++ b/scripts/versions.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash # Don't export them as they're used in the context of other calls -AVALANCHE_VERSION=${AVALANCHE_VERSION:-'v1.10.17'} +AVALANCHE_VERSION=${AVALANCHE_VERSION:-'v1.10.18-rc.8'} GINKGO_VERSION=${GINKGO_VERSION:-'v2.2.0'} # This won't be used, but it's here to make code syncs easier diff --git a/sync/client/client.go b/sync/client/client.go index 5168aa8dda..001989f934 100644 --- a/sync/client/client.go +++ b/sync/client/client.go @@ -351,7 +351,7 @@ func (c *client) get(ctx context.Context, request message.Request, parseFn parse responseIntf, numElements, err = parseFn(c.codec, request, response) if err != nil { lastErr = err - log.Info("could not validate response, retrying", "nodeID", nodeID, "attempt", attempt, "request", request, "err", err) + log.Debug("could not validate response, retrying", "nodeID", nodeID, "attempt", attempt, "request", request, "err", err) c.networkClient.TrackBandwidth(nodeID, 0) metric.IncFailed() metric.IncInvalidResponse() diff --git a/x/warp/predicate_test.go b/x/warp/predicate_test.go index a760de29af..6cd5e02736 100644 --- a/x/warp/predicate_test.go +++ b/x/warp/predicate_test.go @@ -108,8 +108,8 @@ type testValidator struct { vdr *avalancheWarp.Validator } -func (v *testValidator) Less(o *testValidator) bool { - return v.vdr.Less(o.vdr) +func (v *testValidator) Compare(o *testValidator) int { + return v.vdr.Compare(o.vdr) } func newTestValidator() *testValidator { From 08f8bb0c86d2ac7f15523271523b33f7e6f479a0 Mon Sep 17 00:00:00 2001 From: Ceyhun Onur Date: Mon, 25 Dec 2023 14:25:34 +0300 Subject: [PATCH 03/26] fix tests --- plugin/evm/gossip.go | 9 +++++---- plugin/evm/tx_gossip_test.go | 13 +++++++------ 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/plugin/evm/gossip.go b/plugin/evm/gossip.go index 41cea7df1a..db8450bc8e 100644 --- a/plugin/evm/gossip.go +++ b/plugin/evm/gossip.go @@ -78,6 +78,10 @@ func (t txGossipHandler) AppGossip(ctx context.Context, nodeID ids.NodeID, gossi t.appGossipHandler.AppGossip(ctx, nodeID, gossipBytes) } +func (t txGossipHandler) AppRequest(ctx context.Context, nodeID ids.NodeID, deadline time.Time, requestBytes []byte) ([]byte, error) { + return t.appRequestHandler.AppRequest(ctx, nodeID, deadline, requestBytes) +} + func NewGossipEthTxPool(mempool *txpool.TxPool) (*GossipEthTxPool, error) { bloom, err := gossip.NewBloomFilter(txGossipBloomMaxItems, txGossipBloomFalsePositiveRate) if err != nil { @@ -148,10 +152,7 @@ func (g *GossipEthTxPool) GetFilter() ([]byte, []byte, error) { g.lock.RLock() defer g.lock.RUnlock() - bloom, err := g.bloom.Bloom.MarshalBinary() - salt := g.bloom.Salt - - return bloom, salt[:], err + return g.bloom.Marshal() } type GossipEthTxMarshaller struct{} diff --git a/plugin/evm/tx_gossip_test.go b/plugin/evm/tx_gossip_test.go index cf0df24779..3d1e713009 100644 --- a/plugin/evm/tx_gossip_test.go +++ b/plugin/evm/tx_gossip_test.go @@ -19,7 +19,7 @@ import ( "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/snow/engine/common" "github.com/ava-labs/avalanchego/snow/validators" - "github.com/ava-labs/avalanchego/utils" + agoUtils "github.com/ava-labs/avalanchego/utils" "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/coreth/params" @@ -29,12 +29,13 @@ import ( "google.golang.org/protobuf/proto" "github.com/ava-labs/subnet-evm/core/types" + "github.com/ava-labs/subnet-evm/utils" ) func TestEthTxGossip(t *testing.T) { require := require.New(t) ctx := context.Background() - snowCtx := snow.DefaultContextTest() + snowCtx := utils.TestSnowContext() validatorState := &validators.TestState{} snowCtx.ValidatorState = validatorState @@ -84,11 +85,11 @@ func TestEthTxGossip(t *testing.T) { // Ask the VM for any new transactions. We should get nothing at first. emptyBloomFilter, err := gossip.NewBloomFilter(txGossipBloomMaxItems, txGossipBloomFalsePositiveRate) require.NoError(err) - emptyBloomFilterBytes, err := emptyBloomFilter.Bloom.MarshalBinary() + emptyBloomFilterBytes, _, err := emptyBloomFilter.Marshal() require.NoError(err) request := &sdk.PullGossipRequest{ Filter: emptyBloomFilterBytes, - Salt: utils.RandomBytes(32), + Salt: agoUtils.RandomBytes(32), } requestBytes, err := proto.Marshal(request) @@ -148,7 +149,7 @@ func TestEthTxGossip(t *testing.T) { func TestEthTxPushGossipOutbound(t *testing.T) { require := require.New(t) ctx := context.Background() - snowCtx := snow.DefaultContextTest() + snowCtx := utils.TestSnowContext() sender := &common.FakeSender{ SentAppGossip: make(chan []byte, 1), } @@ -199,7 +200,7 @@ func TestEthTxPushGossipOutbound(t *testing.T) { func TestEthTxPushGossipInbound(t *testing.T) { require := require.New(t) ctx := context.Background() - snowCtx := snow.DefaultContextTest() + snowCtx := utils.TestSnowContext() sender := &common.FakeSender{ SentAppGossip: make(chan []byte, 1), From c49eba4ea9b93fa622598bfc8fb786f8e8185e97 Mon Sep 17 00:00:00 2001 From: Ceyhun Onur Date: Mon, 25 Dec 2023 14:40:48 +0300 Subject: [PATCH 04/26] fix imports --- go.mod | 2 +- plugin/evm/gossipper_test.go | 4 ++-- plugin/evm/tx_gossip_test.go | 5 ++--- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index db5a1f4daf..ea6d8c3ad5 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,6 @@ require ( github.com/VictoriaMetrics/fastcache v1.10.0 github.com/ava-labs/avalanche-network-runner v1.7.4-0.20231127162258-2f3ceed8ae4b github.com/ava-labs/avalanchego v1.10.18-rc.8 - github.com/ava-labs/coreth v0.12.9-rc.9.0.20231222191417-2e3f762373e9 github.com/cespare/cp v0.1.0 github.com/cockroachdb/pebble v0.0.0-20230209160836-829675f94811 github.com/davecgh/go-spew v1.1.1 @@ -58,6 +57,7 @@ require ( github.com/DataDog/zstd v1.5.2 // indirect github.com/Microsoft/go-winio v0.5.2 // indirect github.com/NYTimes/gziphandler v1.1.1 // indirect + github.com/ava-labs/coreth v0.12.9-rc.9.0.20231222191417-2e3f762373e9 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bits-and-blooms/bitset v1.7.0 // indirect github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect diff --git a/plugin/evm/gossipper_test.go b/plugin/evm/gossipper_test.go index d18163f998..bf7f91a165 100644 --- a/plugin/evm/gossipper_test.go +++ b/plugin/evm/gossipper_test.go @@ -73,7 +73,7 @@ func getValidEthTxs(key *ecdsa.PrivateKey, count int, gasPrice *big.Int) []*type } // show that locally issued eth txs are gossiped -// Note: channel through which coreth mempool push txs to vm is injected here +// Note: channel through which subnet-evm mempool push txs to vm is injected here // to ease up UT, which target only VM behaviors in response to subnet-evm mempool // signals func TestMempoolEthTxsAddedTxsGossipedAfterActivation(t *testing.T) { @@ -158,7 +158,7 @@ func TestMempoolEthTxsAddedTxsGossipedAfterActivation(t *testing.T) { errs = vm.txPool.AddRemotesSync(ethTxs) assert.Contains(errs[0].Error(), "already known") assert.Contains(errs[1].Error(), "already known") - assert.NoError(errs[2], "failed adding coreth tx to mempool") + assert.NoError(errs[2], "failed adding subnet-evm tx to mempool") attemptAwait(t, &wg, 5*time.Second) } diff --git a/plugin/evm/tx_gossip_test.go b/plugin/evm/tx_gossip_test.go index 3d1e713009..9044750ada 100644 --- a/plugin/evm/tx_gossip_test.go +++ b/plugin/evm/tx_gossip_test.go @@ -22,7 +22,6 @@ import ( agoUtils "github.com/ava-labs/avalanchego/utils" "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/utils/set" - "github.com/ava-labs/coreth/params" "github.com/prometheus/client_golang/prometheus" "github.com/stretchr/testify/require" @@ -174,7 +173,7 @@ func TestEthTxPushGossipOutbound(t *testing.T) { address := testEthAddrs[0] key := testKeys[0] - tx := types.NewTransaction(0, address, big.NewInt(10), 100_000, big.NewInt(params.LaunchMinGasPrice), nil) + tx := types.NewTransaction(0, address, big.NewInt(10), 21000, big.NewInt(testMinGasPrice), nil) signedTx, err := types.SignTx(tx, types.NewEIP155Signer(vm.chainConfig.ChainID), key) require.NoError(err) @@ -225,7 +224,7 @@ func TestEthTxPushGossipInbound(t *testing.T) { address := testEthAddrs[0] key := testKeys[0] - tx := types.NewTransaction(0, address, big.NewInt(10), 100_000, big.NewInt(params.LaunchMinGasPrice), nil) + tx := types.NewTransaction(0, address, big.NewInt(10), 21000, big.NewInt(testMinGasPrice), nil) signedTx, err := types.SignTx(tx, types.NewEIP155Signer(vm.chainConfig.ChainID), key) require.NoError(err) From e8c2bde5112355330f345bae74db2a295931b835 Mon Sep 17 00:00:00 2001 From: Ceyhun Onur Date: Mon, 25 Dec 2023 19:07:49 +0300 Subject: [PATCH 05/26] bump min go version --- .github/workflows/auto-generated-code-checker.yml | 2 +- .github/workflows/bench.yml | 2 +- .github/workflows/ci.yml | 8 ++++---- .github/workflows/release.yml | 2 +- Dockerfile | 2 +- README.md | 2 +- scripts/build.sh | 2 +- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/auto-generated-code-checker.yml b/.github/workflows/auto-generated-code-checker.yml index 39bd2c8434..a83c1f2990 100644 --- a/.github/workflows/auto-generated-code-checker.yml +++ b/.github/workflows/auto-generated-code-checker.yml @@ -16,7 +16,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-go@v3 with: - go-version: '~1.20.10' + go-version: '~1.20.12' check-latest: true - shell: bash run: scripts/mock.gen.sh diff --git a/.github/workflows/bench.yml b/.github/workflows/bench.yml index 12ce8eec47..500c9aaf7f 100644 --- a/.github/workflows/bench.yml +++ b/.github/workflows/bench.yml @@ -11,7 +11,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-go@v3 with: - go-version: '~1.20.10' + go-version: '~1.20.12' check-latest: true - run: go mod download shell: bash diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1f932cbcb2..c391433f68 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,12 +18,12 @@ jobs: shell: bash - uses: actions/setup-go@v3 with: - go-version: '~1.20.10' + go-version: '~1.20.12' check-latest: true - name: golangci-lint uses: golangci/golangci-lint-action@v3 with: - version: v1.54 + version: v1.55 working-directory: . args: --timeout 10m @@ -34,7 +34,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-go@v3 with: - go-version: '~1.20.10' + go-version: '~1.20.12' check-latest: true - run: go mod download shell: bash @@ -66,7 +66,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v3 with: - go-version: '~1.20.10' + go-version: '~1.20.12' check-latest: true - name: Use Node.js uses: actions/setup-node@v3 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index febc34fa75..285349835f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -19,7 +19,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v3 with: - go-version: '~1.20.10' + go-version: '~1.20.12' check-latest: true - name: Set up arm64 cross compiler run: | diff --git a/Dockerfile b/Dockerfile index 11784758dd..54e3274966 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,7 +5,7 @@ ARG AVALANCHE_VERSION # ============= Compilation Stage ================ -FROM golang:1.20.10-bullseye AS builder +FROM golang:1.20.12-bullseye AS builder WORKDIR /build diff --git a/README.md b/README.md index 193e209540..5f2fc45017 100644 --- a/README.md +++ b/README.md @@ -94,7 +94,7 @@ To support these changes, there have been a number of changes to the SubnetEVM b ### Clone Subnet-evm -First install Go 1.20.10 or later. Follow the instructions [here](https://go.dev/doc/install). You can verify by running `go version`. +First install Go 1.20.12 or later. Follow the instructions [here](https://go.dev/doc/install). You can verify by running `go version`. Set `$GOPATH` environment variable properly for Go to look for Go Workspaces. Please read [this](https://go.dev/doc/code) for details. You can verify by running `echo $GOPATH`. diff --git a/scripts/build.sh b/scripts/build.sh index c9b169bee9..a4941b99c4 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -4,7 +4,7 @@ set -o errexit set -o nounset set -o pipefail -go_version_minimum="1.20.10" +go_version_minimum="1.20.12" go_version() { go version | sed -nE -e 's/[^0-9.]+([0-9.]+).+/\1/p' From 0bf3ed332c595a4968851fc30251772f43bf67ef Mon Sep 17 00:00:00 2001 From: Ceyhun Onur Date: Mon, 25 Dec 2023 19:30:04 +0300 Subject: [PATCH 06/26] downgrade golangci --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c391433f68..637aaf012e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,7 +23,7 @@ jobs: - name: golangci-lint uses: golangci/golangci-lint-action@v3 with: - version: v1.55 + version: v1.54 working-directory: . args: --timeout 10m From 987b9aad49f30ab830095fd63fa32956fd4867a2 Mon Sep 17 00:00:00 2001 From: Ceyhun Onur Date: Wed, 27 Dec 2023 20:57:58 +0300 Subject: [PATCH 07/26] remove noop handler --- plugin/evm/gossip.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/plugin/evm/gossip.go b/plugin/evm/gossip.go index db8450bc8e..cee0461313 100644 --- a/plugin/evm/gossip.go +++ b/plugin/evm/gossip.go @@ -69,7 +69,6 @@ func newTxGossipHandler[T gossip.Gossipable]( } type txGossipHandler struct { - p2p.NoOpHandler appGossipHandler p2p.Handler appRequestHandler p2p.Handler } @@ -81,6 +80,9 @@ func (t txGossipHandler) AppGossip(ctx context.Context, nodeID ids.NodeID, gossi func (t txGossipHandler) AppRequest(ctx context.Context, nodeID ids.NodeID, deadline time.Time, requestBytes []byte) ([]byte, error) { return t.appRequestHandler.AppRequest(ctx, nodeID, deadline, requestBytes) } +func (t txGossipHandler) CrossChainAppRequest(context.Context, ids.ID, time.Time, []byte) ([]byte, error) { + return nil, nil +} func NewGossipEthTxPool(mempool *txpool.TxPool) (*GossipEthTxPool, error) { bloom, err := gossip.NewBloomFilter(txGossipBloomMaxItems, txGossipBloomFalsePositiveRate) From f7ac02e4d051ee63636b865af70b75ff6855198f Mon Sep 17 00:00:00 2001 From: Ceyhun Onur Date: Thu, 28 Dec 2023 19:36:37 +0300 Subject: [PATCH 08/26] bump avago rc --- go.mod | 4 ++-- go.sum | 8 ++++---- scripts/versions.sh | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/go.mod b/go.mod index ea6d8c3ad5..d5f62e5ec4 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.20 require ( github.com/VictoriaMetrics/fastcache v1.10.0 github.com/ava-labs/avalanche-network-runner v1.7.4-0.20231127162258-2f3ceed8ae4b - github.com/ava-labs/avalanchego v1.10.18-rc.8 + github.com/ava-labs/avalanchego v1.10.18-rc.9 github.com/cespare/cp v0.1.0 github.com/cockroachdb/pebble v0.0.0-20230209160836-829675f94811 github.com/davecgh/go-spew v1.1.1 @@ -57,7 +57,7 @@ require ( github.com/DataDog/zstd v1.5.2 // indirect github.com/Microsoft/go-winio v0.5.2 // indirect github.com/NYTimes/gziphandler v1.1.1 // indirect - github.com/ava-labs/coreth v0.12.9-rc.9.0.20231222191417-2e3f762373e9 // indirect + github.com/ava-labs/coreth v0.12.10-rc.3 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bits-and-blooms/bitset v1.7.0 // indirect github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect diff --git a/go.sum b/go.sum index 161e2a63a7..73a358d035 100644 --- a/go.sum +++ b/go.sum @@ -61,10 +61,10 @@ github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kd github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/ava-labs/avalanche-network-runner v1.7.4-0.20231127162258-2f3ceed8ae4b h1:iH6q+S7dmBOYCXrZx+nNlS1HBp72L2msiVCLs39Ls5A= github.com/ava-labs/avalanche-network-runner v1.7.4-0.20231127162258-2f3ceed8ae4b/go.mod h1:aeAm8dgJ1xucQKlYoRDMgYjA0UWGwmaICG9wL0WvseU= -github.com/ava-labs/avalanchego v1.10.18-rc.8 h1:IBGS1psMY+HNm3w9kQHaHF1+SIssv7qdNV8H50mAGY4= -github.com/ava-labs/avalanchego v1.10.18-rc.8/go.mod h1:duoSU6Xb1HoVhQThAXqcCY7ik7LPWwQHb/YgdauXrfc= -github.com/ava-labs/coreth v0.12.9-rc.9.0.20231222191417-2e3f762373e9 h1:DiJBkm2IJ/My4u5DP4gq2wIbdflFRuZJbDm8DbgNDdg= -github.com/ava-labs/coreth v0.12.9-rc.9.0.20231222191417-2e3f762373e9/go.mod h1:Xftjgk8T46k5/pWSQWcmdPanNl68kTcufd9S4kB58bM= +github.com/ava-labs/avalanchego v1.10.18-rc.9 h1:/iFB4klsMFZCsp+ibVcC5GK5wNyyM14dkMkkmEwoP2E= +github.com/ava-labs/avalanchego v1.10.18-rc.9/go.mod h1:fUaYA+VmiZBrMj7z+ZV+sepuovnad8rTEjW0klG0vCc= +github.com/ava-labs/coreth v0.12.10-rc.3 h1:kmbN4Pg65iwIfT9JhGKpvGn19SEdnoIeka+LIUUHTjQ= +github.com/ava-labs/coreth v0.12.10-rc.3/go.mod h1:RIbv14KMyWSj4hB1danS+vEPCUsgArZUEo99SaP5nW8= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= diff --git a/scripts/versions.sh b/scripts/versions.sh index d7d978e229..78769ebddb 100644 --- a/scripts/versions.sh +++ b/scripts/versions.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash # Don't export them as they're used in the context of other calls -AVALANCHE_VERSION=${AVALANCHE_VERSION:-'v1.10.18-rc.8'} +AVALANCHE_VERSION=${AVALANCHE_VERSION:-'v1.10.18-rc.9'} GINKGO_VERSION=${GINKGO_VERSION:-'v2.2.0'} # This won't be used, but it's here to make code syncs easier From f90f91f8627393bbe0645f717bfb1d429a7eaf8a Mon Sep 17 00:00:00 2001 From: Ceyhun Onur Date: Thu, 28 Dec 2023 19:44:37 +0300 Subject: [PATCH 09/26] fix uint64 --- eth/gasprice/gasprice.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eth/gasprice/gasprice.go b/eth/gasprice/gasprice.go index 79a33f807b..e00b699307 100644 --- a/eth/gasprice/gasprice.go +++ b/eth/gasprice/gasprice.go @@ -268,7 +268,7 @@ func (oracle *Oracle) estimateNextBaseFee(ctx context.Context) (*big.Int, error) // If the block does have a baseFee, calculate the next base fee // based on the current time and add it to the tip to estimate the // total gas price estimate. - _, nextBaseFee, err := dummy.EstimateNextBaseFee(oracle.backend.ChainConfig(), feeConfig, header, oracle.clock.Unix()) + _, nextBaseFee, err := dummy.EstimateNextBaseFee(oracle.backend.ChainConfig(), feeConfig, header, uint64(oracle.clock.Unix())) return nextBaseFee, err } @@ -347,7 +347,7 @@ func (oracle *Oracle) suggestDynamicFees(ctx context.Context) (*big.Int, *big.In var ( latestBlockNumber = head.Number.Uint64() lowerBlockNumberLimit = uint64(0) - currentTime = oracle.clock.Unix() + currentTime = uint64(oracle.clock.Unix()) tipResults []*big.Int baseFeeResults []*big.Int ) From f35444a194b0af6f511511904c933ad24b0ba1bc Mon Sep 17 00:00:00 2001 From: Ceyhun Onur Date: Wed, 3 Jan 2024 15:24:41 +0300 Subject: [PATCH 10/26] bump avalanchego rc version --- go.mod | 2 +- go.sum | 4 ++-- scripts/versions.sh | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index d5f62e5ec4..96bc4f38f2 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.20 require ( github.com/VictoriaMetrics/fastcache v1.10.0 github.com/ava-labs/avalanche-network-runner v1.7.4-0.20231127162258-2f3ceed8ae4b - github.com/ava-labs/avalanchego v1.10.18-rc.9 + github.com/ava-labs/avalanchego v1.10.18-rc.14 github.com/cespare/cp v0.1.0 github.com/cockroachdb/pebble v0.0.0-20230209160836-829675f94811 github.com/davecgh/go-spew v1.1.1 diff --git a/go.sum b/go.sum index 73a358d035..a54ea76c7f 100644 --- a/go.sum +++ b/go.sum @@ -61,8 +61,8 @@ github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kd github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/ava-labs/avalanche-network-runner v1.7.4-0.20231127162258-2f3ceed8ae4b h1:iH6q+S7dmBOYCXrZx+nNlS1HBp72L2msiVCLs39Ls5A= github.com/ava-labs/avalanche-network-runner v1.7.4-0.20231127162258-2f3ceed8ae4b/go.mod h1:aeAm8dgJ1xucQKlYoRDMgYjA0UWGwmaICG9wL0WvseU= -github.com/ava-labs/avalanchego v1.10.18-rc.9 h1:/iFB4klsMFZCsp+ibVcC5GK5wNyyM14dkMkkmEwoP2E= -github.com/ava-labs/avalanchego v1.10.18-rc.9/go.mod h1:fUaYA+VmiZBrMj7z+ZV+sepuovnad8rTEjW0klG0vCc= +github.com/ava-labs/avalanchego v1.10.18-rc.14 h1:xmWbC7zr9AtUJfkseOTrqeRT/srGg7UBCxSjz8MzHAw= +github.com/ava-labs/avalanchego v1.10.18-rc.14/go.mod h1:FsejaXWTz6rgjpk1dEbXUJvhX/Ip6ADmD4Q8WZHRNuY= github.com/ava-labs/coreth v0.12.10-rc.3 h1:kmbN4Pg65iwIfT9JhGKpvGn19SEdnoIeka+LIUUHTjQ= github.com/ava-labs/coreth v0.12.10-rc.3/go.mod h1:RIbv14KMyWSj4hB1danS+vEPCUsgArZUEo99SaP5nW8= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= diff --git a/scripts/versions.sh b/scripts/versions.sh index 78769ebddb..2c64eae5c2 100644 --- a/scripts/versions.sh +++ b/scripts/versions.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash # Don't export them as they're used in the context of other calls -AVALANCHE_VERSION=${AVALANCHE_VERSION:-'v1.10.18-rc.9'} +AVALANCHE_VERSION=${AVALANCHE_VERSION:-'v1.10.18-rc.14'} GINKGO_VERSION=${GINKGO_VERSION:-'v2.2.0'} # This won't be used, but it's here to make code syncs easier From 61b730beb8d79bac7a0daa45ff34f4d347a5713b Mon Sep 17 00:00:00 2001 From: Ceyhun Onur Date: Wed, 3 Jan 2024 15:32:02 +0300 Subject: [PATCH 11/26] fix linter --- core/txpool/txpool.go | 2 +- eth/gasprice/gasprice.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/core/txpool/txpool.go b/core/txpool/txpool.go index 4a662a7a10..896dcd5ac9 100644 --- a/core/txpool/txpool.go +++ b/core/txpool/txpool.go @@ -1898,7 +1898,7 @@ func (pool *TxPool) updateBaseFeeAt(head *types.Header) error { if err != nil { return err } - _, baseFeeEstimate, err := dummy.EstimateNextBaseFee(pool.chainconfig, feeConfig, head, uint64(time.Now().Unix())) + _, baseFeeEstimate, err := dummy.EstimateNextBaseFee(pool.chainconfig, feeConfig, head, time.Now().Unix()) if err != nil { return err } diff --git a/eth/gasprice/gasprice.go b/eth/gasprice/gasprice.go index e00b699307..79a33f807b 100644 --- a/eth/gasprice/gasprice.go +++ b/eth/gasprice/gasprice.go @@ -268,7 +268,7 @@ func (oracle *Oracle) estimateNextBaseFee(ctx context.Context) (*big.Int, error) // If the block does have a baseFee, calculate the next base fee // based on the current time and add it to the tip to estimate the // total gas price estimate. - _, nextBaseFee, err := dummy.EstimateNextBaseFee(oracle.backend.ChainConfig(), feeConfig, header, uint64(oracle.clock.Unix())) + _, nextBaseFee, err := dummy.EstimateNextBaseFee(oracle.backend.ChainConfig(), feeConfig, header, oracle.clock.Unix()) return nextBaseFee, err } @@ -347,7 +347,7 @@ func (oracle *Oracle) suggestDynamicFees(ctx context.Context) (*big.Int, *big.In var ( latestBlockNumber = head.Number.Uint64() lowerBlockNumberLimit = uint64(0) - currentTime = uint64(oracle.clock.Unix()) + currentTime = oracle.clock.Unix() tipResults []*big.Int baseFeeResults []*big.Int ) From 1fe51f7404e103290735c62d366ac24fe6e78201 Mon Sep 17 00:00:00 2001 From: Ceyhun Onur Date: Wed, 3 Jan 2024 15:34:52 +0300 Subject: [PATCH 12/26] revert txpool uint change --- core/txpool/txpool.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/txpool/txpool.go b/core/txpool/txpool.go index 896dcd5ac9..4a662a7a10 100644 --- a/core/txpool/txpool.go +++ b/core/txpool/txpool.go @@ -1898,7 +1898,7 @@ func (pool *TxPool) updateBaseFeeAt(head *types.Header) error { if err != nil { return err } - _, baseFeeEstimate, err := dummy.EstimateNextBaseFee(pool.chainconfig, feeConfig, head, time.Now().Unix()) + _, baseFeeEstimate, err := dummy.EstimateNextBaseFee(pool.chainconfig, feeConfig, head, uint64(time.Now().Unix())) if err != nil { return err } From 7bc46ace966a2be6fc857c06643ce5fa43da77e2 Mon Sep 17 00:00:00 2001 From: Ceyhun Onur Date: Wed, 3 Jan 2024 16:21:25 +0300 Subject: [PATCH 13/26] bump subnet-evm version --- README.md | 1 + compatibility.json | 1 + plugin/evm/version.go | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5f2fc45017..5ff6f58df3 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,7 @@ The Subnet EVM runs in a separate process from the main AvalancheGo process and [v0.5.8] AvalancheGo@v1.10.13-v1.10.14 (Protocol Version: 29) [v0.5.9] AvalancheGo@v1.10.15-v1.10.17 (Protocol Version: 30) [v0.5.10] AvalancheGo@v1.10.15-v1.10.17 (Protocol Version: 30) +[v0.5.11] AvalancheGo@v1.10.18-v1.10.18 (Protocol Version: 31) ``` ## API diff --git a/compatibility.json b/compatibility.json index 23895c4bfe..614720cee6 100644 --- a/compatibility.json +++ b/compatibility.json @@ -1,5 +1,6 @@ { "rpcChainVMProtocolVersion": { + "v0.5.11": 31, "v0.5.10": 30, "v0.5.9": 30, "v0.5.8": 29, diff --git a/plugin/evm/version.go b/plugin/evm/version.go index 202e74d813..5ecba7d5d7 100644 --- a/plugin/evm/version.go +++ b/plugin/evm/version.go @@ -11,7 +11,7 @@ var ( // GitCommit is set by the build script GitCommit string // Version is the version of Subnet EVM - Version string = "v0.5.10" + Version string = "v0.5.11" ) func init() { From 1782f18055bd14fdb26fa66f1426081783294235 Mon Sep 17 00:00:00 2001 From: Ceyhun Onur Date: Wed, 3 Jan 2024 17:39:37 +0300 Subject: [PATCH 14/26] run simulator in a different step --- .github/workflows/ci.yml | 3 +++ scripts/run_ginkgo_simulator.sh | 28 ++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100755 scripts/run_ginkgo_simulator.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 637aaf012e..86edafeba5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -93,6 +93,9 @@ jobs: - name: Run Warp E2E Tests shell: bash run: AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego DATA_DIR=/tmp/e2e-test/data ./scripts/run_ginkgo_warp.sh + - name: Run E2E Simulator Tests + shell: bash + run: AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego DATA_DIR=/tmp/e2e-test/data ./scripts/run_ginkgo_simulator.sh - name: Upload Artifact if: always() uses: actions/upload-artifact@v3 diff --git a/scripts/run_ginkgo_simulator.sh b/scripts/run_ginkgo_simulator.sh new file mode 100755 index 0000000000..16f36cf398 --- /dev/null +++ b/scripts/run_ginkgo_simulator.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash +set -e + +# This script assumes that an AvalancheGo and Subnet-EVM binaries are available in the standard location +# within the $GOPATH +# The AvalancheGo and PluginDir paths can be specified via the environment variables used in ./scripts/run.sh. + +# Load the versions +SUBNET_EVM_PATH=$( + cd "$(dirname "${BASH_SOURCE[0]}")" + cd .. && pwd +) + +source "$SUBNET_EVM_PATH"/scripts/constants.sh + +source "$SUBNET_EVM_PATH"/scripts/versions.sh + +# Build ginkgo +# to install the ginkgo binary (required for test build and run) +go install -v github.com/onsi/ginkgo/v2/ginkgo@${GINKGO_VERSION} + +TEST_SOURCE_ROOT=$(pwd) + +ACK_GINKGO_RC=true ginkgo build ./tests/load + +./tests/load/load.test \ + --ginkgo.vv \ + --ginkgo.label-filter=${GINKGO_LABEL_FILTER:-""} From 49c3c3c40093d7f2550ab322177cd6957a323909 Mon Sep 17 00:00:00 2001 From: Ceyhun Onur Date: Wed, 3 Jan 2024 17:50:15 +0300 Subject: [PATCH 15/26] remove load test from precompile tests --- .github/workflows/ci.yml | 4 ++-- scripts/{run_ginkgo.sh => run_ginkgo_precompile.sh} | 6 ------ 2 files changed, 2 insertions(+), 8 deletions(-) rename scripts/{run_ginkgo.sh => run_ginkgo_precompile.sh} (86%) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 86edafeba5..338266336d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -87,9 +87,9 @@ jobs: - name: Build Subnet-EVM Plugin Binary shell: bash run: ./scripts/build.sh /tmp/e2e-test/avalanchego/plugins/srEXiWaHuhNyGwPUi444Tu47ZEDwxTWrbQiuD7FmgSAQ6X7Dy - - name: Run E2E Tests + - name: Run E2E Precompile Tests shell: bash - run: AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego DATA_DIR=/tmp/e2e-test/data ./scripts/run_ginkgo.sh + run: AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego DATA_DIR=/tmp/e2e-test/data ./scripts/run_ginkgo_precompile.sh - name: Run Warp E2E Tests shell: bash run: AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego DATA_DIR=/tmp/e2e-test/data ./scripts/run_ginkgo_warp.sh diff --git a/scripts/run_ginkgo.sh b/scripts/run_ginkgo_precompile.sh similarity index 86% rename from scripts/run_ginkgo.sh rename to scripts/run_ginkgo_precompile.sh index 790b3bb9ca..7588b9528d 100755 --- a/scripts/run_ginkgo.sh +++ b/scripts/run_ginkgo_precompile.sh @@ -21,15 +21,9 @@ go install -v github.com/onsi/ginkgo/v2/ginkgo@${GINKGO_VERSION} TEST_SOURCE_ROOT=$(pwd) -ACK_GINKGO_RC=true ginkgo build ./tests/load - # By default, it runs all e2e test cases! # Use "--ginkgo.skip" to skip tests. # Use "--ginkgo.focus" to select tests. TEST_SOURCE_ROOT="$TEST_SOURCE_ROOT" ginkgo run -procs=5 tests/precompile \ --ginkgo.vv \ --ginkgo.label-filter=${GINKGO_LABEL_FILTER:-""} - -./tests/load/load.test \ - --ginkgo.vv \ - --ginkgo.label-filter=${GINKGO_LABEL_FILTER:-""} From d5a24de1fe63c03aa18cdad2784645fce2152ae6 Mon Sep 17 00:00:00 2001 From: Ceyhun Onur Date: Wed, 3 Jan 2024 17:39:37 +0300 Subject: [PATCH 16/26] run simulator in a different step --- .github/workflows/ci.yml | 3 +++ scripts/run_ginkgo_simulator.sh | 28 ++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100755 scripts/run_ginkgo_simulator.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1f932cbcb2..bf5f2fde80 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -93,6 +93,9 @@ jobs: - name: Run Warp E2E Tests shell: bash run: AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego DATA_DIR=/tmp/e2e-test/data ./scripts/run_ginkgo_warp.sh + - name: Run E2E Simulator Tests + shell: bash + run: AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego DATA_DIR=/tmp/e2e-test/data ./scripts/run_ginkgo_simulator.sh - name: Upload Artifact if: always() uses: actions/upload-artifact@v3 diff --git a/scripts/run_ginkgo_simulator.sh b/scripts/run_ginkgo_simulator.sh new file mode 100755 index 0000000000..16f36cf398 --- /dev/null +++ b/scripts/run_ginkgo_simulator.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash +set -e + +# This script assumes that an AvalancheGo and Subnet-EVM binaries are available in the standard location +# within the $GOPATH +# The AvalancheGo and PluginDir paths can be specified via the environment variables used in ./scripts/run.sh. + +# Load the versions +SUBNET_EVM_PATH=$( + cd "$(dirname "${BASH_SOURCE[0]}")" + cd .. && pwd +) + +source "$SUBNET_EVM_PATH"/scripts/constants.sh + +source "$SUBNET_EVM_PATH"/scripts/versions.sh + +# Build ginkgo +# to install the ginkgo binary (required for test build and run) +go install -v github.com/onsi/ginkgo/v2/ginkgo@${GINKGO_VERSION} + +TEST_SOURCE_ROOT=$(pwd) + +ACK_GINKGO_RC=true ginkgo build ./tests/load + +./tests/load/load.test \ + --ginkgo.vv \ + --ginkgo.label-filter=${GINKGO_LABEL_FILTER:-""} From 828e0770a54ea82c922d57e44d6a657e8c9dc053 Mon Sep 17 00:00:00 2001 From: Ceyhun Onur Date: Wed, 3 Jan 2024 17:50:15 +0300 Subject: [PATCH 17/26] remove load test from precompile tests --- .github/workflows/ci.yml | 4 ++-- scripts/{run_ginkgo.sh => run_ginkgo_precompile.sh} | 6 ------ 2 files changed, 2 insertions(+), 8 deletions(-) rename scripts/{run_ginkgo.sh => run_ginkgo_precompile.sh} (86%) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bf5f2fde80..b1772d7312 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -87,9 +87,9 @@ jobs: - name: Build Subnet-EVM Plugin Binary shell: bash run: ./scripts/build.sh /tmp/e2e-test/avalanchego/plugins/srEXiWaHuhNyGwPUi444Tu47ZEDwxTWrbQiuD7FmgSAQ6X7Dy - - name: Run E2E Tests + - name: Run E2E Precompile Tests shell: bash - run: AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego DATA_DIR=/tmp/e2e-test/data ./scripts/run_ginkgo.sh + run: AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego DATA_DIR=/tmp/e2e-test/data ./scripts/run_ginkgo_precompile.sh - name: Run Warp E2E Tests shell: bash run: AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego DATA_DIR=/tmp/e2e-test/data ./scripts/run_ginkgo_warp.sh diff --git a/scripts/run_ginkgo.sh b/scripts/run_ginkgo_precompile.sh similarity index 86% rename from scripts/run_ginkgo.sh rename to scripts/run_ginkgo_precompile.sh index 790b3bb9ca..7588b9528d 100755 --- a/scripts/run_ginkgo.sh +++ b/scripts/run_ginkgo_precompile.sh @@ -21,15 +21,9 @@ go install -v github.com/onsi/ginkgo/v2/ginkgo@${GINKGO_VERSION} TEST_SOURCE_ROOT=$(pwd) -ACK_GINKGO_RC=true ginkgo build ./tests/load - # By default, it runs all e2e test cases! # Use "--ginkgo.skip" to skip tests. # Use "--ginkgo.focus" to select tests. TEST_SOURCE_ROOT="$TEST_SOURCE_ROOT" ginkgo run -procs=5 tests/precompile \ --ginkgo.vv \ --ginkgo.label-filter=${GINKGO_LABEL_FILTER:-""} - -./tests/load/load.test \ - --ginkgo.vv \ - --ginkgo.label-filter=${GINKGO_LABEL_FILTER:-""} From a9b8f3d8dbef2323bdff62de9d119a56b818f4b4 Mon Sep 17 00:00:00 2001 From: Ceyhun Onur Date: Thu, 4 Jan 2024 13:40:30 +0300 Subject: [PATCH 18/26] rename simulator to load test --- .github/workflows/ci.yml | 4 ++-- scripts/{run_ginkgo_simulator.sh => run_ginkgo_load.sh} | 0 2 files changed, 2 insertions(+), 2 deletions(-) rename scripts/{run_ginkgo_simulator.sh => run_ginkgo_load.sh} (100%) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b1772d7312..f07108567f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -93,9 +93,9 @@ jobs: - name: Run Warp E2E Tests shell: bash run: AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego DATA_DIR=/tmp/e2e-test/data ./scripts/run_ginkgo_warp.sh - - name: Run E2E Simulator Tests + - name: Run E2E Load Tests shell: bash - run: AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego DATA_DIR=/tmp/e2e-test/data ./scripts/run_ginkgo_simulator.sh + run: AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego DATA_DIR=/tmp/e2e-test/data ./scripts/run_ginkgo_load.sh - name: Upload Artifact if: always() uses: actions/upload-artifact@v3 diff --git a/scripts/run_ginkgo_simulator.sh b/scripts/run_ginkgo_load.sh similarity index 100% rename from scripts/run_ginkgo_simulator.sh rename to scripts/run_ginkgo_load.sh From dad0b1788ae331ebf1455723a4e6b0a6abadd057 Mon Sep 17 00:00:00 2001 From: Ceyhun Onur Date: Thu, 4 Jan 2024 14:30:03 +0300 Subject: [PATCH 19/26] parallelize e2e steps --- .github/workflows/ci.yml | 49 --------------------- .github/workflows/e2e.yml | 91 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+), 49 deletions(-) create mode 100644 .github/workflows/e2e.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f07108567f..2a1b1f66fc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -54,52 +54,3 @@ jobs: shell: bash - run: CURRENT_BRANCH=${{ github.head_ref || github.ref_name }} PUSH_DOCKER_IMAGE=true ./scripts/build_image.sh shell: bash - - e2e_test: - name: e2e tests - runs-on: ubuntu-latest - steps: - - name: Git checkout - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - name: Set up Go - uses: actions/setup-go@v3 - with: - go-version: '~1.20.10' - check-latest: true - - name: Use Node.js - uses: actions/setup-node@v3 - with: - node-version: "18.15" - - name: NPM Clean Install - run: npm ci - working-directory: ./contracts - - name: Hardhat Clean - run: npx hardhat clean - working-directory: ./contracts - - name: Hardhat Compile - run: npx hardhat compile - working-directory: ./contracts - - name: Install AvalancheGo Release - shell: bash - run: BASEDIR=/tmp/e2e-test AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego ./scripts/install_avalanchego_release.sh - - name: Build Subnet-EVM Plugin Binary - shell: bash - run: ./scripts/build.sh /tmp/e2e-test/avalanchego/plugins/srEXiWaHuhNyGwPUi444Tu47ZEDwxTWrbQiuD7FmgSAQ6X7Dy - - name: Run E2E Precompile Tests - shell: bash - run: AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego DATA_DIR=/tmp/e2e-test/data ./scripts/run_ginkgo_precompile.sh - - name: Run Warp E2E Tests - shell: bash - run: AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego DATA_DIR=/tmp/e2e-test/data ./scripts/run_ginkgo_warp.sh - - name: Run E2E Load Tests - shell: bash - run: AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego DATA_DIR=/tmp/e2e-test/data ./scripts/run_ginkgo_load.sh - - name: Upload Artifact - if: always() - uses: actions/upload-artifact@v3 - with: - name: subnet-evm-e2e-logs - path: /tmp/network-runner-root-data*/ - retention-days: 5 diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml new file mode 100644 index 0000000000..2d0eed4c5e --- /dev/null +++ b/.github/workflows/e2e.yml @@ -0,0 +1,91 @@ +name: E2E Tests + +on: + push: + branches: + - master + tags: + - 'v[0-9]+.[0-9]+.[0-9]+' + pull_request: + +jobs: + setup: + name: e2e test setup + runs-on: ubuntu-latest + steps: + - name: Git checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: Set up Go + uses: actions/setup-go@v3 + with: + go-version: '~1.20.10' + check-latest: true + - name: Use Node.js + uses: actions/setup-node@v3 + with: + node-version: "18.15" + - name: NPM Clean Install + run: npm ci + working-directory: ./contracts + - name: Hardhat Clean + run: npx hardhat clean + working-directory: ./contracts + - name: Hardhat Compile + run: npx hardhat compile + working-directory: ./contracts + - name: Install AvalancheGo Release + shell: bash + run: BASEDIR=/tmp/e2e-test AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego ./scripts/install_avalanchego_release.sh + - name: Build Subnet-EVM Plugin Binary + shell: bash + run: ./scripts/build.sh /tmp/e2e-test/avalanchego/plugins/srEXiWaHuhNyGwPUi444Tu47ZEDwxTWrbQiuD7FmgSAQ6X7Dy + + precompile: + name: Precompile Tests + runs-on: ubuntu-latest + needs: setup + steps: + - name: Run E2E Precompile Tests + shell: bash + run: AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego DATA_DIR=/tmp/e2e-test/precompile-data ./scripts/run_ginkgo_precompile.sh + - name: Upload Artifact + if: always() + uses: actions/upload-artifact@v3 + with: + name: subnet-evm-e2e-logs-precompile + path: /tmp/network-runner-root-data*/ + retention-days: 5 + + warp: + name: Warp Tests + runs-on: ubuntu-latest + needs: setup + steps: + - name: Run Warp E2E Tests + shell: bash + run: AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego DATA_DIR=/tmp/e2e-test/warp-data ./scripts/run_ginkgo_warp.sh + - name: Upload Artifact + if: always() + uses: actions/upload-artifact@v3 + with: + name: subnet-evm-e2e-logs-warp + path: /tmp/network-runner-root-data*/ + retention-days: 5 + + load: + name: Load Tests + runs-on: ubuntu-latest + needs: setup + steps: + - name: Run E2E Load Tests + shell: bash + run: AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego DATA_DIR=/tmp/e2e-test/load-data ./scripts/run_ginkgo_load.sh + - name: Upload Artifact + if: always() + uses: actions/upload-artifact@v3 + with: + name: subnet-evm-e2e-logs-load + path: /tmp/network-runner-root-data*/ + retention-days: 5 From 2a45e5f4465282cede8770e5b9b174798ed88190 Mon Sep 17 00:00:00 2001 From: Ceyhun Onur Date: Thu, 4 Jan 2024 14:36:30 +0300 Subject: [PATCH 20/26] use checkout --- .github/workflows/e2e.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 2d0eed4c5e..47d238de8c 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -47,6 +47,8 @@ jobs: runs-on: ubuntu-latest needs: setup steps: + - name: Git checkout + uses: actions/checkout@v3 - name: Run E2E Precompile Tests shell: bash run: AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego DATA_DIR=/tmp/e2e-test/precompile-data ./scripts/run_ginkgo_precompile.sh @@ -63,6 +65,8 @@ jobs: runs-on: ubuntu-latest needs: setup steps: + - name: Git checkout + uses: actions/checkout@v3 - name: Run Warp E2E Tests shell: bash run: AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego DATA_DIR=/tmp/e2e-test/warp-data ./scripts/run_ginkgo_warp.sh @@ -79,6 +83,8 @@ jobs: runs-on: ubuntu-latest needs: setup steps: + - name: Git checkout + uses: actions/checkout@v3 - name: Run E2E Load Tests shell: bash run: AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego DATA_DIR=/tmp/e2e-test/load-data ./scripts/run_ginkgo_load.sh From b182b18e4992ac90507bfe7605311bf667d78ca8 Mon Sep 17 00:00:00 2001 From: Ceyhun Onur Date: Thu, 4 Jan 2024 14:53:32 +0300 Subject: [PATCH 21/26] split to different workflows --- .github/workflows/e2e.load.yml | 53 +++++++++++++++++++ .../workflows/{e2e.yml => e2e.precompile.yml} | 50 ++--------------- .github/workflows/e2e.warp.yml | 53 +++++++++++++++++++ 3 files changed, 109 insertions(+), 47 deletions(-) create mode 100644 .github/workflows/e2e.load.yml rename .github/workflows/{e2e.yml => e2e.precompile.yml} (55%) create mode 100644 .github/workflows/e2e.warp.yml diff --git a/.github/workflows/e2e.load.yml b/.github/workflows/e2e.load.yml new file mode 100644 index 0000000000..d18a4e9abc --- /dev/null +++ b/.github/workflows/e2e.load.yml @@ -0,0 +1,53 @@ +name: E2E Load Tests + +on: + push: + branches: + - master + tags: + - 'v[0-9]+.[0-9]+.[0-9]+' + pull_request: + +jobs: + setup: + name: e2e load tests + runs-on: ubuntu-latest + steps: + - name: Git checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: Set up Go + uses: actions/setup-go@v3 + with: + go-version: '~1.20.10' + check-latest: true + - name: Use Node.js + uses: actions/setup-node@v3 + with: + node-version: "18.15" + - name: NPM Clean Install + run: npm ci + working-directory: ./contracts + - name: Hardhat Clean + run: npx hardhat clean + working-directory: ./contracts + - name: Hardhat Compile + run: npx hardhat compile + working-directory: ./contracts + - name: Install AvalancheGo Release + shell: bash + run: BASEDIR=/tmp/e2e-test AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego ./scripts/install_avalanchego_release.sh + - name: Build Subnet-EVM Plugin Binary + shell: bash + run: ./scripts/build.sh /tmp/e2e-test/avalanchego/plugins/srEXiWaHuhNyGwPUi444Tu47ZEDwxTWrbQiuD7FmgSAQ6X7Dy + - name: Run E2E Load Tests + shell: bash + run: AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego DATA_DIR=/tmp/e2e-test/load-data ./scripts/run_ginkgo_load.sh + - name: Upload Artifact + if: always() + uses: actions/upload-artifact@v3 + with: + name: subnet-evm-e2e-logs-load + path: /tmp/network-runner-root-data*/ + retention-days: 5 diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.precompile.yml similarity index 55% rename from .github/workflows/e2e.yml rename to .github/workflows/e2e.precompile.yml index 47d238de8c..4f4af2b8e0 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.precompile.yml @@ -1,4 +1,4 @@ -name: E2E Tests +name: E2E Precompile Tests on: push: @@ -9,8 +9,8 @@ on: pull_request: jobs: - setup: - name: e2e test setup + precompile: + name: e2e precompile tests runs-on: ubuntu-latest steps: - name: Git checkout @@ -41,14 +41,6 @@ jobs: - name: Build Subnet-EVM Plugin Binary shell: bash run: ./scripts/build.sh /tmp/e2e-test/avalanchego/plugins/srEXiWaHuhNyGwPUi444Tu47ZEDwxTWrbQiuD7FmgSAQ6X7Dy - - precompile: - name: Precompile Tests - runs-on: ubuntu-latest - needs: setup - steps: - - name: Git checkout - uses: actions/checkout@v3 - name: Run E2E Precompile Tests shell: bash run: AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego DATA_DIR=/tmp/e2e-test/precompile-data ./scripts/run_ginkgo_precompile.sh @@ -59,39 +51,3 @@ jobs: name: subnet-evm-e2e-logs-precompile path: /tmp/network-runner-root-data*/ retention-days: 5 - - warp: - name: Warp Tests - runs-on: ubuntu-latest - needs: setup - steps: - - name: Git checkout - uses: actions/checkout@v3 - - name: Run Warp E2E Tests - shell: bash - run: AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego DATA_DIR=/tmp/e2e-test/warp-data ./scripts/run_ginkgo_warp.sh - - name: Upload Artifact - if: always() - uses: actions/upload-artifact@v3 - with: - name: subnet-evm-e2e-logs-warp - path: /tmp/network-runner-root-data*/ - retention-days: 5 - - load: - name: Load Tests - runs-on: ubuntu-latest - needs: setup - steps: - - name: Git checkout - uses: actions/checkout@v3 - - name: Run E2E Load Tests - shell: bash - run: AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego DATA_DIR=/tmp/e2e-test/load-data ./scripts/run_ginkgo_load.sh - - name: Upload Artifact - if: always() - uses: actions/upload-artifact@v3 - with: - name: subnet-evm-e2e-logs-load - path: /tmp/network-runner-root-data*/ - retention-days: 5 diff --git a/.github/workflows/e2e.warp.yml b/.github/workflows/e2e.warp.yml new file mode 100644 index 0000000000..c655fc4d94 --- /dev/null +++ b/.github/workflows/e2e.warp.yml @@ -0,0 +1,53 @@ +name: E2E Warp Tests + +on: + push: + branches: + - master + tags: + - 'v[0-9]+.[0-9]+.[0-9]+' + pull_request: + +jobs: + warp: + name: e2e warp tests + runs-on: ubuntu-latest + steps: + - name: Git checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: Set up Go + uses: actions/setup-go@v3 + with: + go-version: '~1.20.10' + check-latest: true + - name: Use Node.js + uses: actions/setup-node@v3 + with: + node-version: "18.15" + - name: NPM Clean Install + run: npm ci + working-directory: ./contracts + - name: Hardhat Clean + run: npx hardhat clean + working-directory: ./contracts + - name: Hardhat Compile + run: npx hardhat compile + working-directory: ./contracts + - name: Install AvalancheGo Release + shell: bash + run: BASEDIR=/tmp/e2e-test AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego ./scripts/install_avalanchego_release.sh + - name: Build Subnet-EVM Plugin Binary + shell: bash + run: ./scripts/build.sh /tmp/e2e-test/avalanchego/plugins/srEXiWaHuhNyGwPUi444Tu47ZEDwxTWrbQiuD7FmgSAQ6X7Dy + - name: Run Warp E2E Tests + shell: bash + run: AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego DATA_DIR=/tmp/e2e-test/warp-data ./scripts/run_ginkgo_warp.sh + - name: Upload Artifact + if: always() + uses: actions/upload-artifact@v3 + with: + name: subnet-evm-e2e-logs-warp + path: /tmp/network-runner-root-data*/ + retention-days: 5 From 867aaadaf04914d6990321a46d7539424f5d290b Mon Sep 17 00:00:00 2001 From: Ceyhun Onur Date: Thu, 4 Jan 2024 15:02:52 +0300 Subject: [PATCH 22/26] move to same folder --- .github/workflows/e2e.load.yml | 53 ------------ .github/workflows/e2e.precompile.yml | 53 ------------ .github/workflows/e2e.warp.yml | 53 ------------ .github/workflows/e2e.yml | 124 +++++++++++++++++++++++++++ 4 files changed, 124 insertions(+), 159 deletions(-) delete mode 100644 .github/workflows/e2e.load.yml delete mode 100644 .github/workflows/e2e.precompile.yml delete mode 100644 .github/workflows/e2e.warp.yml create mode 100644 .github/workflows/e2e.yml diff --git a/.github/workflows/e2e.load.yml b/.github/workflows/e2e.load.yml deleted file mode 100644 index d18a4e9abc..0000000000 --- a/.github/workflows/e2e.load.yml +++ /dev/null @@ -1,53 +0,0 @@ -name: E2E Load Tests - -on: - push: - branches: - - master - tags: - - 'v[0-9]+.[0-9]+.[0-9]+' - pull_request: - -jobs: - setup: - name: e2e load tests - runs-on: ubuntu-latest - steps: - - name: Git checkout - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - name: Set up Go - uses: actions/setup-go@v3 - with: - go-version: '~1.20.10' - check-latest: true - - name: Use Node.js - uses: actions/setup-node@v3 - with: - node-version: "18.15" - - name: NPM Clean Install - run: npm ci - working-directory: ./contracts - - name: Hardhat Clean - run: npx hardhat clean - working-directory: ./contracts - - name: Hardhat Compile - run: npx hardhat compile - working-directory: ./contracts - - name: Install AvalancheGo Release - shell: bash - run: BASEDIR=/tmp/e2e-test AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego ./scripts/install_avalanchego_release.sh - - name: Build Subnet-EVM Plugin Binary - shell: bash - run: ./scripts/build.sh /tmp/e2e-test/avalanchego/plugins/srEXiWaHuhNyGwPUi444Tu47ZEDwxTWrbQiuD7FmgSAQ6X7Dy - - name: Run E2E Load Tests - shell: bash - run: AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego DATA_DIR=/tmp/e2e-test/load-data ./scripts/run_ginkgo_load.sh - - name: Upload Artifact - if: always() - uses: actions/upload-artifact@v3 - with: - name: subnet-evm-e2e-logs-load - path: /tmp/network-runner-root-data*/ - retention-days: 5 diff --git a/.github/workflows/e2e.precompile.yml b/.github/workflows/e2e.precompile.yml deleted file mode 100644 index 4f4af2b8e0..0000000000 --- a/.github/workflows/e2e.precompile.yml +++ /dev/null @@ -1,53 +0,0 @@ -name: E2E Precompile Tests - -on: - push: - branches: - - master - tags: - - 'v[0-9]+.[0-9]+.[0-9]+' - pull_request: - -jobs: - precompile: - name: e2e precompile tests - runs-on: ubuntu-latest - steps: - - name: Git checkout - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - name: Set up Go - uses: actions/setup-go@v3 - with: - go-version: '~1.20.10' - check-latest: true - - name: Use Node.js - uses: actions/setup-node@v3 - with: - node-version: "18.15" - - name: NPM Clean Install - run: npm ci - working-directory: ./contracts - - name: Hardhat Clean - run: npx hardhat clean - working-directory: ./contracts - - name: Hardhat Compile - run: npx hardhat compile - working-directory: ./contracts - - name: Install AvalancheGo Release - shell: bash - run: BASEDIR=/tmp/e2e-test AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego ./scripts/install_avalanchego_release.sh - - name: Build Subnet-EVM Plugin Binary - shell: bash - run: ./scripts/build.sh /tmp/e2e-test/avalanchego/plugins/srEXiWaHuhNyGwPUi444Tu47ZEDwxTWrbQiuD7FmgSAQ6X7Dy - - name: Run E2E Precompile Tests - shell: bash - run: AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego DATA_DIR=/tmp/e2e-test/precompile-data ./scripts/run_ginkgo_precompile.sh - - name: Upload Artifact - if: always() - uses: actions/upload-artifact@v3 - with: - name: subnet-evm-e2e-logs-precompile - path: /tmp/network-runner-root-data*/ - retention-days: 5 diff --git a/.github/workflows/e2e.warp.yml b/.github/workflows/e2e.warp.yml deleted file mode 100644 index c655fc4d94..0000000000 --- a/.github/workflows/e2e.warp.yml +++ /dev/null @@ -1,53 +0,0 @@ -name: E2E Warp Tests - -on: - push: - branches: - - master - tags: - - 'v[0-9]+.[0-9]+.[0-9]+' - pull_request: - -jobs: - warp: - name: e2e warp tests - runs-on: ubuntu-latest - steps: - - name: Git checkout - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - name: Set up Go - uses: actions/setup-go@v3 - with: - go-version: '~1.20.10' - check-latest: true - - name: Use Node.js - uses: actions/setup-node@v3 - with: - node-version: "18.15" - - name: NPM Clean Install - run: npm ci - working-directory: ./contracts - - name: Hardhat Clean - run: npx hardhat clean - working-directory: ./contracts - - name: Hardhat Compile - run: npx hardhat compile - working-directory: ./contracts - - name: Install AvalancheGo Release - shell: bash - run: BASEDIR=/tmp/e2e-test AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego ./scripts/install_avalanchego_release.sh - - name: Build Subnet-EVM Plugin Binary - shell: bash - run: ./scripts/build.sh /tmp/e2e-test/avalanchego/plugins/srEXiWaHuhNyGwPUi444Tu47ZEDwxTWrbQiuD7FmgSAQ6X7Dy - - name: Run Warp E2E Tests - shell: bash - run: AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego DATA_DIR=/tmp/e2e-test/warp-data ./scripts/run_ginkgo_warp.sh - - name: Upload Artifact - if: always() - uses: actions/upload-artifact@v3 - with: - name: subnet-evm-e2e-logs-warp - path: /tmp/network-runner-root-data*/ - retention-days: 5 diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml new file mode 100644 index 0000000000..b328b96cb3 --- /dev/null +++ b/.github/workflows/e2e.yml @@ -0,0 +1,124 @@ +name: E2E Warp Tests + +on: + push: + branches: + - master + tags: + - 'v[0-9]+.[0-9]+.[0-9]+' + pull_request: + +jobs: + precompile: + name: e2e precompile tests + runs-on: ubuntu-latest + steps: + - name: Git checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: Set up Go + uses: actions/setup-go@v3 + with: + go-version: '~1.20.10' + check-latest: true + - name: Use Node.js + uses: actions/setup-node@v3 + with: + node-version: "18.15" + - name: NPM Clean Install + run: npm ci + working-directory: ./contracts + - name: Hardhat Clean + run: npx hardhat clean + working-directory: ./contracts + - name: Hardhat Compile + run: npx hardhat compile + working-directory: ./contracts + - name: Install AvalancheGo Release + shell: bash + run: BASEDIR=/tmp/e2e-test AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego ./scripts/install_avalanchego_release.sh + - name: Build Subnet-EVM Plugin Binary + shell: bash + run: ./scripts/build.sh /tmp/e2e-test/avalanchego/plugins/srEXiWaHuhNyGwPUi444Tu47ZEDwxTWrbQiuD7FmgSAQ6X7Dy + - name: Run E2E Precompile Tests + shell: bash + run: AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego DATA_DIR=/tmp/e2e-test/precompile-data ./scripts/run_ginkgo_precompile.sh + - name: Upload Artifact + if: always() + uses: actions/upload-artifact@v3 + with: + name: subnet-evm-e2e-logs-precompile + path: /tmp/network-runner-root-data*/ + retention-days: 5 + warp: + name: e2e warp tests + runs-on: ubuntu-latest + steps: + - name: Git checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: Set up Go + uses: actions/setup-go@v3 + with: + go-version: '~1.20.10' + check-latest: true + - name: Use Node.js + uses: actions/setup-node@v3 + with: + node-version: "18.15" + - name: NPM Clean Install + run: npm ci + working-directory: ./contracts + - name: Hardhat Clean + run: npx hardhat clean + working-directory: ./contracts + - name: Hardhat Compile + run: npx hardhat compile + working-directory: ./contracts + - name: Install AvalancheGo Release + shell: bash + run: BASEDIR=/tmp/e2e-test AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego ./scripts/install_avalanchego_release.sh + - name: Build Subnet-EVM Plugin Binary + shell: bash + run: ./scripts/build.sh /tmp/e2e-test/avalanchego/plugins/srEXiWaHuhNyGwPUi444Tu47ZEDwxTWrbQiuD7FmgSAQ6X7Dy + - name: Run Warp E2E Tests + shell: bash + run: AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego DATA_DIR=/tmp/e2e-test/warp-data ./scripts/run_ginkgo_warp.sh + - name: Upload Artifact + if: always() + uses: actions/upload-artifact@v3 + with: + name: subnet-evm-e2e-logs-warp + path: /tmp/network-runner-root-data*/ + retention-days: 5 + load: + name: e2e load tests + runs-on: ubuntu-latest + steps: + - name: Git checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: Set up Go + uses: actions/setup-go@v3 + with: + go-version: '~1.20.10' + check-latest: true + - name: Install AvalancheGo Release + shell: bash + run: BASEDIR=/tmp/e2e-test AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego ./scripts/install_avalanchego_release.sh + - name: Build Subnet-EVM Plugin Binary + shell: bash + run: ./scripts/build.sh /tmp/e2e-test/avalanchego/plugins/srEXiWaHuhNyGwPUi444Tu47ZEDwxTWrbQiuD7FmgSAQ6X7Dy + - name: Run E2E Load Tests + shell: bash + run: AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego DATA_DIR=/tmp/e2e-test/load-data ./scripts/run_ginkgo_load.sh + - name: Upload Artifact + if: always() + uses: actions/upload-artifact@v3 + with: + name: subnet-evm-e2e-logs-load + path: /tmp/network-runner-root-data*/ + retention-days: 5 From 7f8009f9e3d2077fb08f9ed183d09e1bf9ea4a0d Mon Sep 17 00:00:00 2001 From: Ceyhun Onur Date: Fri, 5 Jan 2024 13:15:11 +0300 Subject: [PATCH 23/26] bump avago --- go.mod | 6 +++--- go.sum | 12 ++++++------ scripts/versions.sh | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/go.mod b/go.mod index 96bc4f38f2..1a152b8c84 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.20 require ( github.com/VictoriaMetrics/fastcache v1.10.0 github.com/ava-labs/avalanche-network-runner v1.7.4-0.20231127162258-2f3ceed8ae4b - github.com/ava-labs/avalanchego v1.10.18-rc.14 + github.com/ava-labs/avalanchego v1.10.18-rc.16 github.com/cespare/cp v0.1.0 github.com/cockroachdb/pebble v0.0.0-20230209160836-829675f94811 github.com/davecgh/go-spew v1.1.1 @@ -57,7 +57,7 @@ require ( github.com/DataDog/zstd v1.5.2 // indirect github.com/Microsoft/go-winio v0.5.2 // indirect github.com/NYTimes/gziphandler v1.1.1 // indirect - github.com/ava-labs/coreth v0.12.10-rc.3 // indirect + github.com/ava-labs/coreth v0.12.10-rc.4 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bits-and-blooms/bitset v1.7.0 // indirect github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect @@ -68,7 +68,7 @@ require ( github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect github.com/cockroachdb/redact v1.1.3 // indirect github.com/consensys/bavard v0.1.13 // indirect - github.com/consensys/gnark-crypto v0.10.0 // indirect + github.com/consensys/gnark-crypto v0.12.1 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/crate-crypto/go-kzg-4844 v0.2.0 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect diff --git a/go.sum b/go.sum index a54ea76c7f..d4d6922ff4 100644 --- a/go.sum +++ b/go.sum @@ -61,10 +61,10 @@ github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kd github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/ava-labs/avalanche-network-runner v1.7.4-0.20231127162258-2f3ceed8ae4b h1:iH6q+S7dmBOYCXrZx+nNlS1HBp72L2msiVCLs39Ls5A= github.com/ava-labs/avalanche-network-runner v1.7.4-0.20231127162258-2f3ceed8ae4b/go.mod h1:aeAm8dgJ1xucQKlYoRDMgYjA0UWGwmaICG9wL0WvseU= -github.com/ava-labs/avalanchego v1.10.18-rc.14 h1:xmWbC7zr9AtUJfkseOTrqeRT/srGg7UBCxSjz8MzHAw= -github.com/ava-labs/avalanchego v1.10.18-rc.14/go.mod h1:FsejaXWTz6rgjpk1dEbXUJvhX/Ip6ADmD4Q8WZHRNuY= -github.com/ava-labs/coreth v0.12.10-rc.3 h1:kmbN4Pg65iwIfT9JhGKpvGn19SEdnoIeka+LIUUHTjQ= -github.com/ava-labs/coreth v0.12.10-rc.3/go.mod h1:RIbv14KMyWSj4hB1danS+vEPCUsgArZUEo99SaP5nW8= +github.com/ava-labs/avalanchego v1.10.18-rc.16 h1:gEH0ZSqbvWKITMk/i6qAeaeEUSAH/BGgfQgxZYAK/ck= +github.com/ava-labs/avalanchego v1.10.18-rc.16/go.mod h1:eJiCzwIhrR9HWeryQ/tRP4w0Kg7bTDJ0t9cxjWxqd6o= +github.com/ava-labs/coreth v0.12.10-rc.4 h1:+Ll3cpi3tZbw37lTa+1a/VnPa7xZktpbAFiuKtDKnIE= +github.com/ava-labs/coreth v0.12.10-rc.4/go.mod h1:8pt5LW6MP/luIdhQA+gvs8LobKE8tP/5APXUiFbfb2c= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= @@ -133,8 +133,8 @@ github.com/cockroachdb/redact v1.1.3/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZ github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ= github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI= -github.com/consensys/gnark-crypto v0.10.0 h1:zRh22SR7o4K35SoNqouS9J/TKHTyU2QWaj5ldehyXtA= -github.com/consensys/gnark-crypto v0.10.0/go.mod h1:Iq/P3HHl0ElSjsg2E1gsMwhAyxnxoKK5nVyZKd+/KhU= +github.com/consensys/gnark-crypto v0.12.1 h1:lHH39WuuFgVHONRl3J0LRBtuYdQTumFSDtJF7HpyG8M= +github.com/consensys/gnark-crypto v0.12.1/go.mod h1:v2Gy7L/4ZRosZ7Ivs+9SfUDr0f5UlG+EM5t7MPHiLuY= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= diff --git a/scripts/versions.sh b/scripts/versions.sh index 2c64eae5c2..c00faf9361 100644 --- a/scripts/versions.sh +++ b/scripts/versions.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash # Don't export them as they're used in the context of other calls -AVALANCHE_VERSION=${AVALANCHE_VERSION:-'v1.10.18-rc.14'} +AVALANCHE_VERSION=${AVALANCHE_VERSION:-'v1.10.18-rc.16'} GINKGO_VERSION=${GINKGO_VERSION:-'v2.2.0'} # This won't be used, but it's here to make code syncs easier From 31dc86de2f718d7ac9580c62ed4b015d14ed4bcf Mon Sep 17 00:00:00 2001 From: Ceyhun Onur Date: Fri, 5 Jan 2024 13:33:54 +0300 Subject: [PATCH 24/26] add time to codec --- peer/network_test.go | 2 +- plugin/evm/message/codec.go | 6 ++++-- predicate/predicate_results.go | 3 ++- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/peer/network_test.go b/peer/network_test.go index e8d61fff1f..c011c339f9 100644 --- a/peer/network_test.go +++ b/peer/network_test.go @@ -887,7 +887,7 @@ func TestNetworkRouting(t *testing.T) { func buildCodec(t *testing.T, types ...interface{}) codec.Manager { codecManager := codec.NewDefaultManager() - c := linearcodec.NewDefault() + c := linearcodec.NewDefault(time.Time{}) for _, typ := range types { assert.NoError(t, c.RegisterType(typ)) } diff --git a/plugin/evm/message/codec.go b/plugin/evm/message/codec.go index e49838cd56..6939ca4978 100644 --- a/plugin/evm/message/codec.go +++ b/plugin/evm/message/codec.go @@ -4,6 +4,8 @@ package message import ( + "time" + "github.com/ava-labs/avalanchego/codec" "github.com/ava-labs/avalanchego/codec/linearcodec" "github.com/ava-labs/avalanchego/utils/units" @@ -22,7 +24,7 @@ var ( func init() { Codec = codec.NewManager(maxMessageSize) - c := linearcodec.NewDefault() + c := linearcodec.NewDefault(time.Time{}) errs := wrappers.Errs{} errs.Add( @@ -53,7 +55,7 @@ func init() { } CrossChainCodec = codec.NewManager(maxMessageSize) - ccc := linearcodec.NewDefault() + ccc := linearcodec.NewDefault(time.Time{}) errs = wrappers.Errs{} errs.Add( diff --git a/predicate/predicate_results.go b/predicate/predicate_results.go index f87b181f44..c28d811fe4 100644 --- a/predicate/predicate_results.go +++ b/predicate/predicate_results.go @@ -6,6 +6,7 @@ package predicate import ( "fmt" "strings" + "time" "github.com/ava-labs/avalanchego/codec" "github.com/ava-labs/avalanchego/codec/linearcodec" @@ -24,7 +25,7 @@ var Codec codec.Manager func init() { Codec = codec.NewManager(MaxResultsSize) - c := linearcodec.NewDefault() + c := linearcodec.NewDefault(time.Time{}) errs := wrappers.Errs{} errs.Add( c.RegisterType(Results{}), From ae4f5ebac84d7ba73303118c73d8899cf951d34e Mon Sep 17 00:00:00 2001 From: Patrick O'Grady Date: Mon, 22 Jan 2024 10:50:45 -0800 Subject: [PATCH 25/26] fix load test (#1043) * tweak global limit * uncomment submit * update consts * update avalanchego version * fix compilation err * simpler fix * remove mempool configs * bump latest avago rc * fix tests * update avalanchego * fix mockgen * bump ANR * remove unnecessary log levels * Fix bloom reset (#1049) * add UT for eth tx pool subscribe * fix eth tx pool subscribtion * don't use journal * simplify test * increase timeout * Update plugin/evm/tx_gossip_test.go Co-authored-by: Darioush Jalali Signed-off-by: Ceyhun Onur --------- Signed-off-by: Ceyhun Onur Co-authored-by: Ceyhun Onur Co-authored-by: Darioush Jalali --- go.mod | 9 ++-- go.sum | 18 ++++--- plugin/evm/gossip.go | 9 ++-- plugin/evm/gossip_test.go | 68 +++++++++++++++++++++++++++ plugin/evm/gossipper_test.go | 4 +- plugin/evm/tx_gossip_test.go | 5 +- plugin/evm/vm.go | 19 ++++---- precompile/contract/mocks.go | 7 ++- precompile/precompileconfig/mocks.go | 17 ++++--- scripts/mock.gen.sh | 7 +-- scripts/versions.sh | 2 +- tests/utils/runner/network_manager.go | 2 +- 12 files changed, 120 insertions(+), 47 deletions(-) diff --git a/go.mod b/go.mod index 1a152b8c84..dde3fad98d 100644 --- a/go.mod +++ b/go.mod @@ -4,8 +4,8 @@ go 1.20 require ( github.com/VictoriaMetrics/fastcache v1.10.0 - github.com/ava-labs/avalanche-network-runner v1.7.4-0.20231127162258-2f3ceed8ae4b - github.com/ava-labs/avalanchego v1.10.18-rc.16 + github.com/ava-labs/avalanche-network-runner v1.7.4-rc.0 + github.com/ava-labs/avalanchego v1.10.18 github.com/cespare/cp v0.1.0 github.com/cockroachdb/pebble v0.0.0-20230209160836-829675f94811 github.com/davecgh/go-spew v1.1.1 @@ -43,7 +43,7 @@ require ( github.com/tyler-smith/go-bip39 v1.1.0 github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa go.uber.org/goleak v1.2.1 - go.uber.org/mock v0.2.0 + go.uber.org/mock v0.4.0 golang.org/x/crypto v0.17.0 golang.org/x/sync v0.5.0 golang.org/x/sys v0.15.0 @@ -57,7 +57,7 @@ require ( github.com/DataDog/zstd v1.5.2 // indirect github.com/Microsoft/go-winio v0.5.2 // indirect github.com/NYTimes/gziphandler v1.1.1 // indirect - github.com/ava-labs/coreth v0.12.10-rc.4 // indirect + github.com/ava-labs/coreth v0.12.10-rc.5 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bits-and-blooms/bitset v1.7.0 // indirect github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect @@ -126,7 +126,6 @@ require ( github.com/rogpeppe/go-internal v1.10.0 // indirect github.com/rs/cors v1.7.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect - github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/spf13/afero v1.8.2 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/subosito/gotenv v1.3.0 // indirect diff --git a/go.sum b/go.sum index d4d6922ff4..5bd15d9519 100644 --- a/go.sum +++ b/go.sum @@ -59,12 +59,12 @@ github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/ava-labs/avalanche-network-runner v1.7.4-0.20231127162258-2f3ceed8ae4b h1:iH6q+S7dmBOYCXrZx+nNlS1HBp72L2msiVCLs39Ls5A= -github.com/ava-labs/avalanche-network-runner v1.7.4-0.20231127162258-2f3ceed8ae4b/go.mod h1:aeAm8dgJ1xucQKlYoRDMgYjA0UWGwmaICG9wL0WvseU= -github.com/ava-labs/avalanchego v1.10.18-rc.16 h1:gEH0ZSqbvWKITMk/i6qAeaeEUSAH/BGgfQgxZYAK/ck= -github.com/ava-labs/avalanchego v1.10.18-rc.16/go.mod h1:eJiCzwIhrR9HWeryQ/tRP4w0Kg7bTDJ0t9cxjWxqd6o= -github.com/ava-labs/coreth v0.12.10-rc.4 h1:+Ll3cpi3tZbw37lTa+1a/VnPa7xZktpbAFiuKtDKnIE= -github.com/ava-labs/coreth v0.12.10-rc.4/go.mod h1:8pt5LW6MP/luIdhQA+gvs8LobKE8tP/5APXUiFbfb2c= +github.com/ava-labs/avalanche-network-runner v1.7.4-rc.0 h1:xNbCMNqenaDr0bb35j27sqwa+C8t8BgRz51vXd6q0QM= +github.com/ava-labs/avalanche-network-runner v1.7.4-rc.0/go.mod h1:B7Ynk/avkCk49CCIWbM4j1UrPlqIi0IHCPAB2MZNvLw= +github.com/ava-labs/avalanchego v1.10.18 h1:ErJ+SJBtN9tVqk3OPRXffpf+MWeQnNZJlBNWQIgAg8A= +github.com/ava-labs/avalanchego v1.10.18/go.mod h1:wqmokVcLXE+9Nfa8wHdGJtjEW35acVf8rkraSZPVBA4= +github.com/ava-labs/coreth v0.12.10-rc.5 h1:FMVvXHssvMQ3Eade7i85Wsx9tuD3kUOFMG8ktHeDTp8= +github.com/ava-labs/coreth v0.12.10-rc.5/go.mod h1:a58HbIBc9jscGc3aL8e7JuG8RfhBBOm63waq1q0YM+U= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= @@ -557,8 +557,6 @@ github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= -github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.8.2 h1:xehSyVa0YnHWsJ49JFljMpg1HX19V6NDZ1fkm1Xznbo= github.com/spf13/afero v1.8.2/go.mod h1:CtAatgMJh6bJEIs48Ay/FOnkljP3WeGUG0MC1RfAqwo= @@ -660,8 +658,8 @@ go.opentelemetry.io/proto/otlp v0.19.0 h1:IVN6GR+mhC4s5yfcTbmzHYODqvWAp3ZedA2SJP go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4= -go.uber.org/mock v0.2.0 h1:TaP3xedm7JaAgScZO7tlvlKrqT0p7I6OsdGB5YNSMDU= -go.uber.org/mock v0.2.0/go.mod h1:J0y0rp9L3xiff1+ZBfKxlC1fz2+aO16tw0tsDOixfuM= +go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= +go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= diff --git a/plugin/evm/gossip.go b/plugin/evm/gossip.go index cee0461313..c1d1585e2b 100644 --- a/plugin/evm/gossip.go +++ b/plugin/evm/gossip.go @@ -85,7 +85,7 @@ func (t txGossipHandler) CrossChainAppRequest(context.Context, ids.ID, time.Time } func NewGossipEthTxPool(mempool *txpool.TxPool) (*GossipEthTxPool, error) { - bloom, err := gossip.NewBloomFilter(txGossipBloomMaxItems, txGossipBloomFalsePositiveRate) + bloom, err := gossip.NewBloomFilter(txGossipBloomMinTargetElements, txGossipBloomTargetFalsePositiveRate, txGossipBloomResetFalsePositiveRate) if err != nil { return nil, fmt.Errorf("failed to initialize bloom filter: %w", err) } @@ -115,10 +115,11 @@ func (g *GossipEthTxPool) Subscribe(ctx context.Context) { return case pendingTxs := <-g.pendingTxs: g.lock.Lock() + optimalElements := (g.mempool.PendingSize() + len(pendingTxs.Txs)) * txGossipBloomChurnMultiplier for _, pendingTx := range pendingTxs.Txs { tx := &GossipEthTx{Tx: pendingTx} g.bloom.Add(tx) - reset, err := gossip.ResetBloomFilterIfNeeded(g.bloom, txGossipMaxFalsePositiveRate) + reset, err := gossip.ResetBloomFilterIfNeeded(g.bloom, optimalElements) if err != nil { log.Error("failed to reset bloom filter", "err", err) continue @@ -128,7 +129,7 @@ func (g *GossipEthTxPool) Subscribe(ctx context.Context) { log.Debug("resetting bloom filter", "reason", "reached max filled ratio") g.mempool.IteratePending(func(tx *types.Transaction) bool { - g.bloom.Add(&GossipEthTx{Tx: pendingTx}) + g.bloom.Add(&GossipEthTx{Tx: tx}) return true }) } @@ -150,7 +151,7 @@ func (g *GossipEthTxPool) Iterate(f func(tx *GossipEthTx) bool) { }) } -func (g *GossipEthTxPool) GetFilter() ([]byte, []byte, error) { +func (g *GossipEthTxPool) GetFilter() ([]byte, []byte) { g.lock.RLock() defer g.lock.RUnlock() diff --git a/plugin/evm/gossip_test.go b/plugin/evm/gossip_test.go index 153507c19b..dff56c03b1 100644 --- a/plugin/evm/gossip_test.go +++ b/plugin/evm/gossip_test.go @@ -4,9 +4,21 @@ package evm import ( + "context" + "math/big" "testing" + "time" + "github.com/ava-labs/avalanchego/network/p2p/gossip" + "github.com/ava-labs/subnet-evm/consensus/dummy" + "github.com/ava-labs/subnet-evm/core" + "github.com/ava-labs/subnet-evm/core/rawdb" + "github.com/ava-labs/subnet-evm/core/txpool" "github.com/ava-labs/subnet-evm/core/types" + "github.com/ava-labs/subnet-evm/core/vm" + "github.com/ava-labs/subnet-evm/params" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" "github.com/stretchr/testify/require" ) @@ -24,3 +36,59 @@ func TestGossipEthTxMarshaller(t *testing.T) { require.NoError(err) require.Equal(want.GossipID(), got.GossipID()) } + +func TestGossipSubscribe(t *testing.T) { + require := require.New(t) + key, err := crypto.GenerateKey() + require.NoError(err) + addr := crypto.PubkeyToAddress(key.PublicKey) + + require.NoError(err) + txPool := setupPoolWithConfig(t, params.TestChainConfig, addr) + defer txPool.Stop() + txPool.SetGasPrice(common.Big1) + txPool.SetMinFee(common.Big0) + + gossipTxPool, err := NewGossipEthTxPool(txPool) + require.NoError(err) + + // use a custom bloom filter to test the bloom filter reset + gossipTxPool.bloom, err = gossip.NewBloomFilter(1, 0.01, 0.0000000000000001) // maxCount =1 + require.NoError(err) + ctx, cancel := context.WithCancel(context.TODO()) + go func() { + gossipTxPool.Subscribe(ctx) + }() + + // create eth txs + ethTxs := getValidEthTxs(key, 10, big.NewInt(226*params.GWei)) + + // Notify mempool about txs + errs := txPool.AddRemotesSync(ethTxs) + for _, err := range errs { + require.NoError(err, "failed adding subnet-evm tx to remote mempool") + } + time.Sleep(1 * time.Second) + cancel() + for i, tx := range ethTxs { + gossipable := &GossipEthTx{Tx: tx} + require.Truef(gossipTxPool.bloom.Has(gossipable), "expected tx to be in bloom filter: index %d", i) + } +} + +func setupPoolWithConfig(t *testing.T, config *params.ChainConfig, fundedAddress common.Address) *txpool.TxPool { + diskdb := rawdb.NewMemoryDatabase() + engine := dummy.NewETHFaker() + + var gspec = &core.Genesis{ + Config: config, + Alloc: core.GenesisAlloc{fundedAddress: core.GenesisAccount{Balance: big.NewInt(1000000000000000000)}}, + } + chain, err := core.NewBlockChain(diskdb, core.DefaultCacheConfig, gspec, engine, vm.Config{}, common.Hash{}, false) + require.NoError(t, err) + testTxPoolConfig := txpool.DefaultConfig + testTxPoolConfig.Journal = "" + pool := txpool.NewTxPool(testTxPoolConfig, config, chain) + + return pool +} diff --git a/plugin/evm/gossipper_test.go b/plugin/evm/gossipper_test.go index bf7f91a165..68bcbd8c1a 100644 --- a/plugin/evm/gossipper_test.go +++ b/plugin/evm/gossipper_test.go @@ -53,8 +53,8 @@ func getValidEthTxs(key *ecdsa.PrivateKey, count int, gasPrice *big.Int) []*type res := make([]*types.Transaction, count) to := common.Address{} - amount := big.NewInt(10000) - gasLimit := uint64(100000) + amount := big.NewInt(0) + gasLimit := uint64(37000) for i := 0; i < count; i++ { tx, _ := types.SignTx( diff --git a/plugin/evm/tx_gossip_test.go b/plugin/evm/tx_gossip_test.go index 9044750ada..b0efc23717 100644 --- a/plugin/evm/tx_gossip_test.go +++ b/plugin/evm/tx_gossip_test.go @@ -82,10 +82,9 @@ func TestEthTxGossip(t *testing.T) { } // Ask the VM for any new transactions. We should get nothing at first. - emptyBloomFilter, err := gossip.NewBloomFilter(txGossipBloomMaxItems, txGossipBloomFalsePositiveRate) - require.NoError(err) - emptyBloomFilterBytes, _, err := emptyBloomFilter.Marshal() + emptyBloomFilter, err := gossip.NewBloomFilter(txGossipBloomMinTargetElements, txGossipBloomTargetFalsePositiveRate, txGossipBloomResetFalsePositiveRate) require.NoError(err) + emptyBloomFilterBytes, _ := emptyBloomFilter.Marshal() request := &sdk.PullGossipRequest{ Filter: emptyBloomFilterBytes, Salt: agoUtils.RandomBytes(32), diff --git a/plugin/evm/vm.go b/plugin/evm/vm.go index f92eaea1ea..8c60da40a9 100644 --- a/plugin/evm/vm.go +++ b/plugin/evm/vm.go @@ -106,15 +106,16 @@ const ( ethTxGossipProtocol = 0x0 // gossip constants - txGossipBloomMaxItems = 8 * 1024 - txGossipBloomFalsePositiveRate = 0.01 - txGossipMaxFalsePositiveRate = 0.05 - txGossipTargetMessageSize = 20 * units.KiB - maxValidatorSetStaleness = time.Minute - txGossipThrottlingPeriod = 10 * time.Second - txGossipThrottlingLimit = 2 - gossipFrequency = 10 * time.Second - txGossipPollSize = 10 + txGossipBloomMinTargetElements = 8 * 1024 + txGossipBloomTargetFalsePositiveRate = 0.01 + txGossipBloomResetFalsePositiveRate = 0.05 + txGossipBloomChurnMultiplier = 3 + txGossipTargetMessageSize = 20 * units.KiB + maxValidatorSetStaleness = time.Minute + txGossipThrottlingPeriod = 10 * time.Second + txGossipThrottlingLimit = 2 + gossipFrequency = 10 * time.Second + txGossipPollSize = 10 ) // Define the API endpoints for the VM diff --git a/precompile/contract/mocks.go b/precompile/contract/mocks.go index 8a208a7e17..5ab8dbac26 100644 --- a/precompile/contract/mocks.go +++ b/precompile/contract/mocks.go @@ -1,5 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/subnet-evm/precompile/contract (interfaces: BlockContext,AccessibleState) +// +// Generated by this command: +// +// mockgen -package=contract -destination=precompile/contract/mocks.go github.com/ava-labs/subnet-evm/precompile/contract BlockContext,AccessibleState +// // Package contract is a generated GoMock package. package contract @@ -46,7 +51,7 @@ func (m *MockBlockContext) GetPredicateResults(arg0 common.Hash, arg1 common.Add } // GetPredicateResults indicates an expected call of GetPredicateResults. -func (mr *MockBlockContextMockRecorder) GetPredicateResults(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockBlockContextMockRecorder) GetPredicateResults(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPredicateResults", reflect.TypeOf((*MockBlockContext)(nil).GetPredicateResults), arg0, arg1) } diff --git a/precompile/precompileconfig/mocks.go b/precompile/precompileconfig/mocks.go index 8d425daefa..614ec5a522 100644 --- a/precompile/precompileconfig/mocks.go +++ b/precompile/precompileconfig/mocks.go @@ -1,5 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/subnet-evm/precompile/precompileconfig (interfaces: Predicater,Config,ChainConfig,Accepter) +// +// Generated by this command: +// +// mockgen -package=precompileconfig -destination=precompile/precompileconfig/mocks.go github.com/ava-labs/subnet-evm/precompile/precompileconfig Predicater,Config,ChainConfig,Accepter +// // Package precompileconfig is a generated GoMock package. package precompileconfig @@ -45,7 +50,7 @@ func (m *MockPredicater) PredicateGas(arg0 []byte) (uint64, error) { } // PredicateGas indicates an expected call of PredicateGas. -func (mr *MockPredicaterMockRecorder) PredicateGas(arg0 interface{}) *gomock.Call { +func (mr *MockPredicaterMockRecorder) PredicateGas(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PredicateGas", reflect.TypeOf((*MockPredicater)(nil).PredicateGas), arg0) } @@ -59,7 +64,7 @@ func (m *MockPredicater) VerifyPredicate(arg0 *PredicateContext, arg1 []byte) er } // VerifyPredicate indicates an expected call of VerifyPredicate. -func (mr *MockPredicaterMockRecorder) VerifyPredicate(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockPredicaterMockRecorder) VerifyPredicate(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "VerifyPredicate", reflect.TypeOf((*MockPredicater)(nil).VerifyPredicate), arg0, arg1) } @@ -96,7 +101,7 @@ func (m *MockConfig) Equal(arg0 Config) bool { } // Equal indicates an expected call of Equal. -func (mr *MockConfigMockRecorder) Equal(arg0 interface{}) *gomock.Call { +func (mr *MockConfigMockRecorder) Equal(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Equal", reflect.TypeOf((*MockConfig)(nil).Equal), arg0) } @@ -152,7 +157,7 @@ func (m *MockConfig) Verify(arg0 ChainConfig) error { } // Verify indicates an expected call of Verify. -func (mr *MockConfigMockRecorder) Verify(arg0 interface{}) *gomock.Call { +func (mr *MockConfigMockRecorder) Verify(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Verify", reflect.TypeOf((*MockConfig)(nil).Verify), arg0) } @@ -217,7 +222,7 @@ func (m *MockChainConfig) IsDurango(arg0 uint64) bool { } // IsDurango indicates an expected call of IsDurango. -func (mr *MockChainConfigMockRecorder) IsDurango(arg0 interface{}) *gomock.Call { +func (mr *MockChainConfigMockRecorder) IsDurango(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsDurango", reflect.TypeOf((*MockChainConfig)(nil).IsDurango), arg0) } @@ -254,7 +259,7 @@ func (m *MockAccepter) Accept(arg0 *AcceptContext, arg1 common.Hash, arg2 uint64 } // Accept indicates an expected call of Accept. -func (mr *MockAccepterMockRecorder) Accept(arg0, arg1, arg2, arg3, arg4, arg5, arg6 interface{}) *gomock.Call { +func (mr *MockAccepterMockRecorder) Accept(arg0, arg1, arg2, arg3, arg4, arg5, arg6 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Accept", reflect.TypeOf((*MockAccepter)(nil).Accept), arg0, arg1, arg2, arg3, arg4, arg5, arg6) } diff --git a/scripts/mock.gen.sh b/scripts/mock.gen.sh index aa548f4cba..ae25b3f587 100755 --- a/scripts/mock.gen.sh +++ b/scripts/mock.gen.sh @@ -13,11 +13,8 @@ if ! [[ "$0" =~ scripts/mock.gen.sh ]]; then exit 255 fi -if ! command -v mockgen &>/dev/null; then - echo "mockgen not found, installing..." - # https://github.com/uber-go/mock - go install -v go.uber.org/mock/mockgen@v0.2.0 -fi +# https://github.com/uber-go/mock +go install -v go.uber.org/mock/mockgen@v0.4.0 if ! command -v go-license &>/dev/null; then echo "go-license not found, installing..." diff --git a/scripts/versions.sh b/scripts/versions.sh index c00faf9361..d773bf1459 100644 --- a/scripts/versions.sh +++ b/scripts/versions.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash # Don't export them as they're used in the context of other calls -AVALANCHE_VERSION=${AVALANCHE_VERSION:-'v1.10.18-rc.16'} +AVALANCHE_VERSION=${AVALANCHE_VERSION:-'v1.10.18'} GINKGO_VERSION=${GINKGO_VERSION:-'v2.2.0'} # This won't be used, but it's here to make code syncs easier diff --git a/tests/utils/runner/network_manager.go b/tests/utils/runner/network_manager.go index ba0cf1e668..138ce73034 100644 --- a/tests/utils/runner/network_manager.go +++ b/tests/utils/runner/network_manager.go @@ -66,7 +66,7 @@ func NewDefaultANRConfig() ANRConfig { AvalancheGoExecPath: os.ExpandEnv("$GOPATH/src/github.com/ava-labs/avalanchego/build/avalanchego"), PluginDir: os.ExpandEnv("$GOPATH/src/github.com/ava-labs/avalanchego/build/plugins"), GlobalNodeConfig: `{ - "log-display-level":"info", + "log-level":"info", "proposervm-use-current-height":true }`, GlobalCChainConfig: `{ From 9b4808adfd1af0314828f7483ecfc23374ea81ba Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Mon, 22 Jan 2024 17:31:04 -0500 Subject: [PATCH 26/26] Fix racey bloom access and replace time.Sleep with require.Eventually --- plugin/evm/gossip_test.go | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/plugin/evm/gossip_test.go b/plugin/evm/gossip_test.go index dff56c03b1..a9f80355e8 100644 --- a/plugin/evm/gossip_test.go +++ b/plugin/evm/gossip_test.go @@ -56,9 +56,8 @@ func TestGossipSubscribe(t *testing.T) { gossipTxPool.bloom, err = gossip.NewBloomFilter(1, 0.01, 0.0000000000000001) // maxCount =1 require.NoError(err) ctx, cancel := context.WithCancel(context.TODO()) - go func() { - gossipTxPool.Subscribe(ctx) - }() + defer cancel() + go gossipTxPool.Subscribe(ctx) // create eth txs ethTxs := getValidEthTxs(key, 10, big.NewInt(226*params.GWei)) @@ -68,12 +67,23 @@ func TestGossipSubscribe(t *testing.T) { for _, err := range errs { require.NoError(err, "failed adding subnet-evm tx to remote mempool") } - time.Sleep(1 * time.Second) - cancel() - for i, tx := range ethTxs { - gossipable := &GossipEthTx{Tx: tx} - require.Truef(gossipTxPool.bloom.Has(gossipable), "expected tx to be in bloom filter: index %d", i) - } + + require.Eventually( + func() bool { + gossipTxPool.lock.RLock() + defer gossipTxPool.lock.RUnlock() + + for _, tx := range ethTxs { + if !gossipTxPool.bloom.Has(&GossipEthTx{Tx: tx}) { + return false + } + } + return true + }, + 10*time.Second, + 10*time.Millisecond, + "expected all transactions to eventually be in the bloom filter", + ) } func setupPoolWithConfig(t *testing.T, config *params.ChainConfig, fundedAddress common.Address) *txpool.TxPool {