From a404195c7bad5cd0d526abb22f97e4ee790430d9 Mon Sep 17 00:00:00 2001 From: Delweng Date: Fri, 21 Oct 2022 17:48:53 +0800 Subject: [PATCH] eth/tracers: fix the issue prestate missing existing contract state (#25996) The prestate tracer did not report accounts that existed at a given address prior to a contract being created at that address. Signed-off-by: Delweng Co-authored-by: Sina Mahmoodi --- .../create_existing_contract.json | 85 +++++++++++++++++++ eth/tracers/native/prestate.go | 23 +++-- 2 files changed, 101 insertions(+), 7 deletions(-) create mode 100644 eth/tracers/internal/tracetest/testdata/prestate_tracer/create_existing_contract.json diff --git a/eth/tracers/internal/tracetest/testdata/prestate_tracer/create_existing_contract.json b/eth/tracers/internal/tracetest/testdata/prestate_tracer/create_existing_contract.json new file mode 100644 index 0000000000..a34d3b759e --- /dev/null +++ b/eth/tracers/internal/tracetest/testdata/prestate_tracer/create_existing_contract.json @@ -0,0 +1,85 @@ +{ + "genesis": { + "difficulty": "6217248151198", + "extraData": "0xd783010103844765746887676f312e342e32856c696e7578", + "gasLimit": "3141592", + "hash": "0xe8bff55fe3e61936ef321cf3afaeb1ba2f7234e1e89535fa8ae39963caebe9c3", + "miner": "0x52bc44d5378309ee2abf1539bf71de1b7d7be3b5", + "mixHash": "0x03da00d5a15a064e5ebddf53cd0aaeb9a8aff0f40c0fb031a74f463d11ec83b8", + "nonce": "0x6575fe08c4167044", + "number": "243825", + "stateRoot": "0x47182fe2e6e740b8a76f82fe5c527d6ad548f805274f21792cf4047235b24fbf", + "timestamp": "1442424328", + "totalDifficulty": "1035061827427752845", + "alloc": { + "0x082d4cdf07f386ffa9258f52a5c49db4ac321ec6": { + "balance": "0xc820f93200f4000", + "nonce": "0x5E", + "code": "0x" + }, + "0x332b656504f4eabb44c8617a42af37461a34e9dc": { + "balance": "0x11faea4f35e5af80000", + "code": "0x" + }, + "0x52bc44d5378309ee2abf1539bf71de1b7d7be3b5": { + "balance": "0xbf681825be002ac452", + "nonce": "0x70FA", + "code": "0x" + }, + "0x82effbaaaf28614e55b2ba440fb198e0e5789b0f": { + "balance": "0xb3d0ac5cb94df6f6b0", + "nonce": "0x1", + "code": "0x" + } + }, + "config": { + "chainId": 1, + "homesteadBlock": 1150000, + "daoForkBlock": 1920000, + "daoForkSupport": true, + "eip150Block": 2463000, + "eip150Hash": "0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0", + "eip155Block": 2675000, + "eip158Block": 2675000, + "byzantiumBlock": 4370000, + "constantinopleBlock": 7280000, + "petersburgBlock": 7280000, + "istanbulBlock": 9069000, + "muirGlacierBlock": 9200000, + "berlinBlock": 12244000, + "londonBlock": 12965000, + "arrowGlacierBlock": 13773000, + "grayGlacierBlock": 15050000, + "terminalTotalDifficultyPassed": true, + "ethash": {} + } + }, + "context": { + "number": "243826", + "difficulty": "6214212385501", + "timestamp": "1442424353", + "gasLimit": "3141592", + "miner": "0x52bc44d5378309ee2abf1539bf71de1b7d7be3b5" + }, + "input": "0xf8e85e850ba43b7400830f42408080b89660606040527382effbaaaf28614e55b2ba440fb198e0e5789b0f600060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908302179055505b600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16ff5b600a80608c6000396000f30060606040526008565b001ca0340b21661e5bb85a46319a15f33a362e5c0f02faa7cdbf9c5808b2134da968eaa0226e6788f8c20e211d436ab7f6298ef32fa4c23a509eeeaac0880d115c17bc3f", + "result": { + "0x082d4cdf07f386ffa9258f52a5c49db4ac321ec6": { + "balance": "0xc820f93200f4000", + "nonce": 94 + }, + "0x332b656504f4eabb44c8617a42af37461a34e9dc": { + "balance": "0x11faea4f35e5af80000", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + }, + "0x52bc44d5378309ee2abf1539bf71de1b7d7be3b5": { + "balance": "0xbf681825be002ac452", + "nonce": 28922 + }, + "0x82effbaaaf28614e55b2ba440fb198e0e5789b0f": { + "balance": "0xb3d0ac5cb94df6f6b0", + "nonce": 1 + } + } +} diff --git a/eth/tracers/native/prestate.go b/eth/tracers/native/prestate.go index b22f6181b9..d50d00c6f7 100644 --- a/eth/tracers/native/prestate.go +++ b/eth/tracers/native/prestate.go @@ -45,6 +45,10 @@ type account struct { Storage map[common.Hash]common.Hash `json:"storage,omitempty"` } +func (a *account) exists() bool { + return a.Balance.Sign() != 0 || a.Nonce > 0 || len(a.Code) > 0 || len(a.Storage) > 0 +} + type accountMarshaling struct { Balance *hexutil.Big Code hexutil.Bytes @@ -116,9 +120,16 @@ func (t *prestateTracer) CaptureStart(env *vm.EVM, from common.Address, to commo // CaptureEnd is called after the call finishes to finalize the tracing. func (t *prestateTracer) CaptureEnd(output []byte, gasUsed uint64, _ time.Duration, err error) { - if t.create && !t.config.DiffMode { - // Exclude created contract. - delete(t.pre, t.to) + if t.config.DiffMode { + return + } + + if t.create { + // Keep existing account prior to contract creation at that address + if s := t.pre[t.to]; s != nil && !s.exists() { + // Exclude newly created contract. + delete(t.pre, t.to) + } } } @@ -229,10 +240,8 @@ func (t *prestateTracer) CaptureTxEnd(restGas uint64) { // the new created contracts' prestate were empty, so delete them for a := range t.created { // the created contract maybe exists in statedb before the creating tx - if s := t.pre[a]; s != nil { - if s.Balance.Sign() == 0 && len(s.Storage) == 0 && len(s.Code) == 0 { - delete(t.pre, a) - } + if s := t.pre[a]; s != nil && !s.exists() { + delete(t.pre, a) } } }