Skip to content

ethclient.EstimateGas blocktag param #25001

Open
@tynes

Description

@tynes

Rationale

The ability to pass a block tag with the RPC call eth_estimateGas was merged in #21545. This was done to make the RPC spec compliant.

The ethclient does not have an extra argument to be able to pass through a block tag, so "pending" is always used.

func (ec *Client) EstimateGas(ctx context.Context, msg ethereum.CallMsg) (uint64, error) {

func (s *PublicBlockChainAPI) EstimateGas(ctx context.Context, args TransactionArgs, blockNrOrHash *rpc.BlockNumberOrHash) (hexutil.Uint64, error) {
bNrOrHash := rpc.BlockNumberOrHashWithNumber(rpc.PendingBlockNumber)

For some users of ethclient, the difference between "pending" and "latest" can result in the gas estimation failing or succeeding. Ideally ethclient.EstimateGas can be extended to accept an additional block tag argument.

This is an API breaking change but fairly simple to fix, passing nil should default to "pending" so that the same behavior is maintained.

Implementation

diff --git a/ethclient/ethclient.go b/ethclient/ethclient.go
index 24edd8648..7704c0673 100644
--- a/ethclient/ethclient.go
+++ b/ethclient/ethclient.go
@@ -509,9 +509,12 @@ func (ec *Client) SuggestGasTipCap(ctx context.Context) (*big.Int, error) {
 // the current pending state of the backend blockchain. There is no guarantee that this is
 // the true gas limit requirement as other transactions may be added or removed by miners,
 // but it should provide a basis for setting a reasonable default.
-func (ec *Client) EstimateGas(ctx context.Context, msg ethereum.CallMsg) (uint64, error) {
+func (ec *Client) EstimateGas(ctx context.Context, msg ethereum.CallMsg, blockNumber *big.Int) (uint64, error) {
 	var hex hexutil.Uint64
-	err := ec.c.CallContext(ctx, &hex, "eth_estimateGas", toCallArg(msg))
+	if blockNumber == nil {
+		blockNumber = big.NewInt(-1)
+	}
+	err := ec.c.CallContext(ctx, &hex, "eth_estimateGas", toCallArg(msg), toBlockNumArg(blockNumber))
 	if err != nil {
 		return 0, err
 	}

The bind.ContractBackend interface will need to be updated as well for it to build.

I am willing to finish the implementation if this is considered an acceptable change.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions