From e294cdc5c4b866ce86bed80223ff8eb52cb878eb Mon Sep 17 00:00:00 2001 From: Rodrigo Villar Date: Thu, 10 Jul 2025 14:59:12 -0400 Subject: [PATCH 1/6] feat(load2): add contract tests --- tests/load2/main/main.go | 94 +++++++++++- tests/load2/tests.go | 302 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 390 insertions(+), 6 deletions(-) diff --git a/tests/load2/main/main.go b/tests/load2/main/main.go index 332c2a844108..83ba3781084c 100644 --- a/tests/load2/main/main.go +++ b/tests/load2/main/main.go @@ -5,9 +5,11 @@ package main import ( "flag" + "math/big" "os" "time" + "github.com/ava-labs/libevm/accounts/abi/bind" "github.com/ava-labs/libevm/ethclient" "github.com/prometheus/client_golang/prometheus" "github.com/stretchr/testify/require" @@ -16,6 +18,7 @@ import ( "github.com/ava-labs/avalanchego/tests/fixture/e2e" "github.com/ava-labs/avalanchego/tests/fixture/tmpnet" "github.com/ava-labs/avalanchego/tests/load" + "github.com/ava-labs/avalanchego/tests/load/c/contracts" "github.com/ava-labs/avalanchego/tests/load2" ) @@ -110,14 +113,103 @@ func main() { chainID, err := workers[0].Client.ChainID(ctx) require.NoError(err) + txOpts, err := bind.NewKeyedTransactorWithChainID(workers[0].PrivKey, chainID) + require.NoError(err) + + _, tx, contract, err := contracts.DeployEVMLoadSimulator(txOpts, workers[0].Client) + require.NoError(err) + + _, err = bind.WaitDeployed(ctx, workers[0].Client, tx) + require.NoError(err) + workers[0].Nonce++ + + randomTest, err := createRandomTest(contract) + require.NoError(err) + generator, err := load2.NewLoadGenerator( workers, chainID, metricsNamespace, registry, - load2.ZeroTransferTest{PollFrequency: pollFrequency}, + randomTest, ) require.NoError(err) generator.Run(tc, ctx, loadTimeout, testTimeout) } + +func createRandomTest(contract *contracts.EVMLoadSimulator) (load2.RandomTest, error) { + count := big.NewInt(5) + weightedTests := []load2.WeightedTest{ + { + Test: load2.ZeroTransferTest{}, + Weight: 100, + }, + { + Test: load2.ReadTest{ + Contract: contract, + Count: count, + }, + Weight: 100, + }, + { + Test: load2.WriteTest{ + Contract: contract, + Count: count, + }, + Weight: 100, + }, + { + Test: load2.StateModificationTest{ + Contract: contract, + Count: count, + }, + Weight: 100, + }, + { + Test: load2.HashingTest{ + Contract: contract, + Count: count, + }, + Weight: 100, + }, + { + Test: load2.MemoryTest{ + Contract: contract, + Count: count, + }, + Weight: 100, + }, + { + Test: load2.CallDepthTest{ + Contract: contract, + Count: count, + }, + Weight: 100, + }, + { + Test: load2.ContractCreationTest{Contract: contract}, + Weight: 100, + }, + { + Test: load2.PureComputeTest{ + Contract: contract, + NumIterations: count, + }, + Weight: 100, + }, + { + Test: load2.LargeEventTest{ + Contract: contract, + NumEvents: count, + }, + Weight: 100, + }, + { + Test: load2.ExternalCallTest{Contract: contract}, + Weight: 100, + }, + } + + return load2.NewRandomTest(weightedTests) +} diff --git a/tests/load2/tests.go b/tests/load2/tests.go index df1837a8a689..e48d1b5f4350 100644 --- a/tests/load2/tests.go +++ b/tests/load2/tests.go @@ -5,9 +5,13 @@ package load2 import ( "context" + "crypto/ecdsa" + "fmt" "math/big" + "math/rand/v2" "time" + "github.com/ava-labs/libevm/accounts/abi/bind" "github.com/ava-labs/libevm/common" "github.com/ava-labs/libevm/core/types" "github.com/ava-labs/libevm/crypto" @@ -15,15 +19,77 @@ import ( "github.com/stretchr/testify/require" "github.com/ava-labs/avalanchego/tests" + "github.com/ava-labs/avalanchego/tests/load/c/contracts" + "github.com/ava-labs/avalanchego/utils/sampler" ) -var _ Test = (*ZeroTransferTest)(nil) +var ( + maxFeeCap = big.NewInt(300000000000) -type ZeroTransferTest struct { - PollFrequency time.Duration + _ Test = (*RandomTest)(nil) + _ Test = (*ZeroTransferTest)(nil) + _ Test = (*ReadTest)(nil) + _ Test = (*WriteTest)(nil) + _ Test = (*StateModificationTest)(nil) + _ Test = (*HashingTest)(nil) + _ Test = (*MemoryTest)(nil) + _ Test = (*CallDepthTest)(nil) + _ Test = (*ContractCreationTest)(nil) + _ Test = (*PureComputeTest)(nil) + _ Test = (*LargeEventTest)(nil) + _ Test = (*ExternalCallTest)(nil) +) + +type RandomTest struct { + tests []Test + weighted sampler.Weighted + totalWeight uint64 +} + +func NewRandomTest(weightedTests []WeightedTest) (RandomTest, error) { + weighted := sampler.NewWeighted() + + // Initialize weighted set + tests := make([]Test, len(weightedTests)) + weights := make([]uint64, len(weightedTests)) + totalWeight := uint64(0) + for i, w := range weightedTests { + tests[i] = w.Test + weights[i] = w.Weight + totalWeight += w.Weight + } + if err := weighted.Initialize(weights); err != nil { + return RandomTest{}, err + } + + return RandomTest{ + tests: tests, + weighted: weighted, + totalWeight: totalWeight, + }, nil +} + +func (r RandomTest) Run( + tc tests.TestContext, + ctx context.Context, + wallet *Wallet, +) { + require := require.New(tc) + + index, ok := r.weighted.Sample(rand.Uint64N(r.totalWeight)) //#nosec G404 + require.True(ok) + + r.tests[index].Run(tc, ctx, wallet) } -func (z ZeroTransferTest) Run( +type WeightedTest struct { + Test Test + Weight uint64 +} + +type ZeroTransferTest struct{} + +func (ZeroTransferTest) Run( tc tests.TestContext, ctx context.Context, wallet *Wallet, @@ -48,5 +114,231 @@ func (z ZeroTransferTest) Run( }) require.NoError(err) - require.NoError(wallet.SendTx(ctx, tx, z.PollFrequency)) + require.NoError(wallet.SendTx(ctx, tx, time.Millisecond)) +} + +type ReadTest struct { + Contract *contracts.EVMLoadSimulator + Count *big.Int +} + +func (r ReadTest) Run( + tc tests.TestContext, + ctx context.Context, + wallet *Wallet, +) { + require := require.New(tc) + + txOpts, err := newTxOpts(wallet.privKey, wallet.chainID, maxFeeCap, wallet.nonce) + require.NoError(err) + + tx, err := r.Contract.SimulateReads(txOpts, r.Count) + require.NoError(err) + + require.NoError(wallet.SendTx(ctx, tx, time.Millisecond)) +} + +type WriteTest struct { + Contract *contracts.EVMLoadSimulator + Count *big.Int +} + +func (r WriteTest) Run( + tc tests.TestContext, + ctx context.Context, + wallet *Wallet, +) { + require := require.New(tc) + + txOpts, err := newTxOpts(wallet.privKey, wallet.chainID, maxFeeCap, wallet.nonce) + require.NoError(err) + + tx, err := r.Contract.SimulateRandomWrite(txOpts, r.Count) + require.NoError(err) + + require.NoError(wallet.SendTx(ctx, tx, time.Millisecond)) +} + +type StateModificationTest struct { + Contract *contracts.EVMLoadSimulator + Count *big.Int +} + +func (s StateModificationTest) Run( + tc tests.TestContext, + ctx context.Context, + wallet *Wallet, +) { + require := require.New(tc) + + txOpts, err := newTxOpts(wallet.privKey, wallet.chainID, maxFeeCap, wallet.nonce) + require.NoError(err) + + tx, err := s.Contract.SimulateModification(txOpts, s.Count) + require.NoError(err) + + require.NoError(wallet.SendTx(ctx, tx, time.Millisecond)) +} + +type HashingTest struct { + Contract *contracts.EVMLoadSimulator + Count *big.Int +} + +func (h HashingTest) Run( + tc tests.TestContext, + ctx context.Context, + wallet *Wallet, +) { + require := require.New(tc) + + txOpts, err := newTxOpts(wallet.privKey, wallet.chainID, maxFeeCap, wallet.nonce) + require.NoError(err) + + tx, err := h.Contract.SimulateHashing(txOpts, h.Count) + require.NoError(err) + + require.NoError(wallet.SendTx(ctx, tx, time.Millisecond)) +} + +type MemoryTest struct { + Contract *contracts.EVMLoadSimulator + Count *big.Int +} + +func (m MemoryTest) Run( + tc tests.TestContext, + ctx context.Context, + wallet *Wallet, +) { + require := require.New(tc) + + txOpts, err := newTxOpts(wallet.privKey, wallet.chainID, maxFeeCap, wallet.nonce) + require.NoError(err) + + tx, err := m.Contract.SimulateMemory(txOpts, m.Count) + require.NoError(err) + + require.NoError(wallet.SendTx(ctx, tx, time.Millisecond)) +} + +type CallDepthTest struct { + Contract *contracts.EVMLoadSimulator + Count *big.Int +} + +func (c CallDepthTest) Run( + tc tests.TestContext, + ctx context.Context, + wallet *Wallet, +) { + require := require.New(tc) + + txOpts, err := newTxOpts(wallet.privKey, wallet.chainID, maxFeeCap, wallet.nonce) + require.NoError(err) + + tx, err := c.Contract.SimulateCallDepth(txOpts, c.Count) + require.NoError(err) + + require.NoError(wallet.SendTx(ctx, tx, time.Millisecond)) +} + +type ContractCreationTest struct { + Contract *contracts.EVMLoadSimulator +} + +func (c ContractCreationTest) Run( + tc tests.TestContext, + ctx context.Context, + wallet *Wallet, +) { + require := require.New(tc) + + txOpts, err := newTxOpts(wallet.privKey, wallet.chainID, maxFeeCap, wallet.nonce) + require.NoError(err) + + tx, err := c.Contract.SimulateContractCreation(txOpts) + require.NoError(err) + + require.NoError(wallet.SendTx(ctx, tx, time.Millisecond)) +} + +type PureComputeTest struct { + Contract *contracts.EVMLoadSimulator + NumIterations *big.Int +} + +func (p PureComputeTest) Run( + tc tests.TestContext, + ctx context.Context, + wallet *Wallet, +) { + require := require.New(tc) + + txOpts, err := newTxOpts(wallet.privKey, wallet.chainID, maxFeeCap, wallet.nonce) + require.NoError(err) + + tx, err := p.Contract.SimulatePureCompute(txOpts, p.NumIterations) + require.NoError(err) + + require.NoError(wallet.SendTx(ctx, tx, time.Millisecond)) +} + +type LargeEventTest struct { + Contract *contracts.EVMLoadSimulator + NumEvents *big.Int +} + +func (l LargeEventTest) Run( + tc tests.TestContext, + ctx context.Context, + wallet *Wallet, +) { + require := require.New(tc) + + txOpts, err := newTxOpts(wallet.privKey, wallet.chainID, maxFeeCap, wallet.nonce) + require.NoError(err) + + tx, err := l.Contract.SimulateLargeEvent(txOpts, l.NumEvents) + require.NoError(err) + + require.NoError(wallet.SendTx(ctx, tx, time.Millisecond)) +} + +type ExternalCallTest struct { + Contract *contracts.EVMLoadSimulator +} + +func (e ExternalCallTest) Run( + tc tests.TestContext, + ctx context.Context, + wallet *Wallet, +) { + require := require.New(tc) + + txOpts, err := newTxOpts(wallet.privKey, wallet.chainID, maxFeeCap, wallet.nonce) + require.NoError(err) + + tx, err := e.Contract.SimulateExternalCall(txOpts) + require.NoError(err) + + require.NoError(wallet.SendTx(ctx, tx, time.Millisecond)) +} + +// newTxOpts returns transactions options for contract calls, with sending disabled +func newTxOpts( + key *ecdsa.PrivateKey, + chainID *big.Int, + maxFeeCap *big.Int, + nonce uint64, +) (*bind.TransactOpts, error) { + txOpts, err := bind.NewKeyedTransactorWithChainID(key, chainID) + if err != nil { + return nil, fmt.Errorf("creating transaction opts: %w", err) + } + txOpts.Nonce = new(big.Int).SetUint64(nonce) + txOpts.GasFeeCap = maxFeeCap + txOpts.GasTipCap = common.Big1 + txOpts.NoSend = true + return txOpts, nil } From 7224ecc2a76067c712171882f41a113c965ed781 Mon Sep 17 00:00:00 2001 From: Rodrigo Villar Date: Fri, 11 Jul 2025 09:30:44 -0400 Subject: [PATCH 2/6] chore: nit --- tests/load2/tests.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/load2/tests.go b/tests/load2/tests.go index e48d1b5f4350..eae81bf5ad4e 100644 --- a/tests/load2/tests.go +++ b/tests/load2/tests.go @@ -334,7 +334,7 @@ func newTxOpts( ) (*bind.TransactOpts, error) { txOpts, err := bind.NewKeyedTransactorWithChainID(key, chainID) if err != nil { - return nil, fmt.Errorf("creating transaction opts: %w", err) + return nil, fmt.Errorf("failed to create transaction opts: %w", err) } txOpts.Nonce = new(big.Int).SetUint64(nonce) txOpts.GasFeeCap = maxFeeCap From 66b8bad5546d0a36e7f04cfe3bc6ab480bf64309 Mon Sep 17 00:00:00 2001 From: Rodrigo Villar Date: Fri, 11 Jul 2025 10:19:19 -0400 Subject: [PATCH 3/6] refactor: create single weight --- tests/load2/main/main.go | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/tests/load2/main/main.go b/tests/load2/main/main.go index 83ba3781084c..cb00348174c9 100644 --- a/tests/load2/main/main.go +++ b/tests/load2/main/main.go @@ -139,75 +139,78 @@ func main() { } func createRandomTest(contract *contracts.EVMLoadSimulator) (load2.RandomTest, error) { + // test params count := big.NewInt(5) + weight := uint64(100) + weightedTests := []load2.WeightedTest{ { Test: load2.ZeroTransferTest{}, - Weight: 100, + Weight: weight, }, { Test: load2.ReadTest{ Contract: contract, Count: count, }, - Weight: 100, + Weight: weight, }, { Test: load2.WriteTest{ Contract: contract, Count: count, }, - Weight: 100, + Weight: weight, }, { Test: load2.StateModificationTest{ Contract: contract, Count: count, }, - Weight: 100, + Weight: weight, }, { Test: load2.HashingTest{ Contract: contract, Count: count, }, - Weight: 100, + Weight: weight, }, { Test: load2.MemoryTest{ Contract: contract, Count: count, }, - Weight: 100, + Weight: weight, }, { Test: load2.CallDepthTest{ Contract: contract, Count: count, }, - Weight: 100, + Weight: weight, }, { Test: load2.ContractCreationTest{Contract: contract}, - Weight: 100, + Weight: weight, }, { Test: load2.PureComputeTest{ Contract: contract, NumIterations: count, }, - Weight: 100, + Weight: weight, }, { Test: load2.LargeEventTest{ Contract: contract, NumEvents: count, }, - Weight: 100, + Weight: weight, }, { Test: load2.ExternalCallTest{Contract: contract}, - Weight: 100, + Weight: weight, }, } From d9f52b0a9d75d9ea861ebd1f523953559827968b Mon Sep 17 00:00:00 2001 From: Rodrigo Villar Date: Fri, 18 Jul 2025 08:46:48 -0400 Subject: [PATCH 4/6] chore: rename weighted test --- tests/load2/main/main.go | 6 +++--- tests/load2/tests.go | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/tests/load2/main/main.go b/tests/load2/main/main.go index ec1a717f4ab9..e7ab582e82d6 100644 --- a/tests/load2/main/main.go +++ b/tests/load2/main/main.go @@ -120,7 +120,7 @@ func main() { require.NoError(err) workers[0].Nonce++ - randomTest, err := createRandomTest(contract) + randomTest, err := createRandomWeightedTest(contract) require.NoError(err) generator, err := load2.NewLoadGenerator( @@ -135,7 +135,7 @@ func main() { generator.Run(tc, ctx, loadTimeout, testTimeout) } -func createRandomTest(contract *contracts.EVMLoadSimulator) (load2.RandomTest, error) { +func createRandomWeightedTest(contract *contracts.EVMLoadSimulator) (load2.RandomWeightedTest, error) { // test params count := big.NewInt(5) weight := uint64(100) @@ -211,5 +211,5 @@ func createRandomTest(contract *contracts.EVMLoadSimulator) (load2.RandomTest, e }, } - return load2.NewRandomTest(weightedTests) + return load2.NewRandomWeightedTest(weightedTests) } diff --git a/tests/load2/tests.go b/tests/load2/tests.go index 14956354d656..25d5bb577651 100644 --- a/tests/load2/tests.go +++ b/tests/load2/tests.go @@ -25,7 +25,7 @@ import ( var ( maxFeeCap = big.NewInt(300000000000) - _ Test = (*RandomTest)(nil) + _ Test = (*RandomWeightedTest)(nil) _ Test = (*ZeroTransferTest)(nil) _ Test = (*ReadTest)(nil) _ Test = (*WriteTest)(nil) @@ -39,13 +39,13 @@ var ( _ Test = (*ExternalCallTest)(nil) ) -type RandomTest struct { +type RandomWeightedTest struct { tests []Test weighted sampler.Weighted totalWeight uint64 } -func NewRandomTest(weightedTests []WeightedTest) (RandomTest, error) { +func NewRandomWeightedTest(weightedTests []WeightedTest) (RandomWeightedTest, error) { weighted := sampler.NewWeighted() // Initialize weighted set @@ -58,17 +58,17 @@ func NewRandomTest(weightedTests []WeightedTest) (RandomTest, error) { totalWeight += w.Weight } if err := weighted.Initialize(weights); err != nil { - return RandomTest{}, err + return RandomWeightedTest{}, err } - return RandomTest{ + return RandomWeightedTest{ tests: tests, weighted: weighted, totalWeight: totalWeight, }, nil } -func (r RandomTest) Run( +func (r RandomWeightedTest) Run( tc tests.TestContext, ctx context.Context, wallet *Wallet, From 5b409b73cf9399d697b914ba51f0a632a9b87165 Mon Sep 17 00:00:00 2001 From: Rodrigo Villar Date: Fri, 18 Jul 2025 09:13:31 -0400 Subject: [PATCH 5/6] refactor: executeContractTx --- tests/load2/tests.go | 119 +++++++++++++------------------------------ 1 file changed, 36 insertions(+), 83 deletions(-) diff --git a/tests/load2/tests.go b/tests/load2/tests.go index 25d5bb577651..5ab3f737bd47 100644 --- a/tests/load2/tests.go +++ b/tests/load2/tests.go @@ -126,15 +126,9 @@ func (r ReadTest) Run( ctx context.Context, wallet *Wallet, ) { - require := require.New(tc) - - txOpts, err := newTxOpts(wallet.privKey, wallet.chainID, maxFeeCap, wallet.nonce) - require.NoError(err) - - tx, err := r.Contract.SimulateReads(txOpts, r.Count) - require.NoError(err) - - require.NoError(wallet.SendTx(ctx, tx)) + executeContractTx(tc, ctx, wallet, func(txOpts *bind.TransactOpts) (*types.Transaction, error) { + return r.Contract.SimulateReads(txOpts, r.Count) + }) } type WriteTest struct { @@ -142,20 +136,14 @@ type WriteTest struct { Count *big.Int } -func (r WriteTest) Run( +func (w WriteTest) Run( tc tests.TestContext, ctx context.Context, wallet *Wallet, ) { - require := require.New(tc) - - txOpts, err := newTxOpts(wallet.privKey, wallet.chainID, maxFeeCap, wallet.nonce) - require.NoError(err) - - tx, err := r.Contract.SimulateRandomWrite(txOpts, r.Count) - require.NoError(err) - - require.NoError(wallet.SendTx(ctx, tx)) + executeContractTx(tc, ctx, wallet, func(txOpts *bind.TransactOpts) (*types.Transaction, error) { + return w.Contract.SimulateRandomWrite(txOpts, w.Count) + }) } type StateModificationTest struct { @@ -168,15 +156,9 @@ func (s StateModificationTest) Run( ctx context.Context, wallet *Wallet, ) { - require := require.New(tc) - - txOpts, err := newTxOpts(wallet.privKey, wallet.chainID, maxFeeCap, wallet.nonce) - require.NoError(err) - - tx, err := s.Contract.SimulateModification(txOpts, s.Count) - require.NoError(err) - - require.NoError(wallet.SendTx(ctx, tx)) + executeContractTx(tc, ctx, wallet, func(txOpts *bind.TransactOpts) (*types.Transaction, error) { + return s.Contract.SimulateModification(txOpts, s.Count) + }) } type HashingTest struct { @@ -189,15 +171,9 @@ func (h HashingTest) Run( ctx context.Context, wallet *Wallet, ) { - require := require.New(tc) - - txOpts, err := newTxOpts(wallet.privKey, wallet.chainID, maxFeeCap, wallet.nonce) - require.NoError(err) - - tx, err := h.Contract.SimulateHashing(txOpts, h.Count) - require.NoError(err) - - require.NoError(wallet.SendTx(ctx, tx)) + executeContractTx(tc, ctx, wallet, func(txOpts *bind.TransactOpts) (*types.Transaction, error) { + return h.Contract.SimulateHashing(txOpts, h.Count) + }) } type MemoryTest struct { @@ -210,15 +186,9 @@ func (m MemoryTest) Run( ctx context.Context, wallet *Wallet, ) { - require := require.New(tc) - - txOpts, err := newTxOpts(wallet.privKey, wallet.chainID, maxFeeCap, wallet.nonce) - require.NoError(err) - - tx, err := m.Contract.SimulateMemory(txOpts, m.Count) - require.NoError(err) - - require.NoError(wallet.SendTx(ctx, tx)) + executeContractTx(tc, ctx, wallet, func(txOpts *bind.TransactOpts) (*types.Transaction, error) { + return m.Contract.SimulateMemory(txOpts, m.Count) + }) } type CallDepthTest struct { @@ -231,15 +201,9 @@ func (c CallDepthTest) Run( ctx context.Context, wallet *Wallet, ) { - require := require.New(tc) - - txOpts, err := newTxOpts(wallet.privKey, wallet.chainID, maxFeeCap, wallet.nonce) - require.NoError(err) - - tx, err := c.Contract.SimulateCallDepth(txOpts, c.Count) - require.NoError(err) - - require.NoError(wallet.SendTx(ctx, tx)) + executeContractTx(tc, ctx, wallet, func(txOpts *bind.TransactOpts) (*types.Transaction, error) { + return c.Contract.SimulateCallDepth(txOpts, c.Count) + }) } type ContractCreationTest struct { @@ -251,15 +215,7 @@ func (c ContractCreationTest) Run( ctx context.Context, wallet *Wallet, ) { - require := require.New(tc) - - txOpts, err := newTxOpts(wallet.privKey, wallet.chainID, maxFeeCap, wallet.nonce) - require.NoError(err) - - tx, err := c.Contract.SimulateContractCreation(txOpts) - require.NoError(err) - - require.NoError(wallet.SendTx(ctx, tx)) + executeContractTx(tc, ctx, wallet, c.Contract.SimulateContractCreation) } type PureComputeTest struct { @@ -272,15 +228,9 @@ func (p PureComputeTest) Run( ctx context.Context, wallet *Wallet, ) { - require := require.New(tc) - - txOpts, err := newTxOpts(wallet.privKey, wallet.chainID, maxFeeCap, wallet.nonce) - require.NoError(err) - - tx, err := p.Contract.SimulatePureCompute(txOpts, p.NumIterations) - require.NoError(err) - - require.NoError(wallet.SendTx(ctx, tx)) + executeContractTx(tc, ctx, wallet, func(txOpts *bind.TransactOpts) (*types.Transaction, error) { + return p.Contract.SimulatePureCompute(txOpts, p.NumIterations) + }) } type LargeEventTest struct { @@ -293,15 +243,9 @@ func (l LargeEventTest) Run( ctx context.Context, wallet *Wallet, ) { - require := require.New(tc) - - txOpts, err := newTxOpts(wallet.privKey, wallet.chainID, maxFeeCap, wallet.nonce) - require.NoError(err) - - tx, err := l.Contract.SimulateLargeEvent(txOpts, l.NumEvents) - require.NoError(err) - - require.NoError(wallet.SendTx(ctx, tx)) + executeContractTx(tc, ctx, wallet, func(txOpts *bind.TransactOpts) (*types.Transaction, error) { + return l.Contract.SimulateLargeEvent(txOpts, l.NumEvents) + }) } type ExternalCallTest struct { @@ -312,13 +256,22 @@ func (e ExternalCallTest) Run( tc tests.TestContext, ctx context.Context, wallet *Wallet, +) { + executeContractTx(tc, ctx, wallet, e.Contract.SimulateExternalCall) +} + +func executeContractTx( + tc tests.TestContext, + ctx context.Context, + wallet *Wallet, + txFunc func(*bind.TransactOpts) (*types.Transaction, error), ) { require := require.New(tc) txOpts, err := newTxOpts(wallet.privKey, wallet.chainID, maxFeeCap, wallet.nonce) require.NoError(err) - tx, err := e.Contract.SimulateExternalCall(txOpts) + tx, err := txFunc(txOpts) require.NoError(err) require.NoError(wallet.SendTx(ctx, tx)) From c2ccfd496f736a054c45df57c3228d5fe8aeb69c Mon Sep 17 00:00:00 2001 From: Rodrigo Villar Date: Fri, 18 Jul 2025 11:04:23 -0400 Subject: [PATCH 6/6] refactor: NewRandomTests --- tests/load2/main/main.go | 94 +------------------------------- tests/load2/tests.go | 115 +++++++++++++++++++++++++++++++++------ 2 files changed, 100 insertions(+), 109 deletions(-) diff --git a/tests/load2/main/main.go b/tests/load2/main/main.go index e7ab582e82d6..96f5dd4259cd 100644 --- a/tests/load2/main/main.go +++ b/tests/load2/main/main.go @@ -5,11 +5,9 @@ package main import ( "flag" - "math/big" "os" "time" - "github.com/ava-labs/libevm/accounts/abi/bind" "github.com/ava-labs/libevm/ethclient" "github.com/prometheus/client_golang/prometheus" "github.com/stretchr/testify/require" @@ -17,7 +15,6 @@ import ( "github.com/ava-labs/avalanchego/tests" "github.com/ava-labs/avalanchego/tests/fixture/e2e" "github.com/ava-labs/avalanchego/tests/fixture/tmpnet" - "github.com/ava-labs/avalanchego/tests/load/c/contracts" "github.com/ava-labs/avalanchego/tests/load2" ) @@ -110,17 +107,7 @@ func main() { chainID, err := workers[0].Client.ChainID(ctx) require.NoError(err) - txOpts, err := bind.NewKeyedTransactorWithChainID(workers[0].PrivKey, chainID) - require.NoError(err) - - _, tx, contract, err := contracts.DeployEVMLoadSimulator(txOpts, workers[0].Client) - require.NoError(err) - - _, err = bind.WaitDeployed(ctx, workers[0].Client, tx) - require.NoError(err) - workers[0].Nonce++ - - randomTest, err := createRandomWeightedTest(contract) + randomTest, err := load2.NewRandomTests(ctx, chainID, &workers[0]) require.NoError(err) generator, err := load2.NewLoadGenerator( @@ -134,82 +121,3 @@ func main() { generator.Run(tc, ctx, loadTimeout, testTimeout) } - -func createRandomWeightedTest(contract *contracts.EVMLoadSimulator) (load2.RandomWeightedTest, error) { - // test params - count := big.NewInt(5) - weight := uint64(100) - - weightedTests := []load2.WeightedTest{ - { - Test: load2.ZeroTransferTest{}, - Weight: weight, - }, - { - Test: load2.ReadTest{ - Contract: contract, - Count: count, - }, - Weight: weight, - }, - { - Test: load2.WriteTest{ - Contract: contract, - Count: count, - }, - Weight: weight, - }, - { - Test: load2.StateModificationTest{ - Contract: contract, - Count: count, - }, - Weight: weight, - }, - { - Test: load2.HashingTest{ - Contract: contract, - Count: count, - }, - Weight: weight, - }, - { - Test: load2.MemoryTest{ - Contract: contract, - Count: count, - }, - Weight: weight, - }, - { - Test: load2.CallDepthTest{ - Contract: contract, - Count: count, - }, - Weight: weight, - }, - { - Test: load2.ContractCreationTest{Contract: contract}, - Weight: weight, - }, - { - Test: load2.PureComputeTest{ - Contract: contract, - NumIterations: count, - }, - Weight: weight, - }, - { - Test: load2.LargeEventTest{ - Contract: contract, - NumEvents: count, - }, - Weight: weight, - }, - { - Test: load2.ExternalCallTest{Contract: contract}, - Weight: weight, - }, - } - - return load2.NewRandomWeightedTest(weightedTests) -} diff --git a/tests/load2/tests.go b/tests/load2/tests.go index 5ab3f737bd47..d0bfd45df636 100644 --- a/tests/load2/tests.go +++ b/tests/load2/tests.go @@ -22,22 +22,105 @@ import ( "github.com/ava-labs/avalanchego/utils/sampler" ) -var ( - maxFeeCap = big.NewInt(300000000000) - - _ Test = (*RandomWeightedTest)(nil) - _ Test = (*ZeroTransferTest)(nil) - _ Test = (*ReadTest)(nil) - _ Test = (*WriteTest)(nil) - _ Test = (*StateModificationTest)(nil) - _ Test = (*HashingTest)(nil) - _ Test = (*MemoryTest)(nil) - _ Test = (*CallDepthTest)(nil) - _ Test = (*ContractCreationTest)(nil) - _ Test = (*PureComputeTest)(nil) - _ Test = (*LargeEventTest)(nil) - _ Test = (*ExternalCallTest)(nil) -) +var maxFeeCap = big.NewInt(300000000000) + +// NewRandomTests creates a RandomWeightedTest containing a collection of EVM +// load testing scenarios. +// +// This function handles the setup of the tests and also assigns each test +// an equal weight, making them equally likely to be selected during random test execution. +func NewRandomTests(ctx context.Context, chainID *big.Int, worker *Worker) (RandomWeightedTest, error) { + txOpts, err := bind.NewKeyedTransactorWithChainID(worker.PrivKey, chainID) + if err != nil { + return RandomWeightedTest{}, err + } + + _, tx, contract, err := contracts.DeployEVMLoadSimulator(txOpts, worker.Client) + if err != nil { + return RandomWeightedTest{}, err + } + + if _, err := bind.WaitDeployed(ctx, worker.Client, tx); err != nil { + return RandomWeightedTest{}, err + } + + worker.Nonce++ + + weight := uint64(100) + count := big.NewInt(5) + weightedTests := []WeightedTest{ + { + Test: ZeroTransferTest{}, + Weight: weight, + }, + { + Test: ReadTest{ + Contract: contract, + Count: count, + }, + Weight: weight, + }, + { + Test: WriteTest{ + Contract: contract, + Count: count, + }, + Weight: weight, + }, + { + Test: StateModificationTest{ + Contract: contract, + Count: count, + }, + Weight: weight, + }, + { + Test: HashingTest{ + Contract: contract, + Count: count, + }, + Weight: weight, + }, + { + Test: MemoryTest{ + Contract: contract, + Count: count, + }, + Weight: weight, + }, + { + Test: CallDepthTest{ + Contract: contract, + Count: count, + }, + Weight: weight, + }, + { + Test: ContractCreationTest{Contract: contract}, + Weight: weight, + }, + { + Test: PureComputeTest{ + Contract: contract, + NumIterations: count, + }, + Weight: weight, + }, + { + Test: LargeEventTest{ + Contract: contract, + NumEvents: count, + }, + Weight: weight, + }, + { + Test: ExternalCallTest{Contract: contract}, + Weight: weight, + }, + } + + return NewRandomWeightedTest(weightedTests) +} type RandomWeightedTest struct { tests []Test