Skip to main content

Crate bal_codec

Crate bal_codec 

Source
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§

AccountChanges
Everything that happened to one account within the block.
BalanceChange
One balance change.
BlockAccessList
The whole list. Wire form is a bare RLP list of AccountChanges (no wrapping struct), so encoding is transparent over accounts.
CodeChange
One code change (deployment or self-destruct).
NonceChange
One nonce change.
SlotChanges
All writes to one slot within the block.
StorageChange
One write to a storage slot.

Enums§

CodecError
Decoding, validation and verification failures.

Constants§

EMPTY_BAL_HASH
Hash of the empty BAL: keccak256(rlp([])) = keccak256(0xc0).

Type Aliases§

BlockAccessIndex
Position of a change in the block’s life cycle. 0 = pre-execution system calls, 1..=n = transactions, n+1 = post-execution.