bind: make WaitMined and WaitDeployed wait interval customizable

This commit is contained in:
0xJordan 2024-03-23 01:14:54 +04:00
parent 064f37d6f6
commit b75abcbc30
3 changed files with 36 additions and 32 deletions

View file

@ -541,7 +541,7 @@ var bindTests = []struct {
struct A { struct A {
bytes32 B; bytes32 B;
} }
function F() public view returns (A[] memory a, uint256[] memory c, bool[] memory d) { function F() public view returns (A[] memory a, uint256[] memory c, bool[] memory d) {
A[] memory a = new A[](2); A[] memory a = new A[](2);
a[0].B = bytes32(uint256(1234) << 96); a[0].B = bytes32(uint256(1234) << 96);
@ -549,7 +549,7 @@ var bindTests = []struct {
bool[] memory d; bool[] memory d;
return (a, c, d); return (a, c, d);
} }
function G() public view returns (A[] memory a) { function G() public view returns (A[] memory a) {
A[] memory a = new A[](2); A[] memory a = new A[](2);
a[0].B = bytes32(uint256(1234) << 96); a[0].B = bytes32(uint256(1234) << 96);
@ -571,10 +571,10 @@ var bindTests = []struct {
// Generate a new random account and a funded simulator // Generate a new random account and a funded simulator
key, _ := crypto.GenerateKey() key, _ := crypto.GenerateKey()
auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
sim := backends.NewSimulatedBackend(types.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000) sim := backends.NewSimulatedBackend(types.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000)
defer sim.Close() defer sim.Close()
// Deploy a structs method invoker contract and execute its default method // Deploy a structs method invoker contract and execute its default method
_, _, structs, err := DeployStructs(auth, sim) _, _, structs, err := DeployStructs(auth, sim)
if err != nil { if err != nil {
@ -1701,13 +1701,13 @@ var bindTests = []struct {
`NewFallbacks`, `NewFallbacks`,
` `
pragma solidity >=0.6.0 <0.7.0; pragma solidity >=0.6.0 <0.7.0;
contract NewFallbacks { contract NewFallbacks {
event Fallback(bytes data); event Fallback(bytes data);
fallback() external { fallback() external {
emit Fallback(msg.data); emit Fallback(msg.data);
} }
event Received(address addr, uint value); event Received(address addr, uint value);
receive() external payable { receive() external payable {
emit Received(msg.sender, msg.value); emit Received(msg.sender, msg.value);
@ -1719,7 +1719,7 @@ var bindTests = []struct {
` `
"bytes" "bytes"
"math/big" "math/big"
"github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends" "github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
@ -1728,22 +1728,22 @@ var bindTests = []struct {
` `
key, _ := crypto.GenerateKey() key, _ := crypto.GenerateKey()
addr := crypto.PubkeyToAddress(key.PublicKey) addr := crypto.PubkeyToAddress(key.PublicKey)
sim := backends.NewSimulatedBackend(types.GenesisAlloc{addr: {Balance: big.NewInt(10000000000000000)}}, 1000000) sim := backends.NewSimulatedBackend(types.GenesisAlloc{addr: {Balance: big.NewInt(10000000000000000)}}, 1000000)
defer sim.Close() defer sim.Close()
opts, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) opts, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
_, _, c, err := DeployNewFallbacks(opts, sim) _, _, c, err := DeployNewFallbacks(opts, sim)
if err != nil { if err != nil {
t.Fatalf("Failed to deploy contract: %v", err) t.Fatalf("Failed to deploy contract: %v", err)
} }
sim.Commit() sim.Commit()
// Test receive function // Test receive function
opts.Value = big.NewInt(100) opts.Value = big.NewInt(100)
c.Receive(opts) c.Receive(opts)
sim.Commit() sim.Commit()
var gotEvent bool var gotEvent bool
iter, _ := c.FilterReceived(nil) iter, _ := c.FilterReceived(nil)
defer iter.Close() defer iter.Close()
@ -1760,14 +1760,14 @@ var bindTests = []struct {
if !gotEvent { if !gotEvent {
t.Fatal("Expect to receive event emitted by receive") t.Fatal("Expect to receive event emitted by receive")
} }
// Test fallback function // Test fallback function
gotEvent = false gotEvent = false
opts.Value = nil opts.Value = nil
calldata := []byte{0x01, 0x02, 0x03} calldata := []byte{0x01, 0x02, 0x03}
c.Fallback(opts, calldata) c.Fallback(opts, calldata)
sim.Commit() sim.Commit()
iter2, _ := c.FilterFallback(nil) iter2, _ := c.FilterFallback(nil)
defer iter2.Close() defer iter2.Close()
for iter2.Next() { for iter2.Next() {
@ -1862,7 +1862,7 @@ var bindTests = []struct {
`NewErrors`, `NewErrors`,
` `
pragma solidity >0.8.4; pragma solidity >0.8.4;
contract NewErrors { contract NewErrors {
error MyError(uint256); error MyError(uint256);
error MyError1(uint256); error MyError1(uint256);
@ -1877,8 +1877,9 @@ var bindTests = []struct {
[]string{`[{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"MyError","type":"error"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"MyError1","type":"error"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"MyError2","type":"error"},{"inputs":[{"internalType":"uint256","name":"a","type":"uint256"},{"internalType":"uint256","name":"b","type":"uint256"},{"internalType":"uint256","name":"c","type":"uint256"}],"name":"MyError3","type":"error"},{"inputs":[],"name":"Error","outputs":[],"stateMutability":"pure","type":"function"}]`}, []string{`[{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"MyError","type":"error"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"MyError1","type":"error"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"MyError2","type":"error"},{"inputs":[{"internalType":"uint256","name":"a","type":"uint256"},{"internalType":"uint256","name":"b","type":"uint256"},{"internalType":"uint256","name":"c","type":"uint256"}],"name":"MyError3","type":"error"},{"inputs":[],"name":"Error","outputs":[],"stateMutability":"pure","type":"function"}]`},
` `
"context" "context"
"time"
"math/big" "math/big"
"github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends" "github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
@ -1892,13 +1893,13 @@ var bindTests = []struct {
sim = backends.NewSimulatedBackend(types.GenesisAlloc{user.From: {Balance: big.NewInt(1000000000000000000)}}, ethconfig.Defaults.Miner.GasCeil) sim = backends.NewSimulatedBackend(types.GenesisAlloc{user.From: {Balance: big.NewInt(1000000000000000000)}}, ethconfig.Defaults.Miner.GasCeil)
) )
defer sim.Close() defer sim.Close()
_, tx, contract, err := DeployNewErrors(user, sim) _, tx, contract, err := DeployNewErrors(user, sim)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
sim.Commit() sim.Commit()
_, err = bind.WaitDeployed(context.Background(), sim, tx) _, err = bind.WaitDeployed(context.Background(), sim, tx, time.Second)
if err != nil { if err != nil {
t.Error(err) t.Error(err)
} }
@ -1917,12 +1918,12 @@ var bindTests = []struct {
name: `ConstructorWithStructParam`, name: `ConstructorWithStructParam`,
contract: ` contract: `
pragma solidity >=0.8.0 <0.9.0; pragma solidity >=0.8.0 <0.9.0;
contract ConstructorWithStructParam { contract ConstructorWithStructParam {
struct StructType { struct StructType {
uint256 field; uint256 field;
} }
constructor(StructType memory st) {} constructor(StructType memory st) {}
} }
`, `,
@ -1930,6 +1931,7 @@ var bindTests = []struct {
abi: []string{`[{"inputs":[{"components":[{"internalType":"uint256","name":"field","type":"uint256"}],"internalType":"struct ConstructorWithStructParam.StructType","name":"st","type":"tuple"}],"stateMutability":"nonpayable","type":"constructor"}]`}, abi: []string{`[{"inputs":[{"components":[{"internalType":"uint256","name":"field","type":"uint256"}],"internalType":"struct ConstructorWithStructParam.StructType","name":"st","type":"tuple"}],"stateMutability":"nonpayable","type":"constructor"}]`},
imports: ` imports: `
"context" "context"
"time"
"math/big" "math/big"
"github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/accounts/abi/bind"
@ -1951,10 +1953,10 @@ var bindTests = []struct {
t.Fatalf("DeployConstructorWithStructParam() got err %v; want nil err", err) t.Fatalf("DeployConstructorWithStructParam() got err %v; want nil err", err)
} }
sim.Commit() sim.Commit()
if _, err = bind.WaitDeployed(context.Background(), sim, tx); err != nil { if _, err = bind.WaitDeployed(context.Background(), sim, tx, time.Second); err != nil {
t.Logf("Deployment tx: %+v", tx) t.Logf("Deployment tx: %+v", tx)
t.Errorf("bind.WaitDeployed(nil, %T, <deployment tx>) got err %v; want nil err", sim, err) t.Errorf("bind.WaitDeployed(nil, %T, <deployment tx>, %T) got err %v; want nil err", sim, err, time.Second)
} }
`, `,
}, },
@ -1979,6 +1981,7 @@ var bindTests = []struct {
abi: []string{`[ { "anonymous": false, "inputs": [ { "indexed": false, "internalType": "int256", "name": "msg", "type": "int256" }, { "indexed": false, "internalType": "int256", "name": "_msg", "type": "int256" } ], "name": "log", "type": "event" }, { "inputs": [ { "components": [ { "internalType": "bytes", "name": "data", "type": "bytes" }, { "internalType": "bytes", "name": "_data", "type": "bytes" } ], "internalType": "struct oracle.request", "name": "req", "type": "tuple" } ], "name": "addRequest", "outputs": [], "stateMutability": "pure", "type": "function" }, { "inputs": [], "name": "getRequest", "outputs": [ { "components": [ { "internalType": "bytes", "name": "data", "type": "bytes" }, { "internalType": "bytes", "name": "_data", "type": "bytes" } ], "internalType": "struct oracle.request", "name": "", "type": "tuple" } ], "stateMutability": "pure", "type": "function" } ]`}, abi: []string{`[ { "anonymous": false, "inputs": [ { "indexed": false, "internalType": "int256", "name": "msg", "type": "int256" }, { "indexed": false, "internalType": "int256", "name": "_msg", "type": "int256" } ], "name": "log", "type": "event" }, { "inputs": [ { "components": [ { "internalType": "bytes", "name": "data", "type": "bytes" }, { "internalType": "bytes", "name": "_data", "type": "bytes" } ], "internalType": "struct oracle.request", "name": "req", "type": "tuple" } ], "name": "addRequest", "outputs": [], "stateMutability": "pure", "type": "function" }, { "inputs": [], "name": "getRequest", "outputs": [ { "components": [ { "internalType": "bytes", "name": "data", "type": "bytes" }, { "internalType": "bytes", "name": "_data", "type": "bytes" } ], "internalType": "struct oracle.request", "name": "", "type": "tuple" } ], "stateMutability": "pure", "type": "function" } ]`},
imports: ` imports: `
"context" "context"
"time"
"math/big" "math/big"
"github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/accounts/abi/bind"
@ -2000,8 +2003,8 @@ var bindTests = []struct {
t.Fatalf("DeployNameConflict() got err %v; want nil err", err) t.Fatalf("DeployNameConflict() got err %v; want nil err", err)
} }
sim.Commit() sim.Commit()
if _, err = bind.WaitDeployed(context.Background(), sim, tx); err != nil { if _, err = bind.WaitDeployed(context.Background(), sim, tx, time.Second); err != nil {
t.Logf("Deployment tx: %+v", tx) t.Logf("Deployment tx: %+v", tx)
t.Errorf("bind.WaitDeployed(nil, %T, <deployment tx>) got err %v; want nil err", sim, err) t.Errorf("bind.WaitDeployed(nil, %T, <deployment tx>) got err %v; want nil err", sim, err)
} }
@ -2020,6 +2023,7 @@ var bindTests = []struct {
abi: []string{`[{"inputs":[{"internalType":"uint256","name":"range","type":"uint256"}],"name":"functionWithKeywordParameter","outputs":[],"stateMutability":"pure","type":"function"}]`}, abi: []string{`[{"inputs":[{"internalType":"uint256","name":"range","type":"uint256"}],"name":"functionWithKeywordParameter","outputs":[],"stateMutability":"pure","type":"function"}]`},
imports: ` imports: `
"context" "context"
"time"
"math/big" "math/big"
"github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/accounts/abi/bind"
@ -2040,7 +2044,7 @@ var bindTests = []struct {
} }
sim.Commit() sim.Commit()
if _, err = bind.WaitDeployed(context.Background(), sim, tx); err != nil { if _, err = bind.WaitDeployed(context.Background(), sim, tx, time.Second); err != nil {
t.Errorf("error deploying the contract: %v", err) t.Errorf("error deploying the contract: %v", err)
} }
`, `,

View file

@ -29,8 +29,8 @@ import (
// WaitMined waits for tx to be mined on the blockchain. // WaitMined waits for tx to be mined on the blockchain.
// It stops waiting when the context is canceled. // It stops waiting when the context is canceled.
func WaitMined(ctx context.Context, b DeployBackend, tx *types.Transaction) (*types.Receipt, error) { func WaitMined(ctx context.Context, b DeployBackend, tx *types.Transaction, waitInterval time.Duration) (*types.Receipt, error) {
queryTicker := time.NewTicker(time.Second) queryTicker := time.NewTicker(waitInterval)
defer queryTicker.Stop() defer queryTicker.Stop()
logger := log.New("hash", tx.Hash()) logger := log.New("hash", tx.Hash())
@ -57,11 +57,11 @@ func WaitMined(ctx context.Context, b DeployBackend, tx *types.Transaction) (*ty
// WaitDeployed waits for a contract deployment transaction and returns the on-chain // WaitDeployed waits for a contract deployment transaction and returns the on-chain
// contract address when it is mined. It stops waiting when ctx is canceled. // contract address when it is mined. It stops waiting when ctx is canceled.
func WaitDeployed(ctx context.Context, b DeployBackend, tx *types.Transaction) (common.Address, error) { func WaitDeployed(ctx context.Context, b DeployBackend, tx *types.Transaction, waitInterval time.Duration) (common.Address, error) {
if tx.To() != nil { if tx.To() != nil {
return common.Address{}, errors.New("tx is not contract creation") return common.Address{}, errors.New("tx is not contract creation")
} }
receipt, err := WaitMined(ctx, b, tx) receipt, err := WaitMined(ctx, b, tx, waitInterval)
if err != nil { if err != nil {
return common.Address{}, err return common.Address{}, err
} }

View file

@ -77,7 +77,7 @@ func TestWaitDeployed(t *testing.T) {
ctx = context.Background() ctx = context.Background()
) )
go func() { go func() {
address, err = bind.WaitDeployed(ctx, backend.Client(), tx) address, err = bind.WaitDeployed(ctx, backend.Client(), tx, time.Second)
close(mined) close(mined)
}() }()
@ -119,7 +119,7 @@ func TestWaitDeployedCornerCases(t *testing.T) {
backend.Client().SendTransaction(ctx, tx) backend.Client().SendTransaction(ctx, tx)
backend.Commit() backend.Commit()
notContractCreation := errors.New("tx is not contract creation") notContractCreation := errors.New("tx is not contract creation")
if _, err := bind.WaitDeployed(ctx, backend.Client(), tx); err.Error() != notContractCreation.Error() { if _, err := bind.WaitDeployed(ctx, backend.Client(), tx, time.Second); err.Error() != notContractCreation.Error() {
t.Errorf("error mismatch: want %q, got %q, ", notContractCreation, err) t.Errorf("error mismatch: want %q, got %q, ", notContractCreation, err)
} }
@ -129,7 +129,7 @@ func TestWaitDeployedCornerCases(t *testing.T) {
go func() { go func() {
contextCanceled := errors.New("context canceled") contextCanceled := errors.New("context canceled")
if _, err := bind.WaitDeployed(ctx, backend.Client(), tx); err.Error() != contextCanceled.Error() { if _, err := bind.WaitDeployed(ctx, backend.Client(), tx, time.Second); err.Error() != contextCanceled.Error() {
t.Errorf("error mismatch: want %q, got %q, ", contextCanceled, err) t.Errorf("error mismatch: want %q, got %q, ", contextCanceled, err)
} }
}() }()