Expand description
§bal-codec
EIP-7928 Block-Level Access List: RLP decoding, ordering/uniqueness
validation, keccak256(rlp(bal)), and verification against the header’s
blockAccessListHash. Knows nothing about Solidity, storage, or nodes —
this is the one crate a spec change touches.
use bal_codec::{BlockAccessList, EMPTY_BAL_HASH};
// The empty BAL is `rlp([])` = 0xc0; its hash is fixed by the EIP.
let bal = BlockAccessList::decode(&[0xc0])?;
assert!(bal.is_empty());
assert_eq!(bal.hash(), EMPTY_BAL_HASH);
bal.verify(EMPTY_BAL_HASH)?;With the json feature, the execution-apis JSON form served by
eth_getBlockAccessList decodes through the same validation:
let v: serde_json::Value = rpc_response["result"].clone();
let bal = BlockAccessList::from_rpc_json(&v)?;
assert_eq!(bal.hash(), header.block_access_list_hash);Lookups use the sorted order the EIP mandates: bal.account(&addr) and
account.slot(&key) are binary searches. A BAL that violates ordering or
uniqueness is rejected, never softly accepted.
Part of balq.
EIP-7928 Block-Level Access List codec.
This crate is the only place the 7928 wire format is known. Everything above it (archive, layout, cli) consumes the typed structures and must not touch RLP.
Wire schema (from the EIP, Review status, subject to change):
StorageChange = [BlockAccessIndex(u32), StorageValue(u256)]
BalanceChange = [BlockAccessIndex(u32), Balance(u256)]
NonceChange = [BlockAccessIndex(u32), Nonce(u64)]
CodeChange = [BlockAccessIndex(u32), Bytecode(bytes)]
SlotChanges = [StorageKey(u256), [StorageChange...]]
AccountChanges = [Address, [SlotChanges...], [StorageKey...],
[BalanceChange...], [NonceChange...], [CodeChange...]]
BlockAccessList = [AccountChanges...]
block_access_list_hash = keccak256(rlp(BlockAccessList))Ordering is part of validity: accounts by address, slots by key, changes by
index, all strictly ascending. A BAL that violates ordering or uniqueness
is rejected by BlockAccessList::decode; it is never softly accepted.
With the json feature, BlockAccessList::from_rpc_json accepts the
execution-apis JSON form served by eth_getBlockAccessList.
Structs§
- Account
Changes - Everything that happened to one account within the block.
- Balance
Change - One balance change.
- Block
Access List - The whole list. Wire form is a bare RLP list of
AccountChanges(no wrapping struct), so encoding is transparent overaccounts. - Code
Change - One code change (deployment or self-destruct).
- Nonce
Change - One nonce change.
- Slot
Changes - All writes to one slot within the block.
- Storage
Change - One write to a storage slot.
Enums§
- Codec
Error - Decoding, validation and verification failures.
Constants§
- EMPTY_
BAL_ HASH - Hash of the empty BAL:
keccak256(rlp([]))=keccak256(0xc0).
Type Aliases§
- Block
Access Index - Position of a change in the block’s life cycle.
0= pre-execution system calls,1..=n= transactions,n+1= post-execution.