Skip to content

Comments

EIP-7928: BAL validation – size cap and uniqueness constraints#9861

Open
matkt wants to merge 11 commits intohyperledger:mainfrom
matkt:feature/eip-7928
Open

EIP-7928: BAL validation – size cap and uniqueness constraints#9861
matkt wants to merge 11 commits intohyperledger:mainfrom
matkt:feature/eip-7928

Conversation

@matkt
Copy link
Contributor

@matkt matkt commented Feb 20, 2026

PR description

EIP-7928: BAL validation – size cap and uniqueness

  • Size cap: bal_items <= block_gas_limit / ITEM_COST (ITEM_COST = 2000). Aligns with EIPs#11323.
  • Uniqueness: Enforces the five BAL uniqueness rules from EIPs#11338 (addresses, storage keys, block_access_index).
  • Forks: Before Amsterdam → reject any block with a BAL (REJECT_ANY_BAL). From Amsterdam → full validation via MainnetBlockAccessListValidator.
  • Tests: MainnetBlockAccessListValidatorTest, MainnetBlockValidatorTest, ProtocolScheduleBuilderTest.
  • References:
    EIPs#11338 – Uniqueness constraints
    EIPs#11323 – BAL size cap simplification

Fixed Issue(s)

Thanks for sending a pull request! Have you done the following?

  • Checked out our contribution guidelines?
  • Considered documentation and added the doc-change-required label to this PR if updates are required.
  • Considered the changelog and included an update if required.
  • For database changes (e.g. KeyValueSegmentIdentifier) considered compatibility and performed forwards and backwards compatibility tests

Locally, you can run these tests to catch failures early:

  • spotless: ./gradlew spotlessApply
  • unit tests: ./gradlew build
  • acceptance tests: ./gradlew acceptanceTest
  • integration tests: ./gradlew integrationTest
  • reference tests: ./gradlew ethereum:referenceTests:referenceTests
  • hive tests: Engine or other RPCs modified?

Signed-off-by: Karim Taam <karim.t2am@gmail.com>
@matkt matkt added block-access-lists amsterdam relating to Glamsterdam fork labels Feb 20, 2026
Signed-off-by: Karim Taam <karim.t2am@gmail.com>
Signed-off-by: Karim Taam <karim.t2am@gmail.com>
Signed-off-by: Karim Taam <karim.t2am@gmail.com>
Signed-off-by: Karim Taam <karim.t2am@gmail.com>
@matkt matkt changed the title add block access list constraints validation EIP-7928: BAL validation – size cap and uniqueness constraints Feb 23, 2026
Signed-off-by: Karim Taam <karim.t2am@gmail.com>
Signed-off-by: Karim Taam <karim.t2am@gmail.com>
@matkt matkt marked this pull request as ready for review February 23, 2026 08:48
Copilot AI review requested due to automatic review settings February 23, 2026 08:48
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 BlockAccessListValidator interface with REJECT_ANY_BAL implementation for pre-Amsterdam forks
  • Implements MainnetBlockAccessListValidator with size cap and uniqueness constraints validation
  • Adds AmsterdamGasCalculator with BLOCK_ACCESS_LIST_ITEM_COST constant

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>
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 =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think ALWAYS_REJECT_BAL might be clearer, or even just REJECT_BAL

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed

}
final long totalAddresses = bal.accountChanges().size();
final long balItems = totalStorageKeys + totalAddresses;
final long maxItems = blockHeader.getGasLimit() / itemCost;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default returns 0 for getBlockAccessListItemCost(). Are we sure that we never divide by 0 here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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<>();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think a BitSet would be more performant for the small integer values of the txIndices.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated

*/
private boolean validateUniquenessConstraints(
final BlockAccessList blockAccessList, final BlockHeader blockHeader) {
final Set<Address> seenAddresses = new HashSet<>();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can set the initial capacity for seenAddresses with blockAccessList.accountChanges().size() allocating all the memory at once

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated

return false;
}

final Set<StorageSlotKey> storageChangeSlots = new HashSet<>();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The initial capacity can be set here as well

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated

}
}

final Set<StorageSlotKey> storageReadSlots = new HashSet<>();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The initial capacity can be set here as well

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated

Signed-off-by: Karim Taam <karim.t2am@gmail.com>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why also not enforce the ordering constraints?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will also add it

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we could also check that all BAL indices are <= len(transactions) + 1.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the proper terminology is balIndices :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will rename it


BlockProcessingResult result =
mainnetBlockValidator.validateAndProcessBlock(
mainnetFrontierBlockValidator.validateAndProcessBlock(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Found the obligatory rename :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

amsterdam relating to Glamsterdam fork block-access-lists

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants