ethclient: Add EstimateGasAt[Hash] to estimate gas against a specific block

pull/27508/head
Lee Bousfield 1 year ago
parent 46ec972c9c
commit cdbfef880d
No known key found for this signature in database
GPG Key ID: 51137D1C9B477CBD
  1. 32
      ethclient/ethclient.go
  2. 27
      ethclient/ethclient_test.go

@ -564,9 +564,13 @@ func (ec *Client) FeeHistory(ctx context.Context, blockCount uint64, lastBlock *
}
// EstimateGas tries to estimate the gas needed to execute a specific transaction based on
// 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.
// the current 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.
//
// Note that the state used by this method is implementation-defined by the remote RPC
// server, but it's reasonable to assume that it will either be the pending or latest
// state.
func (ec *Client) EstimateGas(ctx context.Context, msg ethereum.CallMsg) (uint64, error) {
var hex hexutil.Uint64
err := ec.c.CallContext(ctx, &hex, "eth_estimateGas", toCallArg(msg))
@ -576,6 +580,28 @@ func (ec *Client) EstimateGas(ctx context.Context, msg ethereum.CallMsg) (uint64
return uint64(hex), nil
}
// EstimateGasAt is almost the same as EstimateGas except that it selects the block height
// instead of using the remote RPC's default state for gas estimation.
func (ec *Client) EstimateGasAt(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), toBlockNumArg(blockNumber))
if err != nil {
return 0, err
}
return uint64(hex), nil
}
// EstimateGasAtHash is almost the same as EstimateGas except that it selects the block
// hash instead of using the remote RPC's default state for gas estimation.
func (ec *Client) EstimateGasAtHash(ctx context.Context, msg ethereum.CallMsg, blockHash common.Hash) (uint64, error) {
var hex hexutil.Uint64
err := ec.c.CallContext(ctx, &hex, "eth_estimateGas", toCallArg(msg), rpc.BlockNumberOrHashWithHash(blockHash, false))
if err != nil {
return 0, err
}
return uint64(hex), nil
}
// SendTransaction injects a signed transaction into the pending pool for execution.
//
// If the transaction was a contract creation use the TransactionReceipt method to get the

@ -643,6 +643,33 @@ func testAtFunctions(t *testing.T, client *rpc.Client) {
if !bytes.Equal(code, penCode) {
t.Fatalf("unexpected code: %v %v", code, penCode)
}
// Use HeaderByNumber to get a header for EstimateGasAt and EstimateGasAtHash
latestHeader, err := ec.HeaderByNumber(context.Background(), nil)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
// EstimateGasAt
msg := ethereum.CallMsg{
From: testAddr,
To: &common.Address{},
Gas: 21000,
Value: big.NewInt(1),
}
gas, err := ec.EstimateGasAt(context.Background(), msg, latestHeader.Number)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if gas != 21000 {
t.Fatalf("unexpected gas limit: %v", gas)
}
// EstimateGasAtHash
gas, err = ec.EstimateGasAtHash(context.Background(), msg, latestHeader.Hash())
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if gas != 21000 {
t.Fatalf("unexpected gas limit: %v", gas)
}
}
func testTransactionSender(t *testing.T, client *rpc.Client) {

Loading…
Cancel
Save