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'}