@@ -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
0 commit comments