@@ -150,31 +150,38 @@ func (api *APIImpl) EstimateGas(ctx context.Context, argsOrNil *ethapi2.CallArgs
150
150
}
151
151
defer dbtx .Rollback ()
152
152
153
+ // Use latest block by default
154
+ if blockNrOrHash == nil {
155
+ blockNrOrHash = & latestNumOrHash
156
+ }
157
+
153
158
chainConfig , err := api .chainConfig (ctx , dbtx )
154
159
if err != nil {
155
160
return 0 , err
156
161
}
157
162
engine := api .engine ()
158
163
159
- latestCanBlockNumber , latestCanHash , isLatest , err := rpchelper .GetCanonicalBlockNumber (ctx , latestNumOrHash , dbtx , api ._blockReader , api .filters ) // DoCall cannot be executed on non-canonical blocks
164
+ blockNum , blockHash , isLatest , err := rpchelper .GetCanonicalBlockNumber (ctx , * blockNrOrHash , dbtx , api ._blockReader , api .filters ) // DoCall cannot be executed on non-canonical blocks
160
165
if err != nil {
161
166
return 0 , err
162
167
}
163
168
164
169
// try and get the block from the lru cache first then try DB before failing
165
- block := api .tryBlockFromLru (latestCanHash )
170
+ block := api .tryBlockFromLru (blockHash )
166
171
if block == nil {
167
- block , err = api .blockWithSenders (ctx , dbtx , latestCanHash , latestCanBlockNumber )
172
+ block , err = api .blockWithSenders (ctx , dbtx , blockHash , blockNum )
168
173
if err != nil {
169
174
return 0 , err
170
175
}
171
176
}
177
+
172
178
if block == nil {
173
- return 0 , errors .New ("could not find latest block in cache or db" )
179
+ return 0 , errors .New (fmt . Sprintf ( "could not find the block %s in cache or db" , blockNrOrHash . String ()) )
174
180
}
181
+ header := block .HeaderNoCopy ()
175
182
176
183
txNumsReader := rawdbv3 .TxNums .WithCustomReadTxNumFunc (freezeblocks .ReadTxNumFuncFromBlockReader (ctx , api ._blockReader ))
177
- stateReader , err := rpchelper .CreateStateReaderFromBlockNumber (ctx , dbtx , txNumsReader , latestCanBlockNumber , isLatest , 0 , api .stateCache , chainConfig .ChainName )
184
+ stateReader , err := rpchelper .CreateStateReaderFromBlockNumber (ctx , dbtx , txNumsReader , blockNum , isLatest , 0 , api .stateCache , chainConfig .ChainName )
178
185
if err != nil {
179
186
return 0 , err
180
187
}
@@ -190,36 +197,12 @@ func (api *APIImpl) EstimateGas(ctx context.Context, argsOrNil *ethapi2.CallArgs
190
197
args .From = new (libcommon.Address )
191
198
}
192
199
193
- bNrOrHash := rpc .BlockNumberOrHashWithNumber (rpc .PendingBlockNumber )
194
- if blockNrOrHash != nil {
195
- bNrOrHash = * blockNrOrHash
196
- }
197
-
198
200
// Determine the highest gas limit can be used during the estimation.
199
201
if args .Gas != nil && uint64 (* args .Gas ) >= params .TxGas {
200
202
hi = uint64 (* args .Gas )
201
203
} else {
202
204
// Retrieve the block to act as the gas ceiling
203
- h , err := headerByNumberOrHash (ctx , dbtx , bNrOrHash , api )
204
- if err != nil {
205
- return 0 , err
206
- }
207
- if h == nil {
208
- // if a block number was supplied and there is no header return 0
209
- if blockNrOrHash != nil {
210
- return 0 , nil
211
- }
212
-
213
- // block number not supplied, so we haven't found a pending block, read the latest block instead
214
- h , err = headerByNumberOrHash (ctx , dbtx , latestNumOrHash , api )
215
- if err != nil {
216
- return 0 , err
217
- }
218
- if h == nil {
219
- return 0 , nil
220
- }
221
- }
222
- hi = h .GasLimit
205
+ hi = header .GasLimit
223
206
}
224
207
225
208
var feeCap * big.Int
@@ -271,15 +254,12 @@ func (api *APIImpl) EstimateGas(ctx context.Context, argsOrNil *ethapi2.CallArgs
271
254
}
272
255
gasCap = hi
273
256
274
- header := block .HeaderNoCopy ()
275
-
257
+ caller , err := transactions .NewReusableCaller (engine , stateReader , overrides , header , args , api .GasCap , * blockNrOrHash , dbtx , api ._blockReader , chainConfig , api .evmCallTimeout )
258
+ if err != nil {
259
+ return 0 , err
260
+ }
276
261
// Create a helper to check if a gas allowance results in an executable transaction
277
262
executable := func (gas uint64 ) (bool , * evmtypes.ExecutionResult , error ) {
278
- caller , err := transactions .NewReusableCaller (engine , stateReader , overrides , header , args , api .GasCap , latestNumOrHash , dbtx , api ._blockReader , chainConfig , api .evmCallTimeout )
279
- if err != nil {
280
- return true , nil , err
281
- }
282
-
283
263
result , err := caller .DoCallWithNewGas (ctx , gas , engine , overrides )
284
264
if err != nil {
285
265
if errors .Is (err , core .ErrIntrinsicGas ) {
0 commit comments