Skip to content

Commit da84730

Browse files
authoredMay 27, 2024··
eth_estimateGas: default feeCap to base fee (#10495)
After [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) gas fee must be greater or equal to block's base fee – otherwise `eth_estimateGas` might fail with the fee defaulting to 0 (see #10373 (comment)). Also, this PR removes the `blockNrOrHash` argument from `eth_estimateGas`. geth doesn't have it. Moreover, it was effectively ignored by the previous code anyway with the exception of determining gas limit.
1 parent cb9a019 commit da84730

File tree

3 files changed

+32
-54
lines changed

3 files changed

+32
-54
lines changed
 

‎turbo/jsonrpc/eth_api.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ type EthAPI interface {
9090

9191
// Sending related (see ./eth_call.go)
9292
Call(ctx context.Context, args ethapi2.CallArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides *ethapi2.StateOverrides) (hexutility.Bytes, error)
93-
EstimateGas(ctx context.Context, argsOrNil *ethapi2.CallArgs, blockNrOrHash *rpc.BlockNumberOrHash) (hexutil.Uint64, error)
93+
EstimateGas(ctx context.Context, argsOrNil *ethapi2.CallArgs) (hexutil.Uint64, error)
9494
SendRawTransaction(ctx context.Context, encodedTx hexutility.Bytes) (common.Hash, error)
9595
SendTransaction(_ context.Context, txObject interface{}) (common.Hash, error)
9696
Sign(ctx context.Context, _ common.Address, _ hexutility.Bytes) (hexutility.Bytes, error)

‎turbo/jsonrpc/eth_call.go

+30-52
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ func headerByNumberOrHash(ctx context.Context, tx kv.Tx, blockNrOrHash rpc.Block
111111
}
112112

113113
// EstimateGas implements eth_estimateGas. Returns an estimate of how much gas is necessary to allow the transaction to complete. The transaction will not be added to the blockchain.
114-
func (api *APIImpl) EstimateGas(ctx context.Context, argsOrNil *ethapi2.CallArgs, blockNrOrHash *rpc.BlockNumberOrHash) (hexutil.Uint64, error) {
114+
func (api *APIImpl) EstimateGas(ctx context.Context, argsOrNil *ethapi2.CallArgs) (hexutil.Uint64, error) {
115115
var args ethapi2.CallArgs
116116
// if we actually get CallArgs here, we use them
117117
if argsOrNil != nil {
@@ -135,36 +135,39 @@ func (api *APIImpl) EstimateGas(ctx context.Context, argsOrNil *ethapi2.CallArgs
135135
args.From = new(libcommon.Address)
136136
}
137137

138-
bNrOrHash := rpc.BlockNumberOrHashWithNumber(rpc.PendingBlockNumber)
139-
if blockNrOrHash != nil {
140-
bNrOrHash = *blockNrOrHash
138+
chainConfig, err := api.chainConfig(ctx, dbtx)
139+
if err != nil {
140+
return 0, err
141141
}
142142

143-
// Determine the highest gas limit can be used during the estimation.
144-
if args.Gas != nil && uint64(*args.Gas) >= params.TxGas {
145-
hi = uint64(*args.Gas)
146-
} else {
147-
// Retrieve the block to act as the gas ceiling
148-
h, err := headerByNumberOrHash(ctx, dbtx, bNrOrHash, api)
143+
latestCanBlockNumber, latestCanHash, isLatest, err := rpchelper.GetCanonicalBlockNumber(latestNumOrHash, dbtx, api.filters) // DoCall cannot be executed on non-canonical blocks
144+
if err != nil {
145+
return 0, err
146+
}
147+
148+
// try and get the block from the lru cache first then try DB before failing
149+
block := api.tryBlockFromLru(latestCanHash)
150+
if block == nil {
151+
block, err = api.blockWithSenders(ctx, dbtx, latestCanHash, latestCanBlockNumber)
149152
if err != nil {
150153
return 0, err
151154
}
152-
if h == nil {
153-
// if a block number was supplied and there is no header return 0
154-
if blockNrOrHash != nil {
155-
return 0, nil
156-
}
155+
}
156+
if block == nil {
157+
return 0, fmt.Errorf("could not find latest block in cache or db")
158+
}
157159

158-
// block number not supplied, so we haven't found a pending block, read the latest block instead
159-
h, err = headerByNumberOrHash(ctx, dbtx, latestNumOrHash, api)
160-
if err != nil {
161-
return 0, err
162-
}
163-
if h == nil {
164-
return 0, nil
165-
}
166-
}
167-
hi = h.GasLimit
160+
stateReader, err := rpchelper.CreateStateReaderFromBlockNumber(ctx, dbtx, latestCanBlockNumber, isLatest, 0, api.stateCache, chainConfig.ChainName)
161+
if err != nil {
162+
return 0, err
163+
}
164+
header := block.HeaderNoCopy()
165+
166+
// Determine the highest gas limit can be used during the estimation.
167+
if args.Gas != nil && uint64(*args.Gas) >= params.TxGas {
168+
hi = uint64(*args.Gas)
169+
} else {
170+
hi = header.GasLimit
168171
}
169172

170173
var feeCap *big.Int
@@ -174,6 +177,8 @@ func (api *APIImpl) EstimateGas(ctx context.Context, argsOrNil *ethapi2.CallArgs
174177
feeCap = args.GasPrice.ToInt()
175178
} else if args.MaxFeePerGas != nil {
176179
feeCap = args.MaxFeePerGas.ToInt()
180+
} else if header.BaseFee != nil {
181+
feeCap = new(big.Int).Set(header.BaseFee)
177182
} else {
178183
feeCap = libcommon.Big0
179184
}
@@ -218,35 +223,8 @@ func (api *APIImpl) EstimateGas(ctx context.Context, argsOrNil *ethapi2.CallArgs
218223
}
219224
gasCap = hi
220225

221-
chainConfig, err := api.chainConfig(ctx, dbtx)
222-
if err != nil {
223-
return 0, err
224-
}
225226
engine := api.engine()
226227

227-
latestCanBlockNumber, latestCanHash, isLatest, err := rpchelper.GetCanonicalBlockNumber(latestNumOrHash, dbtx, api.filters) // DoCall cannot be executed on non-canonical blocks
228-
if err != nil {
229-
return 0, err
230-
}
231-
232-
// try and get the block from the lru cache first then try DB before failing
233-
block := api.tryBlockFromLru(latestCanHash)
234-
if block == nil {
235-
block, err = api.blockWithSenders(ctx, dbtx, latestCanHash, latestCanBlockNumber)
236-
if err != nil {
237-
return 0, err
238-
}
239-
}
240-
if block == nil {
241-
return 0, fmt.Errorf("could not find latest block in cache or db")
242-
}
243-
244-
stateReader, err := rpchelper.CreateStateReaderFromBlockNumber(ctx, dbtx, latestCanBlockNumber, isLatest, 0, api.stateCache, chainConfig.ChainName)
245-
if err != nil {
246-
return 0, err
247-
}
248-
header := block.HeaderNoCopy()
249-
250228
caller, err := transactions.NewReusableCaller(engine, stateReader, nil, header, args, api.GasCap, latestNumOrHash, dbtx, api._blockReader, chainConfig, api.evmCallTimeout)
251229
if err != nil {
252230
return 0, err

‎turbo/jsonrpc/eth_call_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ func TestEstimateGas(t *testing.T) {
4949
if _, err := api.EstimateGas(context.Background(), &ethapi.CallArgs{
5050
From: &from,
5151
To: &to,
52-
}, nil); err != nil {
52+
}); err != nil {
5353
t.Errorf("calling EstimateGas: %v", err)
5454
}
5555
}

0 commit comments

Comments
 (0)
Please sign in to comment.