@@ -111,7 +111,7 @@ func headerByNumberOrHash(ctx context.Context, tx kv.Tx, blockNrOrHash rpc.Block
111
111
}
112
112
113
113
// 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 ) {
115
115
var args ethapi2.CallArgs
116
116
// if we actually get CallArgs here, we use them
117
117
if argsOrNil != nil {
@@ -135,36 +135,39 @@ func (api *APIImpl) EstimateGas(ctx context.Context, argsOrNil *ethapi2.CallArgs
135
135
args .From = new (libcommon.Address )
136
136
}
137
137
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
141
141
}
142
142
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 )
149
152
if err != nil {
150
153
return 0 , err
151
154
}
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
+ }
157
159
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
168
171
}
169
172
170
173
var feeCap * big.Int
@@ -174,6 +177,8 @@ func (api *APIImpl) EstimateGas(ctx context.Context, argsOrNil *ethapi2.CallArgs
174
177
feeCap = args .GasPrice .ToInt ()
175
178
} else if args .MaxFeePerGas != nil {
176
179
feeCap = args .MaxFeePerGas .ToInt ()
180
+ } else if header .BaseFee != nil {
181
+ feeCap = new (big.Int ).Set (header .BaseFee )
177
182
} else {
178
183
feeCap = libcommon .Big0
179
184
}
@@ -218,35 +223,8 @@ func (api *APIImpl) EstimateGas(ctx context.Context, argsOrNil *ethapi2.CallArgs
218
223
}
219
224
gasCap = hi
220
225
221
- chainConfig , err := api .chainConfig (ctx , dbtx )
222
- if err != nil {
223
- return 0 , err
224
- }
225
226
engine := api .engine ()
226
227
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
-
250
228
caller , err := transactions .NewReusableCaller (engine , stateReader , nil , header , args , api .GasCap , latestNumOrHash , dbtx , api ._blockReader , chainConfig , api .evmCallTimeout )
251
229
if err != nil {
252
230
return 0 , err
0 commit comments