Skip to content

Commit e842859

Browse files
raxhvlfselmo
authored andcommitted
♻️ refactor: move to test_block_access_lists
1 parent b097a3f commit e842859

File tree

3 files changed

+108
-135
lines changed

3 files changed

+108
-135
lines changed

tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists.py

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
Alloc,
88
Block,
99
BlockchainTestFiller,
10+
Initcode,
1011
Storage,
1112
Transaction,
1213
compute_create_address,
@@ -284,3 +285,109 @@ def test_bal_code_changes(
284285
),
285286
},
286287
)
288+
289+
290+
@pytest.mark.valid_from("Amsterdam")
291+
@pytest.mark.parametrize(
292+
"self_destruct_in_same_tx",
293+
[True, False],
294+
ids=["self_destruct_in_same_tx", "self_destruct_in_a_new_tx"],
295+
)
296+
def test_bal_self_destruct(
297+
pre: Alloc,
298+
blockchain_test: BlockchainTestFiller,
299+
self_destruct_in_same_tx: bool,
300+
):
301+
"""Ensure BAL captures balance changes caused by `SELFDESTRUCT`."""
302+
alice = pre.fund_eoa()
303+
bob = pre.fund_eoa(amount=0)
304+
305+
selfdestruct_code = Op.SELFDESTRUCT(bob)
306+
# A pre existing self-destruct contract
307+
kaboom = pre.deploy_contract(code=selfdestruct_code)
308+
309+
# A template for self-destruct contract
310+
self_destruct_init_code = Initcode(deploy_code=selfdestruct_code)
311+
template = pre.deploy_contract(code=self_destruct_init_code)
312+
313+
if self_destruct_in_same_tx:
314+
# The goal is to create a self-destructing contract in the same
315+
# transaction to trigger deletion of code as per EIP-6780.
316+
# The factory contract below creates a new self-destructing
317+
# contract and calls it in this transaction.
318+
319+
bytecode_size = len(self_destruct_init_code)
320+
factory_bytecode = (
321+
# Clone template memory
322+
Op.EXTCODECOPY(template, 0, 0, bytecode_size)
323+
# Fund 100 wei and deploy the clone
324+
+ Op.CREATE(100, 0, bytecode_size)
325+
# Call the clone, which self-destructs
326+
+ Op.CALL(50_000, Op.DUP6, 0, 0, 0, 0, 0)
327+
+ Op.STOP
328+
)
329+
330+
factory = pre.deploy_contract(code=factory_bytecode)
331+
kaboom_same_tx = compute_create_address(address=factory, nonce=1)
332+
333+
tx = Transaction(
334+
sender=alice,
335+
to=factory if self_destruct_in_same_tx else kaboom,
336+
value=100,
337+
gas_limit=1_000_000,
338+
)
339+
340+
# Determine which account was destructed
341+
self_destructed_account = kaboom_same_tx if self_destruct_in_same_tx else kaboom
342+
343+
block = Block(
344+
txs=[tx],
345+
expected_block_access_list=BlockAccessListExpectation(
346+
account_expectations={
347+
alice: BalAccountExpectation(
348+
nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)],
349+
),
350+
bob: BalAccountExpectation(
351+
balance_changes=[BalBalanceChange(tx_index=1, post_balance=100)]
352+
),
353+
self_destructed_account: BalAccountExpectation(
354+
# When an account is deleted its post nonce is set to 0
355+
# as per EIP-7928.
356+
nonce_changes=[BalNonceChange(tx_index=1, post_nonce=0)]
357+
if self_destruct_in_same_tx
358+
else [],
359+
balance_changes=[BalBalanceChange(tx_index=1, post_balance=0)],
360+
# Expect code to be cleared if self-destructed in same transaction.
361+
code_changes=[BalCodeChange(tx_index=1, new_code="")]
362+
if self_destruct_in_same_tx
363+
else [],
364+
),
365+
}
366+
),
367+
)
368+
369+
post = {
370+
alice: Account(nonce=1),
371+
bob: Account(balance=100),
372+
kaboom: Account(balance=0, code=selfdestruct_code),
373+
}
374+
375+
# If the account was self-destructed in the same transaction,
376+
# we expect the account to non-existent and its balance to be 0.
377+
if self_destruct_in_same_tx:
378+
post.update(
379+
{
380+
factory: Account(
381+
nonce=2, # incremented after CREATE
382+
balance=0, # spent on CREATE
383+
code=factory_bytecode,
384+
),
385+
kaboom_same_tx: Account.NONEXISTENT, # type: ignore
386+
}
387+
)
388+
389+
blockchain_test(
390+
pre=pre,
391+
blocks=[block],
392+
post=post,
393+
)

tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_self_destruct.py

Lines changed: 0 additions & 134 deletions
This file was deleted.

tests/amsterdam/eip7928_block_level_access_lists/test_cases.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
| `test_bal_storage_writes` | Ensure BAL captures storage writes | Alice calls contract that writes to storage slot `0x01` | BAL MUST include storage changes with correct slot and value | ✅ Completed |
88
| `test_bal_storage_reads` | Ensure BAL captures storage reads | Alice calls contract that reads from storage slot `0x01` | BAL MUST include storage access for the read operation | ✅ Completed |
99
| `test_bal_code_changes` | Ensure BAL captures changes to account code | Alice deploys factory contract that creates new contract | BAL MUST include code changes for newly deployed contract | ✅ Completed |
10-
| `test_bal_self_destruct` | Ensure BAL captures balance changes caused by `SELFDESTRUCT` | Alice calls a contract (funded with 100 wei) that executes `SELFDESTRUCT` with Bob as its recipient | BAL MUST include Alice's nonce change (increment), the self-destructing contract's balance change (100 → 0), and Bob's balance change (0 → 100). If the contract is created in the same transaction, BAL MUST also include code changes (new_code = empty bytes, indicating code has been cleared) | ✅ Completed |
10+
| `test_bal_self_destruct` | Ensure BAL captures balance changes caused by `SELFDESTRUCT` | Alice calls a contract (funded with 100 wei) that executes `SELFDESTRUCT` with Bob as its recipient | BAL MUST include Alice's nonce change (increment), the self-destructing contract's balance change (100 → 0), and Bob's balance change (0 → 100). The self-destructing contract MUST also appear with `post_nonce=0`, `post_balance=0`, and `new_code=0x`, indicating an account deletion | ✅ Completed |
1111
| `test_bal_2930_slot_listed_but_untouched` | Ensure 2930 access list alone doesn't appear in BAL | Include `(KV, S=0x01)` in tx's EIP-2930 access list; tx executes code that does **no** `SLOAD`/`SSTORE` to `S` (e.g., pure arithmetic/log). | BAL **MUST NOT** contain any entry for `(KV, S)` — neither reads nor writes — because the slot wasn't touched. | 🟡 Planned |
1212
| `test_bal_2930_slot_listed_and_modified` | Ensure BAL records writes only because the slot is touched | Same access list as above, but tx executes `SSTORE` to `S`. | BAL **MUST** include `storage_changes` for `(KV, S)` (and no separate read record for that slot if implementation deduplicates). Presence in the access list is irrelevant; inclusion is due to the actual write. | 🟡 Planned |
1313
| `test_bal_7702_delegated_create` | BAL tracks EIP-7702 delegation indicator write and contract creation | Alice sends a type-4 (7702) tx authorizing herself to delegate to `Deployer` code which executes `CREATE` | BAL MUST include for **Alice**: `code_changes` (delegation indicator), `nonce_changes` (increment from 7702 processing), and `balance_changes` (post-gas). For **Child**: `code_changes` (runtime bytecode) and `nonce_changes = 1`. | 🟡 Planned |

0 commit comments

Comments
 (0)