Skip to content

Commit 66df1f2

Browse files
authored
account/abi/bind/v2: fix TestDeploymentWithOverrides (#32212)
The root cause of the flaky test was a nonce conflict caused by async contract deployments. This solution defines a custom deployer with automatic nonce management.
1 parent 532a1c2 commit 66df1f2

File tree

2 files changed

+35
-2
lines changed

2 files changed

+35
-2
lines changed

accounts/abi/bind/v2/lib.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ package bind
2828

2929
import (
3030
"errors"
31+
"math/big"
3132

3233
"github.com/ethereum/go-ethereum"
3334
"github.com/ethereum/go-ethereum/accounts/abi"
@@ -241,3 +242,27 @@ func DefaultDeployer(opts *TransactOpts, backend ContractBackend) DeployFn {
241242
return addr, tx, nil
242243
}
243244
}
245+
246+
// DeployerWithNonceAssignment is basically identical to DefaultDeployer,
247+
// but it additionally tracks the nonce to enable automatic assignment.
248+
//
249+
// This is especially useful when deploying multiple contracts
250+
// from the same address — whether they are independent contracts
251+
// or part of a dependency chain that must be deployed in order.
252+
func DeployerWithNonceAssignment(opts *TransactOpts, backend ContractBackend) DeployFn {
253+
var pendingNonce int64
254+
if opts.Nonce != nil {
255+
pendingNonce = opts.Nonce.Int64()
256+
}
257+
return func(input []byte, deployer []byte) (common.Address, *types.Transaction, error) {
258+
if pendingNonce != 0 {
259+
opts.Nonce = big.NewInt(pendingNonce)
260+
}
261+
addr, tx, err := DeployContract(opts, deployer, backend, input)
262+
if err != nil {
263+
return common.Address{}, nil, err
264+
}
265+
pendingNonce = int64(tx.Nonce() + 1)
266+
return addr, tx, nil
267+
}
268+
}

accounts/abi/bind/v2/lib_test.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,14 @@ func makeTestDeployer(backend simulated.Client) func(input, deployer []byte) (co
6565
return bind.DefaultDeployer(bind.NewKeyedTransactor(testKey, chainId), backend)
6666
}
6767

68+
// makeTestDeployerWithNonceAssignment is similar to makeTestDeployer,
69+
// but it returns a deployer that automatically tracks nonce,
70+
// enabling the deployment of multiple contracts from the same account.
71+
func makeTestDeployerWithNonceAssignment(backend simulated.Client) func(input, deployer []byte) (common.Address, *types.Transaction, error) {
72+
chainId, _ := backend.ChainID(context.Background())
73+
return bind.DeployerWithNonceAssignment(bind.NewKeyedTransactor(testKey, chainId), backend)
74+
}
75+
6876
// test that deploying a contract with library dependencies works,
6977
// verifying by calling method on the deployed contract.
7078
func TestDeploymentLibraries(t *testing.T) {
@@ -80,7 +88,7 @@ func TestDeploymentLibraries(t *testing.T) {
8088
Contracts: []*bind.MetaData{&nested_libraries.C1MetaData},
8189
Inputs: map[string][]byte{nested_libraries.C1MetaData.ID: constructorInput},
8290
}
83-
res, err := bind.LinkAndDeploy(deploymentParams, makeTestDeployer(bindBackend.Client))
91+
res, err := bind.LinkAndDeploy(deploymentParams, makeTestDeployerWithNonceAssignment(bindBackend.Client))
8492
if err != nil {
8593
t.Fatalf("err: %+v\n", err)
8694
}
@@ -122,7 +130,7 @@ func TestDeploymentWithOverrides(t *testing.T) {
122130
deploymentParams := &bind.DeploymentParams{
123131
Contracts: nested_libraries.C1MetaData.Deps,
124132
}
125-
res, err := bind.LinkAndDeploy(deploymentParams, makeTestDeployer(bindBackend))
133+
res, err := bind.LinkAndDeploy(deploymentParams, makeTestDeployerWithNonceAssignment(bindBackend))
126134
if err != nil {
127135
t.Fatalf("err: %+v\n", err)
128136
}

0 commit comments

Comments
 (0)