diff --git a/packages/testing/src/execution_testing/test_types/block_access_list/account_absent_values.py b/packages/testing/src/execution_testing/test_types/block_access_list/account_absent_values.py index 5c9c9537f3..e733362326 100644 --- a/packages/testing/src/execution_testing/test_types/block_access_list/account_absent_values.py +++ b/packages/testing/src/execution_testing/test_types/block_access_list/account_absent_values.py @@ -52,14 +52,14 @@ class BalAccountAbsentValues(CamelModel): absent_values = BalAccountAbsentValues( nonce_changes=[ # Forbid exact nonce change at this tx - BalNonceChange(tx_index=1, post_nonce=5), + BalNonceChange(block_access_index=1, post_nonce=5), ], storage_changes=[ BalStorageSlot( slot=0x42, slot_changes=[ # Forbid exact storage change at this slot and tx - BalStorageChange(tx_index=2, post_value=0x99) + BalStorageChange(block_access_index=2, post_value=0x99) ], ) ], @@ -173,22 +173,23 @@ def validate_against(self, account: BalAccountChange) -> None: self._validate_forbidden_changes( account.nonce_changes, self.nonce_changes, - lambda a, f: a.tx_index == f.tx_index + lambda a, f: a.block_access_index == f.block_access_index and a.post_nonce == f.post_nonce, - lambda a: f"Unexpected nonce change found at tx {a.tx_index}", + lambda a: f"Unexpected nonce change found at tx {a.block_access_index}", ) self._validate_forbidden_changes( account.balance_changes, self.balance_changes, - lambda a, f: a.tx_index == f.tx_index + lambda a, f: a.block_access_index == f.block_access_index and a.post_balance == f.post_balance, - lambda a: f"Unexpected balance change found at tx {a.tx_index}", + lambda a: f"Unexpected balance change found at tx {a.block_access_index}", ) self._validate_forbidden_changes( account.code_changes, self.code_changes, - lambda a, f: a.tx_index == f.tx_index and a.new_code == f.new_code, - lambda a: f"Unexpected code change found at tx {a.tx_index}", + lambda a, f: a.block_access_index == f.block_access_index + and a.new_code == f.new_code, + lambda a: f"Unexpected code change found at tx {a.block_access_index}", ) for forbidden_storage_slot in self.storage_changes: @@ -199,11 +200,11 @@ def validate_against(self, account: BalAccountChange) -> None: actual_storage_slot.slot_changes, forbidden_storage_slot.slot_changes, lambda a, f: ( - a.tx_index == f.tx_index + a.block_access_index == f.block_access_index and a.post_value == f.post_value ), lambda a, slot=slot_id: ( - f"Unexpected storage change found at slot {slot} in tx {a.tx_index}" + f"Unexpected storage change found at slot {slot} in tx {a.block_access_index}" ), ) diff --git a/packages/testing/src/execution_testing/test_types/block_access_list/account_changes.py b/packages/testing/src/execution_testing/test_types/block_access_list/account_changes.py index 7f6820061f..92179f8e0d 100644 --- a/packages/testing/src/execution_testing/test_types/block_access_list/account_changes.py +++ b/packages/testing/src/execution_testing/test_types/block_access_list/account_changes.py @@ -15,7 +15,6 @@ CamelModel, HexNumber, RLPSerializable, - StorageKey, ) @@ -24,7 +23,7 @@ class BalNonceChange(CamelModel, RLPSerializable): model_config = CamelModel.model_config | {"extra": "forbid"} - tx_index: HexNumber = Field( + block_access_index: HexNumber = Field( HexNumber(1), description="Transaction index where the change occurred", ) @@ -32,7 +31,7 @@ class BalNonceChange(CamelModel, RLPSerializable): ..., description="Nonce value after the transaction" ) - rlp_fields: ClassVar[List[str]] = ["tx_index", "post_nonce"] + rlp_fields: ClassVar[List[str]] = ["block_access_index", "post_nonce"] class BalBalanceChange(CamelModel, RLPSerializable): @@ -40,7 +39,7 @@ class BalBalanceChange(CamelModel, RLPSerializable): model_config = CamelModel.model_config | {"extra": "forbid"} - tx_index: HexNumber = Field( + block_access_index: HexNumber = Field( HexNumber(1), description="Transaction index where the change occurred", ) @@ -48,7 +47,7 @@ class BalBalanceChange(CamelModel, RLPSerializable): ..., description="Balance after the transaction" ) - rlp_fields: ClassVar[List[str]] = ["tx_index", "post_balance"] + rlp_fields: ClassVar[List[str]] = ["block_access_index", "post_balance"] class BalCodeChange(CamelModel, RLPSerializable): @@ -56,13 +55,13 @@ class BalCodeChange(CamelModel, RLPSerializable): model_config = CamelModel.model_config | {"extra": "forbid"} - tx_index: HexNumber = Field( + block_access_index: HexNumber = Field( HexNumber(1), description="Transaction index where the change occurred", ) new_code: Bytes = Field(..., description="New code bytes") - rlp_fields: ClassVar[List[str]] = ["tx_index", "new_code"] + rlp_fields: ClassVar[List[str]] = ["block_access_index", "new_code"] class BalStorageChange(CamelModel, RLPSerializable): @@ -70,15 +69,15 @@ class BalStorageChange(CamelModel, RLPSerializable): model_config = CamelModel.model_config | {"extra": "forbid"} - tx_index: HexNumber = Field( + block_access_index: HexNumber = Field( HexNumber(1), description="Transaction index where the change occurred", ) - post_value: StorageKey = Field( + post_value: HexNumber = Field( ..., description="Value after the transaction" ) - rlp_fields: ClassVar[List[str]] = ["tx_index", "post_value"] + rlp_fields: ClassVar[List[str]] = ["block_access_index", "post_value"] class BalStorageSlot(CamelModel, RLPSerializable): @@ -86,7 +85,7 @@ class BalStorageSlot(CamelModel, RLPSerializable): model_config = CamelModel.model_config | {"extra": "forbid"} - slot: StorageKey = Field(..., description="Storage slot key") + slot: HexNumber = Field(..., description="Storage slot key") slot_changes: List[BalStorageChange] = Field( default_factory=list, description="List of changes to this slot" ) @@ -112,7 +111,7 @@ class BalAccountChange(CamelModel, RLPSerializable): storage_changes: List[BalStorageSlot] = Field( default_factory=list, description="List of storage changes" ) - storage_reads: List[StorageKey] = Field( + storage_reads: List[HexNumber] = Field( default_factory=list, description="List of storage slots that were read", ) diff --git a/packages/testing/src/execution_testing/test_types/block_access_list/expectations.py b/packages/testing/src/execution_testing/test_types/block_access_list/expectations.py index 6150dfeabd..2c2eefa6a8 100644 --- a/packages/testing/src/execution_testing/test_types/block_access_list/expectations.py +++ b/packages/testing/src/execution_testing/test_types/block_access_list/expectations.py @@ -110,7 +110,7 @@ class BlockAccessListExpectation(CamelModel): expected_block_access_list = BlockAccessListExpectation( account_expectations={ alice: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)] + nonce_changes=[BalNonceChange(block_access_index=1, post_nonce=1)] ), bob: None, # Bob should NOT be in the BAL } @@ -326,8 +326,8 @@ def _compare_account_expectations( slot_actual_idx ] if ( - actual_change.tx_index - == expected_change.tx_index + actual_change.block_access_index + == expected_change.block_access_index and actual_change.post_value == expected_change.post_value ): @@ -361,27 +361,32 @@ def _compare_account_expectations( # Create tuples for comparison (ordering already validated) if field_name == "nonce_changes": expected_tuples = [ - (c.tx_index, c.post_nonce) for c in expected_list + (c.block_access_index, c.post_nonce) + for c in expected_list ] actual_tuples = [ - (c.tx_index, c.post_nonce) for c in actual_list + (c.block_access_index, c.post_nonce) + for c in actual_list ] item_type = "nonce" elif field_name == "balance_changes": expected_tuples = [ - (c.tx_index, int(c.post_balance)) + (c.block_access_index, int(c.post_balance)) for c in expected_list ] actual_tuples = [ - (c.tx_index, int(c.post_balance)) for c in actual_list + (c.block_access_index, int(c.post_balance)) + for c in actual_list ] item_type = "balance" elif field_name == "code_changes": expected_tuples = [ - (c.tx_index, bytes(c.new_code)) for c in expected_list + (c.block_access_index, bytes(c.new_code)) + for c in expected_list ] actual_tuples = [ - (c.tx_index, bytes(c.new_code)) for c in actual_list + (c.block_access_index, bytes(c.new_code)) + for c in actual_list ] item_type = "code" else: diff --git a/packages/testing/src/execution_testing/test_types/block_access_list/modifiers.py b/packages/testing/src/execution_testing/test_types/block_access_list/modifiers.py index 1763970631..d28f7099ba 100644 --- a/packages/testing/src/execution_testing/test_types/block_access_list/modifiers.py +++ b/packages/testing/src/execution_testing/test_types/block_access_list/modifiers.py @@ -54,7 +54,7 @@ def transform(bal: BlockAccessList) -> BlockAccessList: def _modify_field_value( address: Address, - tx_index: int, + block_access_index: int, field_name: str, change_class: type, new_value: Any, @@ -85,9 +85,12 @@ def transform(bal: BlockAccessList) -> BlockAccessList: for j, change in enumerate( storage_slot.slot_changes ): - if change.tx_index == tx_index: + if ( + change.block_access_index + == block_access_index + ): kwargs = { - "tx_index": tx_index, + "block_access_index": block_access_index, value_field: new_value, } storage_slot.slot_changes[j] = ( @@ -98,9 +101,9 @@ def transform(bal: BlockAccessList) -> BlockAccessList: else: # flat structure (nonce, balance, code) for i, change in enumerate(changes): - if change.tx_index == tx_index: + if change.block_access_index == block_access_index: kwargs = { - "tx_index": tx_index, + "block_access_index": block_access_index, value_field: new_value, } changes[i] = change_class(**kwargs) @@ -172,23 +175,28 @@ def remove_code( def modify_nonce( - address: Address, tx_index: int, nonce: int + address: Address, block_access_index: int, nonce: int ) -> Callable[[BlockAccessList], BlockAccessList]: """Set an incorrect nonce value for a specific account and transaction.""" return _modify_field_value( - address, tx_index, "nonce_changes", BalNonceChange, nonce, "post_nonce" + address, + block_access_index, + "nonce_changes", + BalNonceChange, + nonce, + "post_nonce", ) def modify_balance( - address: Address, tx_index: int, balance: int + address: Address, block_access_index: int, balance: int ) -> Callable[[BlockAccessList], BlockAccessList]: """ Set an incorrect balance value for a specific account and transaction. """ return _modify_field_value( address, - tx_index, + block_access_index, "balance_changes", BalBalanceChange, balance, @@ -197,7 +205,7 @@ def modify_balance( def modify_storage( - address: Address, tx_index: int, slot: int, value: int + address: Address, block_access_index: int, slot: int, value: int ) -> Callable[[BlockAccessList], BlockAccessList]: """ Set an incorrect storage value for a specific account, transaction, and @@ -205,7 +213,7 @@ def modify_storage( """ return _modify_field_value( address, - tx_index, + block_access_index, "storage_changes", BalStorageChange, value, @@ -216,11 +224,16 @@ def modify_storage( def modify_code( - address: Address, tx_index: int, code: bytes + address: Address, block_access_index: int, code: bytes ) -> Callable[[BlockAccessList], BlockAccessList]: """Set an incorrect code value for a specific account and transaction.""" return _modify_field_value( - address, tx_index, "code_changes", BalCodeChange, code, "post_code" + address, + block_access_index, + "code_changes", + BalCodeChange, + code, + "post_code", ) @@ -242,46 +255,46 @@ def transform(bal: BlockAccessList) -> BlockAccessList: # Swap in nonce changes if new_account.nonce_changes: for nonce_change in new_account.nonce_changes: - if nonce_change.tx_index == tx1: + if nonce_change.block_access_index == tx1: nonce_indices[tx1] = True - nonce_change.tx_index = HexNumber(tx2) - elif nonce_change.tx_index == tx2: + nonce_change.block_access_index = HexNumber(tx2) + elif nonce_change.block_access_index == tx2: nonce_indices[tx2] = True - nonce_change.tx_index = HexNumber(tx1) + nonce_change.block_access_index = HexNumber(tx1) # Swap in balance changes if new_account.balance_changes: for balance_change in new_account.balance_changes: - if balance_change.tx_index == tx1: + if balance_change.block_access_index == tx1: balance_indices[tx1] = True - balance_change.tx_index = HexNumber(tx2) - elif balance_change.tx_index == tx2: + balance_change.block_access_index = HexNumber(tx2) + elif balance_change.block_access_index == tx2: balance_indices[tx2] = True - balance_change.tx_index = HexNumber(tx1) + balance_change.block_access_index = HexNumber(tx1) # Swap in storage changes (nested structure) if new_account.storage_changes: for storage_slot in new_account.storage_changes: for storage_change in storage_slot.slot_changes: - if storage_change.tx_index == tx1: + if storage_change.block_access_index == tx1: balance_indices[tx1] = True - storage_change.tx_index = HexNumber(tx2) - elif storage_change.tx_index == tx2: + storage_change.block_access_index = HexNumber(tx2) + elif storage_change.block_access_index == tx2: balance_indices[tx2] = True - storage_change.tx_index = HexNumber(tx1) + storage_change.block_access_index = HexNumber(tx1) - # Note: storage_reads is just a list of StorageKey, no tx_index to + # Note: storage_reads is just a list of StorageKey, no block_access_index to # swap # Swap in code changes if new_account.code_changes: for code_change in new_account.code_changes: - if code_change.tx_index == tx1: + if code_change.block_access_index == tx1: code_indices[tx1] = True - code_change.tx_index = HexNumber(tx2) - elif code_change.tx_index == tx2: + code_change.block_access_index = HexNumber(tx2) + elif code_change.block_access_index == tx2: code_indices[tx2] = True - code_change.tx_index = HexNumber(tx1) + code_change.block_access_index = HexNumber(tx1) new_root.append(new_account) diff --git a/packages/testing/src/execution_testing/test_types/block_access_list/t8n.py b/packages/testing/src/execution_testing/test_types/block_access_list/t8n.py index 03b8224bbf..19733a240f 100644 --- a/packages/testing/src/execution_testing/test_types/block_access_list/t8n.py +++ b/packages/testing/src/execution_testing/test_types/block_access_list/t8n.py @@ -84,21 +84,21 @@ def validate_structure(self) -> None: if not change_list: continue - tx_indices = [c.tx_index for c in change_list] + bal_indices = [c.block_access_index for c in change_list] # Check both ordering and duplicates - if tx_indices != sorted(tx_indices): + if bal_indices != sorted(bal_indices): raise BlockAccessListValidationError( - f"Transaction indices not in ascending order in {field_name} of account " - f"{account.address}. Got: {tx_indices}, Expected: {sorted(tx_indices)}" + f"Block access indices not in ascending order in {field_name} of account " + f"{account.address}. Got: {bal_indices}, Expected: {sorted(bal_indices)}" ) - if len(tx_indices) != len(set(tx_indices)): + if len(bal_indices) != len(set(bal_indices)): duplicates = sorted( { idx - for idx in tx_indices - if tx_indices.count(idx) > 1 + for idx in bal_indices + if bal_indices.count(idx) > 1 } ) raise BlockAccessListValidationError( @@ -118,27 +118,29 @@ def validate_structure(self) -> None: f"{account.storage_changes[i].slot}" ) - # Check transaction index ordering and uniqueness within storage slots + # Check bal index ordering and uniqueness within storage slots for storage_slot in account.storage_changes: if not storage_slot.slot_changes: continue - tx_indices = [c.tx_index for c in storage_slot.slot_changes] + bal_indices = [ + c.block_access_index for c in storage_slot.slot_changes + ] # Check both ordering and duplicates - if tx_indices != sorted(tx_indices): + if bal_indices != sorted(bal_indices): raise BlockAccessListValidationError( f"Transaction indices not in ascending order in storage slot " f"{storage_slot.slot} of account {account.address}. " - f"Got: {tx_indices}, Expected: {sorted(tx_indices)}" + f"Got: {bal_indices}, Expected: {sorted(bal_indices)}" ) - if len(tx_indices) != len(set(tx_indices)): + if len(bal_indices) != len(set(bal_indices)): duplicates = sorted( { idx - for idx in tx_indices - if tx_indices.count(idx) > 1 + for idx in bal_indices + if bal_indices.count(idx) > 1 } ) raise BlockAccessListValidationError( diff --git a/packages/testing/src/execution_testing/test_types/tests/test_block_access_list_expectation.py b/packages/testing/src/execution_testing/test_types/tests/test_block_access_list_expectation.py index 899d9647e4..f8b16d4474 100644 --- a/packages/testing/src/execution_testing/test_types/tests/test_block_access_list_expectation.py +++ b/packages/testing/src/execution_testing/test_types/tests/test_block_access_list_expectation.py @@ -29,7 +29,9 @@ def test_address_exclusion_validation_passes() -> None: [ BalAccountChange( address=alice, - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)], + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ], ), ] ) @@ -37,7 +39,9 @@ def test_address_exclusion_validation_passes() -> None: expectation = BlockAccessListExpectation( account_expectations={ alice: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)] + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ] ), bob: None, # expect Bob is not in BAL (correctly) } @@ -55,12 +59,14 @@ def test_address_exclusion_validation_raises_when_address_is_present() -> None: [ BalAccountChange( address=alice, - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)], + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ], ), BalAccountChange( address=bob, balance_changes=[ - BalBalanceChange(tx_index=1, post_balance=100) + BalBalanceChange(block_access_index=1, post_balance=100) ], ), ] @@ -103,7 +109,9 @@ def test_empty_account_changes_definitions( [ BalAccountChange( address=alice, - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)], + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ], ), ] ) @@ -153,14 +161,22 @@ def test_empty_list_validation() -> None: @pytest.mark.parametrize( "field,value", [ - ["nonce_changes", BalNonceChange(tx_index=1, post_nonce=1)], - ["balance_changes", BalBalanceChange(tx_index=1, post_balance=100)], - ["code_changes", BalCodeChange(tx_index=1, new_code=b"code")], + ["nonce_changes", BalNonceChange(block_access_index=1, post_nonce=1)], + [ + "balance_changes", + BalBalanceChange(block_access_index=1, post_balance=100), + ], + [ + "code_changes", + BalCodeChange(block_access_index=1, new_code=b"code"), + ], [ "storage_changes", BalStorageSlot( slot=0x01, - slot_changes=[BalStorageChange(tx_index=1, post_value=0x42)], + slot_changes=[ + BalStorageChange(block_access_index=1, post_value=0x42) + ], ), ], ["storage_reads", 0x01], @@ -179,7 +195,7 @@ def test_empty_list_validation_fails(field: str, value: Any) -> None: alice_acct_change.storage_reads = [value] # set another field to non-empty to avoid all-empty account change alice_acct_change.nonce_changes = [ - BalNonceChange(tx_index=1, post_nonce=1) + BalNonceChange(block_access_index=1, post_nonce=1) ] else: @@ -194,7 +210,7 @@ def test_empty_list_validation_fails(field: str, value: Any) -> None: # match the filled field in actual to avoid all-empty # account expectation alice_acct_expectation.nonce_changes = [ - BalNonceChange(tx_index=1, post_nonce=1) + BalNonceChange(block_access_index=1, post_nonce=1) ] else: setattr(alice_acct_expectation, field, []) @@ -219,9 +235,11 @@ def test_partial_validation() -> None: [ BalAccountChange( address=alice, - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)], + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ], balance_changes=[ - BalBalanceChange(tx_index=1, post_balance=100) + BalBalanceChange(block_access_index=1, post_balance=100) ], storage_reads=[0x01, 0x02], ), @@ -232,7 +250,9 @@ def test_partial_validation() -> None: expectation = BlockAccessListExpectation( account_expectations={ alice: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)], + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ], # balance_changes and storage_reads not set and won't be # validated ), @@ -255,7 +275,9 @@ def test_storage_changes_validation() -> None: BalStorageSlot( slot=0x01, slot_changes=[ - BalStorageChange(tx_index=1, post_value=0x42) + BalStorageChange( + block_access_index=1, post_value=0x42 + ) ], ) ], @@ -271,7 +293,9 @@ def test_storage_changes_validation() -> None: BalStorageSlot( slot=0x01, slot_changes=[ - BalStorageChange(tx_index=1, post_value=0x42) + BalStorageChange( + block_access_index=1, post_value=0x42 + ) ], ) ], @@ -291,7 +315,9 @@ def test_missing_expected_address() -> None: [ BalAccountChange( address=alice, - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)], + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ], ), ] ) @@ -300,7 +326,9 @@ def test_missing_expected_address() -> None: account_expectations={ # wrongly expect Bob to be present bob: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)], + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ], ), } ) @@ -474,9 +502,9 @@ def test_expected_tx_indices_ordering( BalAccountChange( address=addr, nonce_changes=[ - BalNonceChange(tx_index=1, post_nonce=1), - BalNonceChange(tx_index=2, post_nonce=2), - BalNonceChange(tx_index=3, post_nonce=3), + BalNonceChange(block_access_index=1, post_nonce=1), + BalNonceChange(block_access_index=2, post_nonce=2), + BalNonceChange(block_access_index=3, post_nonce=3), ], ) ] @@ -486,7 +514,7 @@ def test_expected_tx_indices_ordering( account_expectations={ addr: BalAccountExpectation( nonce_changes=[ - BalNonceChange(tx_index=idx, post_nonce=idx) + BalNonceChange(block_access_index=idx, post_nonce=idx) for idx in expected_tx_indices ], ), @@ -508,10 +536,12 @@ def test_absent_values_nonce_changes(has_change_should_raise: bool) -> None: """Test nonce_changes_at_tx validator with present/absent changes.""" alice = Address(0xA) - nonce_changes = [BalNonceChange(tx_index=1, post_nonce=1)] + nonce_changes = [BalNonceChange(block_access_index=1, post_nonce=1)] if has_change_should_raise: # add nonce change at tx 2 which should trigger failure - nonce_changes.append(BalNonceChange(tx_index=2, post_nonce=2)) + nonce_changes.append( + BalNonceChange(block_access_index=2, post_nonce=2) + ) actual_bal = BlockAccessList( [ @@ -527,7 +557,9 @@ def test_absent_values_nonce_changes(has_change_should_raise: bool) -> None: # no nonce changes at tx 2 alice: BalAccountExpectation( absent_values=BalAccountAbsentValues( - nonce_changes=[BalNonceChange(tx_index=2, post_nonce=2)] + nonce_changes=[ + BalNonceChange(block_access_index=2, post_nonce=2) + ] ) ) } @@ -547,10 +579,14 @@ def test_absent_values_balance_changes(has_change_should_raise: bool) -> None: """Test balance_changes_at_tx validator with present/absent changes.""" alice = Address(0xA) - balance_changes = [BalBalanceChange(tx_index=1, post_balance=100)] + balance_changes = [ + BalBalanceChange(block_access_index=1, post_balance=100) + ] if has_change_should_raise: # add balance change at tx 2 which should trigger failure - balance_changes.append(BalBalanceChange(tx_index=2, post_balance=200)) + balance_changes.append( + BalBalanceChange(block_access_index=2, post_balance=200) + ) actual_bal = BlockAccessList( [ @@ -566,7 +602,9 @@ def test_absent_values_balance_changes(has_change_should_raise: bool) -> None: alice: BalAccountExpectation( absent_values=BalAccountAbsentValues( balance_changes=[ - BalBalanceChange(tx_index=2, post_balance=200) + BalBalanceChange( + block_access_index=2, post_balance=200 + ) ] ) ), @@ -591,14 +629,18 @@ def test_absent_values_storage_changes(has_change_should_raise: bool) -> None: storage_changes = [ BalStorageSlot( slot=0x01, - slot_changes=[BalStorageChange(tx_index=1, post_value=0x99)], + slot_changes=[ + BalStorageChange(block_access_index=1, post_value=0x99) + ], ) ] if has_change_should_raise: storage_changes.append( BalStorageSlot( slot=0x42, - slot_changes=[BalStorageChange(tx_index=1, post_value=0xBEEF)], + slot_changes=[ + BalStorageChange(block_access_index=1, post_value=0xBEEF) + ], ) ) @@ -620,7 +662,9 @@ def test_absent_values_storage_changes(has_change_should_raise: bool) -> None: BalStorageSlot( slot=0x42, slot_changes=[ - BalStorageChange(tx_index=1, post_value=0xBEEF) + BalStorageChange( + block_access_index=1, post_value=0xBEEF + ) ], ) ] @@ -682,10 +726,12 @@ def test_absent_values_code_changes(has_change_should_raise: bool) -> None: """Test code_changes_at_tx validator with present/absent changes.""" alice = Address(0xA) - code_changes = [BalCodeChange(tx_index=1, new_code=b"\x00")] + code_changes = [BalCodeChange(block_access_index=1, new_code=b"\x00")] if has_change_should_raise: # add code change at tx 2 which should trigger failure - code_changes.append(BalCodeChange(tx_index=2, new_code=b"\x60\x00")) + code_changes.append( + BalCodeChange(block_access_index=2, new_code=b"\x60\x00") + ) actual_bal = BlockAccessList( [ @@ -702,7 +748,9 @@ def test_absent_values_code_changes(has_change_should_raise: bool) -> None: alice: BalAccountExpectation( absent_values=BalAccountAbsentValues( code_changes=[ - BalCodeChange(tx_index=2, new_code=b"\x60\x00") + BalCodeChange( + block_access_index=2, new_code=b"\x60\x00" + ) ] ) ), @@ -732,7 +780,9 @@ def test_multiple_absent_valuess() -> None: BalStorageSlot( slot=0x01, slot_changes=[ - BalStorageChange(tx_index=1, post_value=0x99) + BalStorageChange( + block_access_index=1, post_value=0x99 + ) ], ) ], @@ -750,37 +800,43 @@ def test_multiple_absent_valuess() -> None: BalStorageSlot( slot=0x01, slot_changes=[ - BalStorageChange(tx_index=1, post_value=0x99) + BalStorageChange( + block_access_index=1, post_value=0x99 + ) ], ) ], absent_values=BalAccountAbsentValues( nonce_changes=[ - BalNonceChange(tx_index=1, post_nonce=0), - BalNonceChange(tx_index=2, post_nonce=0), + BalNonceChange(block_access_index=1, post_nonce=0), + BalNonceChange(block_access_index=2, post_nonce=0), ], balance_changes=[ - BalBalanceChange(tx_index=1, post_balance=0), - BalBalanceChange(tx_index=2, post_balance=0), + BalBalanceChange(block_access_index=1, post_balance=0), + BalBalanceChange(block_access_index=2, post_balance=0), ], storage_changes=[ BalStorageSlot( slot=0x42, slot_changes=[ - BalStorageChange(tx_index=1, post_value=0) + BalStorageChange( + block_access_index=1, post_value=0 + ) ], ), BalStorageSlot( slot=0x43, slot_changes=[ - BalStorageChange(tx_index=1, post_value=0) + BalStorageChange( + block_access_index=1, post_value=0 + ) ], ), ], storage_reads=[StorageKey(0x42), StorageKey(0x43)], code_changes=[ - BalCodeChange(tx_index=1, new_code=b""), - BalCodeChange(tx_index=2, new_code=b""), + BalCodeChange(block_access_index=1, new_code=b""), + BalCodeChange(block_access_index=2, new_code=b""), ], ), ), @@ -800,8 +856,8 @@ def test_absent_values_with_multiple_tx_indices() -> None: address=alice, nonce_changes=[ # nonce changes at tx 1 and 3 - BalNonceChange(tx_index=1, post_nonce=1), - BalNonceChange(tx_index=3, post_nonce=2), + BalNonceChange(block_access_index=1, post_nonce=1), + BalNonceChange(block_access_index=3, post_nonce=2), ], ), ] @@ -811,13 +867,13 @@ def test_absent_values_with_multiple_tx_indices() -> None: account_expectations={ alice: BalAccountExpectation( nonce_changes=[ - BalNonceChange(tx_index=1, post_nonce=1), - BalNonceChange(tx_index=3, post_nonce=2), + BalNonceChange(block_access_index=1, post_nonce=1), + BalNonceChange(block_access_index=3, post_nonce=2), ], absent_values=BalAccountAbsentValues( nonce_changes=[ - BalNonceChange(tx_index=2, post_nonce=0), - BalNonceChange(tx_index=4, post_nonce=0), + BalNonceChange(block_access_index=2, post_nonce=0), + BalNonceChange(block_access_index=4, post_nonce=0), ] ), ), @@ -833,8 +889,8 @@ def test_absent_values_with_multiple_tx_indices() -> None: nonce_changes=[ # wrongly forbid change at txs 1 and 2 # (1 exists, so should fail) - BalNonceChange(tx_index=1, post_nonce=1), - BalNonceChange(tx_index=2, post_nonce=0), + BalNonceChange(block_access_index=1, post_nonce=1), + BalNonceChange(block_access_index=2, post_nonce=0), ] ), ), @@ -856,7 +912,9 @@ def test_bal_account_absent_values_comprehensive() -> None: [ BalAccountChange( address=addr, - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)], + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ], ) ] ) @@ -865,7 +923,9 @@ def test_bal_account_absent_values_comprehensive() -> None: account_expectations={ addr: BalAccountExpectation( absent_values=BalAccountAbsentValues( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)] + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ] ) ), } @@ -883,7 +943,7 @@ def test_bal_account_absent_values_comprehensive() -> None: BalAccountChange( address=addr, balance_changes=[ - BalBalanceChange(tx_index=2, post_balance=100) + BalBalanceChange(block_access_index=2, post_balance=100) ], ) ] @@ -894,7 +954,9 @@ def test_bal_account_absent_values_comprehensive() -> None: addr: BalAccountExpectation( absent_values=BalAccountAbsentValues( balance_changes=[ - BalBalanceChange(tx_index=2, post_balance=100) + BalBalanceChange( + block_access_index=2, post_balance=100 + ) ] ) ), @@ -912,7 +974,9 @@ def test_bal_account_absent_values_comprehensive() -> None: [ BalAccountChange( address=addr, - code_changes=[BalCodeChange(tx_index=3, new_code=b"\x60\x00")], + code_changes=[ + BalCodeChange(block_access_index=3, new_code=b"\x60\x00") + ], ) ] ) @@ -922,7 +986,9 @@ def test_bal_account_absent_values_comprehensive() -> None: addr: BalAccountExpectation( absent_values=BalAccountAbsentValues( code_changes=[ - BalCodeChange(tx_index=3, new_code=b"\x60\x00") + BalCodeChange( + block_access_index=3, new_code=b"\x60\x00" + ) ] ) ), @@ -965,7 +1031,9 @@ def test_bal_account_absent_values_comprehensive() -> None: BalStorageSlot( slot=0x01, slot_changes=[ - BalStorageChange(tx_index=1, post_value=99) + BalStorageChange( + block_access_index=1, post_value=99 + ) ], ) ], @@ -981,7 +1049,9 @@ def test_bal_account_absent_values_comprehensive() -> None: BalStorageSlot( slot=0x01, slot_changes=[ - BalStorageChange(tx_index=1, post_value=99) + BalStorageChange( + block_access_index=1, post_value=99 + ) ], ) ] diff --git a/packages/testing/src/execution_testing/test_types/tests/test_block_access_list_t8n.py b/packages/testing/src/execution_testing/test_types/tests/test_block_access_list_t8n.py index 3c884cf2f4..c33cf8a2c7 100644 --- a/packages/testing/src/execution_testing/test_types/tests/test_block_access_list_t8n.py +++ b/packages/testing/src/execution_testing/test_types/tests/test_block_access_list_t8n.py @@ -127,7 +127,7 @@ def test_bal_storage_reads_ordering() -> None: "field_name", ["nonce_changes", "balance_changes", "code_changes"], ) -def test_bal_tx_indices_ordering(field_name: str) -> None: +def test_bal_block_access_indices_ordering(field_name: str) -> None: """ Test that transaction indices must be in ascending order within change lists. """ @@ -138,51 +138,63 @@ def test_bal_tx_indices_ordering(field_name: str) -> None: Union[BalNonceChange, BalBalanceChange, BalCodeChange] ] - # Correct order: tx_index 1, 2, 3 + # Correct order: block_access_index 1, 2, 3 if field_name == "nonce_changes": changes_valid = [ - BalNonceChange(tx_index=HexNumber(1), post_nonce=HexNumber(1)), - BalNonceChange(tx_index=HexNumber(2), post_nonce=HexNumber(2)), - BalNonceChange(tx_index=HexNumber(3), post_nonce=HexNumber(3)), + BalNonceChange( + block_access_index=HexNumber(1), post_nonce=HexNumber(1) + ), + BalNonceChange( + block_access_index=HexNumber(2), post_nonce=HexNumber(2) + ), + BalNonceChange( + block_access_index=HexNumber(3), post_nonce=HexNumber(3) + ), ] changes_invalid = [ - BalNonceChange(tx_index=HexNumber(1), post_nonce=HexNumber(1)), - BalNonceChange(tx_index=HexNumber(3), post_nonce=HexNumber(3)), - BalNonceChange(tx_index=HexNumber(2), post_nonce=HexNumber(2)), + BalNonceChange( + block_access_index=HexNumber(1), post_nonce=HexNumber(1) + ), + BalNonceChange( + block_access_index=HexNumber(3), post_nonce=HexNumber(3) + ), + BalNonceChange( + block_access_index=HexNumber(2), post_nonce=HexNumber(2) + ), ] elif field_name == "balance_changes": changes_valid = [ BalBalanceChange( - tx_index=HexNumber(1), post_balance=HexNumber(100) + block_access_index=HexNumber(1), post_balance=HexNumber(100) ), BalBalanceChange( - tx_index=HexNumber(2), post_balance=HexNumber(200) + block_access_index=HexNumber(2), post_balance=HexNumber(200) ), BalBalanceChange( - tx_index=HexNumber(3), post_balance=HexNumber(300) + block_access_index=HexNumber(3), post_balance=HexNumber(300) ), ] changes_invalid = [ BalBalanceChange( - tx_index=HexNumber(1), post_balance=HexNumber(100) + block_access_index=HexNumber(1), post_balance=HexNumber(100) ), BalBalanceChange( - tx_index=HexNumber(3), post_balance=HexNumber(300) + block_access_index=HexNumber(3), post_balance=HexNumber(300) ), BalBalanceChange( - tx_index=HexNumber(2), post_balance=HexNumber(200) + block_access_index=HexNumber(2), post_balance=HexNumber(200) ), ] elif field_name == "code_changes": changes_valid = [ - BalCodeChange(tx_index=HexNumber(1), new_code=b"code1"), - BalCodeChange(tx_index=HexNumber(2), new_code=b"code2"), - BalCodeChange(tx_index=HexNumber(3), new_code=b"code3"), + BalCodeChange(block_access_index=HexNumber(1), new_code=b"code1"), + BalCodeChange(block_access_index=HexNumber(2), new_code=b"code2"), + BalCodeChange(block_access_index=HexNumber(3), new_code=b"code3"), ] changes_invalid = [ - BalCodeChange(tx_index=HexNumber(1), new_code=b"code1"), - BalCodeChange(tx_index=HexNumber(3), new_code=b"code3"), - BalCodeChange(tx_index=HexNumber(2), new_code=b"code2"), + BalCodeChange(block_access_index=HexNumber(1), new_code=b"code1"), + BalCodeChange(block_access_index=HexNumber(3), new_code=b"code3"), + BalCodeChange(block_access_index=HexNumber(2), new_code=b"code2"), ] bal_valid = BlockAccessList( @@ -196,7 +208,7 @@ def test_bal_tx_indices_ordering(field_name: str) -> None: with pytest.raises( BlockAccessListValidationError, - match=f"Transaction indices not in ascending order in {field_name}", + match=f"Block access indices not in ascending order in {field_name}", ): bal_invalid.validate_structure() @@ -205,7 +217,7 @@ def test_bal_tx_indices_ordering(field_name: str) -> None: "field_name", ["nonce_changes", "balance_changes", "code_changes"], ) -def test_bal_duplicate_tx_indices(field_name: str) -> None: +def test_bal_duplicate_block_access_indices(field_name: str) -> None: """ Test that BAL must not have duplicate tx indices in change lists. """ @@ -213,34 +225,38 @@ def test_bal_duplicate_tx_indices(field_name: str) -> None: changes: List[Union[BalNonceChange, BalBalanceChange, BalCodeChange]] - # Duplicate tx_index=1 + # Duplicate block_access_index=1 if field_name == "nonce_changes": changes = [ - BalNonceChange(tx_index=HexNumber(1), post_nonce=HexNumber(1)), BalNonceChange( - tx_index=HexNumber(1), post_nonce=HexNumber(2) - ), # duplicate tx_index - BalNonceChange(tx_index=HexNumber(2), post_nonce=HexNumber(3)), + block_access_index=HexNumber(1), post_nonce=HexNumber(1) + ), + BalNonceChange( + block_access_index=HexNumber(1), post_nonce=HexNumber(2) + ), # duplicate block_access_index + BalNonceChange( + block_access_index=HexNumber(2), post_nonce=HexNumber(3) + ), ] elif field_name == "balance_changes": changes = [ BalBalanceChange( - tx_index=HexNumber(1), post_balance=HexNumber(100) + block_access_index=HexNumber(1), post_balance=HexNumber(100) ), BalBalanceChange( - tx_index=HexNumber(1), post_balance=HexNumber(200) - ), # duplicate tx_index + block_access_index=HexNumber(1), post_balance=HexNumber(200) + ), # duplicate block_access_index BalBalanceChange( - tx_index=HexNumber(2), post_balance=HexNumber(300) + block_access_index=HexNumber(2), post_balance=HexNumber(300) ), ] elif field_name == "code_changes": changes = [ - BalCodeChange(tx_index=HexNumber(1), new_code=b"code1"), + BalCodeChange(block_access_index=HexNumber(1), new_code=b"code1"), BalCodeChange( - tx_index=HexNumber(1), new_code=b"" - ), # duplicate tx_index - BalCodeChange(tx_index=HexNumber(2), new_code=b"code2"), + block_access_index=HexNumber(1), new_code=b"" + ), # duplicate block_access_index + BalCodeChange(block_access_index=HexNumber(2), new_code=b"code2"), ] bal = BlockAccessList( @@ -254,13 +270,13 @@ def test_bal_duplicate_tx_indices(field_name: str) -> None: bal.validate_structure() -def test_bal_storage_duplicate_tx_indices() -> None: +def test_bal_storage_duplicate_block_access_indices() -> None: """ Test that storage changes must not have duplicate tx indices within same slot. """ addr = Address(0xA) - # Create storage changes with duplicate tx_index within the same slot + # Create storage changes with duplicate block_access_index within the same slot bal = BlockAccessList( [ BalAccountChange( @@ -270,15 +286,15 @@ def test_bal_storage_duplicate_tx_indices() -> None: slot=StorageKey(0), slot_changes=[ BalStorageChange( - tx_index=HexNumber(1), + block_access_index=HexNumber(1), post_value=StorageKey(100), ), BalStorageChange( - tx_index=HexNumber(1), + block_access_index=HexNumber(1), post_value=StorageKey(200), - ), # duplicate tx_index + ), # duplicate block_access_index BalStorageChange( - tx_index=HexNumber(2), + block_access_index=HexNumber(2), post_value=StorageKey(300), ), ], @@ -309,10 +325,12 @@ def test_bal_multiple_violations() -> None: address=bob, # Should come after alice nonce_changes=[ BalNonceChange( - tx_index=HexNumber(1), post_nonce=HexNumber(1) + block_access_index=HexNumber(1), + post_nonce=HexNumber(1), ), BalNonceChange( - tx_index=HexNumber(1), post_nonce=HexNumber(2) + block_access_index=HexNumber(1), + post_nonce=HexNumber(2), ), # duplicate ], ), @@ -342,7 +360,8 @@ def test_bal_single_account_valid() -> None: address=Address(0xA), nonce_changes=[ BalNonceChange( - tx_index=HexNumber(1), post_nonce=HexNumber(1) + block_access_index=HexNumber(1), + post_nonce=HexNumber(1), ) ], ) diff --git a/src/ethereum/forks/amsterdam/block_access_lists/builder.py b/src/ethereum/forks/amsterdam/block_access_lists/builder.py index e860c84068..ff5426746a 100644 --- a/src/ethereum/forks/amsterdam/block_access_lists/builder.py +++ b/src/ethereum/forks/amsterdam/block_access_lists/builder.py @@ -16,7 +16,7 @@ from dataclasses import dataclass, field from typing import TYPE_CHECKING, Dict, List, Set -from ethereum_types.bytes import Bytes, Bytes32 +from ethereum_types.bytes import Bytes from ethereum_types.numeric import U64, U256 from ..fork_types import Address @@ -45,7 +45,7 @@ class AccountData: transaction index where it occurred. """ - storage_changes: Dict[Bytes32, List[StorageChange]] = field( + storage_changes: Dict[U256, List[StorageChange]] = field( default_factory=dict ) """ @@ -53,7 +53,7 @@ class AccountData: Each change includes the transaction index and new value. """ - storage_reads: Set[Bytes32] = field(default_factory=set) + storage_reads: Set[U256] = field(default_factory=set) """ Set of storage slots that were read but not modified. """ @@ -121,9 +121,9 @@ def ensure_account(builder: BlockAccessListBuilder, address: Address) -> None: def add_storage_write( builder: BlockAccessListBuilder, address: Address, - slot: Bytes32, + slot: U256, block_access_index: BlockAccessIndex, - new_value: Bytes32, + new_value: U256, ) -> None: """ Add a storage write operation to the block access list. @@ -171,7 +171,7 @@ def add_storage_write( def add_storage_read( - builder: BlockAccessListBuilder, address: Address, slot: Bytes32 + builder: BlockAccessListBuilder, address: Address, slot: U256 ) -> None: """ Add a storage read operation to the block access list. @@ -482,7 +482,7 @@ def build_block_access_list( # Add all storage reads for address, slot in state_changes.storage_reads: - add_storage_read(builder, address, slot) + add_storage_read(builder, address, U256(int.from_bytes(slot))) # Add all storage writes # Net-zero filtering happens at transaction commit time, not here. @@ -492,10 +492,9 @@ def build_block_access_list( slot, block_access_index, ), value in state_changes.storage_writes.items(): - # Convert U256 to Bytes32 for storage - value_bytes = Bytes32(value.to_bytes(U256(32), "big")) + u256_slot = U256(int.from_bytes(slot)) add_storage_write( - builder, address, slot, block_access_index, value_bytes + builder, address, u256_slot, block_access_index, value ) # Add all balance changes (balance_changes is keyed by (address, index)) diff --git a/src/ethereum/forks/amsterdam/block_access_lists/rlp_types.py b/src/ethereum/forks/amsterdam/block_access_lists/rlp_types.py index c4f49ff4aa..e604d43da1 100644 --- a/src/ethereum/forks/amsterdam/block_access_lists/rlp_types.py +++ b/src/ethereum/forks/amsterdam/block_access_lists/rlp_types.py @@ -10,14 +10,14 @@ from dataclasses import dataclass from typing import List, Tuple -from ethereum_types.bytes import Bytes, Bytes20, Bytes32 +from ethereum_types.bytes import Bytes, Bytes20 from ethereum_types.frozen import slotted_freezable from ethereum_types.numeric import U64, U256, Uint # Type aliases for clarity (matching EIP-7928 specification) Address = Bytes20 -StorageKey = Bytes32 -StorageValue = Bytes32 +StorageKey = U256 +StorageValue = U256 CodeData = Bytes BlockAccessIndex = Uint # uint16 in the spec, but using Uint for compatibility Balance = U256 # Post-transaction balance in wei diff --git a/src/ethereum_spec_tools/evm_tools/t8n/t8n_types.py b/src/ethereum_spec_tools/evm_tools/t8n/t8n_types.py index cb13727f0d..0e84189598 100644 --- a/src/ethereum_spec_tools/evm_tools/t8n/t8n_types.py +++ b/src/ethereum_spec_tools/evm_tools/t8n/t8n_types.py @@ -348,16 +348,16 @@ def _block_access_list_to_json(account_changes: Any) -> Any: storage_changes = [] for slot_change in account.storage_changes: slot_data: Dict[str, Any] = { - "slot": int.from_bytes(slot_change.slot, "big"), + "slot": int(slot_change.slot), "slotChanges": [], } for change in slot_change.changes: slot_data["slotChanges"].append( { - "txIndex": int(change.block_access_index), - "postValue": int.from_bytes( - change.new_value, "big" + "blockAccessIndex": int( + change.block_access_index ), + "postValue": int(change.new_value), } ) storage_changes.append(slot_data) @@ -365,14 +365,13 @@ def _block_access_list_to_json(account_changes: Any) -> Any: if account.storage_reads: account_data["storageReads"] = [ - int.from_bytes(slot, "big") - for slot in account.storage_reads + int(slot) for slot in account.storage_reads ] if account.balance_changes: account_data["balanceChanges"] = [ { - "txIndex": int(change.block_access_index), + "blockAccessIndex": int(change.block_access_index), "postBalance": int(change.post_balance), } for change in account.balance_changes @@ -381,7 +380,7 @@ def _block_access_list_to_json(account_changes: Any) -> Any: if account.nonce_changes: account_data["nonceChanges"] = [ { - "txIndex": int(change.block_access_index), + "blockAccessIndex": int(change.block_access_index), "postNonce": int(change.new_nonce), } for change in account.nonce_changes @@ -390,7 +389,7 @@ def _block_access_list_to_json(account_changes: Any) -> Any: if account.code_changes: account_data["codeChanges"] = [ { - "txIndex": int(change.block_access_index), + "blockAccessIndex": int(change.block_access_index), "newCode": "0x" + change.new_code.hex(), } for change in account.code_changes diff --git a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists.py b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists.py index 32a1052841..f56a142c8b 100644 --- a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists.py +++ b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists.py @@ -55,7 +55,9 @@ def test_bal_nonce_changes( expected_block_access_list=BlockAccessListExpectation( account_expectations={ alice: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)], + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ], ), } ), @@ -110,16 +112,21 @@ def test_bal_balance_changes( expected_block_access_list=BlockAccessListExpectation( account_expectations={ alice: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)], + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ], balance_changes=[ BalBalanceChange( - tx_index=1, post_balance=alice_final_balance + block_access_index=1, + post_balance=alice_final_balance, ) ], ), bob: BalAccountExpectation( balance_changes=[ - BalBalanceChange(tx_index=1, post_balance=100) + BalBalanceChange( + block_access_index=1, post_balance=100 + ) ], ), } @@ -190,14 +197,20 @@ def test_bal_code_changes( expected_block_access_list=BlockAccessListExpectation( account_expectations={ alice: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)], + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ], ), factory_contract: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=2)], + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=2) + ], ), created_contract: BalAccountExpectation( code_changes=[ - BalCodeChange(tx_index=1, new_code=runtime_code_bytes) + BalCodeChange( + block_access_index=1, new_code=runtime_code_bytes + ) ], ), } @@ -275,7 +288,9 @@ def test_bal_account_access_target( expected_block_access_list=BlockAccessListExpectation( account_expectations={ alice: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)] + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ] ), target_contract: BalAccountExpectation.empty(), oracle_contract: BalAccountExpectation.empty(), @@ -314,16 +329,22 @@ def test_bal_callcode_nested_value_transfer( expected_block_access_list=BlockAccessListExpectation( account_expectations={ alice: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)], + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ], ), oracle_contract: BalAccountExpectation( balance_changes=[ - BalBalanceChange(tx_index=1, post_balance=100) + BalBalanceChange( + block_access_index=1, post_balance=100 + ) ], ), bob: BalAccountExpectation( balance_changes=[ - BalBalanceChange(tx_index=1, post_balance=100) + BalBalanceChange( + block_access_index=1, post_balance=100 + ) ], ), target_contract: BalAccountExpectation.empty(), @@ -380,14 +401,18 @@ def test_bal_delegated_storage_writes( expected_block_access_list=BlockAccessListExpectation( account_expectations={ alice: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)], + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ], ), oracle_contract: BalAccountExpectation( storage_changes=[ BalStorageSlot( slot=0x01, slot_changes=[ - BalStorageChange(tx_index=1, post_value=0x42) + BalStorageChange( + block_access_index=1, post_value=0x42 + ) ], ) ], @@ -448,7 +473,9 @@ def test_bal_delegated_storage_reads( expected_block_access_list=BlockAccessListExpectation( account_expectations={ alice: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)], + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ], ), oracle_contract: BalAccountExpectation( storage_reads=[0x01], @@ -511,22 +538,27 @@ def test_bal_block_rewards( expected_block_access_list=BlockAccessListExpectation( account_expectations={ alice: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)], + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ], balance_changes=[ BalBalanceChange( - tx_index=1, post_balance=alice_final_balance + block_access_index=1, + post_balance=alice_final_balance, ) ], ), bob: BalAccountExpectation( balance_changes=[ - BalBalanceChange(tx_index=1, post_balance=100) + BalBalanceChange( + block_access_index=1, post_balance=100 + ) ], ), charlie: BalAccountExpectation( balance_changes=[ BalBalanceChange( - tx_index=1, post_balance=tip_to_charlie + block_access_index=1, post_balance=tip_to_charlie ) ], ), @@ -571,7 +603,9 @@ def test_bal_2930_account_listed_but_untouched( expected_block_access_list=BlockAccessListExpectation( account_expectations={ alice: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)], + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ], ), # The address excluded from BAL since state is not accessed oracle: None, @@ -628,7 +662,9 @@ def test_bal_2930_slot_listed_but_untouched( expected_block_access_list=BlockAccessListExpectation( account_expectations={ alice: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)], + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ], ), # The account was loaded. pure_calculator: BalAccountExpectation.empty(), @@ -688,20 +724,26 @@ def test_bal_2930_slot_listed_and_unlisted_writes( expected_block_access_list=BlockAccessListExpectation( account_expectations={ alice: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)], + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ], ), storage_writer: BalAccountExpectation( storage_changes=[ BalStorageSlot( slot=0x01, slot_changes=[ - BalStorageChange(tx_index=1, post_value=0x42) + BalStorageChange( + block_access_index=1, post_value=0x42 + ) ], ), BalStorageSlot( slot=0x02, slot_changes=[ - BalStorageChange(tx_index=1, post_value=0x43) + BalStorageChange( + block_access_index=1, post_value=0x43 + ) ], ), ], @@ -762,7 +804,9 @@ def test_bal_2930_slot_listed_and_unlisted_reads( expected_block_access_list=BlockAccessListExpectation( account_expectations={ alice: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)], + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ], ), storage_reader: BalAccountExpectation( storage_reads=[0x01, 0x02], @@ -806,10 +850,12 @@ def test_bal_self_transfer( expected_block_access_list=BlockAccessListExpectation( account_expectations={ alice: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)], + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ], balance_changes=[ BalBalanceChange( - tx_index=1, + block_access_index=1, post_balance=start_balance - intrinsic_gas_cost * int(tx.gas_price or 0), ) @@ -848,10 +894,12 @@ def test_bal_zero_value_transfer( expected_block_access_list=BlockAccessListExpectation( account_expectations={ alice: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)], + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ], balance_changes=[ BalBalanceChange( - tx_index=1, + block_access_index=1, post_balance=start_balance - intrinsic_gas_cost * int(tx.gas_price or 0), ) @@ -928,7 +976,9 @@ def test_bal_net_zero_balance_transfer( expected_block_access_list=BlockAccessListExpectation( account_expectations={ alice: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)], + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ], ), net_zero_bal_contract: BalAccountExpectation( # receives transfer_amount and sends transfer_amount away @@ -942,7 +992,7 @@ def test_bal_net_zero_balance_transfer( slot=0x00, slot_changes=[ BalStorageChange( - tx_index=1, + block_access_index=1, post_value=expected_balance_in_slot, ) ], @@ -955,7 +1005,7 @@ def test_bal_net_zero_balance_transfer( recipient: BalAccountExpectation( balance_changes=[ BalBalanceChange( - tx_index=1, post_balance=transfer_amount + block_access_index=1, post_balance=transfer_amount ) ] if transfer_amount > 0 @@ -1003,7 +1053,9 @@ def test_bal_pure_contract_call( expected_block_access_list=BlockAccessListExpectation( account_expectations={ alice: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)], + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ], ), # Ensure called contract is tracked pure_contract: BalAccountExpectation.empty(), @@ -1044,7 +1096,9 @@ def test_bal_noop_storage_write( expected_block_access_list=BlockAccessListExpectation( account_expectations={ alice: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)], + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ], ), storage_contract: BalAccountExpectation( storage_reads=[0x01], @@ -1083,7 +1137,9 @@ def test_bal_aborted_storage_access( expected_block_access_list=BlockAccessListExpectation( account_expectations={ alice: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)] + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ] ), storage_contract: BalAccountExpectation( storage_changes=[], @@ -1165,7 +1221,9 @@ def test_bal_aborted_account_access( expected_block_access_list=BlockAccessListExpectation( account_expectations={ alice: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)] + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ] ), target_contract: BalAccountExpectation.empty(), abort_contract: BalAccountExpectation.empty(), @@ -1207,7 +1265,9 @@ def test_bal_fully_unmutated_account( expected_block_access_list=BlockAccessListExpectation( account_expectations={ alice: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)], + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ], ), oracle: BalAccountExpectation( storage_changes=[], # No net storage changes @@ -1295,16 +1355,19 @@ def test_bal_coinbase_zero_tip( expected_block_access_list=BlockAccessListExpectation( account_expectations={ alice: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)], + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ], balance_changes=[ BalBalanceChange( - tx_index=1, post_balance=alice_final_balance + block_access_index=1, + post_balance=alice_final_balance, ) ], ), bob: BalAccountExpectation( balance_changes=[ - BalBalanceChange(tx_index=1, post_balance=5) + BalBalanceChange(block_access_index=1, post_balance=5) ] ), # Coinbase must be included even with zero tip @@ -1418,11 +1481,15 @@ def test_bal_precompile_funded( expected_block_access_list=BlockAccessListExpectation( account_expectations={ alice: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)], + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ], ), precompile: BalAccountExpectation( balance_changes=[ - BalBalanceChange(tx_index=1, post_balance=value) + BalBalanceChange( + block_access_index=1, post_balance=value + ) ] if value > 0 else [], @@ -1480,7 +1547,9 @@ def test_bal_precompile_call( expected_block_access_list=BlockAccessListExpectation( account_expectations={ alice: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)], + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ], ), oracle: BalAccountExpectation.empty(), precompile: BalAccountExpectation.empty(), @@ -1529,11 +1598,15 @@ def test_bal_nonexistent_value_transfer( expected_block_access_list=BlockAccessListExpectation( account_expectations={ alice: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)], + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ], ), bob: BalAccountExpectation( balance_changes=[ - BalBalanceChange(tx_index=1, post_balance=value) + BalBalanceChange( + block_access_index=1, post_balance=value + ) ] if value > 0 else [], @@ -1611,7 +1684,9 @@ def test_bal_nonexistent_account_access_read_only( expected_block_access_list=BlockAccessListExpectation( account_expectations={ alice: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)], + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ], ), oracle: BalAccountExpectation.empty(), bob: BalAccountExpectation.empty(), @@ -1696,12 +1771,15 @@ def test_bal_nonexistent_account_access_value_transfer( expected_block_access_list=BlockAccessListExpectation( account_expectations={ alice: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)], + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ], ), oracle: BalAccountExpectation( balance_changes=[ BalBalanceChange( - tx_index=1, post_balance=oracle_final_balance + block_access_index=1, + post_balance=oracle_final_balance, ) ] if oracle_has_balance_change @@ -1710,7 +1788,8 @@ def test_bal_nonexistent_account_access_value_transfer( bob: BalAccountExpectation( balance_changes=[ BalBalanceChange( - tx_index=1, post_balance=bob_final_balance + block_access_index=1, + post_balance=bob_final_balance, ) ] if bob_has_balance_change @@ -1786,20 +1865,24 @@ def test_bal_multiple_balance_changes_same_account( account_expectations={ alice: BalAccountExpectation( nonce_changes=[ - BalNonceChange(tx_index=1, post_nonce=1) + BalNonceChange( + block_access_index=1, post_nonce=1 + ) ], ), bob: BalAccountExpectation( nonce_changes=[ - BalNonceChange(tx_index=2, post_nonce=1) + BalNonceChange( + block_access_index=2, post_nonce=1 + ) ], balance_changes=[ BalBalanceChange( - tx_index=1, + block_access_index=1, post_balance=bob_balance_after_tx0, ), BalBalanceChange( - tx_index=2, + block_access_index=2, post_balance=bob_balance_after_tx1, ), ], @@ -1807,7 +1890,8 @@ def test_bal_multiple_balance_changes_same_account( charlie: BalAccountExpectation( balance_changes=[ BalBalanceChange( - tx_index=2, post_balance=spend_amount + block_access_index=2, + post_balance=spend_amount, ) ], ), @@ -1859,9 +1943,15 @@ def test_bal_multiple_storage_writes_same_slot( account_expectations={ alice: BalAccountExpectation( nonce_changes=[ - BalNonceChange(tx_index=1, post_nonce=1), - BalNonceChange(tx_index=2, post_nonce=2), - BalNonceChange(tx_index=3, post_nonce=3), + BalNonceChange( + block_access_index=1, post_nonce=1 + ), + BalNonceChange( + block_access_index=2, post_nonce=2 + ), + BalNonceChange( + block_access_index=3, post_nonce=3 + ), ], ), contract: BalAccountExpectation( @@ -1870,13 +1960,13 @@ def test_bal_multiple_storage_writes_same_slot( slot=1, slot_changes=[ BalStorageChange( - tx_index=1, post_value=1 + block_access_index=1, post_value=1 ), BalStorageChange( - tx_index=2, post_value=2 + block_access_index=2, post_value=2 ), BalStorageChange( - tx_index=3, post_value=3 + block_access_index=3, post_value=3 ), ], ), @@ -1960,7 +2050,7 @@ def test_bal_nested_delegatecall_storage_writes_net_zero( account_expectations = { alice: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)], + nonce_changes=[BalNonceChange(block_access_index=1, post_nonce=1)], ), root_contract: BalAccountExpectation( storage_reads=[0], @@ -2008,10 +2098,10 @@ def test_bal_create_transaction_empty_code( account_expectations = { alice: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)], + nonce_changes=[BalNonceChange(block_access_index=1, post_nonce=1)], ), contract_address: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)], + nonce_changes=[BalNonceChange(block_access_index=1, post_nonce=1)], code_changes=[], # ensure no code_changes recorded ), } @@ -2043,8 +2133,8 @@ def test_bal_cross_tx_storage_revert_to_zero( blobhash scenario where slot changes were being incorrectly filtered as net-zero across transaction boundaries. - Tx1: slot 0 = 0x0 -> 0xABCD (change recorded at tx_index=1) - Tx2: slot 0 = 0xABCD -> 0x0 (change MUST be recorded at tx_index=2) + Tx1: slot 0 = 0x0 -> 0xABCD (change at block_access_index=1) + Tx2: slot 0 = 0xABCD -> 0x0 (change MUST be at block_access_index=2) """ alice = pre.fund_eoa() @@ -2070,8 +2160,8 @@ def test_bal_cross_tx_storage_revert_to_zero( account_expectations = { alice: BalAccountExpectation( nonce_changes=[ - BalNonceChange(tx_index=1, post_nonce=1), - BalNonceChange(tx_index=2, post_nonce=2), + BalNonceChange(block_access_index=1, post_nonce=1), + BalNonceChange(block_access_index=2, post_nonce=2), ], ), contract: BalAccountExpectation( @@ -2079,10 +2169,12 @@ def test_bal_cross_tx_storage_revert_to_zero( BalStorageSlot( slot=0, slot_changes=[ - BalStorageChange(tx_index=1, post_value=0xABCD), + BalStorageChange( + block_access_index=1, post_value=0xABCD + ), # CRITICAL: tx2's write to 0x0 MUST appear # even though it returns slot to original value - BalStorageChange(tx_index=2, post_value=0x0), + BalStorageChange(block_access_index=2, post_value=0x0), ], ), ], @@ -2163,7 +2255,9 @@ def test_bal_cross_block_ripemd160_state_leak( expected_block_access_list=BlockAccessListExpectation( account_expectations={ alice: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)] + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ] ), bob: None, ripemd_caller: BalAccountExpectation.empty(), @@ -2187,7 +2281,9 @@ def test_bal_cross_block_ripemd160_state_leak( account_expectations={ alice: None, bob: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)] + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ] ), # this is the important check ripemd160_addr: None, @@ -2321,23 +2417,33 @@ def test_bal_all_transaction_types( account_expectations={ # Type 0 sender sender_0: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)], + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ], ), # Type 1 sender sender_1: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=2, post_nonce=1)], + nonce_changes=[ + BalNonceChange(block_access_index=2, post_nonce=1) + ], ), # Type 2 sender sender_2: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=3, post_nonce=1)], + nonce_changes=[ + BalNonceChange(block_access_index=3, post_nonce=1) + ], ), # Type 3 sender sender_3: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=4, post_nonce=1)], + nonce_changes=[ + BalNonceChange(block_access_index=4, post_nonce=1) + ], ), # Type 4 sender sender_4: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=5, post_nonce=1)], + nonce_changes=[ + BalNonceChange(block_access_index=5, post_nonce=1) + ], ), # Contract touched by Type 0 contract_0: BalAccountExpectation( @@ -2345,7 +2451,9 @@ def test_bal_all_transaction_types( BalStorageSlot( slot=0x01, slot_changes=[ - BalStorageChange(tx_index=1, post_value=0x01) + BalStorageChange( + block_access_index=1, post_value=0x01 + ) ], ) ], @@ -2356,7 +2464,9 @@ def test_bal_all_transaction_types( BalStorageSlot( slot=0x01, slot_changes=[ - BalStorageChange(tx_index=2, post_value=0x02) + BalStorageChange( + block_access_index=2, post_value=0x02 + ) ], ) ], @@ -2370,7 +2480,9 @@ def test_bal_all_transaction_types( BalStorageSlot( slot=0x01, slot_changes=[ - BalStorageChange(tx_index=3, post_value=0x03) + BalStorageChange( + block_access_index=3, post_value=0x03 + ) ], ) ], @@ -2381,17 +2493,21 @@ def test_bal_all_transaction_types( BalStorageSlot( slot=0x01, slot_changes=[ - BalStorageChange(tx_index=4, post_value=0x04) + BalStorageChange( + block_access_index=4, post_value=0x04 + ) ], ) ], ), # Alice (Type 4 delegation target, executes oracle code) alice: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=5, post_nonce=1)], + nonce_changes=[ + BalNonceChange(block_access_index=5, post_nonce=1) + ], code_changes=[ BalCodeChange( - tx_index=5, + block_access_index=5, new_code=Spec7702.delegation_designation(oracle), ) ], @@ -2399,7 +2515,9 @@ def test_bal_all_transaction_types( BalStorageSlot( slot=0x01, slot_changes=[ - BalStorageChange(tx_index=5, post_value=0x05) + BalStorageChange( + block_access_index=5, post_value=0x05 + ) ], ) ], @@ -2507,7 +2625,9 @@ def test_bal_lexicographic_address_ordering( expected_block_access_list=BlockAccessListExpectation( account_expectations={ alice: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)], + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ], ), contract: BalAccountExpectation.empty(), # These addresses appear in BAL due to BALANCE access diff --git a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_cross_index.py b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_cross_index.py index 72ac91c923..9d32fdf123 100644 --- a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_cross_index.py +++ b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_cross_index.py @@ -82,12 +82,12 @@ def test_bal_withdrawal_contract_cross_index( slot_changes=[ BalStorageChange( # Incremented during tx - tx_index=1, + block_access_index=1, post_value=1, ), BalStorageChange( # Reset during post-exec - tx_index=2, + block_access_index=2, post_value=0, ), ], @@ -97,12 +97,12 @@ def test_bal_withdrawal_contract_cross_index( slot_changes=[ BalStorageChange( # Incremented during tx - tx_index=1, + block_access_index=1, post_value=1, ), BalStorageChange( # Reset during post-exec - tx_index=2, + block_access_index=2, post_value=0, ), ], @@ -154,12 +154,12 @@ def test_bal_consolidation_contract_cross_index( slot_changes=[ BalStorageChange( # Incremented during tx - tx_index=1, + block_access_index=1, post_value=1, ), BalStorageChange( # Reset during post-exec - tx_index=2, + block_access_index=2, post_value=0, ), ], @@ -169,12 +169,12 @@ def test_bal_consolidation_contract_cross_index( slot_changes=[ BalStorageChange( # Incremented during tx - tx_index=1, + block_access_index=1, post_value=1, ), BalStorageChange( # Reset during post-exec - tx_index=2, + block_access_index=2, post_value=0, ), ], @@ -232,13 +232,17 @@ def test_bal_noop_write_filtering( BalStorageSlot( slot=2, slot_changes=[ - BalStorageChange(tx_index=1, post_value=42), + BalStorageChange( + block_access_index=1, post_value=42 + ), ], ), BalStorageSlot( slot=4, slot_changes=[ - BalStorageChange(tx_index=1, post_value=200), + BalStorageChange( + block_access_index=1, post_value=200 + ), ], ), ], diff --git a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_eip4895.py b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_eip4895.py index 16ce09ff90..df35ba66ef 100644 --- a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_eip4895.py +++ b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_eip4895.py @@ -62,7 +62,9 @@ def test_bal_withdrawal_empty_block( account_expectations={ charlie: BalAccountExpectation( balance_changes=[ - BalBalanceChange(tx_index=1, post_balance=11 * GWEI) + BalBalanceChange( + block_access_index=1, post_balance=11 * GWEI + ) ], ), } @@ -115,16 +117,20 @@ def test_bal_withdrawal_and_transaction( expected_block_access_list=BlockAccessListExpectation( account_expectations={ alice: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)], + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ], ), bob: BalAccountExpectation( balance_changes=[ - BalBalanceChange(tx_index=1, post_balance=5) + BalBalanceChange(block_access_index=1, post_balance=5) ], ), charlie: BalAccountExpectation( balance_changes=[ - BalBalanceChange(tx_index=2, post_balance=10 * GWEI) + BalBalanceChange( + block_access_index=2, post_balance=10 * GWEI + ) ], ), } @@ -169,7 +175,9 @@ def test_bal_withdrawal_to_nonexistent_account( account_expectations={ charlie: BalAccountExpectation( balance_changes=[ - BalBalanceChange(tx_index=1, post_balance=10 * GWEI) + BalBalanceChange( + block_access_index=1, post_balance=10 * GWEI + ) ], ), } @@ -216,7 +224,9 @@ def test_bal_withdrawal_no_evm_execution( account_expectations={ oracle: BalAccountExpectation( balance_changes=[ - BalBalanceChange(tx_index=1, post_balance=10 * GWEI) + BalBalanceChange( + block_access_index=1, post_balance=10 * GWEI + ) ], storage_reads=[], storage_changes=[], @@ -275,7 +285,9 @@ def test_bal_withdrawal_and_state_access_same_account( expected_block_access_list=BlockAccessListExpectation( account_expectations={ alice: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)], + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ], ), oracle: BalAccountExpectation( storage_reads=[0x01], @@ -283,12 +295,16 @@ def test_bal_withdrawal_and_state_access_same_account( BalStorageSlot( slot=0x02, slot_changes=[ - BalStorageChange(tx_index=1, post_value=0x99) + BalStorageChange( + block_access_index=1, post_value=0x99 + ) ], ) ], balance_changes=[ - BalBalanceChange(tx_index=2, post_balance=10 * GWEI) + BalBalanceChange( + block_access_index=2, post_balance=10 * GWEI + ) ], ), } @@ -343,12 +359,18 @@ def test_bal_withdrawal_and_value_transfer_same_address( expected_block_access_list=BlockAccessListExpectation( account_expectations={ alice: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)], + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ], ), bob: BalAccountExpectation( balance_changes=[ - BalBalanceChange(tx_index=1, post_balance=5 * GWEI), - BalBalanceChange(tx_index=2, post_balance=15 * GWEI), + BalBalanceChange( + block_access_index=1, post_balance=5 * GWEI + ), + BalBalanceChange( + block_access_index=2, post_balance=15 * GWEI + ), ], ), } @@ -388,7 +410,9 @@ def test_bal_multiple_withdrawals_same_address( account_expectations={ charlie: BalAccountExpectation( balance_changes=[ - BalBalanceChange(tx_index=1, post_balance=30 * GWEI) + BalBalanceChange( + block_access_index=1, post_balance=30 * GWEI + ) ], ), } @@ -443,17 +467,23 @@ def test_bal_withdrawal_and_selfdestruct( expected_block_access_list=BlockAccessListExpectation( account_expectations={ alice: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)], + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ], ), bob: BalAccountExpectation( balance_changes=[ - BalBalanceChange(tx_index=1, post_balance=100 * GWEI) + BalBalanceChange( + block_access_index=1, post_balance=100 * GWEI + ) ], ), oracle: BalAccountExpectation( balance_changes=[ - BalBalanceChange(tx_index=1, post_balance=0), - BalBalanceChange(tx_index=2, post_balance=50 * GWEI), + BalBalanceChange(block_access_index=1, post_balance=0), + BalBalanceChange( + block_access_index=2, post_balance=50 * GWEI + ), ], ), } @@ -510,13 +540,21 @@ def test_bal_withdrawal_and_new_contract( expected_block_access_list=BlockAccessListExpectation( account_expectations={ alice: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)], + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ], ), oracle: BalAccountExpectation( - code_changes=[BalCodeChange(tx_index=1, new_code=code)], + code_changes=[ + BalCodeChange(block_access_index=1, new_code=code) + ], balance_changes=[ - BalBalanceChange(tx_index=1, post_balance=5 * GWEI), - BalBalanceChange(tx_index=2, post_balance=15 * GWEI), + BalBalanceChange( + block_access_index=1, post_balance=5 * GWEI + ), + BalBalanceChange( + block_access_index=2, post_balance=15 * GWEI + ), ], ), } @@ -621,7 +659,9 @@ def test_bal_withdrawal_to_precompiles( account_expectations={ precompile: BalAccountExpectation( balance_changes=[ - BalBalanceChange(tx_index=1, post_balance=10 * GWEI) + BalBalanceChange( + block_access_index=1, post_balance=10 * GWEI + ) ], storage_reads=[], storage_changes=[], @@ -668,7 +708,8 @@ def test_bal_withdrawal_largest_amount( charlie: BalAccountExpectation( balance_changes=[ BalBalanceChange( - tx_index=1, post_balance=max_amount * GWEI + block_access_index=1, + post_balance=max_amount * GWEI, ) ], ), @@ -738,20 +779,23 @@ def test_bal_withdrawal_to_coinbase( expected_block_access_list=BlockAccessListExpectation( account_expectations={ alice: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)], + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ], ), bob: BalAccountExpectation( balance_changes=[ - BalBalanceChange(tx_index=1, post_balance=5) + BalBalanceChange(block_access_index=1, post_balance=5) ], ), coinbase: BalAccountExpectation( balance_changes=[ BalBalanceChange( - tx_index=1, post_balance=tip_to_coinbase + block_access_index=1, post_balance=tip_to_coinbase ), BalBalanceChange( - tx_index=2, post_balance=coinbase_final_balance + block_access_index=2, + post_balance=coinbase_final_balance, ), ], ), @@ -798,7 +842,9 @@ def test_bal_withdrawal_to_coinbase_empty_block( account_expectations={ coinbase: BalAccountExpectation( balance_changes=[ - BalBalanceChange(tx_index=1, post_balance=10 * GWEI) + BalBalanceChange( + block_access_index=1, post_balance=10 * GWEI + ) ], ), } diff --git a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_eip7702.py b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_eip7702.py index a0a6a1e121..009b3550c2 100644 --- a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_eip7702.py +++ b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_eip7702.py @@ -70,17 +70,21 @@ def test_bal_7702_delegation_create( account_expectations = { alice: BalAccountExpectation( nonce_changes=[ - BalNonceChange(tx_index=1, post_nonce=2 if self_funded else 1) + BalNonceChange( + block_access_index=1, post_nonce=2 if self_funded else 1 + ) ], code_changes=[ BalCodeChange( - tx_index=1, + block_access_index=1, new_code=Spec7702.delegation_designation(oracle), ) ], ), bob: BalAccountExpectation( - balance_changes=[BalBalanceChange(tx_index=1, post_balance=10)] + balance_changes=[ + BalBalanceChange(block_access_index=1, post_balance=10) + ] ), # Oracle must not be present in BAL - the account is never accessed oracle: None, @@ -89,7 +93,7 @@ def test_bal_7702_delegation_create( # For sponsored variant, relayer must also be included in BAL if not self_funded: account_expectations[relayer] = BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)], + nonce_changes=[BalNonceChange(block_access_index=1, post_nonce=1)], ) block = Block( @@ -181,24 +185,28 @@ def test_bal_7702_delegation_update( account_expectations = { alice: BalAccountExpectation( nonce_changes=[ - BalNonceChange(tx_index=1, post_nonce=2 if self_funded else 1), - BalNonceChange(tx_index=2, post_nonce=4 if self_funded else 2), + BalNonceChange( + block_access_index=1, post_nonce=2 if self_funded else 1 + ), + BalNonceChange( + block_access_index=2, post_nonce=4 if self_funded else 2 + ), ], code_changes=[ BalCodeChange( - tx_index=1, + block_access_index=1, new_code=Spec7702.delegation_designation(oracle1), ), BalCodeChange( - tx_index=2, + block_access_index=2, new_code=Spec7702.delegation_designation(oracle2), ), ], ), bob: BalAccountExpectation( balance_changes=[ - BalBalanceChange(tx_index=1, post_balance=10), - BalBalanceChange(tx_index=2, post_balance=20), + BalBalanceChange(block_access_index=1, post_balance=10), + BalBalanceChange(block_access_index=2, post_balance=20), ] ), # Both delegation targets must not be present in BAL @@ -211,8 +219,8 @@ def test_bal_7702_delegation_update( if not self_funded: account_expectations[relayer] = BalAccountExpectation( nonce_changes=[ - BalNonceChange(tx_index=1, post_nonce=1), - BalNonceChange(tx_index=2, post_nonce=2), + BalNonceChange(block_access_index=1, post_nonce=1), + BalNonceChange(block_access_index=2, post_nonce=2), ], ) @@ -306,21 +314,25 @@ def test_bal_7702_delegation_clear( account_expectations = { alice: BalAccountExpectation( nonce_changes=[ - BalNonceChange(tx_index=1, post_nonce=2 if self_funded else 1), - BalNonceChange(tx_index=2, post_nonce=4 if self_funded else 2), + BalNonceChange( + block_access_index=1, post_nonce=2 if self_funded else 1 + ), + BalNonceChange( + block_access_index=2, post_nonce=4 if self_funded else 2 + ), ], code_changes=[ BalCodeChange( - tx_index=1, + block_access_index=1, new_code=Spec7702.delegation_designation(oracle), ), - BalCodeChange(tx_index=2, new_code=""), + BalCodeChange(block_access_index=2, new_code=""), ], ), bob: BalAccountExpectation( balance_changes=[ - BalBalanceChange(tx_index=1, post_balance=10), - BalBalanceChange(tx_index=2, post_balance=20), + BalBalanceChange(block_access_index=1, post_balance=10), + BalBalanceChange(block_access_index=2, post_balance=20), ] ), # Both delegation targets must not be present in BAL @@ -333,8 +345,8 @@ def test_bal_7702_delegation_clear( if not self_funded: account_expectations[relayer] = BalAccountExpectation( nonce_changes=[ - BalNonceChange(tx_index=1, post_nonce=1), - BalNonceChange(tx_index=2, post_nonce=2), + BalNonceChange(block_access_index=1, post_nonce=1), + BalNonceChange(block_access_index=2, post_nonce=2), ], ) @@ -395,20 +407,24 @@ def test_bal_7702_delegated_storage_access( account_expectations={ alice: BalAccountExpectation( balance_changes=[ - BalBalanceChange(tx_index=1, post_balance=10) + BalBalanceChange(block_access_index=1, post_balance=10) ], storage_changes=[ BalStorageSlot( slot=0x02, slot_changes=[ - BalStorageChange(tx_index=1, post_value=0x42) + BalStorageChange( + block_access_index=1, post_value=0x42 + ) ], ) ], storage_reads=[0x01], ), bob: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)], + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ], ), # Oracle appears in BAL due to account access # (delegation target) @@ -464,11 +480,13 @@ def test_bal_7702_invalid_nonce_authorization( # Ensuring silent fail bob: BalAccountExpectation( balance_changes=[ - BalBalanceChange(tx_index=1, post_balance=10) + BalBalanceChange(block_access_index=1, post_balance=10) ] ), relayer: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)], + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ], ), # Alice's account was marked warm but no changes were made alice: BalAccountExpectation.empty(), @@ -527,11 +545,13 @@ def test_bal_7702_invalid_chain_id_authorization( # Ensuring silent fail bob: BalAccountExpectation( balance_changes=[ - BalBalanceChange(tx_index=1, post_balance=10) + BalBalanceChange(block_access_index=1, post_balance=10) ] ), relayer: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)], + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ], ), # Oracle must NOT be present - authorization failed so # account never accessed @@ -592,7 +612,9 @@ def test_bal_7702_delegated_via_call_opcode( expected_block_access_list=BlockAccessListExpectation( account_expectations={ bob: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)], + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ], ), caller: BalAccountExpectation.empty(), # `alice` is accessed due to being the call target @@ -641,11 +663,13 @@ def test_bal_7702_null_address_delegation_no_code_change( # because setting code from b"" to b"" is a net-zero change account_expectations = { alice: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=2)], + nonce_changes=[BalNonceChange(block_access_index=1, post_nonce=2)], code_changes=[], # explicit check for no code changes ), bob: BalAccountExpectation( - balance_changes=[BalBalanceChange(tx_index=1, post_balance=10)] + balance_changes=[ + BalBalanceChange(block_access_index=1, post_balance=10) + ] ), } @@ -720,18 +744,24 @@ def test_bal_7702_double_auth_reset( account_expectations={ alice: BalAccountExpectation( nonce_changes=[ - BalNonceChange(tx_index=1, post_nonce=2) + BalNonceChange( + block_access_index=1, post_nonce=2 + ) ], code_changes=[], ), bob: BalAccountExpectation( balance_changes=[ - BalBalanceChange(tx_index=1, post_balance=10) + BalBalanceChange( + block_access_index=1, post_balance=10 + ) ] ), relayer: BalAccountExpectation( nonce_changes=[ - BalNonceChange(tx_index=1, post_nonce=1) + BalNonceChange( + block_access_index=1, post_nonce=1 + ) ], ), contract_a: None, @@ -791,20 +821,22 @@ def test_bal_7702_double_auth_swap( account_expectations = { alice: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=2)], + nonce_changes=[BalNonceChange(block_access_index=1, post_nonce=2)], code_changes=[ # Should show final code (CONTRACT_B), not CONTRACT_A BalCodeChange( - tx_index=1, + block_access_index=1, new_code=Spec7702.delegation_designation(contract_b), ) ], ), bob: BalAccountExpectation( - balance_changes=[BalBalanceChange(tx_index=1, post_balance=10)] + balance_changes=[ + BalBalanceChange(block_access_index=1, post_balance=10) + ] ), relayer: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)], + nonce_changes=[BalNonceChange(block_access_index=1, post_nonce=1)], ), # Neither contract appears in BAL during delegation setup contract_a: None, @@ -901,25 +933,29 @@ def test_bal_selfdestruct_to_7702_delegation( account_expectations = { alice: BalAccountExpectation( # tx1: nonce change for auth, code change for delegation - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)], + nonce_changes=[BalNonceChange(block_access_index=1, post_nonce=1)], code_changes=[ BalCodeChange( - tx_index=1, + block_access_index=1, new_code=Spec7702.delegation_designation(oracle), ) ], # tx2: balance change from selfdestruct balance_changes=[ - BalBalanceChange(tx_index=2, post_balance=alice_final_balance) + BalBalanceChange( + block_access_index=2, post_balance=alice_final_balance + ) ], ), bob: BalAccountExpectation( - balance_changes=[BalBalanceChange(tx_index=1, post_balance=10)] + balance_changes=[ + BalBalanceChange(block_access_index=1, post_balance=10) + ] ), relayer: BalAccountExpectation( nonce_changes=[ - BalNonceChange(tx_index=1, post_nonce=1), - BalNonceChange(tx_index=2, post_nonce=2), + BalNonceChange(block_access_index=1, post_nonce=1), + BalNonceChange(block_access_index=2, post_nonce=2), ], ), caller: BalAccountExpectation.empty(), @@ -927,7 +963,9 @@ def test_bal_selfdestruct_to_7702_delegation( # Explicitly verify ALL fields to avoid false positives victim: BalAccountExpectation( nonce_changes=[], # Contract nonce unchanged - balance_changes=[BalBalanceChange(tx_index=2, post_balance=0)], + balance_changes=[ + BalBalanceChange(block_access_index=2, post_balance=0) + ], code_changes=[], # Code unchanged (post-Cancun SELFDESTRUCT) storage_changes=[], # No storage changes storage_reads=[], # No storage reads @@ -1018,23 +1056,27 @@ def test_bal_withdrawal_to_7702_delegation( account_expectations = { alice: BalAccountExpectation( # tx1: nonce change for auth, code change for delegation - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)], + nonce_changes=[BalNonceChange(block_access_index=1, post_nonce=1)], code_changes=[ BalCodeChange( - tx_index=1, + block_access_index=1, new_code=Spec7702.delegation_designation(oracle), ) ], # tx2 (withdrawal): balance change balance_changes=[ - BalBalanceChange(tx_index=2, post_balance=alice_final_balance) + BalBalanceChange( + block_access_index=2, post_balance=alice_final_balance + ) ], ), bob: BalAccountExpectation( - balance_changes=[BalBalanceChange(tx_index=1, post_balance=10)] + balance_changes=[ + BalBalanceChange(block_access_index=1, post_balance=10) + ] ), relayer: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)], + nonce_changes=[BalNonceChange(block_access_index=1, post_nonce=1)], ), # Oracle MUST NOT appear - withdrawals don't execute recipient code, # so delegation target is never accessed diff --git a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_invalid.py b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_invalid.py index d94f7eaed4..13d18c7fef 100644 --- a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_invalid.py +++ b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_invalid.py @@ -75,7 +75,9 @@ def test_bal_invalid_missing_nonce( account_expectations={ sender: BalAccountExpectation( nonce_changes=[ - BalNonceChange(tx_index=1, post_nonce=1) + BalNonceChange( + block_access_index=1, post_nonce=1 + ) ], ), } @@ -118,11 +120,13 @@ def test_bal_invalid_nonce_value( account_expectations={ sender: BalAccountExpectation( nonce_changes=[ - BalNonceChange(tx_index=1, post_nonce=1) + BalNonceChange( + block_access_index=1, post_nonce=1 + ) ], ), } - ).modify(modify_nonce(sender, tx_index=1, nonce=42)), + ).modify(modify_nonce(sender, block_access_index=1, nonce=42)), ) ], ) @@ -171,7 +175,8 @@ def test_bal_invalid_storage_value( slot=0x01, slot_changes=[ BalStorageChange( - tx_index=1, post_value=0x01 + block_access_index=1, + post_value=0x01, ) ], ), @@ -179,7 +184,8 @@ def test_bal_invalid_storage_value( slot=0x02, slot_changes=[ BalStorageChange( - tx_index=1, post_value=0x02 + block_access_index=1, + post_value=0x02, ) ], ), @@ -187,7 +193,8 @@ def test_bal_invalid_storage_value( slot=0x03, slot_changes=[ BalStorageChange( - tx_index=1, post_value=0x03 + block_access_index=1, + post_value=0x03, ) ], ), @@ -196,7 +203,9 @@ def test_bal_invalid_storage_value( } ).modify( # Corrupt storage value for slot 0x02 - modify_storage(contract, tx_index=1, slot=0x02, value=0xFF) + modify_storage( + contract, block_access_index=1, slot=0x02, value=0xFF + ) ), ) ], @@ -246,21 +255,26 @@ def test_bal_invalid_tx_order( account_expectations={ sender1: BalAccountExpectation( nonce_changes=[ - BalNonceChange(tx_index=1, post_nonce=1) + BalNonceChange( + block_access_index=1, post_nonce=1 + ) ], ), sender2: BalAccountExpectation( nonce_changes=[ - BalNonceChange(tx_index=2, post_nonce=1) + BalNonceChange( + block_access_index=2, post_nonce=1 + ) ], ), receiver: BalAccountExpectation( balance_changes=[ BalBalanceChange( - tx_index=1, post_balance=10**15 + block_access_index=1, post_balance=10**15 ), BalBalanceChange( - tx_index=2, post_balance=3 * 10**15 + block_access_index=2, + post_balance=3 * 10**15, ), ], ), @@ -307,7 +321,9 @@ def test_bal_invalid_account( account_expectations={ sender: BalAccountExpectation( nonce_changes=[ - BalNonceChange(tx_index=1, post_nonce=1) + BalNonceChange( + block_access_index=1, post_nonce=1 + ) ], ), } @@ -316,7 +332,9 @@ def test_bal_invalid_account( BalAccountChange( address=phantom, nonce_changes=[ - BalNonceChange(tx_index=1, post_nonce=1) + BalNonceChange( + block_access_index=1, post_nonce=1 + ) ], ) ) @@ -360,13 +378,15 @@ def test_bal_invalid_duplicate_account( account_expectations={ sender: BalAccountExpectation( nonce_changes=[ - BalNonceChange(tx_index=1, post_nonce=1) + BalNonceChange( + block_access_index=1, post_nonce=1 + ) ], ), receiver: BalAccountExpectation( balance_changes=[ BalBalanceChange( - tx_index=1, post_balance=10**15 + block_access_index=1, post_balance=10**15 ) ], ), @@ -410,13 +430,15 @@ def test_bal_invalid_account_order( account_expectations={ sender: BalAccountExpectation( nonce_changes=[ - BalNonceChange(tx_index=1, post_nonce=1) + BalNonceChange( + block_access_index=1, post_nonce=1 + ) ], ), receiver: BalAccountExpectation( balance_changes=[ BalBalanceChange( - tx_index=1, post_balance=10**15 + block_access_index=1, post_balance=10**15 ) ], ), @@ -471,8 +493,12 @@ def test_bal_invalid_complex_corruption( account_expectations={ sender: BalAccountExpectation( nonce_changes=[ - BalNonceChange(tx_index=1, post_nonce=1), - BalNonceChange(tx_index=2, post_nonce=2), + BalNonceChange( + block_access_index=1, post_nonce=1 + ), + BalNonceChange( + block_access_index=2, post_nonce=2 + ), ], ), contract: BalAccountExpectation( @@ -481,7 +507,8 @@ def test_bal_invalid_complex_corruption( slot=0x01, slot_changes=[ BalStorageChange( - tx_index=1, post_value=0x01 + block_access_index=1, + post_value=0x01, ) ], ), @@ -489,7 +516,8 @@ def test_bal_invalid_complex_corruption( slot=0x02, slot_changes=[ BalStorageChange( - tx_index=1, post_value=0x02 + block_access_index=1, + post_value=0x02, ) ], ), @@ -498,7 +526,7 @@ def test_bal_invalid_complex_corruption( receiver: BalAccountExpectation( balance_changes=[ BalBalanceChange( - tx_index=2, post_balance=10**15 + block_access_index=2, post_balance=10**15 ) ], ), @@ -506,7 +534,7 @@ def test_bal_invalid_complex_corruption( ).modify( remove_nonces(sender), modify_storage( - contract, tx_index=1, slot=0x01, value=0xFF + contract, block_access_index=1, slot=0x01, value=0xFF ), remove_balances(receiver), swap_tx_indices(1, 2), @@ -549,13 +577,15 @@ def test_bal_invalid_missing_account( account_expectations={ sender: BalAccountExpectation( nonce_changes=[ - BalNonceChange(tx_index=1, post_nonce=1) + BalNonceChange( + block_access_index=1, post_nonce=1 + ) ], ), receiver: BalAccountExpectation( balance_changes=[ BalBalanceChange( - tx_index=1, post_balance=10**15 + block_access_index=1, post_balance=10**15 ) ], ), @@ -600,12 +630,16 @@ def test_bal_invalid_balance_value( receiver: BalAccountExpectation( balance_changes=[ BalBalanceChange( - tx_index=1, post_balance=10**15 + block_access_index=1, post_balance=10**15 ) ], ), } - ).modify(modify_balance(receiver, tx_index=1, balance=999999)), + ).modify( + modify_balance( + receiver, block_access_index=1, balance=999999 + ) + ), ) ], ) diff --git a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_opcodes.py b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_opcodes.py index 9e2355b93e..7a07299407 100644 --- a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_opcodes.py +++ b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_opcodes.py @@ -168,7 +168,9 @@ def test_bal_sstore_and_oog( BalStorageSlot( slot=0x01, slot_changes=[ - BalStorageChange(tx_index=1, post_value=0x42) + BalStorageChange( + block_access_index=1, post_value=0x42 + ) ], ), ] @@ -505,11 +507,13 @@ def test_bal_call_no_delegation_and_oog_before_target_access( elif value > 0: account_expectations = { caller: BalAccountExpectation( - balance_changes=[BalBalanceChange(tx_index=1, post_balance=0)] + balance_changes=[ + BalBalanceChange(block_access_index=1, post_balance=0) + ] ), target: BalAccountExpectation( balance_changes=[ - BalBalanceChange(tx_index=1, post_balance=value) + BalBalanceChange(block_access_index=1, post_balance=value) ] ), } @@ -783,7 +787,9 @@ def test_bal_call_7702_delegation_and_oog( account_expectations: Dict[Address, BalAccountExpectation | None] = { caller: ( BalAccountExpectation( - balance_changes=[BalBalanceChange(tx_index=1, post_balance=0)] + balance_changes=[ + BalBalanceChange(block_access_index=1, post_balance=0) + ] ) if value_transferred else BalAccountExpectation.empty() @@ -797,7 +803,7 @@ def test_bal_call_7702_delegation_and_oog( if value_transferred: account_expectations[target] = BalAccountExpectation( balance_changes=[ - BalBalanceChange(tx_index=1, post_balance=value) + BalBalanceChange(block_access_index=1, post_balance=value) ] ) else: @@ -1797,18 +1803,21 @@ def test_bal_self_destruct( expected_block_access_list=BlockAccessListExpectation( account_expectations={ alice: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)], + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ], ), bob: BalAccountExpectation( balance_changes=[ BalBalanceChange( - tx_index=1, post_balance=expected_recipient_balance + block_access_index=1, + post_balance=expected_recipient_balance, ) ] ), self_destructed_account: BalAccountExpectation( balance_changes=[ - BalBalanceChange(tx_index=1, post_balance=0) + BalBalanceChange(block_access_index=1, post_balance=0) ] if pre_funded else [], @@ -1822,7 +1831,9 @@ def test_bal_self_destruct( BalStorageSlot( slot=0x02, slot_changes=[ - BalStorageChange(tx_index=1, post_value=0x42) + BalStorageChange( + block_access_index=1, post_value=0x42 + ) ], ) ] @@ -1935,7 +1946,7 @@ def test_bal_self_destruct_oog( account_expectations: Dict[Address, BalAccountExpectation | None] = { alice: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)], + nonce_changes=[BalNonceChange(block_access_index=1, post_nonce=1)], ), caller_contract: BalAccountExpectation.empty(), selfdestruct_contract: BalAccountExpectation.empty(), @@ -1996,14 +2007,18 @@ def test_bal_storage_write_read_same_frame( expected_block_access_list=BlockAccessListExpectation( account_expectations={ alice: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)], + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ], ), oracle: BalAccountExpectation( storage_changes=[ BalStorageSlot( slot=0x01, slot_changes=[ - BalStorageChange(tx_index=1, post_value=0x42) + BalStorageChange( + block_access_index=1, post_value=0x42 + ) ], ) ], @@ -2085,14 +2100,18 @@ def test_bal_storage_write_read_cross_frame( expected_block_access_list=BlockAccessListExpectation( account_expectations={ alice: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)], + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ], ), oracle: BalAccountExpectation( storage_changes=[ BalStorageSlot( slot=0x01, slot_changes=[ - BalStorageChange(tx_index=1, post_value=0x42) + BalStorageChange( + block_access_index=1, post_value=0x42 + ) ], ) ], @@ -2159,16 +2178,16 @@ def test_bal_create_oog_code_deposit( # nonce/code changes rolled back on OOG) account_expectations = { alice: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)], + nonce_changes=[BalNonceChange(block_access_index=1, post_nonce=1)], ), factory: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=2)], + nonce_changes=[BalNonceChange(block_access_index=1, post_nonce=2)], storage_changes=[ BalStorageSlot( slot=1, slot_changes=[ # SSTORE saves 0 (CREATE failed) - BalStorageChange(tx_index=1, post_value=0), + BalStorageChange(block_access_index=1, post_value=0), ], ) ], @@ -2240,7 +2259,9 @@ def test_bal_sstore_static_context( account_expectations={ alice: BalAccountExpectation( nonce_changes=[ - BalNonceChange(tx_index=1, post_nonce=1) + BalNonceChange( + block_access_index=1, post_nonce=1 + ) ], ), contract_a: BalAccountExpectation( @@ -2249,7 +2270,7 @@ def test_bal_sstore_static_context( slot=0x00, slot_changes=[ BalStorageChange( - tx_index=1, post_value=1 + block_access_index=1, post_value=1 ), ], ), @@ -2307,7 +2328,9 @@ def test_bal_create_contract_init_revert( account_expectations={ alice: BalAccountExpectation( nonce_changes=[ - BalNonceChange(tx_index=1, post_nonce=1) + BalNonceChange( + block_access_index=1, post_nonce=1 + ) ], ), caller: BalAccountExpectation.empty(), @@ -2386,7 +2409,9 @@ def test_bal_call_revert_insufficient_funds( expected_block_access_list=BlockAccessListExpectation( account_expectations={ alice: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)], + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ], ), contract: BalAccountExpectation( # Storage read for slot 0x01 @@ -2396,7 +2421,9 @@ def test_bal_call_revert_insufficient_funds( BalStorageSlot( slot=0x02, slot_changes=[ - BalStorageChange(tx_index=1, post_value=0) + BalStorageChange( + block_access_index=1, post_value=0 + ) ], ) ], @@ -2525,14 +2552,18 @@ def test_bal_create_selfdestruct_to_self_with_call( expected_block_access_list=BlockAccessListExpectation( account_expectations={ alice: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)], + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ], ), factory: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=2)], + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=2) + ], # Balance changes: loses endowment (100) balance_changes=[ BalBalanceChange( - tx_index=1, + block_access_index=1, post_balance=factory_balance - endowment, ) ], @@ -2543,7 +2574,9 @@ def test_bal_create_selfdestruct_to_self_with_call( BalStorageSlot( slot=0x01, slot_changes=[ - BalStorageChange(tx_index=1, post_value=0x42) + BalStorageChange( + block_access_index=1, post_value=0x42 + ) ], ) ], @@ -2646,17 +2679,23 @@ def test_bal_create2_collision( expected_block_access_list=BlockAccessListExpectation( account_expectations={ alice: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)], + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ], ), factory: BalAccountExpectation( # Nonce incremented 1→2 even on failed CREATE2 - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=2)], + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=2) + ], # Storage changes: slot 0 = 0xDEAD → 0 (CREATE2 returned 0) storage_changes=[ BalStorageSlot( slot=0x00, slot_changes=[ - BalStorageChange(tx_index=1, post_value=0) + BalStorageChange( + block_access_index=1, post_value=0 + ) ], ) ], @@ -2726,7 +2765,9 @@ def test_bal_transient_storage_not_tracked( expected_block_access_list=BlockAccessListExpectation( account_expectations={ alice: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)], + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ], ), contract: BalAccountExpectation( # Persistent storage change for slot 0x02 @@ -2734,7 +2775,9 @@ def test_bal_transient_storage_not_tracked( BalStorageSlot( slot=0x02, slot_changes=[ - BalStorageChange(tx_index=1, post_value=0x42) + BalStorageChange( + block_access_index=1, post_value=0x42 + ) ], ) ], @@ -2798,7 +2841,9 @@ def test_bal_selfdestruct_to_precompile( expected_block_access_list=BlockAccessListExpectation( account_expectations={ alice: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)], + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ], ), caller: BalAccountExpectation.empty(), # Victim (selfdestructing contract): balance changes 100→0 @@ -2806,7 +2851,7 @@ def test_bal_selfdestruct_to_precompile( victim: BalAccountExpectation( nonce_changes=[], # Contract nonce unchanged balance_changes=[ - BalBalanceChange(tx_index=1, post_balance=0) + BalBalanceChange(block_access_index=1, post_balance=0) ], code_changes=[], # Code unchanged (post-Cancun) storage_changes=[], # No storage changes @@ -2818,7 +2863,7 @@ def test_bal_selfdestruct_to_precompile( nonce_changes=[], # MUST NOT have nonce changes balance_changes=[ BalBalanceChange( - tx_index=1, post_balance=contract_balance + block_access_index=1, post_balance=contract_balance ) ], code_changes=[], # MUST NOT have code changes @@ -2907,7 +2952,9 @@ def test_bal_create_early_failure( expected_block_access_list=BlockAccessListExpectation( account_expectations={ alice: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)], + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ], ), factory: BalAccountExpectation( # NO nonce_changes - CREATE failed before increment_nonce @@ -2917,7 +2964,9 @@ def test_bal_create_early_failure( BalStorageSlot( slot=0x00, slot_changes=[ - BalStorageChange(tx_index=1, post_value=0) + BalStorageChange( + block_access_index=1, post_value=0 + ) ], ) ], diff --git a/tests/amsterdam/eip7928_block_level_access_lists/test_cases.md b/tests/amsterdam/eip7928_block_level_access_lists/test_cases.md index 77c298110b..0432339ead 100644 --- a/tests/amsterdam/eip7928_block_level_access_lists/test_cases.md +++ b/tests/amsterdam/eip7928_block_level_access_lists/test_cases.md @@ -23,9 +23,9 @@ | `test_bal_noop_storage_write` | Ensure BAL includes storage read but not write for no-op writes where pre-state equals post-state | Contract with pre-existing storage value `0x42` in slot `0x01`; transaction executes `SSTORE(0x01, 0x42)` (writing same value) | BAL **MUST** include the contract address with `storage_reads` for slot `0x01` since it was accessed, but **MUST NOT** include it in `storage_changes` (no actual state change). | ✅ Completed | | `test_bal_fully_unmutated_account` | Ensure BAL captures account that has zero net mutations | Alice sends 0 wei to `Oracle` which writes same pre-existing value to storage | BAL MUST include Alice with `nonce_changes` and balance changes (gas), `Oracle` with `storage_reads` for accessed slot but empty `storage_changes`. | ✅ Completed | | `test_bal_net_zero_balance_transfer` | BAL includes accounts with net-zero balance change but excludes them from balance changes | Contract receives and sends same amount to recipient using CALL or SELFDESTRUCT | BAL **MUST** include contract in `account_changes` without `balance_changes` (net zero). BAL **MUST** record non-zero `balance_changes` for recipient. | ✅ Completed | -| `test_bal_system_contracts_2935_4788` | BAL includes pre-exec system writes for parent hash & beacon root | Build a block with `N` normal txs; 2935 & 4788 active | BAL MUST include `HISTORY_STORAGE_ADDRESS` (EIP-2935) and `BEACON_ROOTS_ADDRESS` (EIP-4788) with `storage_changes` to ring-buffer slots; each write uses `tx_index = N` (system op). | 🟡 Planned | -| `test_bal_system_dequeue_withdrawals_eip7002` | BAL tracks post-exec system dequeues for withdrawals | Pre-populate EIP-7002 withdrawal requests; produce a block where dequeues occur | BAL MUST include the 7002 system contract with `storage_changes` (queue head/tail slots 0–3) using `tx_index = len(txs)` and balance changes for withdrawal recipients. | 🟡 Planned | -| `test_bal_system_dequeue_consolidations_eip7251` | BAL tracks post-exec system dequeues for consolidations | Pre-populate EIP-7251 consolidation requests; produce a block where dequeues occur | BAL MUST include the 7251 system contract with `storage_changes` (queue slots 0–3) using `tx_index = len(txs)`. | 🟡 Planned | +| `test_bal_system_contracts_2935_4788` | BAL includes pre-exec system writes for parent hash & beacon root | Build a block with `N` normal txs; 2935 & 4788 active | BAL MUST include `HISTORY_STORAGE_ADDRESS` (EIP-2935) and `BEACON_ROOTS_ADDRESS` (EIP-4788) with `storage_changes` to ring-buffer slots; each write uses `block_access_index = N` (system op). | 🟡 Planned | +| `test_bal_system_dequeue_withdrawals_eip7002` | BAL tracks post-exec system dequeues for withdrawals | Pre-populate EIP-7002 withdrawal requests; produce a block where dequeues occur | BAL MUST include the 7002 system contract with `storage_changes` (queue head/tail slots 0–3) using `block_access_index = len(txs)` and balance changes for withdrawal recipients. | 🟡 Planned | +| `test_bal_system_dequeue_consolidations_eip7251` | BAL tracks post-exec system dequeues for consolidations | Pre-populate EIP-7251 consolidation requests; produce a block where dequeues occur | BAL MUST include the 7251 system contract with `storage_changes` (queue slots 0–3) using `block_access_index = len(txs)`. | 🟡 Planned | | `test_bal_aborted_storage_access` | Ensure BAL captures storage access in aborted transactions correctly | Alice calls contract that reads storage slot `0x01`, writes to slot `0x02`, then aborts with `REVERT`/`INVALID` | BAL MUST include storage_reads for slots `0x01` and `0x02` (aborted writes become reads), empty storage_changes. Only nonce changes for Alice. | ✅ Completed | | `test_bal_aborted_account_access` | Ensure BAL captures account access in aborted transactions for all account accessing opcodes | Alice calls `AbortContract` that performs account access operations (`BALANCE`, `EXTCODESIZE`, `EXTCODECOPY`, `EXTCODEHASH`, `CALL`, `CALLCODE`, `DELEGATECALL`, `STATICCALL`) on `TargetContract` and aborts via `REVERT`/`INVALID` | BAL MUST include Alice, `TargetContract`, and `AbortContract` in account_changes and nonce changes for Alice. | ✅ Completed | | `test_bal_pure_contract_call` | Ensure BAL captures contract access for pure computation calls | Alice calls `PureContract` that performs pure arithmetic (ADD operation) without storage or balance changes | BAL MUST include Alice and `PureContract` in `account_changes`, and `nonce_changes` for Alice. | ✅ Completed | @@ -75,7 +75,7 @@ | `test_bal_invalid_complex_corruption` | Verify clients reject blocks with multiple BAL corruptions | Alice calls contract with storage writes; BAL has multiple issues: wrong account, missing nonce, wrong storage value | Block **MUST** be rejected with `INVALID_BLOCK_ACCESS_LIST` exception. Clients **MUST** detect any corruption regardless of other issues. | ✅ Completed | | `test_bal_invalid_missing_account` | Verify clients reject blocks with missing required account entries in BAL | Alice sends transaction to Bob; BAL modifier removes Bob's account entry (recipient should be included) | Block **MUST** be rejected with `INVALID_BLOCK_ACCESS_LIST` exception. Clients **MUST** validate all accessed accounts are present. | ✅ Completed | | `test_bal_invalid_balance_value` | Verify clients reject blocks with incorrect balance values in BAL | Alice sends value to Bob; BAL modifier changes balance to incorrect value | Block **MUST** be rejected with `INVALID_BLOCK_ACCESS_LIST` exception. Clients **MUST** validate balance change values match actual state transitions. | ✅ Completed | -| `test_bal_empty_block_no_coinbase` | Ensure BAL correctly handles empty blocks without including coinbase | Block with 0 transactions, no withdrawals. System contracts may perform operations (EIP-2935 parent hash, EIP-4788 beacon root if active). | BAL **MUST NOT** include the coinbase/fee recipient (receives no fees). BAL **MAY** include system contract addresses (EIP-2935 `HISTORY_STORAGE_ADDRESS`, EIP-4788 `BEACON_ROOTS_ADDRESS`) with `storage_changes` at `tx_index=0` (pre-execution system operations). | ✅ Completed | +| `test_bal_empty_block_no_coinbase` | Ensure BAL correctly handles empty blocks without including coinbase | Block with 0 transactions, no withdrawals. System contracts may perform operations (EIP-2935 parent hash, EIP-4788 beacon root if active). | BAL **MUST NOT** include the coinbase/fee recipient (receives no fees). BAL **MAY** include system contract addresses (EIP-2935 `HISTORY_STORAGE_ADDRESS`, EIP-4788 `BEACON_ROOTS_ADDRESS`) with `storage_changes` at `block_access_index=0` (pre-execution system operations). | ✅ Completed | | `test_bal_coinbase_zero_tip` | Ensure BAL includes coinbase even when priority fee is zero | Block with 1 transaction: Alice sends 5 wei to Bob with priority fee = 0 (base fee burned post-EIP-1559) | BAL **MUST** include Alice with `balance_changes` (gas cost) and `nonce_changes`. BAL **MUST** include Bob with `balance_changes`. BAL **MUST** include coinbase with empty changes. | ✅ Completed | | `test_bal_withdrawal_empty_block` | Ensure BAL captures withdrawal balance changes in empty block | Charlie starts with 1 gwei. Block with 0 transactions and 1 withdrawal of 10 gwei to Charlie | BAL **MUST** include Charlie with `balance_changes` at `block_access_index = 1`. Charlie's `balance_changes` **MUST** show final balance of 11 gwei. All other fields (storage_reads, storage_changes, nonce_changes, code_changes) **MUST** be empty. | ✅ Completed | | `test_bal_withdrawal_and_transaction` | Ensure BAL captures both transaction and withdrawal balance changes | Block with 1 transaction: Alice sends 5 wei to Bob. 1 withdrawal of 10 gwei to Charlie | BAL **MUST** include Alice with `nonce_changes` and `balance_changes` at `block_access_index = 1`. BAL **MUST** include Bob with `balance_changes` at `block_access_index = 1`. BAL **MUST** include Charlie with `balance_changes` at `block_access_index = 2` showing final balance after receiving 10 gwei. All other fields for Charlie **MUST** be empty. | ✅ Completed | @@ -101,13 +101,13 @@ | `test_bal_all_transaction_types` | Ensure BAL correctly captures state changes from all transaction types in a single block | Single block with 5 transactions: Type 0 (Legacy), Type 1 (EIP-2930 Access List), Type 2 (EIP-1559), Type 3 (EIP-4844 Blob), Type 4 (EIP-7702 Set Code). Each tx writes to contract storage. Note: Access list addresses are pre-warmed but NOT recorded in BAL (no state access). | BAL **MUST** include: (1) All 5 senders with `nonce_changes`. (2) Contracts 0-3 with `storage_changes`. (3) Alice (7702 target) with `nonce_changes`, `code_changes` (delegation), `storage_changes`. (4) Oracle (delegation source) with empty changes. | ✅ Completed | | `test_bal_create2_collision` | Ensure BAL handles CREATE2 address collision correctly | Factory contract (nonce=1, storage slot 0=0xDEAD) executes `CREATE2(salt=0, initcode)` targeting address that already has `code=STOP, nonce=1`. Pre-deploy contract at calculated CREATE2 target address before factory deployment. | BAL **MUST** include: (1) Factory with `nonce_changes` (1→2, incremented even on failed CREATE2), `storage_changes` for slot 0 (0xDEAD→0, stores failure). (2) Collision address with empty changes (accessed during collision check, no state changes). CREATE2 returns 0. Collision address **MUST NOT** have `nonce_changes` or `code_changes`. | ✅ Completed | | `test_bal_create_selfdestruct_to_self_with_call` | Ensure BAL handles init code that calls external contract then selfdestructs to itself | Factory executes `CREATE2` with endowment=100. Init code (embedded in factory via CODECOPY): (1) `CALL(Oracle, 0)` - Oracle writes to its storage slot 0x01. (2) `SSTORE(0x01, 0x42)` - write to own storage. (3) `SELFDESTRUCT(SELF)` - selfdestruct to own address. Contract created and destroyed in same tx. | BAL **MUST** include: (1) Factory with `nonce_changes`, `balance_changes` (loses 100). (2) Oracle with `storage_changes` for slot 0x01 (external call succeeded). (3) Created address with `storage_reads` for slot 0x01 (aborted write becomes read) - **MUST NOT** have `nonce_changes`, `code_changes`, `storage_changes`, or `balance_changes` (ephemeral contract, balance burned via SELFDESTRUCT to self). | ✅ Completed | -| `test_bal_selfdestruct_to_7702_delegation` | Ensure BAL correctly handles SELFDESTRUCT to a 7702 delegated account (no code execution on recipient) | Tx1: Alice authorizes delegation to Oracle (sets code to `0xef0100\|\|Oracle`). Tx2: Victim contract (balance=100) executes `SELFDESTRUCT(Alice)`. Two separate transactions in same block. Note: Alice starts with initial balance which accumulates with selfdestruct. | BAL **MUST** include: (1) Alice at tx_index=1 with `code_changes` (delegation), `nonce_changes`. (2) Alice at tx_index=2 with `balance_changes` (receives selfdestruct). (3) Victim at tx_index=2 with `balance_changes` (100→0). **Oracle MUST NOT appear in tx2** - per EVM spec, SELFDESTRUCT transfers balance without executing recipient code, so delegation target is never accessed. | ✅ Completed | +| `test_bal_selfdestruct_to_7702_delegation` | Ensure BAL correctly handles SELFDESTRUCT to a 7702 delegated account (no code execution on recipient) | Tx1: Alice authorizes delegation to Oracle (sets code to `0xef0100\|\|Oracle`). Tx2: Victim contract (balance=100) executes `SELFDESTRUCT(Alice)`. Two separate transactions in same block. Note: Alice starts with initial balance which accumulates with selfdestruct. | BAL **MUST** include: (1) Alice at block_access_index=1 with `code_changes` (delegation), `nonce_changes`. (2) Alice at block_access_index=2 with `balance_changes` (receives selfdestruct). (3) Victim at block_access_index=2 with `balance_changes` (100→0). **Oracle MUST NOT appear in tx2** - per EVM spec, SELFDESTRUCT transfers balance without executing recipient code, so delegation target is never accessed. | ✅ Completed | | `test_bal_call_revert_insufficient_funds` | Ensure BAL handles CALL failure due to insufficient balance (not OOG) | Contract (balance=100, storage slot 0x02=0xDEAD) executes: `SLOAD(0x01), CALL(target, value=1000), SSTORE(0x02, result)`. CALL fails because 1000 > 100. Target address 0xDEAD (pre-existing with non-zero balance to avoid pruning). Note: slot 0x02 must start non-zero so SSTORE(0) is a change. | BAL **MUST** include: (1) Contract with `storage_reads` for slot 0x01, `storage_changes` for slot 0x02 (value=0, CALL returned failure). (2) Target (0xDEAD) **MUST** appear in BAL with empty changes - target is accessed before balance check fails. | ✅ Completed | | `test_bal_lexicographic_address_ordering` | Ensure BAL enforces strict lexicographic byte-wise ordering | Pre-fund three addresses with specific byte patterns: `addr_low = 0x0000...0001`, `addr_mid = 0x0000...0100`, `addr_high = 0x0100...0000`. Contract touches them in reverse order: `BALANCE(addr_high), BALANCE(addr_low), BALANCE(addr_mid)`. Additionally, include two endian-trap addresses that are byte-reversals of each other: `addr_endian_low = 0x0100000000000000000000000000000000000002`, `addr_endian_high = 0x0200000000000000000000000000000000000001`. Note: `reverse(addr_endian_low) = addr_endian_high`. Correct lexicographic order: `addr_endian_low < addr_endian_high` (0x01 < 0x02 at byte 0). If implementation incorrectly reverses bytes before comparing, it would get `addr_endian_low > addr_endian_high` (wrong). | BAL account list **MUST** be sorted lexicographically by address bytes: `addr_low` < `addr_mid` < `addr_high` < `addr_endian_low` < `addr_endian_high`, regardless of access order. The endian-trap addresses specifically catch byte-reversal bugs where addresses are compared with wrong byte order. Complements `test_bal_invalid_account_order` which tests rejection; this tests correct generation. | ✅ Completed | | `test_bal_transient_storage_not_tracked` | Ensure BAL excludes EIP-1153 transient storage operations | Contract executes: `TSTORE(0x01, 0x42)` (transient write), `TLOAD(0x01)` (transient read), `SSTORE(0x02, result)` (persistent write using transient value). | BAL **MUST** include slot 0x02 in `storage_changes` (persistent storage was modified). BAL **MUST NOT** include slot 0x01 in `storage_reads` or `storage_changes` (transient storage is not persisted, not needed for stateless execution). This verifies TSTORE/TLOAD don't pollute BAL. | ✅ Completed | | `test_bal_selfdestruct_to_precompile` | Ensure BAL captures SELFDESTRUCT with precompile as beneficiary | Caller triggers victim contract (balance=100) to execute `SELFDESTRUCT(0x0000...0001)` (ecrecover precompile). Precompile starts with balance=0. | BAL **MUST** include: (1) Contract with `balance_changes` (100→0, loses balance to selfdestruct). (2) Precompile address 0x01 with `balance_changes` (0→100, receives selfdestruct balance). Precompile **MUST NOT** have `code_changes` or `nonce_changes`. This complements `test_bal_withdrawal_to_precompiles` (withdrawal) and `test_bal_precompile_funded` (tx value). | ✅ Completed | | `test_bal_self_destruct_oog` | Ensure BAL correctly tracks SELFDESTRUCT beneficiary based on gas boundaries | Alice calls `Caller` contract which CALLs `SelfDestructContract` with precisely controlled gas. `SelfDestructContract` attempts SELFDESTRUCT to new account `Beneficiary`. Static gas = G_VERY_LOW + G_SELF_DESTRUCT + G_COLD_ACCOUNT_ACCESS. Parameterized: (1) OOG before state access (gas = static - 1), (2) OOG after state access (gas = static, but insufficient for G_NEW_ACCOUNT). | For OOG before state access: BAL **MUST NOT** include `Beneficiary` (no state access occurred). For OOG after state access: BAL **MUST** include `Beneficiary` with empty changes (state was accessed before G_NEW_ACCOUNT check failed). Both cases: Alice with `nonce_changes`, `Caller` and `SelfDestructContract` with empty changes. Contract balance unchanged. | ✅ Completed | -| `test_bal_withdrawal_to_7702_delegation` | Ensure BAL correctly handles withdrawal to a 7702 delegated account (no code execution on recipient) | Tx1: Alice authorizes delegation to Oracle (sets code to `0xef0100\|\|Oracle`). Withdrawal: 10 gwei sent to Alice. Single block with tx + withdrawal. | BAL **MUST** include: (1) Alice at tx_index=1 with `code_changes` (delegation), `nonce_changes`. (2) Alice at tx_index=2 with `balance_changes` (receives withdrawal). **Oracle MUST NOT appear** - withdrawals credit balance without executing recipient code, so delegation target is never accessed. This complements `test_bal_selfdestruct_to_7702_delegation` (selfdestruct) and `test_bal_withdrawal_no_evm_execution` (withdrawal to contract). | ✅ Completed | +| `test_bal_withdrawal_to_7702_delegation` | Ensure BAL correctly handles withdrawal to a 7702 delegated account (no code execution on recipient) | Tx1: Alice authorizes delegation to Oracle (sets code to `0xef0100\|\|Oracle`). Withdrawal: 10 gwei sent to Alice. Single block with tx + withdrawal. | BAL **MUST** include: (1) Alice at block_access_index=1 with `code_changes` (delegation), `nonce_changes`. (2) Alice at block_access_index=2 with `balance_changes` (receives withdrawal). **Oracle MUST NOT appear** - withdrawals credit balance without executing recipient code, so delegation target is never accessed. This complements `test_bal_selfdestruct_to_7702_delegation` (selfdestruct) and `test_bal_withdrawal_no_evm_execution` (withdrawal to contract). | ✅ Completed | | `test_init_collision_create_tx` | Ensure BAL tracks CREATE collisions correctly (pre-Amsterdam test with BAL) | CREATE transaction targeting address with existing storage aborts | BAL **MUST** show empty expectations for collision address (no changes occur due to abort) | ✅ Completed | | `test_call_to_pre_authorized_oog` | Ensure BAL handles OOG during EIP-7702 delegation access (pre-Amsterdam test with BAL) | Call to delegated account that OOGs before accessing delegation contract | BAL **MUST** include auth_signer (code read for delegation check) but **MUST NOT** include delegation contract (OOG before access) | ✅ Completed | | `test_selfdestruct_created_in_same_tx_with_revert` | Ensure BAL tracks selfdestruct with revert correctly (pre-Amsterdam test with BAL) | Contract created and selfdestructed in same tx with nested revert | BAL **MUST** track storage reads and balance changes for selfdestruct even with reverts | ✅ Completed | diff --git a/tests/cancun/create/test_create_oog_from_eoa_refunds.py b/tests/cancun/create/test_create_oog_from_eoa_refunds.py index ee7f14571a..050f54c91e 100644 --- a/tests/cancun/create/test_create_oog_from_eoa_refunds.py +++ b/tests/cancun/create/test_create_oog_from_eoa_refunds.py @@ -356,13 +356,17 @@ def test_create_oog_from_eoa_refunds( ) created_bal = BalAccountExpectation( nonce_changes=[ - BalNonceChange(tx_index=1, post_nonce=expected_nonce) + BalNonceChange( + block_access_index=1, post_nonce=expected_nonce + ) ], storage_changes=[ BalStorageSlot( slot=0, slot_changes=[ - BalStorageChange(tx_index=1, post_value=1) + BalStorageChange( + block_access_index=1, post_value=1 + ) ], ), ], @@ -404,7 +408,9 @@ def test_create_oog_from_eoa_refunds( bal_expectation = BlockAccessListExpectation( account_expectations={ sender: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)], + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ], ), created_address: created_bal, } diff --git a/tests/cancun/eip6780_selfdestruct/test_selfdestruct_revert.py b/tests/cancun/eip6780_selfdestruct/test_selfdestruct_revert.py index ab2d22f112..634bfac822 100644 --- a/tests/cancun/eip6780_selfdestruct/test_selfdestruct_revert.py +++ b/tests/cancun/eip6780_selfdestruct/test_selfdestruct_revert.py @@ -454,7 +454,7 @@ def test_selfdestruct_created_in_same_tx_with_revert( # noqa SC200 BalAccountExpectation( balance_changes=[ BalBalanceChange( - tx_index=1, + block_access_index=1, post_balance=1 if selfdestruct_on_outer_call == 1 else 2, @@ -467,11 +467,15 @@ def test_selfdestruct_created_in_same_tx_with_revert( # noqa SC200 selfdestruct_with_transfer_contract_address ] = BalAccountExpectation( storage_reads=[1], - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)], - balance_changes=[BalBalanceChange(tx_index=1, post_balance=1)], + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ], + balance_changes=[ + BalBalanceChange(block_access_index=1, post_balance=1) + ], code_changes=[ BalCodeChange( - tx_index=1, + block_access_index=1, new_code=selfdestruct_with_transfer_contract_code, ), ], @@ -479,7 +483,9 @@ def test_selfdestruct_created_in_same_tx_with_revert( # noqa SC200 BalStorageSlot( slot=0, slot_changes=[ - BalStorageChange(tx_index=1, post_value=1), + BalStorageChange( + block_access_index=1, post_value=1 + ), ], ), ], diff --git a/tests/frontier/opcodes/test_call_and_callcode_gas_calculation.py b/tests/frontier/opcodes/test_call_and_callcode_gas_calculation.py index 015217521d..ae3dd53df2 100644 --- a/tests/frontier/opcodes/test_call_and_callcode_gas_calculation.py +++ b/tests/frontier/opcodes/test_call_and_callcode_gas_calculation.py @@ -230,7 +230,7 @@ def expected_block_access_list( else: empty_account_expectation = BalAccountExpectation( balance_changes=[ - BalBalanceChange(tx_index=1, post_balance=1) + BalBalanceChange(block_access_index=1, post_balance=1) ] ) else: @@ -246,14 +246,16 @@ def expected_block_access_list( empty_account: empty_account_expectation, caller_address: BalAccountExpectation( balance_changes=[ - BalBalanceChange(tx_index=1, post_balance=4) + BalBalanceChange(block_access_index=1, post_balance=4) ], storage_reads=[0] if gas_shortage else [], storage_changes=[ BalStorageSlot( slot=0x00, slot_changes=[ - BalStorageChange(tx_index=1, post_value=1), + BalStorageChange( + block_access_index=1, post_value=1 + ), ], ), ] @@ -262,7 +264,11 @@ def expected_block_access_list( ), callee_address: BalAccountExpectation( balance_changes=( - [BalBalanceChange(tx_index=1, post_balance=2)] + [ + BalBalanceChange( + block_access_index=1, post_balance=2 + ) + ] if not gas_shortage and callee_opcode == Op.CALL else [] ), diff --git a/tests/prague/eip7702_set_code_tx/test_gas.py b/tests/prague/eip7702_set_code_tx/test_gas.py index b415684bf7..93c2747019 100644 --- a/tests/prague/eip7702_set_code_tx/test_gas.py +++ b/tests/prague/eip7702_set_code_tx/test_gas.py @@ -1279,7 +1279,9 @@ def test_call_to_pre_authorized_oog( # delegation is NOT tracked (OOG before reading it) account_expectations = { tx.sender: BalAccountExpectation( - nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)], + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ], ), callee_address: BalAccountExpectation.empty(), # read for calculating delegation access cost: