From 95af47c0bf4d0ec9371417f49572f834637e6643 Mon Sep 17 00:00:00 2001 From: Delweng Date: Sun, 16 Oct 2022 21:34:37 +0800 Subject: [PATCH 1/7] eth/tracers: prestate don't exclude existing contract Signed-off-by: Delweng --- eth/tracers/native/prestate.go | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/eth/tracers/native/prestate.go b/eth/tracers/native/prestate.go index b22f6181b944..91dcd651c321 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) isExists() bool { + return a.Balance.Sign() > 0 || len(a.Storage) > 0 || len(a.Code) > 0 +} + type accountMarshaling struct { Balance *hexutil.Big Code hexutil.Bytes @@ -116,8 +120,12 @@ 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. + if t.config.DiffMode { + return + } + + if t.create && !t.pre[t.to].isExists() { + // Exclude newly created contract. delete(t.pre, t.to) } } @@ -230,7 +238,7 @@ func (t *prestateTracer) CaptureTxEnd(restGas uint64) { 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 { + if !s.isExists() { delete(t.pre, a) } } From 90502c75e798fb1835c834db59dca9742aa2997a Mon Sep 17 00:00:00 2001 From: Delweng Date: Sun, 16 Oct 2022 21:35:13 +0800 Subject: [PATCH 2/7] eth/tracers: add testcase of create existing contract Signed-off-by: Delweng --- .../create_existing_contract.json | 88 +++++++++++++++++++ 1 file changed, 88 insertions(+) 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 000000000000..f590e4557871 --- /dev/null +++ b/eth/tracers/internal/tracetest/testdata/prestate_tracer/create_existing_contract.json @@ -0,0 +1,88 @@ +{ + "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", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + }, + "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 + } + } +} From 07ab36a1e26dac5887540ae6bf786ba4ef64f9f4 Mon Sep 17 00:00:00 2001 From: Delweng Date: Wed, 19 Oct 2022 19:05:15 +0800 Subject: [PATCH 3/7] eth/tracers: check account t.to nullable Signed-off-by: Delweng --- eth/tracers/native/prestate.go | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/eth/tracers/native/prestate.go b/eth/tracers/native/prestate.go index 91dcd651c321..98ba326521f4 100644 --- a/eth/tracers/native/prestate.go +++ b/eth/tracers/native/prestate.go @@ -124,9 +124,13 @@ func (t *prestateTracer) CaptureEnd(output []byte, gasUsed uint64, _ time.Durati return } - if t.create && !t.pre[t.to].isExists() { - // Exclude newly created contract. - delete(t.pre, t.to) + if t.create { + if s := t.pre[t.to]; s != nil { + if !s.isExists() { + // Exclude newly created contract. + delete(t.pre, t.to) + } + } } } From f6966de792de992389e0fafa2def75bda8ab8047 Mon Sep 17 00:00:00 2001 From: Delweng Date: Wed, 19 Oct 2022 21:15:00 +0800 Subject: [PATCH 4/7] eth/tracers: rename prestate's isExists to empty Signed-off-by: Delweng --- eth/tracers/native/prestate.go | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/eth/tracers/native/prestate.go b/eth/tracers/native/prestate.go index 98ba326521f4..91bae240c80d 100644 --- a/eth/tracers/native/prestate.go +++ b/eth/tracers/native/prestate.go @@ -45,8 +45,8 @@ type account struct { Storage map[common.Hash]common.Hash `json:"storage,omitempty"` } -func (a *account) isExists() bool { - return a.Balance.Sign() > 0 || len(a.Storage) > 0 || len(a.Code) > 0 +func (a *account) empty() bool { + return a.Nonce == 0 && a.Balance.Sign() == 0 && len(a.Code) == 0 && len(a.Storage) == 0 } type accountMarshaling struct { @@ -125,11 +125,9 @@ func (t *prestateTracer) CaptureEnd(output []byte, gasUsed uint64, _ time.Durati } if t.create { - if s := t.pre[t.to]; s != nil { - if !s.isExists() { - // Exclude newly created contract. - delete(t.pre, t.to) - } + if s := t.pre[t.to]; s != nil && s.empty() { + // Exclude newly created contract. + delete(t.pre, t.to) } } } @@ -241,10 +239,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.isExists() { - delete(t.pre, a) - } + if s := t.pre[a]; s != nil && s.empty() { + delete(t.pre, a) } } } From 07fce98111b7f24e19882de2406486b77d95d396 Mon Sep 17 00:00:00 2001 From: Delweng Date: Thu, 20 Oct 2022 07:58:11 +0800 Subject: [PATCH 5/7] eth/tracers: rename prestate's empty to exists, formaer mabye collision with consensus Signed-off-by: Delweng --- eth/tracers/native/prestate.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/eth/tracers/native/prestate.go b/eth/tracers/native/prestate.go index 91bae240c80d..54c08fc1a7af 100644 --- a/eth/tracers/native/prestate.go +++ b/eth/tracers/native/prestate.go @@ -45,7 +45,7 @@ type account struct { Storage map[common.Hash]common.Hash `json:"storage,omitempty"` } -func (a *account) empty() bool { +func (a *account) exists() bool { return a.Nonce == 0 && a.Balance.Sign() == 0 && len(a.Code) == 0 && len(a.Storage) == 0 } @@ -125,7 +125,7 @@ func (t *prestateTracer) CaptureEnd(output []byte, gasUsed uint64, _ time.Durati } if t.create { - if s := t.pre[t.to]; s != nil && s.empty() { + if s := t.pre[t.to]; s != nil && s.exists() { // Exclude newly created contract. delete(t.pre, t.to) } @@ -239,7 +239,7 @@ 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 && s.empty() { + if s := t.pre[a]; s != nil && s.exists() { delete(t.pre, a) } } From b28996a15221e6fea7afd38abc219801aa064ab5 Mon Sep 17 00:00:00 2001 From: Sina Mahmoodi Date: Thu, 20 Oct 2022 13:08:20 +0200 Subject: [PATCH 6/7] fix exists semantics based on name --- eth/tracers/native/prestate.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/eth/tracers/native/prestate.go b/eth/tracers/native/prestate.go index 54c08fc1a7af..fcf2653a4406 100644 --- a/eth/tracers/native/prestate.go +++ b/eth/tracers/native/prestate.go @@ -46,7 +46,7 @@ type account struct { } func (a *account) exists() bool { - return a.Nonce == 0 && a.Balance.Sign() == 0 && len(a.Code) == 0 && len(a.Storage) == 0 + return a.Balance.Sign() != 0 || a.Nonce > 0 || len(a.Code) > 0 || len(a.Storage) > 0 } type accountMarshaling struct { @@ -125,7 +125,7 @@ func (t *prestateTracer) CaptureEnd(output []byte, gasUsed uint64, _ time.Durati } if t.create { - if s := t.pre[t.to]; s != nil && s.exists() { + if s := t.pre[t.to]; s != nil && !s.exists() { // Exclude newly created contract. delete(t.pre, t.to) } @@ -239,7 +239,7 @@ 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 && s.exists() { + if s := t.pre[a]; s != nil && !s.exists() { delete(t.pre, a) } } From 222647f5178665792f2a608c933f12dabb12c43e Mon Sep 17 00:00:00 2001 From: Sina Mahmoodi Date: Thu, 20 Oct 2022 13:14:50 +0200 Subject: [PATCH 7/7] minor --- .../testdata/prestate_tracer/create_existing_contract.json | 5 +---- eth/tracers/native/prestate.go | 1 + 2 files changed, 2 insertions(+), 4 deletions(-) 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 index f590e4557871..a34d3b759ee1 100644 --- a/eth/tracers/internal/tracetest/testdata/prestate_tracer/create_existing_contract.json +++ b/eth/tracers/internal/tracetest/testdata/prestate_tracer/create_existing_contract.json @@ -19,10 +19,7 @@ }, "0x332b656504f4eabb44c8617a42af37461a34e9dc": { "balance": "0x11faea4f35e5af80000", - "code": "0x", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000000000000000000000000000000000000000000000" - } + "code": "0x" }, "0x52bc44d5378309ee2abf1539bf71de1b7d7be3b5": { "balance": "0xbf681825be002ac452", diff --git a/eth/tracers/native/prestate.go b/eth/tracers/native/prestate.go index fcf2653a4406..d50d00c6f7c9 100644 --- a/eth/tracers/native/prestate.go +++ b/eth/tracers/native/prestate.go @@ -125,6 +125,7 @@ func (t *prestateTracer) CaptureEnd(output []byte, gasUsed uint64, _ time.Durati } 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)