Skip to content

Commit 3d98643

Browse files
committed
add markdown docstrings
1 parent 5a483ba commit 3d98643

File tree

6 files changed

+605
-108
lines changed

6 files changed

+605
-108
lines changed

src/ethereum/osaka/block_access_lists/builder.py

Lines changed: 189 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,18 @@
22
Block Access List Builder for EIP-7928
33
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
44
5-
This module implements the Block Access List builder that tracks all account and storage
6-
accesses during block execution and constructs the final BlockAccessList.
5+
This module implements the Block Access List builder that tracks all account
6+
and storage accesses during block execution and constructs the final
7+
[`BlockAccessList`].
8+
9+
The builder follows a two-phase approach:
10+
11+
1. **Collection Phase**: During transaction execution, all state accesses are
12+
recorded via the tracking functions.
13+
2. **Build Phase**: After block execution, the accumulated data is sorted
14+
and encoded into the final deterministic format.
15+
16+
[`BlockAccessList`]: ref:ethereum.osaka.ssz_types.BlockAccessList
717
"""
818

919
from dataclasses import dataclass, field
@@ -27,33 +37,75 @@
2737
@dataclass
2838
class AccountData:
2939
"""
30-
Account data stored in the builder.
40+
Account data stored in the builder during block execution.
41+
42+
This dataclass tracks all changes made to a single account throughout
43+
the execution of a block, organized by the type of change and the
44+
transaction index where it occurred.
3145
"""
3246
storage_changes: Dict[Bytes, List[StorageChange]] = field(default_factory=dict)
47+
"""
48+
Mapping from storage slot to list of changes made to that slot.
49+
Each change includes the transaction index and new value.
50+
"""
51+
3352
storage_reads: Set[Bytes] = field(default_factory=set)
53+
"""
54+
Set of storage slots that were read but not modified.
55+
"""
56+
3457
balance_changes: List[BalanceChange] = field(default_factory=list)
58+
"""
59+
List of balance changes for this account, ordered by transaction index.
60+
"""
61+
3562
nonce_changes: List[NonceChange] = field(default_factory=list)
63+
"""
64+
List of nonce changes for this account, ordered by transaction index.
65+
"""
66+
3667
code_changes: List[CodeChange] = field(default_factory=list)
68+
"""
69+
List of code changes (contract deployments) for this account,
70+
ordered by transaction index.
71+
"""
3772

3873

3974
@dataclass
4075
class BlockAccessListBuilder:
4176
"""
42-
Builder for constructing `BlockAccessList` efficiently during transaction
77+
Builder for constructing [`BlockAccessList`] efficiently during transaction
4378
execution.
4479
4580
The builder accumulates all account and storage accesses during block
46-
execution and constructs a deterministic access list following the pattern:
47-
address -> field -> tx_index -> change
81+
execution and constructs a deterministic access list. Changes are tracked
82+
by address, field type, and transaction index to enable efficient
83+
reconstruction of state changes.
84+
85+
[`BlockAccessList`]: ref:ethereum.osaka.ssz_types.BlockAccessList
4886
"""
4987
accounts: Dict[Address, AccountData] = field(default_factory=dict)
88+
"""
89+
Mapping from account address to its tracked changes during block execution.
90+
"""
5091

5192

5293
def ensure_account(builder: BlockAccessListBuilder, address: Address) -> None:
5394
"""
54-
Ensure account exists in builder.
95+
Ensure an account exists in the builder's tracking structure.
96+
97+
Creates an empty [`AccountData`] entry for the given address if it
98+
doesn't already exist. This function is idempotent and safe to call
99+
multiple times for the same address.
55100
56-
Creates an empty account entry if it doesn't already exist.
101+
Parameters
102+
----------
103+
builder :
104+
The block access list builder instance.
105+
address :
106+
The account address to ensure exists.
107+
108+
[`AccountData`]: ref:ethereum.osaka.block_access_lists.builder.AccountData
57109
"""
58110
if address not in builder.accounts:
59111
builder.accounts[address] = AccountData()
@@ -63,21 +115,35 @@ def add_storage_write(
63115
builder: BlockAccessListBuilder,
64116
address: Address,
65117
slot: Bytes,
66-
tx_index: int,
118+
tx_index: U32,
67119
new_value: Bytes
68120
) -> None:
69121
"""
70-
Add storage write to the block access list.
122+
Add a storage write operation to the block access list.
71123
72124
Records a storage slot modification for a given address at a specific
73-
transaction index.
125+
transaction index. Multiple writes to the same slot are tracked
126+
separately, maintaining the order and transaction index of each change.
127+
128+
Parameters
129+
----------
130+
builder :
131+
The block access list builder instance.
132+
address :
133+
The account address whose storage is being modified.
134+
slot :
135+
The storage slot being written to.
136+
tx_index :
137+
The index of the transaction making this change.
138+
new_value :
139+
The new value being written to the storage slot.
74140
"""
75141
ensure_account(builder, address)
76142

77143
if slot not in builder.accounts[address].storage_changes:
78144
builder.accounts[address].storage_changes[slot] = []
79145

80-
change = StorageChange(tx_index=U32(tx_index), new_value=new_value)
146+
change = StorageChange(tx_index=tx_index, new_value=new_value)
81147
builder.accounts[address].storage_changes[slot].append(change)
82148

83149

@@ -87,10 +153,22 @@ def add_storage_read(
87153
slot: Bytes
88154
) -> None:
89155
"""
90-
Add storage read to the block access list.
156+
Add a storage read operation to the block access list.
91157
92-
Records a storage slot read for a given address. Only slots that are
93-
not also written to will be included in the final access list.
158+
Records that a storage slot was read during execution. Storage slots
159+
that are both read and written will only appear in the storage changes
160+
list, not in the storage reads list, as per [EIP-7928].
161+
162+
Parameters
163+
----------
164+
builder :
165+
The block access list builder instance.
166+
address :
167+
The account address whose storage is being read.
168+
slot :
169+
The storage slot being read.
170+
171+
[EIP-7928]: https://eips.ethereum.org/EIPS/eip-7928
94172
"""
95173
ensure_account(builder, address)
96174
builder.accounts[address].storage_reads.add(slot)
@@ -99,73 +177,147 @@ def add_storage_read(
99177
def add_balance_change(
100178
builder: BlockAccessListBuilder,
101179
address: Address,
102-
tx_index: int,
180+
tx_index: U32,
103181
post_balance: Bytes
104182
) -> None:
105183
"""
106-
Add balance change to the block access list.
184+
Add a balance change to the block access list.
107185
108-
Records a balance change for a given address at a specific transaction
109-
index.
186+
Records the post-transaction balance for an account after it has been
187+
modified. This includes changes from transfers, gas fees, block rewards,
188+
and any other balance-affecting operations.
189+
190+
Parameters
191+
----------
192+
builder :
193+
The block access list builder instance.
194+
address :
195+
The account address whose balance changed.
196+
tx_index :
197+
The index of the transaction causing this change.
198+
post_balance :
199+
The account balance after the change, encoded as bytes.
110200
"""
111201
ensure_account(builder, address)
112202

113-
change = BalanceChange(tx_index=U32(tx_index), post_balance=post_balance)
203+
change = BalanceChange(tx_index=tx_index, post_balance=post_balance)
114204
builder.accounts[address].balance_changes.append(change)
115205

116206

117207
def add_nonce_change(
118208
builder: BlockAccessListBuilder,
119209
address: Address,
120-
tx_index: int,
121-
new_nonce: int
210+
tx_index: U32,
211+
new_nonce: U64
122212
) -> None:
123213
"""
124-
Add nonce change to the block access list.
214+
Add a nonce change to the block access list.
215+
216+
Records a nonce increment for an account. This occurs when an EOA sends
217+
a transaction or when a contract performs [`CREATE`] or [`CREATE2`]
218+
operations.
125219
126-
Records a nonce change for a given address at a specific transaction
127-
index.
220+
Parameters
221+
----------
222+
builder :
223+
The block access list builder instance.
224+
address :
225+
The account address whose nonce changed.
226+
tx_index :
227+
The index of the transaction causing this change.
228+
new_nonce :
229+
The new nonce value after the change.
230+
231+
[`CREATE`]: ref:ethereum.osaka.vm.instructions.system.create
232+
[`CREATE2`]: ref:ethereum.osaka.vm.instructions.system.create2
128233
"""
129234
ensure_account(builder, address)
130235

131-
change = NonceChange(tx_index=U32(tx_index), new_nonce=U64(new_nonce))
236+
change = NonceChange(tx_index=tx_index, new_nonce=new_nonce)
132237
builder.accounts[address].nonce_changes.append(change)
133238

134239

135240
def add_code_change(
136241
builder: BlockAccessListBuilder,
137242
address: Address,
138-
tx_index: int,
243+
tx_index: U32,
139244
new_code: Bytes
140245
) -> None:
141246
"""
142-
Add code change to the block access list.
247+
Add a code change to the block access list.
248+
249+
Records contract code deployment or modification. This typically occurs
250+
during contract creation via [`CREATE`], [`CREATE2`], or [`SETCODE`]
251+
operations.
252+
253+
Parameters
254+
----------
255+
builder :
256+
The block access list builder instance.
257+
address :
258+
The account address receiving new code.
259+
tx_index :
260+
The index of the transaction deploying the code.
261+
new_code :
262+
The deployed contract bytecode.
143263
144-
Records a code change for a given address at a specific transaction
145-
index.
264+
[`CREATE`]: ref:ethereum.osaka.vm.instructions.system.create
265+
[`CREATE2`]: ref:ethereum.osaka.vm.instructions.system.create2
266+
[`SETCODE`]: ref:ethereum.osaka.vm.instructions.system.setcode
146267
"""
147268
ensure_account(builder, address)
148269

149-
change = CodeChange(tx_index=U32(tx_index), new_code=new_code)
270+
change = CodeChange(tx_index=tx_index, new_code=new_code)
150271
builder.accounts[address].code_changes.append(change)
151272

152273

153274
def add_touched_account(builder: BlockAccessListBuilder, address: Address) -> None:
154275
"""
155-
Add an account that was touched but not changed.
276+
Add an account that was accessed but not modified.
277+
278+
Records that an account was accessed during execution without any state
279+
changes. This is used for operations like [`EXTCODEHASH`], [`BALANCE`],
280+
[`EXTCODESIZE`], and [`EXTCODECOPY`] that read account data without
281+
modifying it.
282+
283+
Parameters
284+
----------
285+
builder :
286+
The block access list builder instance.
287+
address :
288+
The account address that was accessed.
156289
157-
Used for operations like EXTCODEHASH or BALANCE checks that access
158-
an account without modifying it.
290+
[`EXTCODEHASH`]: ref:ethereum.osaka.vm.instructions.environment.extcodehash
291+
[`BALANCE`]: ref:ethereum.osaka.vm.instructions.environment.balance
292+
[`EXTCODESIZE`]: ref:ethereum.osaka.vm.instructions.environment.extcodesize
293+
[`EXTCODECOPY`]: ref:ethereum.osaka.vm.instructions.environment.extcodecopy
159294
"""
160295
ensure_account(builder, address)
161296

162297

163298
def build(builder: BlockAccessListBuilder) -> BlockAccessList:
164299
"""
165-
Build the final BlockAccessList.
300+
Build the final [`BlockAccessList`] from accumulated changes.
301+
302+
Constructs a deterministic block access list by sorting all accumulated
303+
changes. The resulting list is ordered by:
304+
305+
1. Account addresses (lexicographically)
306+
2. Within each account:
307+
- Storage slots (lexicographically)
308+
- Transaction indices (numerically) for each change type
309+
310+
Parameters
311+
----------
312+
builder :
313+
The block access list builder containing all tracked changes.
314+
315+
Returns
316+
-------
317+
block_access_list :
318+
The final sorted and encoded block access list.
166319
167-
Constructs a sorted and deterministic block access list from all
168-
accumulated changes.
320+
[`BlockAccessList`]: ref:ethereum.osaka.ssz_types.BlockAccessList
169321
"""
170322
account_changes_list = []
171323

0 commit comments

Comments
 (0)