Skip to content

Conversation

@AnkushinDaniil
Copy link
Contributor

@AnkushinDaniil AnkushinDaniil commented Dec 27, 2025

Fixes Closes Resolves #

Please choose one of the keywords above to refer to the issue this PR solves followed by the issue number (e.g. Fixes #000). If no issue number, remove the line. Also, remove everything marked optional that is not applicable. Remove this note after reading.

Changes

  • Add _deletedThisBlock HashSet to track accounts deleted during block processing
  • Modify CreateEmptyAccountIfDeletedOrNew to check block-level deletions for cross-transaction zombie account recreation
  • Track deletions in commit logic: empty account cleanup, EIP-158 implicit deletion, and explicit delete operations
  • Clear deletion tracking in ResetBlockChanges

Types of changes

What types of changes does your code introduce?

  • Bugfix (a non-breaking change that fixes an issue)
  • New feature (a non-breaking change that adds functionality)
  • Breaking change (a change that causes existing functionality not to work as expected)
  • Optimization
  • Refactoring
  • Documentation update
  • Build-related changes
  • Other: Description

Testing

Requires testing

  • Yes
  • No

If yes, did you write tests?

  • Yes
  • No

Notes on testing

Tested via Arbitrum plugin tests which compare state roots against Nitro reference implementation

Documentation

Requires documentation update

  • Yes
  • No

Requires explanation in Release Notes

  • Yes
  • No

Remarks

Required for Arbitrum's pre-FixZombieAccounts behavior where zero-value transfers must recreate deleted accounts as empty "zombie" accounts. After the WorldState refactor, CreateEmptyAccountIfDeletedOrNew could only detect deletions within the same transaction's cache. This change enables detection of accounts deleted in earlier transactions within the same block.

Comment on lines +460 to +468
{
// Account was deleted earlier in this block
_needsStateRootUpdate = true;
if (_logger.IsTrace) TraceBlockLevel(address);

Account account = Account.TotallyEmpty;
StackList<int> stack = SetupCache(address);
PushRecreateEmpty(address, account, stack);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks weird - like it belongs to the if but it does in fact is in else

Copy link
Contributor

@asdacap asdacap left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure you cant put this in plugin?

@LukaszRozmej
Copy link
Member

Are you sure you cant put this in plugin?

It would be great to be in the plugin but we would have to expose StateProvider?

@asdacap
Copy link
Contributor

asdacap commented Dec 28, 2025

Can't this be done with a decorated IWorldState?

@damian-orzechowski
Copy link
Contributor

damian-orzechowski commented Dec 29, 2025

Can't this be done with a decorated IWorldState?

Tried this with the original change, but it wasn't possible

@AnkushinDaniil AnkushinDaniil deleted the daniil/fix/cross-transaction-deletions branch January 8, 2026 13:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants