@@ -114,7 +114,7 @@ func headerByNumberOrHash(ctx context.Context, tx kv.Tx, blockNrOrHash rpc.Block
114114}
115115
116116// 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.
117- func (api * APIImpl ) EstimateGas (ctx context.Context , argsOrNil * ethapi2.CallArgs , blockNrOrHash * rpc. BlockNumberOrHash ) (hexutil.Uint64 , error ) {
117+ func (api * APIImpl ) EstimateGas (ctx context.Context , argsOrNil * ethapi2.CallArgs ) (hexutil.Uint64 , error ) {
118118 var args ethapi2.CallArgs
119119 // if we actually get CallArgs here, we use them
120120 if argsOrNil != nil {
@@ -138,36 +138,39 @@ func (api *APIImpl) EstimateGas(ctx context.Context, argsOrNil *ethapi2.CallArgs
138138 args .From = new (libcommon.Address )
139139 }
140140
141- bNrOrHash := rpc . BlockNumberOrHashWithNumber ( rpc . PendingBlockNumber )
142- if blockNrOrHash != nil {
143- bNrOrHash = * blockNrOrHash
141+ chainConfig , err := api . chainConfig ( ctx , dbtx )
142+ if err != nil {
143+ return 0 , err
144144 }
145145
146- // Determine the highest gas limit can be used during the estimation.
147- if args .Gas != nil && uint64 (* args .Gas ) >= params .TxGas {
148- hi = uint64 (* args .Gas )
149- } else {
150- // Retrieve the block to act as the gas ceiling
151- h , err := headerByNumberOrHash (ctx , dbtx , bNrOrHash , api )
146+ latestCanBlockNumber , latestCanHash , isLatest , err := rpchelper .GetCanonicalBlockNumber (latestNumOrHash , dbtx , api .filters ) // DoCall cannot be executed on non-canonical blocks
147+ if err != nil {
148+ return 0 , err
149+ }
150+
151+ // try and get the block from the lru cache first then try DB before failing
152+ block := api .tryBlockFromLru (latestCanHash )
153+ if block == nil {
154+ block , err = api .blockWithSenders (ctx , dbtx , latestCanHash , latestCanBlockNumber )
152155 if err != nil {
153156 return 0 , err
154157 }
155- if h == nil {
156- // if a block number was supplied and there is no header return 0
157- if blockNrOrHash != nil {
158- return 0 , nil
159- }
158+ }
159+ if block == nil {
160+ return 0 , fmt .Errorf ("could not find latest block in cache or db" )
161+ }
160162
161- // block number not supplied, so we haven't found a pending block, read the latest block instead
162- h , err = headerByNumberOrHash (ctx , dbtx , latestNumOrHash , api )
163- if err != nil {
164- return 0 , err
165- }
166- if h == nil {
167- return 0 , nil
168- }
169- }
170- hi = h .GasLimit
163+ stateReader , err := rpchelper .CreateStateReaderFromBlockNumber (ctx , dbtx , latestCanBlockNumber , isLatest , 0 , api .stateCache , api .historyV3 (dbtx ), chainConfig .ChainName )
164+ if err != nil {
165+ return 0 , err
166+ }
167+ header := block .HeaderNoCopy ()
168+
169+ // Determine the highest gas limit can be used during the estimation.
170+ if args .Gas != nil && uint64 (* args .Gas ) >= params .TxGas {
171+ hi = uint64 (* args .Gas )
172+ } else {
173+ hi = header .GasLimit
171174 }
172175
173176 var feeCap * big.Int
@@ -177,6 +180,8 @@ func (api *APIImpl) EstimateGas(ctx context.Context, argsOrNil *ethapi2.CallArgs
177180 feeCap = args .GasPrice .ToInt ()
178181 } else if args .MaxFeePerGas != nil {
179182 feeCap = args .MaxFeePerGas .ToInt ()
183+ } else if header .BaseFee != nil {
184+ feeCap = new (big.Int ).Set (header .BaseFee )
180185 } else {
181186 feeCap = libcommon .Big0
182187 }
@@ -221,35 +226,8 @@ func (api *APIImpl) EstimateGas(ctx context.Context, argsOrNil *ethapi2.CallArgs
221226 }
222227 gasCap = hi
223228
224- chainConfig , err := api .chainConfig (ctx , dbtx )
225- if err != nil {
226- return 0 , err
227- }
228229 engine := api .engine ()
229230
230- latestCanBlockNumber , latestCanHash , isLatest , err := rpchelper .GetCanonicalBlockNumber (latestNumOrHash , dbtx , api .filters ) // DoCall cannot be executed on non-canonical blocks
231- if err != nil {
232- return 0 , err
233- }
234-
235- // try and get the block from the lru cache first then try DB before failing
236- block := api .tryBlockFromLru (latestCanHash )
237- if block == nil {
238- block , err = api .blockWithSenders (ctx , dbtx , latestCanHash , latestCanBlockNumber )
239- if err != nil {
240- return 0 , err
241- }
242- }
243- if block == nil {
244- return 0 , fmt .Errorf ("could not find latest block in cache or db" )
245- }
246-
247- stateReader , err := rpchelper .CreateStateReaderFromBlockNumber (ctx , dbtx , latestCanBlockNumber , isLatest , 0 , api .stateCache , api .historyV3 (dbtx ), chainConfig .ChainName )
248- if err != nil {
249- return 0 , err
250- }
251- header := block .HeaderNoCopy ()
252-
253231 caller , err := transactions .NewReusableCaller (engine , stateReader , nil , header , args , api .GasCap , latestNumOrHash , dbtx , api ._blockReader , chainConfig , api .evmCallTimeout )
254232 if err != nil {
255233 return 0 , err
0 commit comments