Skip to content

Commit ff4c8ff

Browse files
author
Test User
committed
execution/vm: use explicit touch for zero-value syscalls
1 parent a7cc693 commit ff4c8ff

2 files changed

Lines changed: 30 additions & 23 deletions

File tree

execution/state/intra_block_state.go

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -937,22 +937,7 @@ func (sdb *IntraBlockState) AddBalance(addr accounts.Address, amount uint256.Int
937937
// EIP161: We must check emptiness for the objects such that the account
938938
// clearing (0,0,0 objects) can take effect.
939939
if amount.IsZero() {
940-
stateObject, err := sdb.GetOrNewStateObject(addr)
941-
if err != nil {
942-
return err
943-
}
944-
945-
if stateObject.data.Empty() {
946-
versionWritten(sdb, addr, BalancePath, accounts.NilKey, uint256.Int{})
947-
if _, ok := sdb.journal.dirties[addr]; !ok {
948-
if dbg.TraceTransactionIO && (sdb.trace || dbg.TraceAccount(addr.Handle())) {
949-
fmt.Printf("%d (%d.%d) Touch %x\n", sdb.blockNum, sdb.txIndex, sdb.version, addr)
950-
}
951-
sdb.touchAccount(addr)
952-
}
953-
}
954-
955-
return nil
940+
return sdb.TouchAccount(addr)
956941
}
957942

958943
prev, wasCommited, _ := sdb.getBalance(addr)
@@ -992,6 +977,27 @@ func (sdb *IntraBlockState) touchAccount(addr accounts.Address) {
992977
}
993978
}
994979

980+
// TouchAccount materializes an empty account and records the zero-balance touch
981+
// needed for state clearing and trie consistency.
982+
func (sdb *IntraBlockState) TouchAccount(addr accounts.Address) error {
983+
stateObject, err := sdb.GetOrNewStateObject(addr)
984+
if err != nil {
985+
return err
986+
}
987+
988+
if stateObject.data.Empty() {
989+
versionWritten(sdb, addr, BalancePath, accounts.NilKey, uint256.Int{})
990+
if _, ok := sdb.journal.dirties[addr]; !ok {
991+
if dbg.TraceTransactionIO && (sdb.trace || dbg.TraceAccount(addr.Handle())) {
992+
fmt.Printf("%d (%d.%d) Touch %x\n", sdb.blockNum, sdb.txIndex, sdb.version, addr)
993+
}
994+
sdb.touchAccount(addr)
995+
}
996+
}
997+
998+
return nil
999+
}
1000+
9951001
func (sdb *IntraBlockState) getVersionedAccount(addr accounts.Address, readStorage bool) (*accounts.Account, ReadSource, Version, error) {
9961002
if sdb.versionMap == nil {
9971003
return nil, UnknownSource, UnknownVersion, nil
@@ -1122,10 +1128,11 @@ func (sdb *IntraBlockState) refreshVersionedAccount(addr accounts.Address, readA
11221128
// SubBalance subtracts amount from the account associated with addr.
11231129
// DESCRIBED: docs/programmers_guide/guide.md#address---identifier-of-an-account
11241130
func (sdb *IntraBlockState) SubBalance(addr accounts.Address, amount uint256.Int, reason tracing.BalanceChangeReason) error {
1125-
if amount.IsZero() && addr != params.SystemAddress {
1126-
// We skip this early exit if the sender is the system address
1127-
// because Gnosis has a special logic to create an empty system account
1128-
// even after Spurious Dragon (see PR 5645 and Issue 18276).
1131+
if amount.IsZero() {
1132+
if addr == params.SystemAddress {
1133+
// Gnosis keeps an empty system account even after Spurious Dragon.
1134+
return sdb.TouchAccount(addr)
1135+
}
11291136
return nil
11301137
}
11311138

execution/vm/evm.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -248,10 +248,10 @@ func (evm *EVM) call(typ OpCode, caller accounts.Address, callerAddress accounts
248248
evm.intraBlockState.CreateAccount(addr, false)
249249
}
250250
// System calls still need the sender-side zero-balance touch so AuRa
251-
// creates the empty system account and BAL tracking sees caller state
252-
// access, but they must not execute the full transfer semantics.
251+
// keeps the empty system account in the PMT, but they must not execute
252+
// the full transfer semantics.
253253
if syscall && value.IsZero() {
254-
if err := evm.intraBlockState.SubBalance(caller, value, tracing.BalanceChangeTransfer); err != nil {
254+
if err := evm.intraBlockState.TouchAccount(caller); err != nil {
255255
return nil, 0, fmt.Errorf("%w: %w", ErrIntraBlockStateFailed, err)
256256
}
257257
} else {

0 commit comments

Comments
 (0)