EIP-7928: BAL validation – size cap and uniqueness constraints#9861
EIP-7928: BAL validation – size cap and uniqueness constraints#9861matkt wants to merge 11 commits intohyperledger:mainfrom
Conversation
Signed-off-by: Karim Taam <karim.t2am@gmail.com>
Signed-off-by: Karim Taam <karim.t2am@gmail.com>
There was a problem hiding this comment.
Pull request overview
This PR implements BAL (Block Access List) validation for EIP-7928, introducing size cap constraints and uniqueness requirements. The implementation enforces that bal_items <= block_gas_limit / ITEM_COST (where ITEM_COST = 2000) and validates five uniqueness rules from the EIP. For forks before Amsterdam, any block containing a BAL is rejected; from Amsterdam onwards, full validation is performed via MainnetBlockAccessListValidator.
Changes:
- Introduces
BlockAccessListValidatorinterface withREJECT_ANY_BALimplementation for pre-Amsterdam forks - Implements
MainnetBlockAccessListValidatorwith size cap and uniqueness constraints validation - Adds
AmsterdamGasCalculatorwithBLOCK_ACCESS_LIST_ITEM_COSTconstant
Reviewed changes
Copilot reviewed 13 out of 13 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
GasCalculator.java |
Adds interface method for BAL item cost (returns 0 by default) |
AmsterdamGasCalculator.java |
New gas calculator implementing BAL item cost of 2000 |
BlockAccessListValidator.java |
New interface defining BAL validation with pre-Amsterdam rejection strategy |
MainnetBlockAccessListValidator.java |
Implements BAL validation logic with size cap and uniqueness constraints |
BlockAccessListFactory.java |
Minor documentation update (comment fix) |
MainnetBlockValidator.java |
Integrates BAL validator into block validation flow |
MainnetBlockValidatorBuilder.java |
Adds BAL validator parameter to builder methods |
ProtocolSpecBuilder.java |
Adds BAL validator builder configuration |
MainnetProtocolSpecs.java |
Configures Amsterdam fork with BAL validation |
MainnetBlockAccessListValidatorTest.java |
Comprehensive test coverage for BAL validation rules |
MainnetBlockValidatorTest.java |
Tests BAL validator integration in block validation |
ProtocolScheduleBuilderTest.java |
Tests fork-specific BAL validation behavior |
BlockImportExceptionHandlingTest.java |
Updates test setup to include BAL validator |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Signed-off-by: Karim Taam <karim.t2am@gmail.com>
| * Rejects any block that includes a BAL (returns false when present). Used for forks before | ||
| * Amsterdam, where blocks must not contain a block access list. | ||
| */ | ||
| BlockAccessListValidator REJECT_ANY_BAL = |
There was a problem hiding this comment.
I think ALWAYS_REJECT_BAL might be clearer, or even just REJECT_BAL
| } | ||
| final long totalAddresses = bal.accountChanges().size(); | ||
| final long balItems = totalStorageKeys + totalAddresses; | ||
| final long maxItems = blockHeader.getGasLimit() / itemCost; |
There was a problem hiding this comment.
The default returns 0 for getBlockAccessListItemCost(). Are we sure that we never divide by 0 here?
There was a problem hiding this comment.
I don't think it's possible because this part of the code will be used only when BAL is activated. And an item on BAL should always have a cost. Just to be sure I added a condition to not do this check if the cost is zero
| private boolean validateUniquenessConstraints( | ||
| final BlockAccessList blockAccessList, final BlockHeader blockHeader) { | ||
| final Set<Address> seenAddresses = new HashSet<>(); | ||
| final Set<Integer> seenTxIndices = new HashSet<>(); |
There was a problem hiding this comment.
I think a BitSet would be more performant for the small integer values of the txIndices.
| */ | ||
| private boolean validateUniquenessConstraints( | ||
| final BlockAccessList blockAccessList, final BlockHeader blockHeader) { | ||
| final Set<Address> seenAddresses = new HashSet<>(); |
There was a problem hiding this comment.
You can set the initial capacity for seenAddresses with blockAccessList.accountChanges().size() allocating all the memory at once
| return false; | ||
| } | ||
|
|
||
| final Set<StorageSlotKey> storageChangeSlots = new HashSet<>(); |
There was a problem hiding this comment.
The initial capacity can be set here as well
| } | ||
| } | ||
|
|
||
| final Set<StorageSlotKey> storageReadSlots = new HashSet<>(); |
There was a problem hiding this comment.
The initial capacity can be set here as well
Signed-off-by: Karim Taam <karim.t2am@gmail.com>
cdc2836 to
d56ca58
Compare
There was a problem hiding this comment.
Why also not enforce the ordering constraints?
There was a problem hiding this comment.
Maybe we could also check that all BAL indices are <= len(transactions) + 1.
There was a problem hiding this comment.
good point , I think we should add it to the spec
| final BlockAccessList blockAccessList, final BlockHeader blockHeader) { | ||
| final int accountCount = blockAccessList.accountChanges().size(); | ||
| final Set<Address> seenAddresses = new HashSet<>(accountCount); | ||
| final BitSet seenTxIndices = new BitSet(); |
There was a problem hiding this comment.
I think the proper terminology is balIndices :)
|
|
||
| BlockProcessingResult result = | ||
| mainnetBlockValidator.validateAndProcessBlock( | ||
| mainnetFrontierBlockValidator.validateAndProcessBlock( |
There was a problem hiding this comment.
Found the obligatory rename :)
PR description
EIP-7928: BAL validation – size cap and uniqueness
bal_items <= block_gas_limit / ITEM_COST(ITEM_COST = 2000). Aligns with EIPs#11323.REJECT_ANY_BAL). From Amsterdam → full validation viaMainnetBlockAccessListValidator.MainnetBlockAccessListValidatorTest,MainnetBlockValidatorTest,ProtocolScheduleBuilderTest.EIPs#11338 – Uniqueness constraints
EIPs#11323 – BAL size cap simplification
Fixed Issue(s)
Thanks for sending a pull request! Have you done the following?
doc-change-requiredlabel to this PR if updates are required.Locally, you can run these tests to catch failures early:
./gradlew spotlessApply./gradlew build./gradlew acceptanceTest./gradlew integrationTest./gradlew ethereum:referenceTests:referenceTests