accounts/abi/bind/v2: modify the default deployer to block until the transaction is accepted/rejected from the pool.

This commit is contained in:
Jared Wasinger 2025-07-08 20:05:25 +09:00
parent e71487b033
commit d97d3716ca
2 changed files with 38 additions and 1 deletions

View file

@ -103,6 +103,9 @@ type ContractTransactor interface {
// PendingNonceAt retrieves the current pending nonce associated with an account.
PendingNonceAt(ctx context.Context, account common.Address) (uint64, error)
// TransactionByHash retrieves the transaction corresponding to the given hash.
TransactionByHash(ctx context.Context, txHash common.Hash) (tx *types.Transaction, isPending bool, err error)
}
// DeployBackend wraps the operations needed by WaitMined and WaitDeployed.

View file

@ -27,14 +27,16 @@
package bind
import (
"context"
"errors"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/log"
"time"
)
// ContractEvent is a type constraint for ABI event types.
@ -227,6 +229,34 @@ func DeployContract(opts *TransactOpts, bytecode []byte, backend ContractBackend
return crypto.CreateAddress(opts.From, tx.Nonce()), tx, nil
}
// waitAccepted polls the backend until the transaction is accepted or the
// context is cancelled. If the transaction was not accepted into the pool,
// an error is returned.
func waitAccepted(ctx context.Context, d ContractBackend, txHash common.Hash) error {
queryTicker := time.NewTicker(time.Second)
defer queryTicker.Stop()
logger := log.New("hash", txHash)
for {
_, _, err := d.TransactionByHash(ctx, txHash)
if err == nil {
return nil
}
if errors.Is(err, ethereum.NotFound) { // TODO: check this is emitted
logger.Trace("Transaction not yet accepted")
} else {
logger.Trace("Transaction submission failed", "err", err)
}
// Wait for the next round.
select {
case <-ctx.Done():
return ctx.Err()
case <-queryTicker.C:
}
}
}
// DefaultDeployer returns a DeployFn that signs and submits creation transactions
// using the given signer.
//
@ -238,6 +268,10 @@ func DefaultDeployer(opts *TransactOpts, backend ContractBackend) DeployFn {
if err != nil {
return common.Address{}, nil, err
}
ctx, _ := context.WithTimeout(context.Background(), 5*time.Second)
if err := waitAccepted(ctx, backend, tx.Hash()); err != nil {
return common.Address{}, nil, err
}
return addr, tx, nil
}
}