From 354c4bff8649bdd32735f741f587a30e68234866 Mon Sep 17 00:00:00 2001 From: Rodrigo Villar Date: Mon, 7 Jul 2025 16:25:09 -0400 Subject: [PATCH 1/4] refactor: replace polling with subcription-based acceptance --- tests/load2/main/main.go | 2 +- tests/load2/tests.go | 9 ++---- tests/load2/wallet.go | 65 ++++++++++++++++++++++++---------------- 3 files changed, 44 insertions(+), 32 deletions(-) diff --git a/tests/load2/main/main.go b/tests/load2/main/main.go index 332c2a844108..3531a02e6707 100644 --- a/tests/load2/main/main.go +++ b/tests/load2/main/main.go @@ -115,7 +115,7 @@ func main() { chainID, metricsNamespace, registry, - load2.ZeroTransferTest{PollFrequency: pollFrequency}, + load2.ZeroTransferTest{}, ) require.NoError(err) diff --git a/tests/load2/tests.go b/tests/load2/tests.go index df1837a8a689..c552b455e125 100644 --- a/tests/load2/tests.go +++ b/tests/load2/tests.go @@ -6,7 +6,6 @@ package load2 import ( "context" "math/big" - "time" "github.com/ava-labs/libevm/common" "github.com/ava-labs/libevm/core/types" @@ -19,11 +18,9 @@ import ( var _ Test = (*ZeroTransferTest)(nil) -type ZeroTransferTest struct { - PollFrequency time.Duration -} +type ZeroTransferTest struct{} -func (z ZeroTransferTest) Run( +func (ZeroTransferTest) Run( tc tests.TestContext, ctx context.Context, wallet *Wallet, @@ -48,5 +45,5 @@ func (z ZeroTransferTest) Run( }) require.NoError(err) - require.NoError(wallet.SendTx(ctx, tx, z.PollFrequency)) + require.NoError(wallet.SendTx(ctx, tx)) } diff --git a/tests/load2/wallet.go b/tests/load2/wallet.go index 257b613d98f9..4e3dc867d12b 100644 --- a/tests/load2/wallet.go +++ b/tests/load2/wallet.go @@ -6,16 +6,13 @@ package load2 import ( "context" "crypto/ecdsa" - "errors" - "fmt" "math/big" "time" "github.com/ava-labs/libevm/common" "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/crypto" "github.com/ava-labs/libevm/ethclient" - - ethereum "github.com/ava-labs/libevm" ) type Wallet struct { @@ -47,8 +44,22 @@ func newWallet( func (w *Wallet) SendTx( ctx context.Context, tx *types.Transaction, - pingFrequency time.Duration, ) error { + // start listening for blocks + headers := make(chan *types.Header) + sub, err := w.client.SubscribeNewHead(ctx, headers) + if err != nil { + return err + } + + defer func() { + sub.Unsubscribe() + + // wait for err chan to close before safely closing headers + <-sub.Err() + close(headers) + }() + startTime := time.Now() if err := w.client.SendTransaction(ctx, tx); err != nil { return err @@ -57,7 +68,14 @@ func (w *Wallet) SendTx( issuanceDuration := time.Since(startTime) w.metrics.issue(issuanceDuration) - if err := awaitTx(ctx, w.client, tx.Hash(), pingFrequency); err != nil { + if err := await( + ctx, + w.client, + headers, + sub.Err(), + crypto.PubkeyToAddress(w.privKey.PublicKey), + tx.Nonce(), + ); err != nil { return err } @@ -70,32 +88,29 @@ func (w *Wallet) SendTx( return nil } -func awaitTx( +func await( ctx context.Context, client *ethclient.Client, - txHash common.Hash, - pingFrequency time.Duration, + headers chan *types.Header, + errs <-chan error, + address common.Address, + nonce uint64, ) error { - ticker := time.NewTicker(pingFrequency) - defer ticker.Stop() - for { - receipt, err := client.TransactionReceipt(ctx, txHash) - if err == nil { - if receipt.Status != types.ReceiptStatusSuccessful { - return fmt.Errorf("failed tx: %d", receipt.Status) - } - return nil - } - - if !errors.Is(err, ethereum.NotFound) { - return err - } - select { case <-ctx.Done(): return ctx.Err() - case <-ticker.C: + case err := <-errs: + return err + case h := <-headers: + latestNonce, err := client.NonceAt(ctx, address, h.Number) + if err != nil { + return err + } + + if latestNonce >= nonce { + return nil + } } } } From 68bc28ce7f783af7bf7b78bda51e72f888037895 Mon Sep 17 00:00:00 2001 From: Rodrigo Villar Date: Tue, 8 Jul 2025 11:31:30 -0400 Subject: [PATCH 2/4] chore: query for tx status --- tests/load2/wallet.go | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/tests/load2/wallet.go b/tests/load2/wallet.go index 4e3dc867d12b..c92dfc13b460 100644 --- a/tests/load2/wallet.go +++ b/tests/load2/wallet.go @@ -6,6 +6,7 @@ package load2 import ( "context" "crypto/ecdsa" + "fmt" "math/big" "time" @@ -68,13 +69,11 @@ func (w *Wallet) SendTx( issuanceDuration := time.Since(startTime) w.metrics.issue(issuanceDuration) - if err := await( + if err := w.awaitTx( ctx, - w.client, headers, sub.Err(), - crypto.PubkeyToAddress(w.privKey.PublicKey), - tx.Nonce(), + tx.Hash(), ); err != nil { return err } @@ -88,13 +87,11 @@ func (w *Wallet) SendTx( return nil } -func await( +func (w Wallet) awaitTx( ctx context.Context, - client *ethclient.Client, headers chan *types.Header, errs <-chan error, - address common.Address, - nonce uint64, + txHash common.Hash, ) error { for { select { @@ -103,12 +100,25 @@ func await( case err := <-errs: return err case h := <-headers: - latestNonce, err := client.NonceAt(ctx, address, h.Number) + latestNonce, err := w.client.NonceAt( + ctx, + crypto.PubkeyToAddress(w.privKey.PublicKey), + h.Number, + ) if err != nil { return err } - if latestNonce >= nonce { + if latestNonce == w.nonce+1 { + receipt, err := w.client.TransactionReceipt(ctx, txHash) + if err != nil { + return err + } + + if receipt.Status != types.ReceiptStatusSuccessful { + return fmt.Errorf("failed tx: %d", receipt.Status) + } + return nil } } From bc4de3cbbc15e77a1b9cd8d2384fee7dd21c2df2 Mon Sep 17 00:00:00 2001 From: Rodrigo Villar Date: Wed, 9 Jul 2025 08:53:09 -0400 Subject: [PATCH 3/4] refactor: split error assignment from check --- tests/load2/wallet.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/load2/wallet.go b/tests/load2/wallet.go index c92dfc13b460..6d4de459c701 100644 --- a/tests/load2/wallet.go +++ b/tests/load2/wallet.go @@ -69,12 +69,13 @@ func (w *Wallet) SendTx( issuanceDuration := time.Since(startTime) w.metrics.issue(issuanceDuration) - if err := w.awaitTx( + err = w.awaitTx( ctx, headers, sub.Err(), tx.Hash(), - ); err != nil { + ) + if err != nil { return err } From e5c687197a9d604bfc843a6a8d352f46dbc66d99 Mon Sep 17 00:00:00 2001 From: Rodrigo Villar Date: Wed, 9 Jul 2025 08:56:33 -0400 Subject: [PATCH 4/4] refactor: compute address once --- tests/load2/wallet.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/load2/wallet.go b/tests/load2/wallet.go index 6d4de459c701..76bfb94b6bf4 100644 --- a/tests/load2/wallet.go +++ b/tests/load2/wallet.go @@ -94,6 +94,7 @@ func (w Wallet) awaitTx( errs <-chan error, txHash common.Hash, ) error { + account := crypto.PubkeyToAddress(w.privKey.PublicKey) for { select { case <-ctx.Done(): @@ -103,7 +104,7 @@ func (w Wallet) awaitTx( case h := <-headers: latestNonce, err := w.client.NonceAt( ctx, - crypto.PubkeyToAddress(w.privKey.PublicKey), + account, h.Number, ) if err != nil {