-
Notifications
You must be signed in to change notification settings - Fork 151
core: Add touched address tracking to StateDB for tx filtering #601
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Arbitrum needs to track all addresses touched during transaction execution to support address-based filtering at the sequencer level. This enables compliance use cases where transactions interacting with certain addresses must be rejected before inclusion. The implementation follows the existing arbTxFilter pattern in ArbitrumExtraData, adding a touchedAddresses map that collects addresses during execution. Three methods are added to the StateDB interface: AddTouchedAddress, GetTouchedAddresses, and ClearTouchedAddresses. The collection is automatically cleared at transaction boundaries via SetTxContext.
Capture the beneficiary address in opSelfdestruct and opSelfdestruct6780 for transaction filtering.
core/vm/interface.go
Outdated
|
|
||
| // Arbitrum | ||
| AddTouchedAddress(addr common.Address) | ||
| GetTouchedAddresses() []common.Address |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After thinking a lot.. this has two problems:
- it does unnecessary work for normal chains where there is no filter required, and for normal nodes which aren't sequencers.
- it doesn't allow room for starting to check addresses while the transaction is being processed.
I think it's better to register an address filter inside the stateDB, so stateDB will pass immediately any touchedaddress to the filter, and the filter could chose to start checking in parallel or not. Also, normal nodes/chians will just use an oopFilter that will do nothing in relation to AddTouchedAddress.
In that case - GetTouchedAddresses and ClearTouchedAddresses are not needed. StateDb willl pass through IsTxFiltered and ClearTxFilter to the filter.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the comment, I think I've addressed it now and I think it simplifies the design a lot.
Implement address filtering that checks addresses immediately as they're touched during execution, rather than collecting them for later checking. The AddressFilter interface is registered in StateDB, and TouchAddress() checks the filter immediately, calling FilterTx() if the address is filtered.
core/state/statedb_arbitrum.go
Outdated
| // AddressFilter checks if addresses should be filtered from transactions. | ||
| // Used by Arbitrum for transaction filtering based on touched addresses. | ||
| type AddressFilter interface { | ||
| IsFiltered(addr common.Address) bool |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this requires the filter to return a synchronous response per address.
I want the filter to have (not exact names):
- TouchAddress - submits the address, called by TouchAddress (can also return an immediate filter if beneficiary, or possibly just an error)
- IsFiltered - checks if any address was filtered, called by IsTxFiletered
- ClearAddresses - resets previous addresses, called by ClearTxFiler
That way we could look in large databases using separate goroutines while main thread is executing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed it with a stateless and stateful part of the filter.
Address review feedback requesting async-capable address filtering: - TouchAddress submits addresses for checking (can start async checks) - IsFiltered blocks until all checks complete and returns result - Fresh state created per-tx in SetTxContext (replaces ClearAddresses) This design allows implementations to check addresses in parallel using separate goroutines while the main thread executes, enabling lookups in large databases without blocking execution. The two-part interface (AddressChecker/AddressCheckerState) lets each implementation choose its own synchronization strategy (sync, WaitGroup, channels, batch RPC) without coupling StateDB to a specific pattern.
tsahee
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Arbitrum needs to track all addresses touched during transaction execution to support address-based filtering at the sequencer level. This enables compliance use cases on certain chains where transactions interacting with certain addresses must be rejected before inclusion.
The implementation follows the existing arbTxFilter pattern in ArbitrumExtraData, adding a touchedAddresses map that collects addresses during execution. Three methods are added to the StateDB interface: AddTouchedAddress, GetTouchedAddresses, and ClearTouchedAddresses. The collection is automatically cleared at transaction boundaries via SetTxContext.
SELFDESTRUCT is handled by adding the SELFDESTRUCT beneficiary to touched addresses. The beneficiary address is captured in opSelfdestruct and opSelfdestruct6780.
pulled in by OffchainLabs/nitro#4157
fixes: NIT-4221