@@ -194,21 +194,33 @@ def _validate_bal_ordering(bal: "BlockAccessList") -> None:
194
194
f"{ bal .root [i - 1 ].address } >= { bal .root [i ].address } "
195
195
)
196
196
197
- # Check transaction index ordering within accounts
197
+ # Check transaction index ordering and uniqueness within accounts
198
198
for account in bal .root :
199
- change_lists : List [BlockAccessListChangeLists ] = [
200
- account .nonce_changes ,
201
- account .balance_changes ,
202
- account .code_changes ,
199
+ changes_to_check : List [tuple [ str , BlockAccessListChangeLists ] ] = [
200
+ ( "nonce_changes" , account .nonce_changes ) ,
201
+ ( "balance_changes" , account .balance_changes ) ,
202
+ ( "code_changes" , account .code_changes ) ,
203
203
]
204
- for change_list in change_lists :
205
- for i in range (1 , len (change_list )):
206
- if change_list [i - 1 ].tx_index >= change_list [i ].tx_index :
207
- raise BlockAccessListValidationError (
208
- f"Transaction indices not in ascending order in account "
209
- f"{ account .address } : { change_list [i - 1 ].tx_index } >= "
210
- f"{ change_list [i ].tx_index } "
211
- )
204
+
205
+ for field_name , change_list in changes_to_check :
206
+ if not change_list :
207
+ continue
208
+
209
+ tx_indices = [c .tx_index for c in change_list ]
210
+
211
+ # Check both ordering and duplicates
212
+ if tx_indices != sorted (tx_indices ):
213
+ raise BlockAccessListValidationError (
214
+ f"Transaction indices not in ascending order in { field_name } of account "
215
+ f"{ account .address } . Got: { tx_indices } , Expected: { sorted (tx_indices )} "
216
+ )
217
+
218
+ if len (tx_indices ) != len (set (tx_indices )):
219
+ duplicates = sorted ({idx for idx in tx_indices if tx_indices .count (idx ) > 1 })
220
+ raise BlockAccessListValidationError (
221
+ f"Duplicate transaction indices in { field_name } of account "
222
+ f"{ account .address } . Duplicates: { duplicates } "
223
+ )
212
224
213
225
# Check storage slot ordering
214
226
for i in range (1 , len (account .storage_changes )):
@@ -219,19 +231,28 @@ def _validate_bal_ordering(bal: "BlockAccessList") -> None:
219
231
f"{ account .storage_changes [i ].slot } "
220
232
)
221
233
222
- # Check transaction index ordering within storage slots
234
+ # Check transaction index ordering and uniqueness within storage slots
223
235
for storage_slot in account .storage_changes :
224
- for i in range (1 , len (storage_slot .slot_changes )):
225
- if (
226
- storage_slot .slot_changes [i - 1 ].tx_index
227
- >= storage_slot .slot_changes [i ].tx_index
228
- ):
229
- raise BlockAccessListValidationError (
230
- f"Transaction indices not in ascending order in storage slot "
231
- f"{ storage_slot .slot } of account { account .address } : "
232
- f"{ storage_slot .slot_changes [i - 1 ].tx_index } >= "
233
- f"{ storage_slot .slot_changes [i ].tx_index } "
234
- )
236
+ if not storage_slot .slot_changes :
237
+ continue
238
+
239
+ tx_indices = [c .tx_index for c in storage_slot .slot_changes ]
240
+
241
+ # Check both ordering and duplicates
242
+ if tx_indices != sorted (tx_indices ):
243
+ raise BlockAccessListValidationError (
244
+ f"Transaction indices not in ascending order in storage slot "
245
+ f"{ storage_slot .slot } of account { account .address } . "
246
+ f"Got: { tx_indices } , Expected: { sorted (tx_indices )} "
247
+ )
248
+
249
+ if len (tx_indices ) != len (set (tx_indices )):
250
+ duplicates = sorted ({idx for idx in tx_indices if tx_indices .count (idx ) > 1 })
251
+ raise BlockAccessListValidationError (
252
+ f"Duplicate transaction indices in storage slot "
253
+ f"{ storage_slot .slot } of account { account .address } . "
254
+ f"Duplicates: { duplicates } "
255
+ )
235
256
236
257
# Check storage reads ordering
237
258
for i in range (1 , len (account .storage_reads )):
0 commit comments