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 <delweng@gmail.com>
Co-authored-by: Sina Mahmoodi <itz.s1na@gmail.com>
This commit is contained in:
Delweng
2022-10-21 11:48:53 +02:00
committed by GitHub
co-authored by Sina Mahmoodi
parent 9b9a1b677d
commit a404195c7b
2 changed files with 101 additions and 7 deletions
+16 -7
View File
@@ -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)
}
}
}