Skip to content

Conversation

@OlivierBBB
Copy link
Collaborator

@OlivierBBB OlivierBBB commented Oct 22, 2025

Note

Adds parameterized empty-block test scenarios and enables Besu-based execution/tracing with null-transaction placeholders, plus a minor Osaka import fix.

  • Tests:
    • Parameterize EmptyBlockTests to run with/without Besu across multiple empty/non-empty sequences (EENENE, NEEN, NEEE, ENNE, EEEE, EEEN, E).
    • Factor shared setup into class fields and builderFromBlockTypeList(...); conditionally validate hub/logs only when not using Besu.
  • Testing infrastructure:
    • MultiBlockExecutionEnvironment gains runWithBesuNode; when enabled, flattens blocks into a per-block stream including null for empty blocks and executes via BesuExecutionTools.
    • BesuExecutionTools accepts null transactions to represent empty blocks, requires at least one entry, computes trace start/end when all are empty, and aligns proof requests accordingly.
  • Minor:
    • Update Osaka gas-cap import to TraceOsaka.EIP_7825_TRANSACTION_GAS_LIMIT_CAP in OsakaUserTransaction.

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

@cursor
Copy link

cursor bot commented Oct 23, 2025

Bug: Null Transaction Handling Bug

When oneTxPerBlock is false, the executeTest method attempts to send all transactions without checking if they are null. This leads to a NullPointerException when calling .encoded() on a null transaction, a check that is present in the oneTxPerBlock true path.

Fix in Cursor Fix in Web

@cursor
Copy link

cursor bot commented Oct 23, 2025

Bug: Transaction List Nulls Cause Block Number Errors

The firstBlockNumber calculation is off when oneTxPerBlock is true and the transactions list includes nulls. The current logic subtracts numberOfLeadingEmptyBlocks from an already adjusted firstBlockNumber, which can lead to invalid block numbers (like zero or negative) and an incorrect tracing range.

Fix in Cursor Fix in Web

@cursor
Copy link

cursor bot commented Oct 23, 2025

Bug: Block Number Calculation Incorrect for Non-Standard Genesis Blocks

When blockNumbers.isEmpty() is true (all transactions are null), firstBlockNumber is set to 1 and finalBlockNumber is set to transactions.size(). This assumes the starting block number is 1, but blocks may start at a different number. The calculation should use the genesis block configuration or track the actual block numbers created, not hardcode 1.

Fix in Cursor Fix in Web

@cursor
Copy link

cursor bot commented Oct 23, 2025

Bug: Null Transaction Handling Mismatch

The else branch, which sends all transactions in a single block, doesn't filter out null transactions from the transactions list. This causes a NullPointerException when txs.next() returns null and encoded() is called, unlike the if branch which correctly handles these null entries.

Fix in Cursor Fix in Web

@cursor
Copy link

cursor bot commented Oct 23, 2025

Bug: Test Initialization Order Causes Null References

Instance fields (senderKeyPair, receivingAccount, storingNumber, logging, storing, reading) are initialized with references to chainConfig, but chainConfig is only initialized by the test framework after instance field initialization. This will cause these fields to use a null or uninitialized chainConfig, leading to NullPointerException or incorrect bytecode compilation. These fields should either be initialized lazily in a @beforeeach method or moved into the test methods themselves.

Fix in Cursor Fix in Web

@amkCha
Copy link
Collaborator

amkCha commented Nov 6, 2025

Thanks for fixing the daily ref tests !!

String txHash =
besuNode.execute(ethTransactions.sendRawTransaction(tx.encoded().toHexString()));
txHashes.add(txHash);
}
Copy link

Choose a reason for hiding this comment

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

Bug: NullPointer on Null Transactions in Else Branch

NullPointerException when oneTxPerBlock is false and transactions list contains null values. The else branch (lines 216-223) attempts to call .encoded() on txs.next() without checking if the transaction is null first. When a null transaction is encountered (representing an empty block), this will throw a NullPointerException. The if branch (lines 207-214) correctly handles null transactions with a null check, but the else branch is missing this protection.

Fix in Cursor Fix in Web

null);
besuExecTools.executeTest();
return;
}
Copy link

Choose a reason for hiding this comment

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

Bug: Early Exit Prevents Tracer Initialization

When runWithBesuNode is true, the run() method returns early without initializing the tracer field, leaving it null. Tests that call getHub() after running with Besu node will encounter a NullPointerException since getHub() returns tracer.getHub() and tracer is null.

Fix in Cursor Fix in Web

various configurations of empty / nonempty blocks, in particular

E
EEEE
EEEN
NEEN
NEEE
ENNE
EENENE

where E = empty block, N = nonempty block
@amkCha amkCha force-pushed the prover-tests-for-empty-blocks branch from 419045b to 7a66335 Compare November 20, 2025 11:53
@amkCha amkCha force-pushed the prover-tests-for-empty-blocks branch from 7a66335 to 5342cec Compare November 20, 2025 12:00
for (State.HubTransactionState state : hub.getState().getAll()) {
for (TraceSection section : state.traceSections().trace()) {
if (section instanceof LogSection) {
nbOfLog += 1;

Check failure

Code scanning / CodeQL

Implicit narrowing conversion in compound assignment High test

Implicit cast of source type int to narrower destination type
short
.

Copilot Autofix

AI 5 days ago

The best way to fix this problem is to widen the type of nbOfLog from short to int. This prevents any implicit narrowing conversion when performing compound assignment operations like nbOfLog += 1;. The code's logic and surrounding assumptions are not altered: the only change is the variable's type. You should update the declaration at line 180 from short to int. No additional imports or refactoring are required, and no other code changes are necessary.


Suggested changeset 1
arithmetization/src/test/java/net/consensys/linea/zktracer/EmptyBlockTests.java

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/EmptyBlockTests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/EmptyBlockTests.java
--- a/arithmetization/src/test/java/net/consensys/linea/zktracer/EmptyBlockTests.java
+++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/EmptyBlockTests.java
@@ -177,7 +177,7 @@
 
       if (!runWithBesu) {
         final State hub = env.getHub().state();
-        short nbOfLog = 0;
+        int nbOfLog = 0;
         for (State.HubTransactionState state : hub.getState().getAll()) {
           for (TraceSection section : state.traceSections().trace()) {
             if (section instanceof LogSection) {
EOF
@@ -177,7 +177,7 @@

if (!runWithBesu) {
final State hub = env.getHub().state();
short nbOfLog = 0;
int nbOfLog = 0;
for (State.HubTransactionState state : hub.getState().getAll()) {
for (TraceSection section : state.traceSections().trace()) {
if (section instanceof LogSection) {
Copilot is powered by AI and may make mistakes. Always verify output.
@amkCha amkCha enabled auto-merge (squash) November 20, 2025 15:48
long startBlockNumber = Collections.min(blockNumbers);
long endBlockNumber = Collections.max(blockNumbers);
TraceFile traceFile = traceAndCheckTracer(startBlockNumber, endBlockNumber, currentFork);
checkState(blockNumbers.isEmpty() == allTransactionsAreNull);
Copy link

Choose a reason for hiding this comment

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

Bug: Assertion failure for mixed empty blocks

The assertion checkState(blockNumbers.isEmpty() == allTransactionsAreNull) fails when processing an empty block in a test suite containing a mix of empty and non-empty blocks. For an empty block, blockNumbers is empty (no receipts), but allTransactionsAreNull is false, causing an IllegalStateException.

Fix in Cursor Fix in Web

long startBlockNumber = Collections.min(blockNumbers);
long endBlockNumber = Collections.max(blockNumbers);
TraceFile traceFile = traceAndCheckTracer(startBlockNumber, endBlockNumber, currentFork);
checkState(blockNumbers.isEmpty() == allTransactionsAreNull);
Copy link

Choose a reason for hiding this comment

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

Bug: Invalid assertion for mixed empty blocks

The checkState condition enforces that empty blocks (empty blockNumbers) can only occur if every transaction in the test is null. This causes an IllegalStateException when running tests with a mix of empty and non-empty blocks, as processing a single empty block results in blockNumbers being empty while allTransactionsAreNull is false.

Fix in Cursor Fix in Web

long firstBlockNumber = blockNumbers.isEmpty() ? 1 : Collections.min(blockNumbers);
long finalBlockNumber =
blockNumbers.isEmpty() ? transactions.size() : Collections.max(blockNumbers);
TraceFile traceFile = traceAndCheckTracer(firstBlockNumber, finalBlockNumber, currentFork);
Copy link

Choose a reason for hiding this comment

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

Bug: Trace generation requests non-existent blocks

When handling an empty block, finalBlockNumber defaults to the total number of transactions (transactions.size()). In sequential execution, this triggers a trace request for the entire planned block range before subsequent blocks have been mined, which will cause RPC errors by requesting blocks that do not yet exist.

Fix in Cursor Fix in Web

long startBlockNumber = Collections.min(blockNumbers);
long endBlockNumber = Collections.max(blockNumbers);
TraceFile traceFile = traceAndCheckTracer(startBlockNumber, endBlockNumber, currentFork);
checkState(blockNumbers.isEmpty() == allTransactionsAreNull);
Copy link

Choose a reason for hiding this comment

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

Bug: Null transaction causes NullPointerException when oneTxPerBlock false

When oneTxPerBlock is false, the code calls txs.next().encoded() without checking if the transaction is null. Null transactions represent empty blocks in this implementation, so calling .encoded() on null will throw a NullPointerException. The null check added for the oneTxPerBlock == true case is missing here.

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