Skip to content

Conversation

@OlivierBBB
Copy link
Collaborator

@OlivierBBB OlivierBBB commented Nov 12, 2025

Note

Introduces fork-aware MODEXP (London/Osaka) with new metadata, pricing, and OOB flows; refactors Blake/MODEXP modules; updates MMU/Hub/Counter/RPC to pass fork; and extends tests accordingly.

  • Fork-aware tracing and limits:
    • Pass Fork into ZkCounter, Hub (MMU), and RPC creators; compute MODEXP/BLAKE rows and sizes per fork (London vs Osaka).
  • MODEXP (EIP-7823/7883) implementation:
    • New fork-specific classes: London/OsakaModexpSubsection, London/OsakaModexpMetadata, London/OsakaModexpPricingOobCall, London/OsakaModexpXbsOobCall.
    • Adjust success criteria, pricing, input bounds, lead-log multiplier (8→16 in Osaka), and max input size; update OOB/XBS flows and result handling.
  • Blake/MODEXP refactor:
    • Replace BlakeModexpData with abstract BlakeModexp and BlakeModexpOperation plus London/Osaka variants; compute row counts dynamically; use fork-specific indices.
    • Update BLAKE2f handling to use new ops and counts (numberOfRowsBlake).
  • MMU updates:
    • Make Mmu, MmuInstructions, ModexpData, ModexpZero fork-aware; adjust micro-row counts and component sizes per fork.
  • Hub/Call flow:
    • CallSection selects London/Osaka MODEXP subsection; PrecompileSubsection sets return data using fork max sizes.
  • RPC & Tests:
    • RPC counters instantiate ZkCounter with fork; numerous tests updated/added to cover Osaka behavior and gas/pricing changes.

Written by Cursor Bugbot for commit cfa8e8e. This will update automatically on new commits. Configure here.

public static MmuCall forModexpExtractMbs(
final Hub hub, final ModexpSubsection subsection, final ModexpMetadata metaData) {
public static MmuCall extractMbsForModexp(
final Hub hub, final LondonModexpSubsection subsection, final ModexpMetadata metaData) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is it normal ? What's happening for OsakaModexpSection ?

}

public int getMaxInputSize() {
return 512;
Copy link
Collaborator

Choose a reason for hiding this comment

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

this constant has a name somewhere ...

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It doesn't in the HUB constraints.

With Lorenzo and François
the old tests were overwriting mbs in memory !
super(hub, callSection, modexpMetadata);
checkState(
modexpMetadata instanceof OsakaModexpMetadata,
"modexpMetadata must be LondonModexpMetadata");
Copy link

Choose a reason for hiding this comment

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

Bug: Error Message Confuses Metadata Types

The error message in the checkState validation says "modexpMetadata must be LondonModexpMetadata" but the check validates that modexpMetadata instanceof OsakaModexpMetadata. The error message is incorrect and misleading - it should say "modexpMetadata must be OsakaModexpMetadata" to match the actual validation being performed.

Fix in Cursor Fix in Web


import static net.consensys.linea.zktracer.module.blake2fmodexpdata.BlakeModexpDataOperation.BLAKE2f_HASH_INPUT_OFFSET;
import static net.consensys.linea.zktracer.module.blake2fmodexpdata.BlakeModexpDataOperation.BLAKE2f_HASH_INPUT_SIZE;
import static net.consensys.linea.zktracer.module.blake2fmodexpdata.BlakeModexpOperation.BLAKE2f_HASH_INPUT_OFFSET;
Copy link
Collaborator

Choose a reason for hiding this comment

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

why rm the data ? We have it for other modules (EcData, etc ...)

}

private void callWcpForIdCheck(final int operationID) {
private void callWcpForIdCheck(final long operationID) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

operation is from hubStamp, whicj is a i32, so int is enough no ?

return blake2fComponents.isPresent();
}

public static int legalModexpComponentByteSize(Fork fork) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

should add a commet to say that legal is accepted by linea in Prague vs non exceptionnal in Osaka

Copy link
Collaborator

Choose a reason for hiding this comment

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

LondonBlakeModexp == OsakaBmakeModexp as it's the underlying operation which is different depeding on the Fork. So Imho, it seems no need to have an abstract BlakeModexpData and two extends. Only keep a non abstract BlakeModexppData seems enough.

public static MmuCall forModexpExtractBbs(
final Hub hub, final ModexpSubsection subsection, final ModexpMetadata metaData) {
public static MmuCall extractBbsForModexp(
final Hub hub, final LondonModexpSubsection subsection, final ModexpMetadata metaData) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

why sopecialized a LondonModexpSection, and not only an abstract ModexpSubsection ?
As it is, it seems we only accept London (but as Osaka extends London it works), so it's strange.

rlpAddr = new RlpAddr(this, trm, keccak);
blockdata = setBlockData(this, wcp, euc, chain);
mmu = new Mmu(euc, wcp);
mmu = new Mmu(euc, wcp, fork);
Copy link
Collaborator

Choose a reason for hiding this comment

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

we should refactor the mmuCall to give as an input only the ModexMetaData ...

In a next cleaning PR

}
}

// arguments.clear();
Copy link
Collaborator

Choose a reason for hiding this comment

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

?

# junit.jupiter.execution.parallel.enabled = true
# junit.jupiter.execution.parallel.mode.default = concurrent
# junit.jupiter.execution.parallel.config.strategy = dynamic
junit.jupiter.execution.parallel.enabled = true
Copy link
Collaborator

Choose a reason for hiding this comment

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

wut ?

// Configure chain information and fork before any tests are run, including any methods used as
// MethodSource.
TracerTestBase.chainConfig = ChainConfig.MAINNET_TESTCONFIG(getForkOrDefault(OSAKA));
TracerTestBase.chainConfig = ChainConfig.MAINNET_TESTCONFIG(getForkOrDefault(PRAGUE));
Copy link
Collaborator

Choose a reason for hiding this comment

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

back to osaka, the release will be for Osaka

Copy link
Collaborator

Choose a reason for hiding this comment

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

to delete

}

protected boolean allXbsesAreInBounds() {
return true;
Copy link

Choose a reason for hiding this comment

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

Bug: Missing maxNumberOfLines override in LondonModexpSubsection

The LondonModexpSubsection class doesn't override the maxNumberOfLines() method that was present in the original ModexpSubsection class. This causes it to inherit the default implementation from PrecompileSubsection which returns 0, instead of the correct value NB_ROWS_HUB_PRC_MODEXP (13). This affects line counting for MODEXP precompile operations and could lead to incorrect trace sizing calculations.

Fix in Cursor Fix in Web

}

protected boolean allXbsesAreInBounds() {
return true;
Copy link

Choose a reason for hiding this comment

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

Bug: Missing maxNumberOfLines override in LondonModexpSubsection

The LondonModexpSubsection class was refactored from ModexpSubsection but the maxNumberOfLines() method override was removed. The diff shows the old ModexpSubsection had this method returning NB_ROWS_HUB_PRC_MODEXP (value 13), but the new LondonModexpSubsection doesn't override it, causing it to inherit the default return value of 0 from PrecompileSubsection. This breaks the precompile subsection initialization in the constructor which calls new ArrayList<>(maxNumberOfLines()), potentially causing incorrect memory allocation and fragment list sizing for MODEXP operations.

Fix in Cursor Fix in Web

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants