ethereum / go-ethereum

Go implementation of the Ethereum protocol
https://geth.ethereum.org
GNU Lesser General Public License v3.0
46.8k stars 19.76k forks source link

debug_traceCall returning inaccurate gasUsed when both blockOverrides and stateOverrides are used #29996

Open Bitwise0x opened 1 month ago

Bitwise0x commented 1 month ago

System information Geth 1.14.5 Go Version: go1.22.4

The gas returned from debug_traceCall with stateOverrides often resulting inaccuracy when trying to simulate for the next block. Over estimating in all the cases. Am I missing something?



``` ` // Adding 12 seconds to the current timestamp
nextBlockTime = header.Time + 12
tx := request{To: transaction.To().Hex(), From: from.Hex(), Value: fmt.Sprintf("0x%x", transaction.Value()), Gas: fmt.Sprintf("0x%x", transaction.Gas()), GasPrice: "0x" + transaction.GasFeeCap().Text(16),Data: hexutil.Encode(transaction.Data())}
    params := make(map[string]interface{})
    params[]"tracer"] = "callTracer"
    params["tracerConfig"] = tracerConfig{OnlyTopCall: true}
        params["blockOverrides"] = make(map[string]interface{})
    params["blockOverrides"].(map[string]interface{})["number"] = "0x" + nextBlock.Text(16)
    params["blockOverrides"].(map[string]interface{})["time"] = fmt.Sprintf("0x%x", nextBlockTime)
    if overrides != nil {
        params["stateOverrides"] = make(map[string]interface{})
        switch stateoverride := params["stateOverrides"].(type) {
        case map[string]interface{}:
            for key, value := range overrides {
                stateoveride[key] = make(map[string]interface{})
                switch statediff := stateoveride[key].(type) {
                case map[string]interface{}:
                    statediff["stateDiff"] = make(map[string]string)
                    statediff["stateDiff"] = value
                }
            }
        }
    }
gClient.Call(&result, "debug_traceCall", tx, "latest", params)``
Bitwise0x commented 1 month ago

@karalabe @rjl493456442 @holiman

s1na commented 1 month ago

The gas returned is how much gas was used during the simulation. It is not necessarily a good estimate for submitting the tx. For that you should rather use eth_estimateGas.

Otherwise if it is inaccurate it helps if you demonstrate what you expect and what is returned.

Bitwise0x commented 1 month ago

@s1na Why is debug_traceCall not accurate when both stateOverrides and blockOverrides are used within the same call? I am trying to simulate my transaction beneath another transaction, and was expecting an accurate gasUsed.

debug_traceCall with just blockOverrides works perfectly. however, when combined with stateOverrides, it overestimates gas usage by approximately 5-15k.

s1na commented 3 weeks ago

@Bitwise0x This is a difficult question to answer. You are modifying the state, that can change the flow of execution and require a different amount of gas. When submitting on chain the state might not be the same as in your override though.

Ideally you give me something to reproduce.