eth/tracers: fix codehash in prestate diffmode (#34675)
Some checks are pending
/ Linux Build (push) Waiting to run
/ Linux Build (arm) (push) Waiting to run
/ Keeper Build (push) Waiting to run
/ Windows Build (push) Waiting to run
/ Docker Image (push) Waiting to run

Fixes https://github.com/ethereum/go-ethereum/issues/34648.
This commit is contained in:
Sina M 2026-04-16 10:51:26 +02:00 committed by GitHub
parent b1baab4427
commit f63e9f3a80
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 125 additions and 17 deletions

View file

@ -0,0 +1,98 @@
{
"genesis": {
"blobGasUsed": "0",
"difficulty": "0",
"excessBlobGas": "0",
"extraData": "0x",
"gasLimit": "11511229",
"hash": "0x455b93a512baa4ed5e117508b184a6bb03904b94d665ce38931728eca9cdd8fe",
"miner": "0x71562b71999873db5b286df957af199ec94617f7",
"mixHash": "0x042877c4fab9f022d29590ae83bad89d6181afb1d6e107619911ea52e5901364",
"nonce": "0x0000000000000000",
"number": "1",
"parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
"stateRoot": "0xc8688ad6433e6b9f4edeb82360d2b99c8e919f493a01cacbe7c4a97184f5d043",
"timestamp": "1775654796",
"alloc": {
"0x71562b71999873db5b286df957af199ec94617f7": {
"balance": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffdb64910c3bf7",
"nonce": "1"
},
"0xe85a1c0e9d5b1c9b417c6c1b34c22cd77f623f50": {
"balance": "0x0",
"code": "0xef0100d313d93607c016a85e63e557a11ca5ab0b53ad83",
"codeHash": "0x9eea9f41ed2b35e6234d1e1c14e88c1136f85d56ed1f32a7efc0096d998dad3d",
"nonce": "1"
}
},
"config": {
"chainId": 1337,
"homesteadBlock": 0,
"eip150Block": 0,
"eip155Block": 0,
"eip158Block": 0,
"byzantiumBlock": 0,
"constantinopleBlock": 0,
"petersburgBlock": 0,
"istanbulBlock": 0,
"muirGlacierBlock": 0,
"berlinBlock": 0,
"londonBlock": 0,
"arrowGlacierBlock": 0,
"grayGlacierBlock": 0,
"shanghaiTime": 0,
"cancunTime": 0,
"pragueTime": 0,
"terminalTotalDifficulty": 0,
"blobSchedule": {
"cancun": {
"target": 3,
"max": 6,
"baseFeeUpdateFraction": 3338477
},
"prague": {
"target": 6,
"max": 9,
"baseFeeUpdateFraction": 5007716
}
}
}
},
"context": {
"number": "2",
"difficulty": "0",
"timestamp": "1775654797",
"gasLimit": "11522469",
"miner": "0x71562b71999873db5b286df957af199ec94617f7",
"baseFeePerGas": "766499147"
},
"input": "0x04f8cd82053901843b9aca008477359400830186a09471562b71999873db5b286df957af199ec94617f78080c0f85ef85c8205399400000000000000000000000000000000000000000101a011fc0271f2566e7ebe5ddbff6d48ea97a19afa248452a392781096b7e3b89177a0020107ecefe99c90429b416fe4d1eead5a7fa253761e85cd7cdc7df6e5032d7f80a098495fb16c904f0b67b49afe868b28b0159c8df07522bed99ef6ff2cc2ac2935a048857a9c385d91735a9fdccabc66de7a5ea1897f523a5b9a352e281642a76e6b",
"tracerConfig": {
"diffMode": true
},
"result": {
"post": {
"0x71562b71999873db5b286df957af199ec94617f7": {
"balance": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffc1bd12c85eb7",
"nonce": 2
},
"0xe85a1c0e9d5b1c9b417c6c1b34c22cd77f623f50": {
"code": "0x",
"codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470",
"nonce": 2
}
},
"pre": {
"0x71562b71999873db5b286df957af199ec94617f7": {
"balance": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffdb64910c3bf7",
"nonce": 1
},
"0xe85a1c0e9d5b1c9b417c6c1b34c22cd77f623f50": {
"balance": "0x0",
"code": "0xef0100d313d93607c016a85e63e557a11ca5ab0b53ad83",
"codeHash": "0x9eea9f41ed2b35e6234d1e1c14e88c1136f85d56ed1f32a7efc0096d998dad3d",
"nonce": 1
}
}
}
}

View file

@ -16,14 +16,14 @@ var _ = (*accountMarshaling)(nil)
func (a account) MarshalJSON() ([]byte, error) {
type account struct {
Balance *hexutil.Big `json:"balance,omitempty"`
Code hexutil.Bytes `json:"code,omitempty"`
Code *hexutil.Bytes `json:"code,omitempty"`
CodeHash *common.Hash `json:"codeHash,omitempty"`
Nonce uint64 `json:"nonce,omitempty"`
Storage map[common.Hash]common.Hash `json:"storage,omitempty"`
}
var enc account
enc.Balance = (*hexutil.Big)(a.Balance)
enc.Code = a.Code
enc.Code = (*hexutil.Bytes)(a.Code)
enc.CodeHash = a.CodeHash
enc.Nonce = a.Nonce
enc.Storage = a.Storage
@ -47,7 +47,7 @@ func (a *account) UnmarshalJSON(input []byte) error {
a.Balance = (*big.Int)(dec.Balance)
}
if dec.Code != nil {
a.Code = *dec.Code
a.Code = (*[]byte)(dec.Code)
}
if dec.CodeHash != nil {
a.CodeHash = dec.CodeHash

View file

@ -44,21 +44,24 @@ func init() {
type stateMap = map[common.Address]*account
type account struct {
Balance *big.Int `json:"balance,omitempty"`
Code []byte `json:"code,omitempty"`
Balance *big.Int `json:"balance,omitempty"`
// Code is a pointer so omitempty can omit unchanged code (nil) while
// still emitting "0x" when code is cleared (e.g. EIP-7702 deauth).
Code *[]byte `json:"code,omitempty"`
CodeHash *common.Hash `json:"codeHash,omitempty"`
Nonce uint64 `json:"nonce,omitempty"`
Storage map[common.Hash]common.Hash `json:"storage,omitempty"`
empty bool
empty bool
}
func (a *account) exists() bool {
return a.Nonce > 0 || len(a.Code) > 0 || len(a.Storage) > 0 || (a.Balance != nil && a.Balance.Sign() != 0)
return a.Nonce > 0 || (a.Code != nil && len(*a.Code) > 0) || len(a.Storage) > 0 || (a.Balance != nil && a.Balance.Sign() != 0)
}
type accountMarshaling struct {
Balance *hexutil.Big
Code hexutil.Bytes
Code *hexutil.Bytes
}
type prestateTracer struct {
@ -266,24 +269,28 @@ func (t *prestateTracer) processDiffState() {
modified = true
postAccount.Nonce = newNonce
}
prevCodeHash := common.Hash{}
// Empty code hashes are excluded from the prestate, so default
// to EmptyCodeHash to match what GetCodeHash returns for codeless accounts.
prevCodeHash := types.EmptyCodeHash
if t.pre[addr].CodeHash != nil {
prevCodeHash = *t.pre[addr].CodeHash
}
// Empty code hashes are excluded from the prestate. Normalize
// the empty code hash to a zero hash to make it comparable.
if newCodeHash == types.EmptyCodeHash {
newCodeHash = common.Hash{}
}
if newCodeHash != prevCodeHash {
modified = true
postAccount.CodeHash = &newCodeHash
}
if !t.config.DisableCode {
newCode := t.env.StateDB.GetCode(addr)
if !bytes.Equal(newCode, t.pre[addr].Code) {
var prevCode []byte
if t.pre[addr].Code != nil {
prevCode = *t.pre[addr].Code
}
if !bytes.Equal(newCode, prevCode) {
modified = true
postAccount.Code = newCode
if newCode == nil {
newCode = []byte{}
}
postAccount.Code = &newCode
}
}
@ -323,10 +330,13 @@ func (t *prestateTracer) lookupAccount(addr common.Address) {
return
}
code := t.env.StateDB.GetCode(addr)
acc := &account{
Balance: t.env.StateDB.GetBalance(addr).ToBig(),
Nonce: t.env.StateDB.GetNonce(addr),
Code: t.env.StateDB.GetCode(addr),
}
if len(code) > 0 {
acc.Code = &code
}
codeHash := t.env.StateDB.GetCodeHash(addr)
// If the code is empty, we don't need to store it in the prestate.