From bb628f9562dc66eb4fe71bd292771d3768263392 Mon Sep 17 00:00:00 2001 From: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> Date: Tue, 12 Dec 2023 03:26:19 -0500 Subject: [PATCH 01/11] refactor unit tests Signed-off-by: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 +- peer/network_test.go | 10 +- plugin/evm/tx_gossip_test.go | 247 ++++++++++++++++++++--------------- plugin/evm/vm.go | 141 +++++++++++--------- plugin/evm/vm_test.go | 18 +++ scripts/versions.sh | 2 +- 7 files changed, 240 insertions(+), 184 deletions(-) diff --git a/go.mod b/go.mod index 9cd0967481..ad84ba1477 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.20 require ( github.com/VictoriaMetrics/fastcache v1.10.0 - github.com/ava-labs/avalanchego v1.10.18-rc.0 + github.com/ava-labs/avalanchego v1.10.18-0.20231212085650-4df2d3f2f052 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 a6e1835c60..aa0c899210 100644 --- a/go.sum +++ b/go.sum @@ -55,8 +55,8 @@ 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/avalanchego v1.10.18-rc.0 h1:8tsu5qB/Fp5NFZuJQR48q6wMHGJxGfzvlGxvxdnjg6o= -github.com/ava-labs/avalanchego v1.10.18-rc.0/go.mod h1:ZbZteX1xINA3U31/akSGO/ZrcVAA7V6tDle0ENJ3DPI= +github.com/ava-labs/avalanchego v1.10.18-0.20231212085650-4df2d3f2f052 h1:JQTyutUtLRairI/DI99LG9dJNcfM7v0nn2+qg9718gM= +github.com/ava-labs/avalanchego v1.10.18-0.20231212085650-4df2d3f2f052/go.mod h1:npeYlspwYFUNHgCcm7vEjvsHQilLy3ymtSGJ4iZSRto= 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/peer/network_test.go b/peer/network_test.go index c077e7736a..5c4820cb08 100644 --- a/peer/network_test.go +++ b/peer/network_test.go @@ -814,17 +814,9 @@ func TestNetworkCrossChainAppRequestAfterShutdown(t *testing.T) { func TestNetworkRouting(t *testing.T) { require := require.New(t) - sender := &testAppSender{ - sendAppRequestFn: func(_ context.Context, s set.Set[ids.NodeID], u uint32, bytes []byte) error { - return nil - }, - sendAppResponseFn: func(id ids.NodeID, u uint32, bytes []byte) error { - return nil - }, - } protocol := 0 handler := &testSDKHandler{} - p2pNetwork := p2p.NewNetwork(logging.NoLog{}, sender, prometheus.NewRegistry(), "") + p2pNetwork := p2p.NewNetwork(logging.NoLog{}, &p2p.FakeSender{}, prometheus.NewRegistry(), "") _, err := p2pNetwork.NewAppProtocol(uint64(protocol), handler) require.NoError(err) diff --git a/plugin/evm/tx_gossip_test.go b/plugin/evm/tx_gossip_test.go index 92bd3951a0..cabc7dfde9 100644 --- a/plugin/evm/tx_gossip_test.go +++ b/plugin/evm/tx_gossip_test.go @@ -10,62 +10,90 @@ import ( "testing" "time" + "github.com/ava-labs/avalanchego/chains/atomic" + "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/crypto/secp256k1" "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/utils/set" + "github.com/ava-labs/avalanchego/vms/components/avax" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" "github.com/prometheus/client_golang/prometheus" "github.com/stretchr/testify/require" "google.golang.org/protobuf/proto" - "github.com/ava-labs/coreth/core" "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/params" ) func TestEthTxGossip(t *testing.T) { require := require.New(t) + ctx := context.Background() + snowCtx := snow.DefaultContextTest() + validatorState := &validators.TestState{} + snowCtx.ValidatorState = validatorState - // set up prefunded address - importAmount := uint64(1_000_000_000) - issuer, vm, _, _, sender := GenesisVMWithUTXOs(t, true, genesisJSONLatest, "", "", map[ids.ShortID]uint64{ - testShortIDAddrs[0]: importAmount, - }) - defer func() { - require.NoError(vm.Shutdown(context.Background())) - }() - - txPoolNewHeads := make(chan core.NewTxPoolHeadEvent) - vm.txPool.SubscribeNewHeadEvent(txPoolNewHeads) - - importTx, err := vm.newImportTx(vm.ctx.XChainID, testEthAddrs[0], initialBaseFee, []*secp256k1.PrivateKey{testKeys[0]}) + pk, err := secp256k1.NewPrivateKey() require.NoError(err) - require.NoError(vm.mempool.AddLocalTx(importTx)) - <-issuer - - blk, err := vm.BuildBlock(context.Background()) + address := GetEthAddress(pk) + genesis := newPrefundedGenesis(100_000_000_000_000_000, address) + genesisBytes, err := genesis.MarshalJSON() require.NoError(err) - require.NoError(blk.Verify(context.Background())) - require.NoError(vm.SetPreference(context.Background(), blk.ID())) - require.NoError(blk.Accept(context.Background())) - <-txPoolNewHeads + responseSender := &p2p.FakeSender{ + SentAppResponse: make(chan []byte, 1), + } + vm := &VM{ + p2pSender: responseSender, + atomicTxGossipHandler: &p2p.NoOpHandler{}, + atomicTxGossiper: &gossip.NoOpGossiper{}, + } + + require.NoError(vm.Initialize( + ctx, + snowCtx, + memdb.New(), + genesisBytes, + nil, + nil, + make(chan common.Message), + nil, + &common.SenderTest{}, + )) + require.NoError(vm.SetState(ctx, snow.NormalOp)) + + defer func() { + 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 := &p2p.FakeSender{ + SentAppRequest: make(chan []byte, 1), + } + network := p2p.NewNetwork(logging.NoLog{}, peerSender, prometheus.NewRegistry(), "") - // we're only making client requests, so we don't need a server handler - client, err := router.NewAppProtocol(ethTxGossipProtocol, nil) + client, err := network.NewAppProtocol(ethTxGossipProtocol, &p2p.NoOpHandler{}) require.NoError(err) + // 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() @@ -79,34 +107,6 @@ func TestEthTxGossip(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) @@ -116,14 +116,14 @@ func TestEthTxGossip(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 - address := testEthAddrs[0] - key := testKeys[0].ToECDSA() tx := types.NewTransaction(0, address, big.NewInt(10), 100_000, big.NewInt(params.LaunchMinGasPrice), nil) - signedTx, err := types.SignTx(tx, types.NewEIP155Signer(vm.chainID), key) + signedTx, err := types.SignTx(tx, types.NewEIP155Signer(vm.chainID), pk.ToECDSA()) require.NoError(err) errs := vm.txPool.AddLocals([]*types.Transaction{signedTx}) @@ -148,70 +148,93 @@ func TestEthTxGossip(t *testing.T) { 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 TestAtomicTxGossip(t *testing.T) { require := require.New(t) + ctx := context.Background() + snowCtx := snow.DefaultContextTest() + snowCtx.AVAXAssetID = ids.GenerateTestID() + snowCtx.XChainID = ids.GenerateTestID() + validatorState := &validators.TestState{ + GetSubnetIDF: func(context.Context, ids.ID) (ids.ID, error) { + return ids.Empty, nil + }, + } + snowCtx.ValidatorState = validatorState + memory := atomic.NewMemory(memdb.New()) + snowCtx.SharedMemory = memory.NewSharedMemory(ids.Empty) - // set up prefunded address - importAmount := uint64(1_000_000_000) - issuer, vm, _, _, sender := GenesisVMWithUTXOs(t, true, genesisJSONApricotPhase0, "", "", map[ids.ShortID]uint64{ - testShortIDAddrs[0]: importAmount, - }) + pk, err := secp256k1.NewPrivateKey() + require.NoError(err) + address := GetEthAddress(pk) + genesis := newPrefundedGenesis(100_000_000_000_000_000, address) + genesisBytes, err := genesis.MarshalJSON() + require.NoError(err) + + responseSender := &p2p.FakeSender{ + SentAppResponse: make(chan []byte, 1), + } + vm := &VM{ + p2pSender: responseSender, + ethTxGossipHandler: &p2p.NoOpHandler{}, + ethTxGossiper: &gossip.NoOpGossiper{}, + } + + require.NoError(vm.Initialize( + ctx, + snowCtx, + memdb.New(), + genesisBytes, + nil, + nil, + make(chan common.Message), + nil, + &common.SenderTest{}, + )) + require.NoError(vm.SetState(ctx, snow.NormalOp)) defer func() { - require.NoError(vm.Shutdown(context.Background())) + require.NoError(vm.Shutdown(ctx)) }() // sender for the peer requesting gossip from [vm] - peerSender := &common.SenderTest{} + peerSender := &p2p.FakeSender{ + SentAppRequest: make(chan []byte, 1), + } network := p2p.NewNetwork(logging.NoLog{}, peerSender, prometheus.NewRegistry(), "") - // we're only making client requests, so we don't need a server handler - client, err := network.NewAppProtocol(atomicTxGossipProtocol, nil) + client, err := network.NewAppProtocol(atomicTxGossipProtocol, &p2p.NoOpHandler{}) require.NoError(err) + // 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) - bloomBytes, err := emptyBloomFilter.Bloom.MarshalBinary() + emptyBloomFilterBytes, err := emptyBloomFilter.Bloom.MarshalBinary() require.NoError(err) request := &sdk.PullGossipRequest{ - Filter: bloomBytes, - Salt: emptyBloomFilter.Salt[:], + Filter: emptyBloomFilterBytes, + Salt: utils.RandomBytes(32), } + requestBytes, err := proto.Marshal(request) require.NoError(err) - requestingNodeID := ids.GenerateTestNodeID() wg := &sync.WaitGroup{} - peerSender.SendAppRequestF = func(ctx context.Context, _ 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(network.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) @@ -221,15 +244,25 @@ func TestAtomicTxGossip(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 new tx to the vm - importTx, err := vm.newImportTx(vm.ctx.XChainID, testEthAddrs[0], initialBaseFee, []*secp256k1.PrivateKey{testKeys[0]}) + // Issue a tx to the VM + utxo, err := addUTXO( + memory, + snowCtx, + ids.GenerateTestID(), + 0, + snowCtx.AVAXAssetID, + 100_000_000_000, + pk.PublicKey().Address(), + ) require.NoError(err) - - require.NoError(vm.mempool.AddLocalTx(importTx)) - <-issuer + tx, err := vm.newImportTxWithUTXOs(vm.ctx.XChainID, address, initialBaseFee, secp256k1fx.NewKeychain(pk), []*avax.UTXO{utxo}) + require.NoError(err) + require.NoError(vm.mempool.AddLocalTx(tx)) // wait so we aren't throttled by the vm time.Sleep(5 * time.Second) @@ -245,10 +278,12 @@ func TestAtomicTxGossip(t *testing.T) { gotTx := &GossipAtomicTx{} require.NoError(gotTx.Unmarshal(response.Gossip[0])) - require.Equal(importTx.InputUTXOs(), gotTx.Tx.InputUTXOs()) + require.Equal(tx.ID(), gotTx.GetID()) 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() } diff --git a/plugin/evm/vm.go b/plugin/evm/vm.go index 8049a8ef84..fcc26e1c78 100644 --- a/plugin/evm/vm.go +++ b/plugin/evm/vm.go @@ -343,6 +343,12 @@ type VM struct { // Avalanche Warp Messaging backend // Used to serve BLS signatures of warp messages over RPC warpBackend warp.Backend + + p2pSender p2p.AppSender + ethTxGossipHandler p2p.Handler + atomicTxGossipHandler p2p.Handler + ethTxGossiper gossip.Gossiper + atomicTxGossiper gossip.Gossiper } // Codec implements the secp256k1fx interface @@ -584,7 +590,11 @@ func (vm *VM) Initialize( } // initialize peer network - p2pNetwork := p2p.NewNetwork(vm.ctx.Log, appSender, vm.sdkMetrics, "p2p") + if vm.p2pSender == nil { + vm.p2pSender = p2p.NewSender(appSender) + } + + p2pNetwork := p2p.NewNetwork(vm.ctx.Log, vm.p2pSender, vm.sdkMetrics, "p2p") 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) @@ -1068,94 +1078,95 @@ func (vm *VM) initBlockBuilding() error { vm.shutdownWg.Done() }() - var ( - ethTxGossipHandler p2p.Handler - atomicTxGossipHandler p2p.Handler - ) + if vm.ethTxGossipHandler == nil { + vm.ethTxGossipHandler, err = gossip.NewHandler[*GossipEthTx](ethTxPool, ethTxGossipHandlerConfig, vm.sdkMetrics) + if err != nil { + return err + } - ethTxGossipHandler, err = gossip.NewHandler[*GossipEthTx](ethTxPool, ethTxGossipHandlerConfig, vm.sdkMetrics) - if err != nil { - return err - } - ethTxGossipHandler = &p2p.ValidatorHandler{ - ValidatorSet: vm.validators, - Handler: &p2p.ThrottlerHandler{ - Handler: ethTxGossipHandler, - Throttler: p2p.NewSlidingWindowThrottler(throttlingPeriod, throttlingLimit), - Log: vm.ctx.Log, - }, - Log: vm.ctx.Log, + vm.ethTxGossipHandler = &p2p.ValidatorHandler{ + ValidatorSet: vm.validators, + Handler: &p2p.ThrottlerHandler{ + Handler: vm.ethTxGossipHandler, + Throttler: p2p.NewSlidingWindowThrottler(throttlingPeriod, throttlingLimit), + Log: vm.ctx.Log, + }, + Log: vm.ctx.Log, + } } - ethTxGossipClient, err := vm.Network.NewAppProtocol(ethTxGossipProtocol, ethTxGossipHandler, p2p.WithValidatorSampling(vm.validators)) + ethTxGossipClient, err := vm.Network.NewAppProtocol(ethTxGossipProtocol, vm.ethTxGossipHandler, p2p.WithValidatorSampling(vm.validators)) if err != nil { return err } - atomicTxGossipHandler, err = gossip.NewHandler[*GossipAtomicTx](vm.mempool, atomicTxGossipHandlerConfig, vm.sdkMetrics) - if err != nil { - return err - } + if vm.atomicTxGossipHandler == nil { + vm.atomicTxGossipHandler, err = gossip.NewHandler[*GossipAtomicTx](vm.mempool, atomicTxGossipHandlerConfig, vm.sdkMetrics) + if err != nil { + return err + } - atomicTxGossipHandler = &p2p.ValidatorHandler{ - ValidatorSet: vm.validators, - Handler: &p2p.ThrottlerHandler{ - Throttler: p2p.NewSlidingWindowThrottler(throttlingPeriod, throttlingLimit), - Handler: atomicTxGossipHandler, - Log: vm.ctx.Log, - }, - Log: vm.ctx.Log, + vm.atomicTxGossipHandler = &p2p.ValidatorHandler{ + ValidatorSet: vm.validators, + Handler: &p2p.ThrottlerHandler{ + Throttler: p2p.NewSlidingWindowThrottler(throttlingPeriod, throttlingLimit), + Handler: vm.atomicTxGossipHandler, + Log: vm.ctx.Log, + }, + Log: vm.ctx.Log, + } } - atomicTxGossipClient, err := vm.Network.NewAppProtocol(atomicTxGossipProtocol, atomicTxGossipHandler, p2p.WithValidatorSampling(vm.validators)) + atomicTxGossipClient, err := vm.Network.NewAppProtocol(atomicTxGossipProtocol, vm.atomicTxGossipHandler, p2p.WithValidatorSampling(vm.validators)) if err != nil { return err } - var ( - ethTxGossiper gossip.Gossiper - atomicTxGossiper gossip.Gossiper - ) - ethTxGossiper, err = gossip.NewPullGossiper[GossipEthTx, *GossipEthTx]( - ethTxGossipConfig, - vm.ctx.Log, - ethTxPool, - ethTxGossipClient, - vm.sdkMetrics, - ) - if err != nil { - return err - } - ethTxGossiper = gossip.ValidatorGossiper{ - Gossiper: ethTxGossiper, - NodeID: vm.ctx.NodeID, - Validators: vm.validators, + if vm.ethTxGossiper == nil { + vm.ethTxGossiper, err = gossip.NewPullGossiper[GossipEthTx, *GossipEthTx]( + ethTxGossipConfig, + vm.ctx.Log, + ethTxPool, + ethTxGossipClient, + vm.sdkMetrics, + ) + if err != nil { + return err + } + + vm.ethTxGossiper = gossip.ValidatorGossiper{ + Gossiper: vm.ethTxGossiper, + NodeID: vm.ctx.NodeID, + Validators: vm.validators, + } } vm.shutdownWg.Add(1) go func() { - gossip.Every(ctx, vm.ctx.Log, ethTxGossiper, gossipFrequency) + gossip.Every(ctx, vm.ctx.Log, vm.ethTxGossiper, gossipFrequency) vm.shutdownWg.Done() }() - atomicTxGossiper, err = gossip.NewPullGossiper[GossipAtomicTx, *GossipAtomicTx]( - atomicTxGossipConfig, - vm.ctx.Log, - vm.mempool, - atomicTxGossipClient, - vm.sdkMetrics, - ) - if err != nil { - return err - } - atomicTxGossiper = gossip.ValidatorGossiper{ - Gossiper: atomicTxGossiper, - NodeID: vm.ctx.NodeID, - Validators: vm.validators, + if vm.atomicTxGossiper == nil { + vm.atomicTxGossiper, err = gossip.NewPullGossiper[GossipAtomicTx, *GossipAtomicTx]( + atomicTxGossipConfig, + vm.ctx.Log, + vm.mempool, + atomicTxGossipClient, + vm.sdkMetrics, + ) + if err != nil { + return err + } + vm.atomicTxGossiper = gossip.ValidatorGossiper{ + Gossiper: vm.atomicTxGossiper, + NodeID: vm.ctx.NodeID, + Validators: vm.validators, + } } vm.shutdownWg.Add(1) go func() { - gossip.Every(ctx, vm.ctx.Log, atomicTxGossiper, gossipFrequency) + gossip.Every(ctx, vm.ctx.Log, vm.atomicTxGossiper, gossipFrequency) vm.shutdownWg.Done() }() diff --git a/plugin/evm/vm_test.go b/plugin/evm/vm_test.go index 0ba3b17c87..0f4dea63e9 100644 --- a/plugin/evm/vm_test.go +++ b/plugin/evm/vm_test.go @@ -126,6 +126,24 @@ func init() { } } +func newPrefundedGenesis( + balance int, + addresses ...common.Address, +) *core.Genesis { + alloc := core.GenesisAlloc{} + for _, address := range addresses { + alloc[address] = core.GenesisAccount{ + Balance: big.NewInt(int64(balance)), + } + } + + return &core.Genesis{ + Config: params.TestChainConfig, + Difficulty: big.NewInt(0), + Alloc: alloc, + } +} + // BuildGenesisTest returns the genesis bytes for Coreth VM to be used in testing func BuildGenesisTest(t *testing.T, genesisJSON string) []byte { ss := StaticService{} diff --git a/scripts/versions.sh b/scripts/versions.sh index 89f15a1d24..76fbe3a455 100644 --- a/scripts/versions.sh +++ b/scripts/versions.sh @@ -1,4 +1,4 @@ #!/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.0'} +avalanche_version=${AVALANCHE_VERSION:-'sender-refactor'} From c936826875a21e0de3090f358bd2bd9d15ef0550 Mon Sep 17 00:00:00 2001 From: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> Date: Tue, 12 Dec 2023 13:46:00 -0500 Subject: [PATCH 02/11] nit Signed-off-by: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- peer/network_test.go | 2 +- plugin/evm/tx_gossip_test.go | 8 ++++---- plugin/evm/vm.go | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/go.mod b/go.mod index ad84ba1477..abe6f0a38a 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.20 require ( github.com/VictoriaMetrics/fastcache v1.10.0 - github.com/ava-labs/avalanchego v1.10.18-0.20231212085650-4df2d3f2f052 + github.com/ava-labs/avalanchego v1.10.18-0.20231212183827-1578bb29776c 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 aa0c899210..f5838abe1b 100644 --- a/go.sum +++ b/go.sum @@ -55,8 +55,8 @@ 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/avalanchego v1.10.18-0.20231212085650-4df2d3f2f052 h1:JQTyutUtLRairI/DI99LG9dJNcfM7v0nn2+qg9718gM= -github.com/ava-labs/avalanchego v1.10.18-0.20231212085650-4df2d3f2f052/go.mod h1:npeYlspwYFUNHgCcm7vEjvsHQilLy3ymtSGJ4iZSRto= +github.com/ava-labs/avalanchego v1.10.18-0.20231212183827-1578bb29776c h1:ZD58N48KMzpPzhtVCp8h8kxS93XxlkDXmxIO4+I+mrc= +github.com/ava-labs/avalanchego v1.10.18-0.20231212183827-1578bb29776c/go.mod h1:npeYlspwYFUNHgCcm7vEjvsHQilLy3ymtSGJ4iZSRto= 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/peer/network_test.go b/peer/network_test.go index 5c4820cb08..b50bcac6a7 100644 --- a/peer/network_test.go +++ b/peer/network_test.go @@ -816,7 +816,7 @@ func TestNetworkRouting(t *testing.T) { require := require.New(t) protocol := 0 handler := &testSDKHandler{} - p2pNetwork := p2p.NewNetwork(logging.NoLog{}, &p2p.FakeSender{}, prometheus.NewRegistry(), "") + p2pNetwork := p2p.NewNetwork(logging.NoLog{}, &common.FakeSender{}, prometheus.NewRegistry(), "") _, err := p2pNetwork.NewAppProtocol(uint64(protocol), handler) require.NoError(err) diff --git a/plugin/evm/tx_gossip_test.go b/plugin/evm/tx_gossip_test.go index cabc7dfde9..99390ee299 100644 --- a/plugin/evm/tx_gossip_test.go +++ b/plugin/evm/tx_gossip_test.go @@ -48,7 +48,7 @@ func TestEthTxGossip(t *testing.T) { genesisBytes, err := genesis.MarshalJSON() require.NoError(err) - responseSender := &p2p.FakeSender{ + responseSender := &common.FakeSender{ SentAppResponse: make(chan []byte, 1), } vm := &VM{ @@ -75,7 +75,7 @@ func TestEthTxGossip(t *testing.T) { }() // sender for the peer requesting gossip from [vm] - peerSender := &p2p.FakeSender{ + peerSender := &common.FakeSender{ SentAppRequest: make(chan []byte, 1), } network := p2p.NewNetwork(logging.NoLog{}, peerSender, prometheus.NewRegistry(), "") @@ -176,7 +176,7 @@ func TestAtomicTxGossip(t *testing.T) { genesisBytes, err := genesis.MarshalJSON() require.NoError(err) - responseSender := &p2p.FakeSender{ + responseSender := &common.FakeSender{ SentAppResponse: make(chan []byte, 1), } vm := &VM{ @@ -203,7 +203,7 @@ func TestAtomicTxGossip(t *testing.T) { }() // sender for the peer requesting gossip from [vm] - peerSender := &p2p.FakeSender{ + peerSender := &common.FakeSender{ SentAppRequest: make(chan []byte, 1), } network := p2p.NewNetwork(logging.NoLog{}, peerSender, prometheus.NewRegistry(), "") diff --git a/plugin/evm/vm.go b/plugin/evm/vm.go index fcc26e1c78..837c940891 100644 --- a/plugin/evm/vm.go +++ b/plugin/evm/vm.go @@ -344,7 +344,7 @@ type VM struct { // Used to serve BLS signatures of warp messages over RPC warpBackend warp.Backend - p2pSender p2p.AppSender + p2pSender commonEng.AppSender ethTxGossipHandler p2p.Handler atomicTxGossipHandler p2p.Handler ethTxGossiper gossip.Gossiper @@ -591,7 +591,7 @@ func (vm *VM) Initialize( // initialize peer network if vm.p2pSender == nil { - vm.p2pSender = p2p.NewSender(appSender) + vm.p2pSender = appSender } p2pNetwork := p2p.NewNetwork(vm.ctx.Log, vm.p2pSender, vm.sdkMetrics, "p2p") From d8cab34563a93d81dc53ea80a5ed509681ce0d0e Mon Sep 17 00:00:00 2001 From: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> Date: Tue, 12 Dec 2023 13:50:14 -0500 Subject: [PATCH 03/11] nit Signed-off-by: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> --- peer/network_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/peer/network_test.go b/peer/network_test.go index b50bcac6a7..5f2d7318e6 100644 --- a/peer/network_test.go +++ b/peer/network_test.go @@ -425,6 +425,7 @@ func TestRequestMinVersion(t *testing.T) { responseBytes, _, err := client.SendAppRequestAny( context.Background(), &version.Application{ + Name: "avalanche", Major: 2, Minor: 0, Patch: 0, From 7cc3b6864db9e8d5937e47bb7a7c0fd6ef410451 Mon Sep 17 00:00:00 2001 From: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> Date: Tue, 12 Dec 2023 13:50:42 -0500 Subject: [PATCH 04/11] nit Signed-off-by: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> --- scripts/versions.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/versions.sh b/scripts/versions.sh index 76fbe3a455..acdcddf94f 100644 --- a/scripts/versions.sh +++ b/scripts/versions.sh @@ -1,4 +1,4 @@ #!/usr/bin/env bash # Don't export them as they're used in the context of other calls -avalanche_version=${AVALANCHE_VERSION:-'sender-refactor'} +avalanche_version=${AVALANCHE_VERSION:-'1578bb2'} From 55f9a36953e250f50b3fa9cad281d2a6e6b2b3b7 Mon Sep 17 00:00:00 2001 From: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> Date: Tue, 12 Dec 2023 16:19:59 -0500 Subject: [PATCH 05/11] nit Signed-off-by: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> --- plugin/evm/vm.go | 1 + 1 file changed, 1 insertion(+) diff --git a/plugin/evm/vm.go b/plugin/evm/vm.go index 837c940891..2c3f9a33fb 100644 --- a/plugin/evm/vm.go +++ b/plugin/evm/vm.go @@ -344,6 +344,7 @@ type VM struct { // Used to serve BLS signatures of warp messages over RPC warpBackend warp.Backend + // Can be overridden in unit tests p2pSender commonEng.AppSender ethTxGossipHandler p2p.Handler atomicTxGossipHandler p2p.Handler From f9ec2ecc2714cd8870745b954f31920e074167a3 Mon Sep 17 00:00:00 2001 From: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> Date: Tue, 12 Dec 2023 17:04:37 -0500 Subject: [PATCH 06/11] nit Signed-off-by: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- peer/network.go | 6 +++--- peer/network_test.go | 2 +- plugin/evm/syncervm_test.go | 2 +- scripts/versions.sh | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index abe6f0a38a..e478779e0e 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.20 require ( github.com/VictoriaMetrics/fastcache v1.10.0 - github.com/ava-labs/avalanchego v1.10.18-0.20231212183827-1578bb29776c + github.com/ava-labs/avalanchego v1.10.18-0.20231212215606-cb0f72d18f35 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 f5838abe1b..52546947ca 100644 --- a/go.sum +++ b/go.sum @@ -55,8 +55,8 @@ 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/avalanchego v1.10.18-0.20231212183827-1578bb29776c h1:ZD58N48KMzpPzhtVCp8h8kxS93XxlkDXmxIO4+I+mrc= -github.com/ava-labs/avalanchego v1.10.18-0.20231212183827-1578bb29776c/go.mod h1:npeYlspwYFUNHgCcm7vEjvsHQilLy3ymtSGJ4iZSRto= +github.com/ava-labs/avalanchego v1.10.18-0.20231212215606-cb0f72d18f35 h1:arKzZnblbQiFWUZ9QDiVxLtDQkkgCiXJknw09NYOaJk= +github.com/ava-labs/avalanchego v1.10.18-0.20231212215606-cb0f72d18f35/go.mod h1:Nipo+jZEKDO8DgE5Z2IytDeplsT61DzvYQHhZoBqCG4= 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/peer/network.go b/peer/network.go index f59783b751..dfad0bd790 100644 --- a/peer/network.go +++ b/peer/network.go @@ -280,7 +280,7 @@ 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 { +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) @@ -382,13 +382,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 { +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.Debug("forwarding AppRequestFailed to SDK network", "nodeID", nodeID, "requestID", requestID) - return n.network.AppRequestFailed(ctx, nodeID, requestID) + return n.network.AppRequestFailed(ctx, nodeID, requestID, appErr) } // We must release the slot diff --git a/peer/network_test.go b/peer/network_test.go index 5f2d7318e6..fec3d10144 100644 --- a/peer/network_test.go +++ b/peer/network_test.go @@ -843,7 +843,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) } diff --git a/plugin/evm/syncervm_test.go b/plugin/evm/syncervm_test.go index 66923153fb..dd35759a3c 100644 --- a/plugin/evm/syncervm_test.go +++ b/plugin/evm/syncervm_test.go @@ -91,7 +91,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/scripts/versions.sh b/scripts/versions.sh index acdcddf94f..3fe865b03c 100644 --- a/scripts/versions.sh +++ b/scripts/versions.sh @@ -1,4 +1,4 @@ #!/usr/bin/env bash # Don't export them as they're used in the context of other calls -avalanche_version=${AVALANCHE_VERSION:-'1578bb2'} +avalanche_version=${AVALANCHE_VERSION:-'cb0f72d'} From 1c67c383292a173589aa2c8ef1b30247e5838a51 Mon Sep 17 00:00:00 2001 From: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> Date: Tue, 12 Dec 2023 19:46:14 -0500 Subject: [PATCH 07/11] nit Signed-off-by: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> --- peer/network_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/peer/network_test.go b/peer/network_test.go index fec3d10144..8484ae9dc1 100644 --- a/peer/network_test.go +++ b/peer/network_test.go @@ -425,7 +425,7 @@ func TestRequestMinVersion(t *testing.T) { responseBytes, _, err := client.SendAppRequestAny( context.Background(), &version.Application{ - Name: "avalanche", + Name: version.LegacyAppName, Major: 2, Minor: 0, Patch: 0, From ce28e4973b4d8c43dfbc34d3ed9f63e97e852adb Mon Sep 17 00:00:00 2001 From: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> Date: Wed, 13 Dec 2023 09:44:19 -0500 Subject: [PATCH 08/11] Squashed commit of the following: commit 056800c7179e7c87818e294659f1735caffff97f Author: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> Date: Wed Dec 13 00:28:59 2023 -0500 Update to new SDK API (#421) commit 42db2c2b17b4b6de75610cb7157695d8959b530f Author: Ceyhun Onur <ceyhun.onur@avalabs.org> Date: Tue Dec 12 19:05:37 2023 +0300 show strings in pointers (#414) Signed-off-by: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 +- params/config.go | 33 ++++++++++------- peer/network.go | 29 +++++++++------ peer/network_test.go | 71 ++++++++++++++++++++++++++---------- plugin/evm/tx_gossip_test.go | 10 ++--- plugin/evm/vm.go | 70 +++++++++++++++++++---------------- scripts/versions.sh | 2 +- 8 files changed, 134 insertions(+), 87 deletions(-) diff --git a/go.mod b/go.mod index e478779e0e..6709bd2e0f 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.20 require ( github.com/VictoriaMetrics/fastcache v1.10.0 - github.com/ava-labs/avalanchego v1.10.18-0.20231212215606-cb0f72d18f35 + github.com/ava-labs/avalanchego v1.10.18-rc.2 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 52546947ca..e0f2a4960c 100644 --- a/go.sum +++ b/go.sum @@ -55,8 +55,8 @@ 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/avalanchego v1.10.18-0.20231212215606-cb0f72d18f35 h1:arKzZnblbQiFWUZ9QDiVxLtDQkkgCiXJknw09NYOaJk= -github.com/ava-labs/avalanchego v1.10.18-0.20231212215606-cb0f72d18f35/go.mod h1:Nipo+jZEKDO8DgE5Z2IytDeplsT61DzvYQHhZoBqCG4= +github.com/ava-labs/avalanchego v1.10.18-rc.2 h1:fjks/pUp7HmGzjupl+f3MfGo5cLkCrDnoCarL8NyqlA= +github.com/ava-labs/avalanchego v1.10.18-rc.2/go.mod h1:D0tP5nGZtGb/vNOzvROUGUER+Gcar73l9qP97vbEarY= 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/params/config.go b/params/config.go index 6b362c14de..c62aa40652 100644 --- a/params/config.go +++ b/params/config.go @@ -581,18 +581,18 @@ func (c *ChainConfig) Description() string { if c.MuirGlacierBlock != nil { banner += fmt.Sprintf(" - Muir Glacier: #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/muir-glacier.md)\n", c.MuirGlacierBlock) } - banner += fmt.Sprintf(" - Apricot Phase 1 Timestamp: #%-8v (https://github.com/ava-labs/avalanchego/releases/tag/v1.3.0)\n", c.ApricotPhase1BlockTimestamp) - banner += fmt.Sprintf(" - Apricot Phase 2 Timestamp: #%-8v (https://github.com/ava-labs/avalanchego/releases/tag/v1.4.0)\n", c.ApricotPhase2BlockTimestamp) - banner += fmt.Sprintf(" - Apricot Phase 3 Timestamp: #%-8v (https://github.com/ava-labs/avalanchego/releases/tag/v1.5.0)\n", c.ApricotPhase3BlockTimestamp) - banner += fmt.Sprintf(" - Apricot Phase 4 Timestamp: #%-8v (https://github.com/ava-labs/avalanchego/releases/tag/v1.6.0)\n", c.ApricotPhase4BlockTimestamp) - banner += fmt.Sprintf(" - Apricot Phase 5 Timestamp: #%-8v (https://github.com/ava-labs/avalanchego/releases/tag/v1.7.0)\n", c.ApricotPhase5BlockTimestamp) - banner += fmt.Sprintf(" - Apricot Phase P6 Timestamp #%-8v (https://github.com/ava-labs/avalanchego/releases/tag/v1.8.0)\n", c.ApricotPhasePre6BlockTimestamp) - banner += fmt.Sprintf(" - Apricot Phase 6 Timestamp: #%-8v (https://github.com/ava-labs/avalanchego/releases/tag/v1.8.0)\n", c.ApricotPhase6BlockTimestamp) - banner += fmt.Sprintf(" - Apricot Phase Post-6 Timestamp: #%-8v (https://github.com/ava-labs/avalanchego/releases/tag/v1.8.0\n", c.ApricotPhasePost6BlockTimestamp) - banner += fmt.Sprintf(" - Banff Timestamp: #%-8v (https://github.com/ava-labs/avalanchego/releases/tag/v1.9.0)\n", c.BanffBlockTimestamp) - banner += fmt.Sprintf(" - Cortina Timestamp: #%-8v (https://github.com/ava-labs/avalanchego/releases/tag/v1.10.0)\n", c.CortinaBlockTimestamp) - banner += fmt.Sprintf(" - DUpgrade Timestamp: #%-8v (https://github.com/ava-labs/avalanchego/releases/tag/v1.11.0)\n", c.DUpgradeBlockTimestamp) - banner += fmt.Sprintf(" - Cancun Timestamp: #%-8v (https://github.com/ava-labs/avalanchego/releases/tag/v1.12.0)\n", c.CancunTime) + banner += fmt.Sprintf(" - Apricot Phase 1 Timestamp: @%-10v (https://github.com/ava-labs/avalanchego/releases/tag/v1.3.0)\n", ptrToString(c.ApricotPhase1BlockTimestamp)) + banner += fmt.Sprintf(" - Apricot Phase 2 Timestamp: @%-10v (https://github.com/ava-labs/avalanchego/releases/tag/v1.4.0)\n", ptrToString(c.ApricotPhase2BlockTimestamp)) + banner += fmt.Sprintf(" - Apricot Phase 3 Timestamp: @%-10v (https://github.com/ava-labs/avalanchego/releases/tag/v1.5.0)\n", ptrToString(c.ApricotPhase3BlockTimestamp)) + banner += fmt.Sprintf(" - Apricot Phase 4 Timestamp: @%-10v (https://github.com/ava-labs/avalanchego/releases/tag/v1.6.0)\n", ptrToString(c.ApricotPhase4BlockTimestamp)) + banner += fmt.Sprintf(" - Apricot Phase 5 Timestamp: @%-10v (https://github.com/ava-labs/avalanchego/releases/tag/v1.7.0)\n", ptrToString(c.ApricotPhase5BlockTimestamp)) + banner += fmt.Sprintf(" - Apricot Phase P6 Timestamp @%-10v (https://github.com/ava-labs/avalanchego/releases/tag/v1.8.0)\n", ptrToString(c.ApricotPhasePre6BlockTimestamp)) + banner += fmt.Sprintf(" - Apricot Phase 6 Timestamp: @%-10v (https://github.com/ava-labs/avalanchego/releases/tag/v1.8.0)\n", ptrToString(c.ApricotPhase6BlockTimestamp)) + banner += fmt.Sprintf(" - Apricot Phase Post-6 Timestamp: @%-10v (https://github.com/ava-labs/avalanchego/releases/tag/v1.8.0\n", ptrToString(c.ApricotPhasePost6BlockTimestamp)) + banner += fmt.Sprintf(" - Banff Timestamp: @%-10v (https://github.com/ava-labs/avalanchego/releases/tag/v1.9.0)\n", ptrToString(c.BanffBlockTimestamp)) + banner += fmt.Sprintf(" - Cortina Timestamp: @%-10v (https://github.com/ava-labs/avalanchego/releases/tag/v1.10.0)\n", ptrToString(c.CortinaBlockTimestamp)) + banner += fmt.Sprintf(" - DUpgrade Timestamp: @%-10v (https://github.com/ava-labs/avalanchego/releases/tag/v1.11.0)\n", ptrToString(c.DUpgradeBlockTimestamp)) + banner += fmt.Sprintf(" - Cancun Timestamp: @%-10v (https://github.com/ava-labs/avalanchego/releases/tag/v1.12.0)\n", ptrToString(c.CancunTime)) banner += "\n" return banner } @@ -1042,7 +1042,14 @@ func (err *ConfigCompatError) Error() string { if err.StoredBlock != nil { return fmt.Sprintf("mismatching %s in database (have block %d, want block %d, rewindto block %d)", err.What, err.StoredBlock, err.NewBlock, err.RewindToBlock) } - return fmt.Sprintf("mismatching %s in database (have timestamp %d, want timestamp %d, rewindto timestamp %d)", err.What, err.StoredTime, err.NewTime, err.RewindToTime) + return fmt.Sprintf("mismatching %s in database (have timestamp %s, want timestamp %s, rewindto timestamp %d)", err.What, ptrToString(err.StoredTime), ptrToString(err.NewTime), err.RewindToTime) +} + +func ptrToString(val *uint64) string { + if val == nil { + return "nil" + } + return fmt.Sprintf("%d", *val) } // Rules wraps ChainConfig and is merely syntactic sugar or can be used for functions diff --git a/peer/network.go b/peer/network.go index dfad0bd790..904001b106 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{}, @@ -331,7 +332,7 @@ func (n *network) AppRequest(ctx context.Context, nodeID ids.NodeID, requestID u var req message.Request if _, err := n.codec.Unmarshal(request, &req); err != nil { log.Debug("forwarding AppRequest to SDK network", "nodeID", nodeID, "requestID", requestID, "requestLen", len(request), "err", err) - return n.network.AppRequest(ctx, nodeID, requestID, deadline, request) + return n.p2pNetwork.AppRequest(ctx, nodeID, requestID, deadline, request) } bufferedDeadline, err := calculateTimeUntilDeadline(deadline, n.appStats) @@ -367,7 +368,7 @@ func (n *network) AppResponse(ctx context.Context, nodeID ids.NodeID, requestID handler, exists := n.markRequestFulfilled(requestID) if !exists { log.Debug("forwarding AppResponse to SDK network", "nodeID", nodeID, "requestID", requestID, "responseLen", len(response)) - return n.network.AppResponse(ctx, nodeID, requestID, response) + return n.p2pNetwork.AppResponse(ctx, nodeID, requestID, response) } // We must release the slot @@ -388,7 +389,7 @@ func (n *network) AppRequestFailed(ctx context.Context, nodeID ids.NodeID, reque handler, exists := n.markRequestFulfilled(requestID) if !exists { log.Debug("forwarding AppRequestFailed to SDK network", "nodeID", nodeID, "requestID", requestID) - return n.network.AppRequestFailed(ctx, nodeID, requestID, appErr) + return n.p2pNetwork.AppRequestFailed(ctx, nodeID, requestID, appErr) } // We must release the slot @@ -476,7 +477,7 @@ func (n *network) Connected(ctx context.Context, nodeID ids.NodeID, nodeVersion } 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 @@ -490,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 @@ -543,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 8484ae9dc1..75ec24b76d 100644 --- a/peer/network_test.go +++ b/peer/network_test.go @@ -58,7 +58,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()) } @@ -94,7 +96,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() @@ -146,7 +150,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"} @@ -198,7 +204,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) @@ -252,7 +260,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") } @@ -278,7 +286,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)) @@ -327,7 +337,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( @@ -404,7 +416,9 @@ func TestRequestMinVersion(t *testing.T) { } // passing nil as codec works because the net.AppRequest is never called - 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) @@ -414,6 +428,7 @@ func TestRequestMinVersion(t *testing.T) { context.Background(), nodeID, &version.Application{ + Name: version.Client, Major: 1, Minor: 7, Patch: 1, @@ -425,14 +440,14 @@ func TestRequestMinVersion(t *testing.T) { responseBytes, _, err := client.SendAppRequestAny( context.Background(), &version.Application{ - Name: version.LegacyAppName, + 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 @@ -469,7 +484,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() @@ -509,7 +526,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)) @@ -536,7 +555,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{}) @@ -585,7 +606,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 @@ -625,7 +648,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) @@ -660,7 +685,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{ @@ -712,7 +739,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) @@ -772,7 +801,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{ @@ -817,9 +848,9 @@ func TestNetworkRouting(t *testing.T) { require := require.New(t) protocol := 0 handler := &testSDKHandler{} - p2pNetwork := p2p.NewNetwork(logging.NoLog{}, &common.FakeSender{}, 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) diff --git a/plugin/evm/tx_gossip_test.go b/plugin/evm/tx_gossip_test.go index 99390ee299..15c00e0d63 100644 --- a/plugin/evm/tx_gossip_test.go +++ b/plugin/evm/tx_gossip_test.go @@ -78,10 +78,9 @@ func TestEthTxGossip(t *testing.T) { peerSender := &common.FakeSender{ SentAppRequest: make(chan []byte, 1), } - network := p2p.NewNetwork(logging.NoLog{}, peerSender, prometheus.NewRegistry(), "") - - client, err := network.NewAppProtocol(ethTxGossipProtocol, &p2p.NoOpHandler{}) + 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() @@ -206,10 +205,9 @@ func TestAtomicTxGossip(t *testing.T) { peerSender := &common.FakeSender{ SentAppRequest: make(chan []byte, 1), } - network := p2p.NewNetwork(logging.NoLog{}, peerSender, prometheus.NewRegistry(), "") - - client, err := network.NewAppProtocol(atomicTxGossipProtocol, &p2p.NoOpHandler{}) + network, err := p2p.NewNetwork(logging.NoLog{}, peerSender, prometheus.NewRegistry(), "") require.NoError(err) + client := network.NewClient(atomicTxGossipProtocol) // we only accept gossip requests from validators requestingNodeID := ids.GenerateTestNodeID() diff --git a/plugin/evm/vm.go b/plugin/evm/vm.go index 2c3f9a33fb..1c0e2d617d 100644 --- a/plugin/evm/vm.go +++ b/plugin/evm/vm.go @@ -595,7 +595,10 @@ func (vm *VM) Initialize( vm.p2pSender = appSender } - p2pNetwork := p2p.NewNetwork(vm.ctx.Log, vm.p2pSender, vm.sdkMetrics, "p2p") + p2pNetwork, err := p2p.NewNetwork(vm.ctx.Log, appSender, 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) @@ -1080,50 +1083,48 @@ func (vm *VM) initBlockBuilding() error { }() if vm.ethTxGossipHandler == nil { - vm.ethTxGossipHandler, err = gossip.NewHandler[*GossipEthTx](ethTxPool, ethTxGossipHandlerConfig, vm.sdkMetrics) + ethTxGossipHandler, err = gossip.NewHandler[*GossipEthTx](ethTxPool, ethTxGossipHandlerConfig, vm.sdkMetrics) if err != nil { return err } - vm.ethTxGossipHandler = &p2p.ValidatorHandler{ - ValidatorSet: vm.validators, - Handler: &p2p.ThrottlerHandler{ - Handler: vm.ethTxGossipHandler, - Throttler: p2p.NewSlidingWindowThrottler(throttlingPeriod, throttlingLimit), - Log: vm.ctx.Log, - }, - Log: vm.ctx.Log, - } + ethTxGossipHandler = p2p.NewThrottlerHandler( + ethTxGossipHandler, + p2p.NewSlidingWindowThrottler(throttlingPeriod, throttlingLimit), + vm.ctx.Log, + ) + + ethTxGossipHandler = p2p.NewValidatorHandler(ethTxGossipHandler, vm.validators, vm.ctx.Log) + vm.ethTxGossipHandler = vm.ethTxGossipHandler } - ethTxGossipClient, err := vm.Network.NewAppProtocol(ethTxGossipProtocol, vm.ethTxGossipHandler, p2p.WithValidatorSampling(vm.validators)) - if err != nil { + + if err := vm.Network.AddHandler(ethTxGossipProtocol, vm.ethTxGossipHandler); err != nil { return err } if vm.atomicTxGossipHandler == nil { - vm.atomicTxGossipHandler, err = gossip.NewHandler[*GossipAtomicTx](vm.mempool, atomicTxGossipHandlerConfig, vm.sdkMetrics) - if err != nil { + atomicTxGossipHandler := p2p.NewThrottlerHandler( + atomicTxGossipHandler, + p2p.NewSlidingWindowThrottler(throttlingLimit, throttlingLimit), + vm.ctx.Log, + ) + + atomicTxGossipHandler = p2p.NewValidatorHandler(atomicTxGossipHandler, vm.validators, vm.ctx.Log) + + if err := vm.Network.AddHandler(atomicTxGossipProtocol, atomicTxGossipHandler); err != nil { return err } - vm.atomicTxGossipHandler = &p2p.ValidatorHandler{ - ValidatorSet: vm.validators, - Handler: &p2p.ThrottlerHandler{ - Throttler: p2p.NewSlidingWindowThrottler(throttlingPeriod, throttlingLimit), - Handler: vm.atomicTxGossipHandler, - Log: vm.ctx.Log, - }, - Log: vm.ctx.Log, - } + vm.atomicTxGossipHandler = atomicTxGossipHandler } - atomicTxGossipClient, err := vm.Network.NewAppProtocol(atomicTxGossipProtocol, vm.atomicTxGossipHandler, p2p.WithValidatorSampling(vm.validators)) - if err != nil { + if err := vm.Network.AddHandler(atomicTxGossipProtocol, vm.atomicTxGossipHandler); err != nil { return err } if vm.ethTxGossiper == nil { - vm.ethTxGossiper, err = gossip.NewPullGossiper[GossipEthTx, *GossipEthTx]( + ethTxGossipClient := vm.Network.NewClient(ethTxGossipProtocol, p2p.WithValidatorSampling(vm.validators)) + ethTxGossiper, err := gossip.NewPullGossiper[GossipEthTx, *GossipEthTx]( ethTxGossipConfig, vm.ctx.Log, ethTxPool, @@ -1134,11 +1135,13 @@ func (vm *VM) initBlockBuilding() error { return err } - vm.ethTxGossiper = gossip.ValidatorGossiper{ - Gossiper: vm.ethTxGossiper, + ethTxGossiper = gossip.ValidatorGossiper{ + Gossiper: ethTxGossiper, NodeID: vm.ctx.NodeID, Validators: vm.validators, } + + vm.ethTxGossiper = ethTxGossiper } vm.shutdownWg.Add(1) @@ -1148,7 +1151,8 @@ func (vm *VM) initBlockBuilding() error { }() if vm.atomicTxGossiper == nil { - vm.atomicTxGossiper, err = gossip.NewPullGossiper[GossipAtomicTx, *GossipAtomicTx]( + atomicTxGossipClient := vm.Network.NewClient(atomicTxGossipProtocol, p2p.WithValidatorSampling(vm.validators)) + atomicTxGossiper, err := gossip.NewPullGossiper[GossipAtomicTx, *GossipAtomicTx]( atomicTxGossipConfig, vm.ctx.Log, vm.mempool, @@ -1158,11 +1162,13 @@ func (vm *VM) initBlockBuilding() error { if err != nil { return err } - vm.atomicTxGossiper = gossip.ValidatorGossiper{ - Gossiper: vm.atomicTxGossiper, + atomicTxGossiper = gossip.ValidatorGossiper{ + Gossiper: atomicTxGossiper, NodeID: vm.ctx.NodeID, Validators: vm.validators, } + + vm.atomicTxGossiper = atomicTxGossiper } vm.shutdownWg.Add(1) diff --git a/scripts/versions.sh b/scripts/versions.sh index 3fe865b03c..a74887d206 100644 --- a/scripts/versions.sh +++ b/scripts/versions.sh @@ -1,4 +1,4 @@ #!/usr/bin/env bash # Don't export them as they're used in the context of other calls -avalanche_version=${AVALANCHE_VERSION:-'cb0f72d'} +avalanche_version=${AVALANCHE_VERSION:-'v1.10.18-rc.2'} From bfc85104e3cd8ffb6574073eaea84b6b4eb81aa8 Mon Sep 17 00:00:00 2001 From: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> Date: Wed, 13 Dec 2023 09:51:08 -0500 Subject: [PATCH 09/11] nit Signed-off-by: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> --- peer/network_test.go | 1 + plugin/evm/vm.go | 29 +++++++++++++---------------- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/peer/network_test.go b/peer/network_test.go index 75ec24b76d..d3f065b242 100644 --- a/peer/network_test.go +++ b/peer/network_test.go @@ -848,6 +848,7 @@ func TestNetworkRouting(t *testing.T) { require := require.New(t) protocol := 0 handler := &testSDKHandler{} + sender := &common.SenderTest{} p2pNetwork, err := p2p.NewNetwork(logging.NoLog{}, sender, prometheus.NewRegistry(), "") require.NoError(err) require.NoError(p2pNetwork.AddHandler(uint64(protocol), handler)) diff --git a/plugin/evm/vm.go b/plugin/evm/vm.go index 1c0e2d617d..d85a097eee 100644 --- a/plugin/evm/vm.go +++ b/plugin/evm/vm.go @@ -1083,6 +1083,7 @@ func (vm *VM) initBlockBuilding() error { }() if vm.ethTxGossipHandler == nil { + var ethTxGossipHandler p2p.Handler ethTxGossipHandler, err = gossip.NewHandler[*GossipEthTx](ethTxPool, ethTxGossipHandlerConfig, vm.sdkMetrics) if err != nil { return err @@ -1094,8 +1095,7 @@ func (vm *VM) initBlockBuilding() error { vm.ctx.Log, ) - ethTxGossipHandler = p2p.NewValidatorHandler(ethTxGossipHandler, vm.validators, vm.ctx.Log) - vm.ethTxGossipHandler = vm.ethTxGossipHandler + vm.ethTxGossipHandler = p2p.NewValidatorHandler(ethTxGossipHandler, vm.validators, vm.ctx.Log) } if err := vm.Network.AddHandler(ethTxGossipProtocol, vm.ethTxGossipHandler); err != nil { @@ -1103,19 +1103,19 @@ func (vm *VM) initBlockBuilding() error { } if vm.atomicTxGossipHandler == nil { - atomicTxGossipHandler := p2p.NewThrottlerHandler( + var atomicTxGossipHandler p2p.Handler + atomicTxGossipHandler, err = gossip.NewHandler[*GossipAtomicTx](vm.mempool, atomicTxGossipHandlerConfig, vm.sdkMetrics) + if err != nil { + return err + } + + atomicTxGossipHandler = p2p.NewThrottlerHandler( atomicTxGossipHandler, p2p.NewSlidingWindowThrottler(throttlingLimit, throttlingLimit), vm.ctx.Log, ) - atomicTxGossipHandler = p2p.NewValidatorHandler(atomicTxGossipHandler, vm.validators, vm.ctx.Log) - - if err := vm.Network.AddHandler(atomicTxGossipProtocol, atomicTxGossipHandler); err != nil { - return err - } - - vm.atomicTxGossipHandler = atomicTxGossipHandler + vm.atomicTxGossipHandler = p2p.NewValidatorHandler(atomicTxGossipHandler, vm.validators, vm.ctx.Log) } if err := vm.Network.AddHandler(atomicTxGossipProtocol, vm.atomicTxGossipHandler); err != nil { @@ -1135,13 +1135,11 @@ func (vm *VM) initBlockBuilding() error { return err } - ethTxGossiper = gossip.ValidatorGossiper{ + vm.ethTxGossiper = &gossip.ValidatorGossiper{ Gossiper: ethTxGossiper, NodeID: vm.ctx.NodeID, Validators: vm.validators, } - - vm.ethTxGossiper = ethTxGossiper } vm.shutdownWg.Add(1) @@ -1162,13 +1160,12 @@ func (vm *VM) initBlockBuilding() error { if err != nil { return err } - atomicTxGossiper = gossip.ValidatorGossiper{ + + vm.atomicTxGossiper = &gossip.ValidatorGossiper{ Gossiper: atomicTxGossiper, NodeID: vm.ctx.NodeID, Validators: vm.validators, } - - vm.atomicTxGossiper = atomicTxGossiper } vm.shutdownWg.Add(1) From 08cda51a3cd353a4234723ab461c28f7976d1388 Mon Sep 17 00:00:00 2001 From: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> Date: Wed, 13 Dec 2023 09:55:14 -0500 Subject: [PATCH 10/11] nit Signed-off-by: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> --- peer/network_test.go | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/peer/network_test.go b/peer/network_test.go index eaa708e045..073beb897d 100644 --- a/peer/network_test.go +++ b/peer/network_test.go @@ -846,9 +846,17 @@ func TestNetworkCrossChainAppRequestAfterShutdown(t *testing.T) { func TestNetworkRouting(t *testing.T) { require := require.New(t) + sender := &testAppSender{ + sendAppRequestFn: func(_ context.Context, s set.Set[ids.NodeID], u uint32, bytes []byte) error { + return nil + }, + sendAppResponseFn: func(id ids.NodeID, u uint32, bytes []byte) error { + return nil + }, + } protocol := 0 handler := &testSDKHandler{} - p2pNetwork, err := p2p.NewNetwork(logging.NoLog{}, &common.SenderTest{}, prometheus.NewRegistry(), "") + p2pNetwork, err := p2p.NewNetwork(logging.NoLog{}, sender, prometheus.NewRegistry(), "") require.NoError(err) require.NoError(p2pNetwork.AddHandler(uint64(protocol), handler)) From 5e1c5a703159dc8537f31ef14a513b13ac7dd9d7 Mon Sep 17 00:00:00 2001 From: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> Date: Wed, 13 Dec 2023 11:03:16 -0500 Subject: [PATCH 11/11] Update plugin/evm/vm.go Co-authored-by: Darioush Jalali <darioush.jalali@avalabs.org> Signed-off-by: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> --- plugin/evm/vm.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin/evm/vm.go b/plugin/evm/vm.go index 382846b3b5..4ae8bea834 100644 --- a/plugin/evm/vm.go +++ b/plugin/evm/vm.go @@ -344,7 +344,7 @@ type VM struct { // Used to serve BLS signatures of warp messages over RPC warpBackend warp.Backend - // Can be overridden in unit tests + // Initialize only sets these if nil so they can be overridden in tests p2pSender commonEng.AppSender ethTxGossipHandler p2p.Handler atomicTxGossipHandler p2p.Handler