Skip to content

Commit 9500cc0

Browse files
authored
Basic fix to historical eth_estimateGas (#13903)
Needed for #13636 (But doesn't optimally achieve the requirements yet)
1 parent 5cabc4d commit 9500cc0

File tree

1 file changed

+17
-37
lines changed

1 file changed

+17
-37
lines changed

turbo/jsonrpc/eth_call.go

Lines changed: 17 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -150,31 +150,38 @@ func (api *APIImpl) EstimateGas(ctx context.Context, argsOrNil *ethapi2.CallArgs
150150
}
151151
defer dbtx.Rollback()
152152

153+
// Use latest block by default
154+
if blockNrOrHash == nil {
155+
blockNrOrHash = &latestNumOrHash
156+
}
157+
153158
chainConfig, err := api.chainConfig(ctx, dbtx)
154159
if err != nil {
155160
return 0, err
156161
}
157162
engine := api.engine()
158163

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
160165
if err != nil {
161166
return 0, err
162167
}
163168

164169
// 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)
166171
if block == nil {
167-
block, err = api.blockWithSenders(ctx, dbtx, latestCanHash, latestCanBlockNumber)
172+
block, err = api.blockWithSenders(ctx, dbtx, blockHash, blockNum)
168173
if err != nil {
169174
return 0, err
170175
}
171176
}
177+
172178
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()))
174180
}
181+
header := block.HeaderNoCopy()
175182

176183
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)
178185
if err != nil {
179186
return 0, err
180187
}
@@ -190,36 +197,12 @@ func (api *APIImpl) EstimateGas(ctx context.Context, argsOrNil *ethapi2.CallArgs
190197
args.From = new(libcommon.Address)
191198
}
192199

193-
bNrOrHash := rpc.BlockNumberOrHashWithNumber(rpc.PendingBlockNumber)
194-
if blockNrOrHash != nil {
195-
bNrOrHash = *blockNrOrHash
196-
}
197-
198200
// Determine the highest gas limit can be used during the estimation.
199201
if args.Gas != nil && uint64(*args.Gas) >= params.TxGas {
200202
hi = uint64(*args.Gas)
201203
} else {
202204
// 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
223206
}
224207

225208
var feeCap *big.Int
@@ -271,15 +254,12 @@ func (api *APIImpl) EstimateGas(ctx context.Context, argsOrNil *ethapi2.CallArgs
271254
}
272255
gasCap = hi
273256

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+
}
276261
// Create a helper to check if a gas allowance results in an executable transaction
277262
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-
283263
result, err := caller.DoCallWithNewGas(ctx, gas, engine, overrides)
284264
if err != nil {
285265
if errors.Is(err, core.ErrIntrinsicGas) {

0 commit comments

Comments
 (0)