Skip to content

Commit 116f183

Browse files
committed
resolve conflicts
1 parent 91fee11 commit 116f183

2 files changed

Lines changed: 46 additions & 22 deletions

File tree

execution/state/intra_block_state.go

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -952,22 +952,7 @@ func (sdb *IntraBlockState) AddBalance(addr accounts.Address, amount uint256.Int
952952
// EIP161: We must check emptiness for the objects such that the account
953953
// clearing (0,0,0 objects) can take effect.
954954
if amount.IsZero() {
955-
stateObject, err := sdb.GetOrNewStateObject(addr)
956-
if err != nil {
957-
return err
958-
}
959-
960-
if stateObject.data.Empty() {
961-
versionWritten(sdb, addr, BalancePath, accounts.NilKey, uint256.Int{})
962-
if _, ok := sdb.journal.dirties[addr]; !ok {
963-
if dbg.TraceTransactionIO && (sdb.trace || dbg.TraceAccount(addr.Handle())) {
964-
fmt.Printf("%d (%d.%d) Touch %x\n", sdb.blockNum, sdb.txIndex, sdb.version, addr)
965-
}
966-
sdb.touchAccount(addr)
967-
}
968-
}
969-
970-
return nil
955+
return sdb.TouchAccount(addr)
971956
}
972957

973958
prev, wasCommited, _ := sdb.getBalance(addr)
@@ -1007,6 +992,27 @@ func (sdb *IntraBlockState) touchAccount(addr accounts.Address) {
1007992
}
1008993
}
1009994

995+
// TouchAccount materializes an empty account and records the zero-balance touch
996+
// needed for state clearing and trie consistency.
997+
func (sdb *IntraBlockState) TouchAccount(addr accounts.Address) error {
998+
stateObject, err := sdb.GetOrNewStateObject(addr)
999+
if err != nil {
1000+
return err
1001+
}
1002+
1003+
if stateObject.data.Empty() {
1004+
versionWritten(sdb, addr, BalancePath, accounts.NilKey, uint256.Int{})
1005+
if _, ok := sdb.journal.dirties[addr]; !ok {
1006+
if dbg.TraceTransactionIO && (sdb.trace || dbg.TraceAccount(addr.Handle())) {
1007+
fmt.Printf("%d (%d.%d) Touch %x\n", sdb.blockNum, sdb.txIndex, sdb.version, addr)
1008+
}
1009+
sdb.touchAccount(addr)
1010+
}
1011+
}
1012+
1013+
return nil
1014+
}
1015+
10101016
func (sdb *IntraBlockState) getVersionedAccount(addr accounts.Address, readStorage bool) (*accounts.Account, ReadSource, Version, error) {
10111017
if sdb.versionMap == nil {
10121018
return nil, UnknownSource, UnknownVersion, nil
@@ -1137,10 +1143,11 @@ func (sdb *IntraBlockState) refreshVersionedAccount(addr accounts.Address, readA
11371143
// SubBalance subtracts amount from the account associated with addr.
11381144
// DESCRIBED: docs/programmers_guide/guide.md#address---identifier-of-an-account
11391145
func (sdb *IntraBlockState) SubBalance(addr accounts.Address, amount uint256.Int, reason tracing.BalanceChangeReason) error {
1140-
if amount.IsZero() && addr != params.SystemAddress {
1141-
// We skip this early exit if the sender is the system address
1142-
// because Gnosis has a special logic to create an empty system account
1143-
// even after Spurious Dragon (see PR 5645 and Issue 18276).
1146+
if amount.IsZero() {
1147+
if addr == params.SystemAddress {
1148+
// Gnosis keeps an empty system account even after Spurious Dragon.
1149+
return sdb.TouchAccount(addr)
1150+
}
11441151
return nil
11451152
}
11461153

execution/vm/evm.go

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,10 @@ func (evm *EVM) SetCallGasTemp(gas uint64) {
244244
evm.callGasTemp = gas
245245
}
246246

247+
func isSystemCall(caller accounts.Address) bool {
248+
return caller == params.SystemAddress
249+
}
250+
247251
// SetPrecompiles sets the precompiles for the EVM
248252
func (evm *EVM) SetPrecompiles(precompiles PrecompiledContracts) {
249253
evm.precompiles = precompiles
@@ -291,13 +295,15 @@ func (evm *EVM) call(typ OpCode, caller accounts.Address, callerAddress accounts
291295
if depth > int(params.CallCreateDepth) {
292296
return nil, gas, ErrDepth
293297
}
298+
syscall := isSystemCall(caller)
299+
294300
if typ == CALL || typ == CALLCODE {
295301
// Fail if we're trying to transfer more than the available balance.
296302
// Only check when value is non-zero — matching geth's short-circuit
297303
// behavior. Calling CanTransfer for zero-value calls (e.g. system
298304
// calls) creates spurious balance reads on the caller that pollute
299305
// the Block Access List (EIP-7928).
300-
if !value.IsZero() {
306+
if !syscall && !value.IsZero() {
301307
canTransfer, err := evm.Context.CanTransfer(evm.intraBlockState, caller, value)
302308
if err != nil {
303309
return nil, mdgas.MdGas{}, err
@@ -322,7 +328,18 @@ func (evm *EVM) call(typ OpCode, caller accounts.Address, callerAddress accounts
322328
}
323329
evm.intraBlockState.CreateAccount(addr, false)
324330
}
325-
evm.Context.Transfer(evm.intraBlockState, caller, addr, value, bailout, evm.chainRules)
331+
// System calls still need the sender-side zero-balance touch so AuRa
332+
// keeps the empty system account in the PMT, but they must not execute
333+
// the full transfer semantics.
334+
if syscall && value.IsZero() {
335+
if err := evm.intraBlockState.TouchAccount(caller); err != nil {
336+
return nil, mdgas.MdGas{}, fmt.Errorf("%w: %w", ErrIntraBlockStateFailed, err)
337+
}
338+
} else {
339+
// Calling Transfer is required even for zero-value transfers to
340+
// ensure the usual touch/state-clearing behavior is applied.
341+
evm.Context.Transfer(evm.intraBlockState, caller, addr, value, bailout, evm.chainRules)
342+
}
326343
} else if typ == STATICCALL {
327344
// We do an AddBalance of zero here, just in order to trigger a touch.
328345
// This doesn't matter on Mainnet, where all empties are gone at the time of Byzantium,

0 commit comments

Comments
 (0)