Skip to content

test: add unit tests across all morph-reth crates#62

Merged
panos-xyz merged 3 commits intomainfrom
panos/unit-tests
Mar 31, 2026
Merged

test: add unit tests across all morph-reth crates#62
panos-xyz merged 3 commits intomainfrom
panos/unit-tests

Conversation

@panos-xyz
Copy link
Copy Markdown
Contributor

@panos-xyz panos-xyz commented Mar 26, 2026

Summary

  • Add #[cfg(test)] modules to every morph-reth crate with comprehensive coverage
  • Covers: chainspec, primitives, revm, evm, consensus, txpool, payload-builder, payload-types, engine-api, rpc, node
  • 500+ unit tests total, all passing

Scope

This PR contains only inline unit tests (no E2E test infrastructure or integration tests — those will follow in separate PRs).

Minor accompanying refactors:

  • Remove unused From<MorphConsensusError> for ConsensusError impl
  • Remove unused morph-evm dev-dependency from revm crate
  • Rename query_erc20_balancequery_balance_via_system_call
  • Clean up EIP-4788 trace override imports

Dependencies

Some tests cover behavior fixed in:

Those PRs should merge first to avoid trivial conflicts.

Test plan

  • cargo check --all --tests — compiles clean
  • cargo clippy --all --all-targets -- -D warnings — no warnings
  • cargo test --all — all tests pass

Summary by CodeRabbit

  • New Features

    • Small public constructors and builder improvements for payload and L2 data types.
  • Bug Fixes

    • More consistent validation/error mapping across consensus and transaction flows.
    • Corrected Morph transaction fee reimbursement and EVM block environment handling (PREVRANDAO/related behavior).
  • Tests

    • Extensive unit-test coverage added across consensus, engine, EVM, payloads, RPC, txpool, and primitives.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 26, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 4425b02f-8095-47b0-9e25-8ca95dbe58d1

📥 Commits

Reviewing files that changed from the base of the PR and between 87a7ea7 and 9ed10b9.

📒 Files selected for processing (1)
  • crates/rpc/Cargo.toml
💤 Files with no reviewable changes (1)
  • crates/rpc/Cargo.toml

📝 Walkthrough

Walkthrough

Adds extensive unit tests across many crates, removes the From<MorphConsensusError> for reth_consensus::ConsensusError impl and replaces implicit .into() error conversions with explicit ConsensusError::Other(...), makes a constructor const fn change, small control-flow adjustments (notably fee reimbursement), and several focused refactors. No production constant values were changed.

Changes

Cohort / File(s) Summary
Chainspec
crates/chainspec/src/constants.rs, crates/chainspec/src/hardfork.rs, crates/chainspec/src/spec.rs
Added tests for chain IDs, genesis hashes/state roots, hardfork ordering/mapping; duplicated a doc comment header.
Consensus
crates/consensus/src/error.rs, crates/consensus/src/validation.rs
Removed From<MorphConsensusError> for reth_consensus::ConsensusError; replaced implicit .into() uses with ConsensusError::Other(e.to_string()); added/updated validation tests.
Engine API
crates/engine-api/src/builder.rs, crates/engine-api/src/error.rs, crates/engine-api/src/validator.rs
Added tests for EngineStateTracker, executable-data overrides, error-code mappings, and Jade activation boundary behavior.
EVM / Assembler / Config / Receipts
crates/evm/src/assemble.rs, crates/evm/src/config.rs, crates/evm/src/block/mod.rs, crates/evm/src/block/receipt.rs
Added assembler and extensive receipt tests; set prevrandao to B256::ZERO in next_evm_env; replaced a closure with inline struct literals.
Payload builder & types
crates/payload/builder/src/builder.rs, crates/payload/types/...
Made with_config a const fn; changed constructor init style; added From<EthPayloadBuilderAttributes> and new() ctors; many payload/serde/payload-id tests.
Primitives: headers & receipts
crates/primitives/src/header.rs, crates/primitives/src/receipt/envelope.rs, crates/primitives/src/receipt/mod.rs, crates/primitives/src/transaction/envelope.rs
Added header RLP/size/HeaderMut tests; switched Typed2718/ty to explicit variant match; refactored per-variant RLP dispatch; changed tx-type predicates to use tx_type().
REVM: handler, token fee, precompiles, evm, l1block
crates/revm/src/handler.rs, crates/revm/src/token_fee.rs, crates/revm/src/precompiles.rs, crates/revm/src/evm.rs, crates/revm/src/l1block.rs, crates/revm/Cargo.toml
Explicitly handle fee_token_id == 0 ETH reimbursement path; refactored ERC20 balance query into query_balance_via_system_call with a public wrapper; added BLOCKHASH/precompile/L1 gas/fee tests; removed a dev-dep entry.
RPC & types
crates/rpc/src/error.rs, crates/rpc/src/eth/mod.rs, crates/rpc/src/eth/receipt.rs, crates/rpc/src/eth/transaction.rs, crates/rpc/src/types/*, crates/rpc/Cargo.toml
Added tests for API error display/JSON-RPC codes; adjusted Trace::apply_pre_execution_changes trait bounds/signature; added receipt/transaction conversion and serialization tests; tiny manifest whitespace change.
Txpool, node & validator
crates/txpool/src/*, crates/node/src/args.rs, crates/node/src/validator.rs
Expanded txpool error/predicate/display tests; updated morph-tx validation tests (fee-paths, missing token cases); pooled tx roundtrip tests; node arg parsing and validator expectation tests.
Misc small refactors/tests
crates/evm/src/block/mod.rs, crates/revm/src/tx.rs, crates/payload/types/src/*, crates/primitives/*
Minor refactors (split chained assignments, inline struct literals), added new() constructors, and numerous focused unit tests across modules.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

Suggested labels

enhancement

Suggested reviewers

  • anylots
  • chengwenxi

Poem

🐇 I hopped through tests both near and far,
Counting hashes, fees, and every star.
With tiny tweaks and assertions bright,
The rabbit cheers: "This suite runs right!" 🥕

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding unit tests across all morph-reth crates. It is concise, clear, and reflects the primary objective of the changeset.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch panos/unit-tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@panos-xyz panos-xyz requested review from anylots and chengwenxi March 26, 2026 04:59
Copy link
Copy Markdown
Contributor

@chengwenxi chengwenxi left a comment

Choose a reason for hiding this comment

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

LGTM. 500+ unit tests across all crates — excellent coverage improvement. Production code changes are correct refactors. Minor items for follow-up:

  • Remove duplicate use alloy_consensus::Transaction as TransactionTrait in transaction.rs
  • Add prevrandao == B256::ZERO assertion to test_next_evm_env_increments_block_number
  • Restore or replace test_validate_l1_messages_in_block_skipped_messages_allowed (or document new semantics from PR #59)
  • Remove unnecessary use std::boxed::Box / use std::string::String in precompiles.rs

Add #[cfg(test)] modules to every crate with comprehensive coverage:
- chainspec: constants, hardfork ordering, chain spec construction
- primitives: header, receipt envelope, transaction encoding/decoding
- revm: error types, EVM config, L1 block fee calculation, precompiles,
  token fee logic, transaction environment
- evm: block assembler, receipt builder, EVM config hardfork mapping
- consensus: header validation, L1 message sequencing, timestamp rules
- txpool: error types, MorphTx validation, transaction type handling
- payload-builder: execution info, builder configuration
- payload-types: attributes, executable/safe L2 data, params
- engine-api: builder state tracker, error types, validator
- rpc: error types, receipt/transaction serialization, request types
- node: CLI args, engine validator

Minor accompanying refactors:
- Remove unused From<MorphConsensusError> for ConsensusError impl
- Remove unused morph-evm dev-dependency from revm crate
- Rename query_erc20_balance to query_balance_via_system_call
- Clean up EIP-4788 trace override imports
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
crates/revm/src/token_fee.rs (1)

248-269: ⚠️ Potential issue | 🟠 Major

Propagate DB errors out of the new helper.

read_token_balance_with_fallback() still distinguishes EVMError::Database(_) from other call failures, but this helper now converts every Err into Ok(U256::ZERO). That masks storage/backend failures as a zero balance and turns TokenInfoFetchFailed into spurious balance validation errors.

Suggested fix
 fn query_balance_via_system_call<DB, I>(
     evm: &mut MorphEvm<DB, I>,
     token: Address,
     account: Address,
 ) -> Result<U256, EVMError<DB::Error, MorphInvalidTransaction>>
 where
     DB: Database,
 {
     let calldata = encode_balance_of_calldata(account);
     match evm.system_call_one(token, calldata) {
         Ok(result) if result.is_success() => {
             if let Some(output) = result.output()
                 && output.len() >= 32
             {
                 return Ok(U256::from_be_slice(&output[..32]));
             }
             Ok(U256::ZERO)
         }
         Ok(_) => Ok(U256::ZERO),
-        Err(_) => Ok(U256::ZERO),
+        Err(err) => Err(err),
     }
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/revm/src/token_fee.rs` around lines 248 - 269, The helper
query_balance_via_system_call currently swallows all evm.system_call_one errors
and returns Ok(U256::ZERO), masking real DB/backend failures; change the Err(_)
arm to propagate the error (return Err(e)) so EVMError::Database(...) is
forwarded to callers (e.g., read_token_balance_with_fallback) instead of being
treated as a zero balance; keep the existing behavior for Ok(result) when the
call is non-success or output is missing (return Ok(U256::ZERO)), but ensure the
Err path returns the original EVMError from system_call_one.
🧹 Nitpick comments (5)
crates/txpool/src/transaction.rs (1)

326-332: Tighten the cache test to assert identity, not just equal bytes.

test_encoded_2718_is_cached currently proves deterministic encoding, but not that the same cached instance is reused. Consider asserting pointer identity too.

♻️ Suggested improvement
 #[test]
 fn test_encoded_2718_is_cached() {
     let tx = create_legacy_pooled_tx();
-    let bytes1 = tx.encoded_2718().clone();
-    let bytes2 = tx.encoded_2718().clone();
-    assert_eq!(bytes1, bytes2, "cached encoding should be identical");
-    assert!(!bytes1.is_empty());
+    let bytes1 = tx.encoded_2718();
+    let bytes2 = tx.encoded_2718();
+    assert!(std::ptr::eq(bytes1, bytes2), "should return the same cached Bytes instance");
+    assert!(!bytes1.is_empty());
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/txpool/src/transaction.rs` around lines 326 - 332, The test
test_encoded_2718_is_cached should assert that the cached buffer instance is
reused, not just that two encodings are equal; change the test to obtain the two
values without forcing independent allocations and assert pointer identity
(e.g., if encoded_2718() returns an Arc<Vec<u8>> use Arc::ptr_eq(&a, &b), or if
it returns a Vec<u8> or slice compare their as_ptr() addresses) instead of only
assert_eq!(bytes1, bytes2), and keep the non-empty check; reference the test
function name test_encoded_2718_is_cached and the encoded_2718() accessor when
making this change.
crates/chainspec/src/spec.rs (1)

134-137: Remove the duplicated section banner.

Line 134-Line 137 repeats the same “Chain Specification Parser (CLI)” header that already exists a few lines above, so trimming this duplicate will keep the file structure cleaner.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/chainspec/src/spec.rs` around lines 134 - 137, Remove the duplicated
banner "Chain Specification Parser (CLI)" found in the second occurrence (the
block starting with //
=============================================================================
and the header line) so only the first instance remains; locate the duplicate
comment block containing the exact string "Chain Specification Parser (CLI)" and
delete that repeated banner lines (the surrounding //
=============================================================================
lines and the header comment) to leave a single header for the Chain
Specification Parser (CLI).
crates/engine-api/src/builder.rs (1)

1189-1197: Test intent/name mismatch in non-canonical-event case.

At Line 1189, test_engine_state_tracker_ignores_non_canonical_events doesn’t actually dispatch a non-canonical event, so the test currently validates only initial state. Consider renaming it or adding an explicit non-canonical event assertion.

Suggested minimal rename
-    fn test_engine_state_tracker_ignores_non_canonical_events() {
+    fn test_engine_state_tracker_initial_state_without_events() {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/engine-api/src/builder.rs` around lines 1189 - 1197, The test named
test_engine_state_tracker_ignores_non_canonical_events currently only constructs
EngineStateTracker::default and asserts tracker.current_head().is_none() but
never dispatches a non-canonical event; either rename the test to reflect it
only checks initial state (e.g.,
test_engine_state_tracker_initial_state_is_none) or modify it to actually send a
non-canonical event and assert the head remains unchanged — locate the test
function test_engine_state_tracker_ignores_non_canonical_events and either
change its name or call the appropriate non-canonical event handler on the
EngineStateTracker (e.g., use the same event enum variant used elsewhere such as
LiveSyncProgress or another non-canonical variant) and then assert
tracker.current_head().is_none() after the event.
crates/node/src/validator.rs (1)

556-582: Make the Jade-off assertion independent of MORPH_HOODI.

This test depends on Hoodi's current hardfork schedule, so a future Jade activation will turn it into a false failure even if validate_state_root() is unchanged. A local chainspec fixture with Jade explicitly disabled, or at least an explicit precondition assert, would keep it stable.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/node/src/validator.rs` around lines 556 - 582, The test
test_validate_state_root_jade_not_active_always_ok currently relies on the
global MORPH_HOODI schedule via test_chain_spec(); make it deterministic by
either creating a local chainspec fixture with Jade explicitly disabled (e.g.,
construct a ChainSpec passed into MorphEngineValidator::new(...) where the Jade
activation is None or set beyond the test block) or add an explicit precondition
assert that Jade is not active before calling validate_state_root(&recovered,
...). Update the test to use that local chainspec or assert the precondition so
MorphEngineValidator::new(test_chain_spec()) and the call to validate_state_root
are guaranteed to run with Jade off regardless of external hardfork changes.
crates/consensus/src/validation.rs (1)

960-976: Add back one success case for skipped L1 queue indices.

The docs and implementation intentionally allow header.next_l1_msg_index > last_queue_index + 1, but this section now only covers exact-match and too-small values. Keeping one positive test for the > path would protect that Morph-specific invariant.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/consensus/src/validation.rs` around lines 960 - 976, The test suite
removed a positive case that verifies header.next_l1_msg_index can be greater
than last_queue_index+1; add back a success test that calls
validate_l1_messages_in_block with a sequence of L1 messages (e.g.,
create_l1_msg_tx(0), create_l1_msg_tx(1), create_l1_msg_tx(2),
create_regular_tx()) and a header next_l1_msg_index strictly larger than last+1
(for example 5) and assert the call returns Ok; create a test named like
test_validate_l1_messages_in_block_skipped_next_l1_msg_index_success (or update
the existing test set) to ensure validate_l1_messages_in_block accepts the >
case.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@crates/payload/builder/src/builder.rs`:
- Around line 789-792: The test shows ExecutionInfo::new stores u64::MAX in
next_l1_message_index but that is unsafe because the builder later increments
the index with a plain + 1 and will wrap/panic; fix by preventing creation or
unsafe increment: either (A) change ExecutionInfo::new to validate and reject
u64::MAX (return Result or assert that next_l1_message_index != u64::MAX) so
invalid state cannot be constructed, or (B) change the builder's increment site
(the code that does next_l1_message_index + 1) to use checked_add/saturating_add
and return a clear validation error instead of wrapping; update the test for
ExecutionInfo::new accordingly if you choose validation on construction. Ensure
you reference ExecutionInfo::new, next_l1_message_index, and the builder
increment (+ 1) when making the change.

---

Outside diff comments:
In `@crates/revm/src/token_fee.rs`:
- Around line 248-269: The helper query_balance_via_system_call currently
swallows all evm.system_call_one errors and returns Ok(U256::ZERO), masking real
DB/backend failures; change the Err(_) arm to propagate the error (return
Err(e)) so EVMError::Database(...) is forwarded to callers (e.g.,
read_token_balance_with_fallback) instead of being treated as a zero balance;
keep the existing behavior for Ok(result) when the call is non-success or output
is missing (return Ok(U256::ZERO)), but ensure the Err path returns the original
EVMError from system_call_one.

---

Nitpick comments:
In `@crates/chainspec/src/spec.rs`:
- Around line 134-137: Remove the duplicated banner "Chain Specification Parser
(CLI)" found in the second occurrence (the block starting with //
=============================================================================
and the header line) so only the first instance remains; locate the duplicate
comment block containing the exact string "Chain Specification Parser (CLI)" and
delete that repeated banner lines (the surrounding //
=============================================================================
lines and the header comment) to leave a single header for the Chain
Specification Parser (CLI).

In `@crates/consensus/src/validation.rs`:
- Around line 960-976: The test suite removed a positive case that verifies
header.next_l1_msg_index can be greater than last_queue_index+1; add back a
success test that calls validate_l1_messages_in_block with a sequence of L1
messages (e.g., create_l1_msg_tx(0), create_l1_msg_tx(1), create_l1_msg_tx(2),
create_regular_tx()) and a header next_l1_msg_index strictly larger than last+1
(for example 5) and assert the call returns Ok; create a test named like
test_validate_l1_messages_in_block_skipped_next_l1_msg_index_success (or update
the existing test set) to ensure validate_l1_messages_in_block accepts the >
case.

In `@crates/engine-api/src/builder.rs`:
- Around line 1189-1197: The test named
test_engine_state_tracker_ignores_non_canonical_events currently only constructs
EngineStateTracker::default and asserts tracker.current_head().is_none() but
never dispatches a non-canonical event; either rename the test to reflect it
only checks initial state (e.g.,
test_engine_state_tracker_initial_state_is_none) or modify it to actually send a
non-canonical event and assert the head remains unchanged — locate the test
function test_engine_state_tracker_ignores_non_canonical_events and either
change its name or call the appropriate non-canonical event handler on the
EngineStateTracker (e.g., use the same event enum variant used elsewhere such as
LiveSyncProgress or another non-canonical variant) and then assert
tracker.current_head().is_none() after the event.

In `@crates/node/src/validator.rs`:
- Around line 556-582: The test
test_validate_state_root_jade_not_active_always_ok currently relies on the
global MORPH_HOODI schedule via test_chain_spec(); make it deterministic by
either creating a local chainspec fixture with Jade explicitly disabled (e.g.,
construct a ChainSpec passed into MorphEngineValidator::new(...) where the Jade
activation is None or set beyond the test block) or add an explicit precondition
assert that Jade is not active before calling validate_state_root(&recovered,
...). Update the test to use that local chainspec or assert the precondition so
MorphEngineValidator::new(test_chain_spec()) and the call to validate_state_root
are guaranteed to run with Jade off regardless of external hardfork changes.

In `@crates/txpool/src/transaction.rs`:
- Around line 326-332: The test test_encoded_2718_is_cached should assert that
the cached buffer instance is reused, not just that two encodings are equal;
change the test to obtain the two values without forcing independent allocations
and assert pointer identity (e.g., if encoded_2718() returns an Arc<Vec<u8>> use
Arc::ptr_eq(&a, &b), or if it returns a Vec<u8> or slice compare their as_ptr()
addresses) instead of only assert_eq!(bytes1, bytes2), and keep the non-empty
check; reference the test function name test_encoded_2718_is_cached and the
encoded_2718() accessor when making this change.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a064bbac-4c24-478b-8b3c-ed7b26066d37

📥 Commits

Reviewing files that changed from the base of the PR and between cf3ce29 and 880a235.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (43)
  • crates/chainspec/src/constants.rs
  • crates/chainspec/src/hardfork.rs
  • crates/chainspec/src/spec.rs
  • crates/consensus/src/error.rs
  • crates/consensus/src/validation.rs
  • crates/engine-api/src/builder.rs
  • crates/engine-api/src/error.rs
  • crates/engine-api/src/validator.rs
  • crates/evm/src/assemble.rs
  • crates/evm/src/block/mod.rs
  • crates/evm/src/block/receipt.rs
  • crates/evm/src/config.rs
  • crates/node/src/args.rs
  • crates/node/src/validator.rs
  • crates/payload/builder/src/builder.rs
  • crates/payload/types/src/attributes.rs
  • crates/payload/types/src/executable_l2_data.rs
  • crates/payload/types/src/lib.rs
  • crates/payload/types/src/params.rs
  • crates/payload/types/src/safe_l2_data.rs
  • crates/primitives/src/header.rs
  • crates/primitives/src/receipt/envelope.rs
  • crates/primitives/src/receipt/mod.rs
  • crates/primitives/src/transaction/envelope.rs
  • crates/revm/Cargo.toml
  • crates/revm/src/error.rs
  • crates/revm/src/evm.rs
  • crates/revm/src/handler.rs
  • crates/revm/src/l1block.rs
  • crates/revm/src/precompiles.rs
  • crates/revm/src/token_fee.rs
  • crates/revm/src/tx.rs
  • crates/rpc/Cargo.toml
  • crates/rpc/src/error.rs
  • crates/rpc/src/eth/mod.rs
  • crates/rpc/src/eth/receipt.rs
  • crates/rpc/src/eth/transaction.rs
  • crates/rpc/src/types/receipt.rs
  • crates/rpc/src/types/request.rs
  • crates/rpc/src/types/transaction.rs
  • crates/txpool/src/error.rs
  • crates/txpool/src/morph_tx_validation.rs
  • crates/txpool/src/transaction.rs
💤 Files with no reviewable changes (2)
  • crates/consensus/src/error.rs
  • crates/revm/Cargo.toml

Comment on lines +789 to +792
fn test_execution_info_new_with_max_index() {
let info = ExecutionInfo::new(u64::MAX);
assert_eq!(info.next_l1_message_index, u64::MAX);
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

u64::MAX is still unsafe in the real L1-message path.

This boundary case only proves ExecutionInfo::new() stores u64::MAX. The builder later increments the queue index with a plain + 1, so an L1 message at u64::MAX will still wrap/panic instead of surfacing a validation error.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/payload/builder/src/builder.rs` around lines 789 - 792, The test shows
ExecutionInfo::new stores u64::MAX in next_l1_message_index but that is unsafe
because the builder later increments the index with a plain + 1 and will
wrap/panic; fix by preventing creation or unsafe increment: either (A) change
ExecutionInfo::new to validate and reject u64::MAX (return Result or assert that
next_l1_message_index != u64::MAX) so invalid state cannot be constructed, or
(B) change the builder's increment site (the code that does
next_l1_message_index + 1) to use checked_add/saturating_add and return a clear
validation error instead of wrapping; update the test for ExecutionInfo::new
accordingly if you choose validation on construction. Ensure you reference
ExecutionInfo::new, next_l1_message_index, and the builder increment (+ 1) when
making the change.

panos-xyz and others added 2 commits March 31, 2026 22:17
The merge of main into the branch produced a duplicate
[dev-dependencies] section which breaks cargo.
@panos-xyz panos-xyz merged commit 9c05968 into main Mar 31, 2026
10 checks passed
@panos-xyz panos-xyz deleted the panos/unit-tests branch March 31, 2026 14:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants