From 8200bbf4a01be37c795c69413c285a044f2804b8 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Tue, 28 Jan 2025 00:07:21 +0100 Subject: [PATCH] accounts/abi/bind/v2: provide only one version of WaitMined, WaitDeployed WaitMinedHash & WaitDeployedHash are more versatile, they only need the hash. --- accounts/abi/bind/old.go | 11 +++++++---- accounts/abi/bind/v2/backend.go | 5 +++++ accounts/abi/bind/v2/lib_test.go | 12 ++++++------ accounts/abi/bind/v2/util.go | 32 +++++++++---------------------- accounts/abi/bind/v2/util_test.go | 9 ++++----- 5 files changed, 31 insertions(+), 38 deletions(-) diff --git a/accounts/abi/bind/old.go b/accounts/abi/bind/old.go index 5f41aee70f..b79144effe 100644 --- a/accounts/abi/bind/old.go +++ b/accounts/abi/bind/old.go @@ -239,23 +239,26 @@ func (m *MetaData) GetAbi() (*abi.ABI, error) { // WaitMined waits for tx to be mined on the blockchain. // It stops waiting when the context is canceled. func WaitMined(ctx context.Context, b DeployBackend, tx *types.Transaction) (*types.Receipt, error) { - return bind2.WaitMined(ctx, b, tx) + return bind2.WaitMined(ctx, b, tx.Hash()) } // WaitMinedHash waits for a transaction with the provided hash to be mined on the blockchain. // It stops waiting when the context is canceled. func WaitMinedHash(ctx context.Context, b DeployBackend, hash common.Hash) (*types.Receipt, error) { - return bind2.WaitMinedHash(ctx, b, hash) + return bind2.WaitMined(ctx, b, hash) } // 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. func WaitDeployed(ctx context.Context, b DeployBackend, tx *types.Transaction) (common.Address, error) { - return bind2.WaitDeployed(ctx, b, tx) + if tx.To() != nil { + return common.Address{}, errors.New("tx is not contract creation") + } + return bind2.WaitDeployed(ctx, b, tx.Hash()) } // WaitDeployedHash waits for a contract deployment transaction with the provided hash and returns the on-chain // contract address when it is mined. It stops waiting when ctx is canceled. func WaitDeployedHash(ctx context.Context, b DeployBackend, hash common.Hash) (common.Address, error) { - return bind2.WaitDeployedHash(ctx, b, hash) + return bind2.WaitDeployed(ctx, b, hash) } diff --git a/accounts/abi/bind/v2/backend.go b/accounts/abi/bind/v2/backend.go index 38b3046970..7c88480bdc 100644 --- a/accounts/abi/bind/v2/backend.go +++ b/accounts/abi/bind/v2/backend.go @@ -43,6 +43,11 @@ var ( // ErrNoCodeAfterDeploy is returned by WaitDeployed if contract creation leaves // an empty contract behind. ErrNoCodeAfterDeploy = errors.New("no contract code after deployment") + + // Returned by WaitDeployed when the receipt for the transaction hash does not contain + // a contract address. This error may indicated that the transaction hash was not a + // CREATE transaction. + ErrNoAddressInReceipt = errors.New("no contract address in receipt") ) // ContractCaller defines the methods needed to allow operating with a contract on a read diff --git a/accounts/abi/bind/v2/lib_test.go b/accounts/abi/bind/v2/lib_test.go index 6a37c3e814..27412c2a34 100644 --- a/accounts/abi/bind/v2/lib_test.go +++ b/accounts/abi/bind/v2/lib_test.go @@ -120,7 +120,7 @@ func TestDeploymentLibraries(t *testing.T) { t.Fatalf("deployment should have generated 5 addresses. got %d", len(res.Addrs)) } for _, tx := range res.Txs { - _, err = bind.WaitDeployed(context.Background(), bindBackend, tx) + _, err = bind.WaitDeployed(context.Background(), bindBackend, tx.Hash()) if err != nil { t.Fatalf("error deploying library: %+v", err) } @@ -161,7 +161,7 @@ func TestDeploymentWithOverrides(t *testing.T) { t.Fatalf("deployment should have generated 4 addresses. got %d", len(res.Addrs)) } for _, tx := range res.Txs { - _, err = bind.WaitDeployed(context.Background(), bindBackend, tx) + _, err = bind.WaitDeployed(context.Background(), bindBackend, tx.Hash()) if err != nil { t.Fatalf("error deploying library: %+v", err) } @@ -182,7 +182,7 @@ func TestDeploymentWithOverrides(t *testing.T) { t.Fatalf("deployment should have generated 1 address. got %d", len(res.Addrs)) } for _, tx := range res.Txs { - _, err = bind.WaitDeployed(context.Background(), bindBackend, tx) + _, err = bind.WaitDeployed(context.Background(), bindBackend, tx.Hash()) if err != nil { t.Fatalf("error deploying library: %+v", err) } @@ -215,7 +215,7 @@ func TestEvents(t *testing.T) { } backend.Commit() - if _, err := bind.WaitDeployed(context.Background(), backend, res.Txs[events.CMetaData.Pattern]); err != nil { + if _, err := bind.WaitDeployed(context.Background(), backend, res.Txs[events.CMetaData.Pattern].Hash()); err != nil { t.Fatalf("WaitDeployed failed %v", err) } @@ -242,7 +242,7 @@ func TestEvents(t *testing.T) { t.Fatalf("failed to send transaction: %v", err) } backend.Commit() - if _, err := bind.WaitMined(context.Background(), backend, tx); err != nil { + if _, err := bind.WaitMined(context.Background(), backend, tx.Hash()); err != nil { t.Fatalf("error waiting for tx to be mined: %v", err) } @@ -314,7 +314,7 @@ func TestErrors(t *testing.T) { } backend.Commit() - if _, err := bind.WaitDeployed(context.Background(), backend, res.Txs[solc_errors.CMetaData.Pattern]); err != nil { + if _, err := bind.WaitDeployed(context.Background(), backend, res.Txs[solc_errors.CMetaData.Pattern].Hash()); err != nil { t.Fatalf("WaitDeployed failed %v", err) } diff --git a/accounts/abi/bind/v2/util.go b/accounts/abi/bind/v2/util.go index c83116e9a1..438848a753 100644 --- a/accounts/abi/bind/v2/util.go +++ b/accounts/abi/bind/v2/util.go @@ -29,19 +29,13 @@ import ( // WaitMined waits for tx to be mined on the blockchain. // It stops waiting when the context is canceled. -func WaitMined(ctx context.Context, b DeployBackend, tx *types.Transaction) (*types.Receipt, error) { - return WaitMinedHash(ctx, b, tx.Hash()) -} - -// WaitMinedHash waits for a transaction with the provided hash to be mined on the blockchain. -// It stops waiting when the context is canceled. -func WaitMinedHash(ctx context.Context, b DeployBackend, hash common.Hash) (*types.Receipt, error) { +func WaitMined(ctx context.Context, b DeployBackend, txHash common.Hash) (*types.Receipt, error) { queryTicker := time.NewTicker(time.Second) defer queryTicker.Stop() - logger := log.New("hash", hash) + logger := log.New("hash", txHash) for { - receipt, err := b.TransactionReceipt(ctx, hash) + receipt, err := b.TransactionReceipt(ctx, txHash) if err == nil { return receipt, nil } @@ -61,24 +55,16 @@ func WaitMinedHash(ctx context.Context, b DeployBackend, hash common.Hash) (*typ } } -// 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. -func WaitDeployed(ctx context.Context, b DeployBackend, tx *types.Transaction) (common.Address, error) { - if tx.To() != nil { - return common.Address{}, errors.New("tx is not contract creation") - } - return WaitDeployedHash(ctx, b, tx.Hash()) -} - -// WaitDeployedHash waits for a contract deployment transaction with the provided hash and returns the on-chain -// contract address when it is mined. It stops waiting when ctx is canceled. -func WaitDeployedHash(ctx context.Context, b DeployBackend, hash common.Hash) (common.Address, error) { - receipt, err := WaitMinedHash(ctx, b, hash) +// WaitDeployed waits for a contract deployment transaction with the provided hash and +// returns the on-chain contract address when it is mined. It stops waiting when ctx is +// canceled. +func WaitDeployed(ctx context.Context, b DeployBackend, hash common.Hash) (common.Address, error) { + receipt, err := WaitMined(ctx, b, hash) if err != nil { return common.Address{}, err } if receipt.ContractAddress == (common.Address{}) { - return common.Address{}, errors.New("zero address") + return common.Address{}, ErrNoAddressInReceipt } // Check that code has indeed been deployed at the address. // This matters on pre-Homestead chains: OOG in the constructor diff --git a/accounts/abi/bind/v2/util_test.go b/accounts/abi/bind/v2/util_test.go index 26ac78c96f..b1b647a7b9 100644 --- a/accounts/abi/bind/v2/util_test.go +++ b/accounts/abi/bind/v2/util_test.go @@ -75,7 +75,7 @@ func TestWaitDeployed(t *testing.T) { ctx = context.Background() ) go func() { - address, err = bind.WaitDeployed(ctx, backend.Client(), tx) + address, err = bind.WaitDeployed(ctx, backend.Client(), tx.Hash()) close(mined) }() @@ -120,9 +120,8 @@ func TestWaitDeployedCornerCases(t *testing.T) { t.Errorf("failed to send transaction: %q", err) } backend.Commit() - notContractCreation := errors.New("tx is not contract creation") - if _, err := bind.WaitDeployed(ctx, backend.Client(), tx); err.Error() != notContractCreation.Error() { - t.Errorf("error mismatch: want %q, got %q, ", notContractCreation, err) + if _, err := bind.WaitDeployed(ctx, backend.Client(), tx.Hash()); err != bind.ErrNoAddressInReceipt { + t.Errorf("error mismatch: want %q, got %q, ", bind.ErrNoAddressInReceipt, err) } // Create a transaction that is not mined. @@ -131,7 +130,7 @@ func TestWaitDeployedCornerCases(t *testing.T) { go func() { 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.Hash()); err.Error() != contextCanceled.Error() { t.Errorf("error mismatch: want %q, got %q, ", contextCanceled, err) } }()