Skip to content

Conversation

@ameten
Copy link
Collaborator

@ameten ameten commented Nov 17, 2025

Description

Lander Transaction Submission Observability:

  • Transaction will stay in Submit Queue until they are included

Related issues

Backward compatibility

Yes

Testing

Unit tests

Summary by CodeRabbit

  • New Features
    • Introduced a "Ready to Submit" stage, a dedicated submit stage, and new routing so operations can be re-queued for submission instead of being confirmed immediately; preparation now considers the submit queue when deciding routing.
  • Bug Fixes
    • Updated disposition mappings (including Submit, PostSubmitSuccess, PostSubmitFailure), added runtime warnings, refined error handling, and brief sleeps to reduce busy-waiting; confirmation is deferred to the new submission workflow.
  • Tests
    • Expanded coverage across prepare/submit/confirm flows, multi-UUID and error scenarios, concurrency; updated test helpers and test metrics.

✏️ Tip: You can customize this high-level summary in your review settings.

@changeset-bot
Copy link

changeset-bot bot commented Nov 17, 2025

⚠️ No Changeset found

Latest commit: a06712b

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 17, 2025

📝 Walkthrough

Walkthrough

This change adds a Submit stage and a PendingOperationStatus::ReadyToSubmit path, refactors disposition mapping into Submit/PostSubmitSuccess/PostSubmitFailure, routes operations through Prepare → Submit → Confirm via new filtering functions, updates signatures to accept a submit queue, and expands tests and test utilities.

Changes

Cohort / File(s) Change Summary
Core message processor
rust/main/agents/relayer/src/msg/message_processor.rs
Integrate ReadyToSubmit into flow; submit_lander_task batches and calls filter_operations_for_submit; submit_via_lander refactored to push ReadyToSubmit into submit queue instead of direct confirm; add short sleeps for empty/backpressure cases.
Disposition logic
rust/main/agents/relayer/src/msg/message_processor/disposition.rs
Add Submit, PostSubmitSuccess, PostSubmitFailure to OperationDisposition; change operation_disposition_by_payload_status visibility to pub(crate); map payload/tx statuses into new disposition set; add warning logs and explicit handling of missing/erroneous UUIDs.
Disposition tests
rust/main/agents/relayer/src/msg/message_processor/disposition/tests.rs
Update expectations to reflect Submit/PostSubmit mappings for various payload/tx statuses and error scenarios.
Stage module
rust/main/agents/relayer/src/msg/message_processor/stage.rs
Add pub(crate) mod submit;.
Prepare stage
rust/main/agents/relayer/src/msg/message_processor/stage/prepare.rs
filter_operations_for_preparation now accepts submit_queue; route Submit to enqueue as ReadyToSubmit, PostSubmit* to confirm/retry paths; add determine_operation_disposition and helper to remove payload-message linkage.
Prepare stage tests
rust/main/agents/relayer/src/msg/message_processor/stage/prepare/tests/*
Extend tests to cover Submit/ReadyToSubmit/Mempool/Included/Finalized/Retry/Drop and DB/entrypoint error cases; thread submit_queue into assertions.
New submit stage
rust/main/agents/relayer/src/msg/message_processor/stage/submit.rs, rust/main/agents/relayer/src/msg/message_processor/stage/submit/tests.rs
Add filter_operations_for_submit to compute dispositions and route ops: return PreSubmit ops for resubmission, requeue Submit as ReadyToSubmit, and send PostSubmit* to confirmation; add comprehensive unit and concurrency tests.
Test utilities
rust/main/agents/relayer/src/msg/message_processor/tests/tests_common.rs
Add destination: HyperlaneDomain to MockQueueOperation, update constructors and destination_domain(); add create_test_metrics() helper returning MessageProcessorMetrics.

Sequence Diagram(s)

sequenceDiagram
    rect rgba(200,230,200,0.3)
    participant LP as LanderTask
    participant PREP as Prepare
    participant SQ as SubmitQueue
    participant SUB as Submit
    participant CQ as ConfirmQueue
    participant EP as Entrypoint/DB
    end

    LP->>PREP: batch -> filter_operations_for_preparation
    PREP->>EP: query payload/tx status
    alt PreSubmit
        PREP->>LP: return ops for payload resubmit
    else Submit
        PREP->>SQ: enqueue op as ReadyToSubmit
    else PostSubmitSuccess/PostSubmitFailure
        PREP->>CQ: enqueue for confirmation or retry/linkage removal
    end

    SQ->>SUB: ReadyToSubmit batch -> filter_operations_for_submit
    SUB->>EP: re-query payload/tx status
    alt PreSubmit
        SUB->>SUB: return ops for immediate resubmit
    else Submit
        SUB->>SQ: re-queue op as ReadyToSubmit
    else PostSubmitSuccess/PostSubmitFailure
        SUB->>CQ: enqueue for confirmation or retry handling
    end

    CQ->>EP: confirmation checks / finalize
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

  • Inspect ReadyToSubmit re-queue loop for potential livelock/backpressure and sleep/backoff behavior.
  • Verify disposition mapping coverage in disposition.rs (including InTransaction variants and Retry).
  • Review updated signatures where submit_queue is threaded through prepare/tests and confirm all call sites updated.
  • Check multithreaded tests in submit stage for race conditions and mock expectations.

Possibly related PRs

Suggested reviewers

  • yjamin
  • kamiyaa

Poem

In queues where weary ops abide,
ReadyToSubmit takes a stride,
Prepare nudges, Submit sighs,
Confirm stamps truths beneath the skies,
Pipelines hum — all's patched and tidy.

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately captures the main objective of enabling observability for Lander transaction submission, which is reflected in the architectural changes throughout the changeset.
Description check ✅ Passed The description provides the essential information (what, why, backward compatibility, testing), though it could be more detailed about the technical approach and scope.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch ameten/lander-tx-submission-observability

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1b5361d and 3081492.

📒 Files selected for processing (1)
  • rust/main/agents/relayer/src/msg/message_processor/disposition/tests.rs (9 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (12)
  • GitHub Check: infra-test
  • GitHub Check: build-and-push-to-gcr
  • GitHub Check: lander-coverage
  • GitHub Check: test-rs
  • GitHub Check: lint-rs
  • GitHub Check: e2e-matrix (cosmosnative)
  • GitHub Check: e2e-matrix (radix)
  • GitHub Check: e2e-matrix (starknet)
  • GitHub Check: e2e-matrix (cosmwasm)
  • GitHub Check: e2e-matrix (sealevel)
  • GitHub Check: e2e-matrix (evm)
  • GitHub Check: yarn-install
🔇 Additional comments (10)
rust/main/agents/relayer/src/msg/message_processor/disposition/tests.rs (10)

144-145: Looks good, these test updates align with the new disposition model.

The mapping of Dropped payload status to PostSubmitFailure makes sense semantically - the payload was submitted but then failed/dropped.


185-186: Correct mapping for dropped transactions.

Consistent with the payload dropped test, this properly maps transaction failures to PostSubmitFailure.


226-227: Good distinction between submission phases.

Mapping PendingInclusion to Submit correctly represents that the transaction is still in-flight during the submission phase, not yet finalized.


263-264: Proper success state for finalized transactions.

The mapping to PostSubmitSuccess correctly represents the terminal success state when a transaction is finalized.


344-345: Consistent handling for multiple UUIDs.

The first payload UUID is finalized, so PostSubmitSuccess is the correct expectation. Aligns well with the single-UUID finalized test.


381-382: Right disposition for ready-to-submit payloads.

Mapping ReadyToSubmit status to Submit disposition makes sense - the payload is ready and should enter the active submission phase.


418-419: Appropriate failure state for retry scenarios.

The Retry status (due to reorg) correctly maps to PostSubmitFailure - the previous submission was invalidated and needs to be retried.


455-456: Correct in-flight state for mempool transactions.

Transactions in the mempool are still in the submission phase, so mapping to Submit is appropriate and consistent with PendingInclusion.


492-493: Success state for included transactions.

Even though the block is unfinalized, a transaction that's included has successfully completed submission, so PostSubmitSuccess is the right disposition.


18-495: Well-organized test coverage for the new disposition model.

All test updates are semantically consistent and correctly map payload/transaction states to the appropriate disposition variants:

  • Error cases (DB, no UUIDs, entrypoint) → PreSubmit
  • Dropped/failed states → PostSubmitFailure
  • In-flight states (mempool, pending inclusion, ready to submit) → Submit
  • Success states (finalized, included) → PostSubmitSuccess

The refactoring provides better observability by distinguishing between different post-submission outcomes.


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.

Copy link
Contributor

@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: 0

🧹 Nitpick comments (5)
rust/main/agents/relayer/src/msg/message_processor/stage/submit.rs (1)

22-70: Submit-stage routing matches disposition model; consider optional parallelism

This function does what it says on the tin: it reuses operation_disposition_by_payload_status and cleanly routes PreSubmit ops back to the caller, keeps Submit ones in the submit queue with ReadyToSubmit, and pushes PostSubmit through confirm_op. Nice and easy to follow.

If batches ever get large or payload status calls are slow, you might eventually want to fan these lookups out (e.g. futures::future::join_all over the ops) instead of awaiting each one in sequence, but that’s polish rather than a blocker.

rust/main/agents/relayer/src/msg/message_processor/stage/submit/tests.rs (1)

18-915: Submit-stage tests nicely pin down all status paths

This suite hammers filter_operations_for_submit from every angle: errors, all drop reasons, retry, the three Submit‑class statuses, included/finalized, empty/mixed batches, and queue state after routing. The expectations match the production logic (PreSubmit → returned, Submit → re‑queued, PostSubmit → confirm), so behavior is well‑pinned.

If you ever get tired of repeating the same setup dance, you could pull some of the “one op + status X → expected queue/vec state” patterns into helpers, but as it stands it’s readable and does the job.

rust/main/agents/relayer/src/msg/message_processor/stage/prepare/tests/tests_filter_operations_for_preparation.rs (2)

245-312: Submitted vs non‑submitted mixed batches align with disposition mapping

The “all submitted”, “none submitted”, and mixed‑batch tests correctly exercise Finalized vs not‑found vs PendingInclusion cases, and the asserts on result lengths and confirm/submit queue sizes match the OperationDisposition mapping. There’s some repetition across these setups, but nothing that hurts readability; factoring a small helper for common batch construction is optional.

Also applies to: 314-356, 359-461


744-1050: New tests for Submit/PostSubmit variants thoroughly exercise routing

The ReadyToSubmit, Mempool, Included, “all to submit”, and mixed‑Submit‑variant tests nicely prove that Submit dispositions stay in the submit queue and PostSubmit ones move to confirm. If you ever want to tighten things further, a tiny helper to peek IDs or statuses in the queues (not just lengths) could catch mis‑routing bugs early, but as is this already covers the main behavior well.

rust/main/agents/relayer/src/msg/message_processor.rs (1)

557-594: Lander submit loop and submit_via_lander keep ops in the submit pipeline until inclusion

The new submit_lander_task pattern—pop batch, filter via filter_operations_for_submit, sleep when nothing is PreSubmit, then call submit_via_lander on the rest—gives a clear separation between “needs payload” and “waiting on inclusion”. Having submit_via_lander store the payload mapping and push the op back with ReadyToSubmit ensures the operation sticks in the submit queue until status flips to Included/Finalized and filter_operations_for_submit hands it off to confirm_op. Only small thought: if you ever want to track “sent to Lander” separately from “moved to confirm queue”, an extra metric hook here could help, but functionally this flow looks sound.

Also applies to: 596-602, 652-659

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9594322 and e9c5570.

📒 Files selected for processing (10)
  • rust/main/agents/relayer/src/msg/message_processor.rs (6 hunks)
  • rust/main/agents/relayer/src/msg/message_processor/disposition.rs (2 hunks)
  • rust/main/agents/relayer/src/msg/message_processor/disposition/tests.rs (4 hunks)
  • rust/main/agents/relayer/src/msg/message_processor/stage.rs (1 hunks)
  • rust/main/agents/relayer/src/msg/message_processor/stage/prepare.rs (3 hunks)
  • rust/main/agents/relayer/src/msg/message_processor/stage/prepare/tests/tests_determine_operation_disposition.rs (17 hunks)
  • rust/main/agents/relayer/src/msg/message_processor/stage/prepare/tests/tests_filter_operations_for_preparation.rs (30 hunks)
  • rust/main/agents/relayer/src/msg/message_processor/stage/submit.rs (1 hunks)
  • rust/main/agents/relayer/src/msg/message_processor/stage/submit/tests.rs (1 hunks)
  • rust/main/agents/relayer/src/msg/message_processor/tests/tests_common.rs (4 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-07-02T13:58:07.164Z
Learnt from: daniel-savu
Repo: hyperlane-xyz/hyperlane-monorepo PR: 6668
File: rust/main/lander/src/dispatcher/stages/building_stage/building.rs:41-41
Timestamp: 2025-07-02T13:58:07.164Z
Learning: In Rust lander BuildingStage, the update_metrics() call should be positioned after checking if payloads are empty to avoid unnecessary metrics updates during idle polling loops. The queue.len() operation is lightweight for VecDeque-based queues.

Applied to files:

  • rust/main/agents/relayer/src/msg/message_processor/tests/tests_common.rs
  • rust/main/agents/relayer/src/msg/message_processor.rs
🧬 Code graph analysis (9)
rust/main/agents/relayer/src/msg/message_processor/stage.rs (1)
rust/main/agents/relayer/src/msg/message_processor/tests/tests_common.rs (1)
  • submit (105-107)
rust/main/agents/relayer/src/msg/message_processor/disposition.rs (1)
rust/main/agents/relayer/src/msg/message_processor/tests/tests_common.rs (1)
  • id (59-61)
rust/main/agents/relayer/src/msg/message_processor/tests/tests_common.rs (3)
rust/main/agents/relayer/src/msg/message_processor.rs (2)
  • new (106-147)
  • new (991-1003)
rust/main/hyperlane-core/src/chain.rs (1)
  • new_test_domain (333-341)
rust/main/hyperlane-base/src/metrics/core.rs (1)
  • processor_queue_length (594-596)
rust/main/agents/relayer/src/msg/message_processor/stage/prepare.rs (1)
rust/main/agents/relayer/src/msg/message_processor.rs (2)
  • batch (466-466)
  • batch (805-811)
rust/main/agents/relayer/src/msg/message_processor/stage/submit/tests.rs (2)
rust/main/agents/relayer/src/msg/message_processor/tests/tests_common.rs (6)
  • submit (105-107)
  • create_test_metrics (185-214)
  • create_test_queue (164-182)
  • new (33-39)
  • id (59-61)
  • with_first_prepare (41-44)
rust/main/agents/relayer/src/msg/message_processor/stage/submit.rs (1)
  • filter_operations_for_submit (22-70)
rust/main/agents/relayer/src/msg/message_processor/stage/prepare/tests/tests_determine_operation_disposition.rs (3)
rust/main/agents/relayer/src/msg/message_processor/tests/tests_common.rs (3)
  • create_test_queue (164-182)
  • new (33-39)
  • with_first_prepare (41-44)
rust/main/hyperlane-core/src/chain.rs (1)
  • new_test_domain (333-341)
rust/main/agents/relayer/src/msg/message_processor/stage/prepare.rs (1)
  • filter_operations_for_preparation (24-63)
rust/main/agents/relayer/src/msg/message_processor/stage/submit.rs (2)
rust/main/agents/relayer/src/msg/message_processor.rs (1)
  • confirm_op (712-737)
rust/main/agents/relayer/src/msg/message_processor/disposition.rs (1)
  • operation_disposition_by_payload_status (25-73)
rust/main/agents/relayer/src/msg/message_processor/stage/prepare/tests/tests_filter_operations_for_preparation.rs (3)
rust/main/agents/relayer/src/msg/message_processor/tests/tests_common.rs (4)
  • create_test_queue (164-182)
  • new (33-39)
  • with_first_prepare (41-44)
  • id (59-61)
rust/main/agents/relayer/src/msg/message_processor/stage/prepare.rs (1)
  • filter_operations_for_preparation (24-63)
rust/main/hyperlane-core/src/chain.rs (1)
  • new_test_domain (333-341)
rust/main/agents/relayer/src/msg/message_processor.rs (2)
rust/main/agents/relayer/src/msg/op_batch.rs (1)
  • submit (30-52)
rust/main/agents/relayer/src/msg/pending_message.rs (1)
  • submit (375-422)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
  • GitHub Check: build-and-push-to-gcr
  • GitHub Check: e2e-matrix (starknet)
  • GitHub Check: e2e-matrix (radix)
  • GitHub Check: e2e-matrix (sealevel)
  • GitHub Check: e2e-matrix (cosmosnative)
  • GitHub Check: e2e-matrix (evm)
  • GitHub Check: e2e-matrix (cosmwasm)
  • GitHub Check: lander-coverage
  • GitHub Check: test-rs
  • GitHub Check: lint-rs
🔇 Additional comments (15)
rust/main/agents/relayer/src/msg/message_processor/stage.rs (1)

1-2: Submit stage wiring looks fine

The new submit module is wired in cleanly alongside prepare, matching the new stage implementation under stage::submit.

rust/main/agents/relayer/src/msg/message_processor/disposition/tests.rs (1)

225-228: Disposition expectations now line up with routing semantics

The updated expectations for PendingInclusion, ReadyToSubmit, Retry, and Mempool map neatly onto the new disposition logic (Submit for in‑pipeline, PreSubmit for retryable states). That keeps these tests in step with operation_disposition_by_payload_status and the new submit/post‑submit routing.

Also applies to: 380-383, 417-420, 454-457

rust/main/agents/relayer/src/msg/message_processor/stage/prepare/tests/tests_determine_operation_disposition.rs (1)

7-714: Thorough disposition coverage around prepare stage

These tests now walk through pretty much every path: manual vs non‑manual retry, DB failures, all payload and transaction drop reasons, reorgs, in‑flight submission states, included/finalized cases, multiple UUIDs, and entrypoint errors. The expectations around “returned vs queued (submit/confirm)” line up with the disposition semantics and the updated filter_operations_for_preparation.

Nothing stands out as off; this is solid safety net for the swampy edge cases.

rust/main/agents/relayer/src/msg/message_processor/stage/prepare/tests/tests_filter_operations_for_preparation.rs (4)

8-10: Submit queue wiring and empty‑batch behavior look consistent

Bringing in PendingOperationStatus and the extra submit_queue parameter, plus asserting both queues are empty for an empty batch, lines up cleanly with the new routing semantics and keeps the base case honest. Nothing funky hiding in this setup.

Also applies to: 26-45


51-98: Manual retry and DB‑failure scenarios are well covered

The manual‑retry tests (including store failures and mixed batches) match the determine_operation_disposition behavior: manual ops are forced back to PreSubmit even when DB calls fail, while submitted ops flow to the confirm queue. The expectations on DB call counts and queue lengths look accurate and give good confidence in this corner of the swamp.

Also applies to: 100-152, 155-243


463-507: Error, dropped, and non‑manual retry paths behave as intended

DB errors, dropped payloads/transactions, entrypoint errors, and non‑manual retries are all explicitly tested and end up either back in PreSubmit or in the confirm queue when finalized, matching the documented behavior. This gives solid coverage of the messier failure paths without any obvious mismatches.

Also applies to: 509-601, 603-700


703-742: Empty payload UUIDs edge case is handled cleanly

Treating Some(vec![]) as PreSubmit and asserting that no queues are touched is a good little edge‑case guard, and mirrors the disposition logic exactly. No tweaks needed here.

rust/main/agents/relayer/src/msg/message_processor.rs (2)

22-26: Importing ReadyToSubmit and submit‑stage filter fits the new pipeline

Pulling in PendingOperationStatus::ReadyToSubmit and filter_operations_for_submit wires this module into the new three‑stage flow cleanly, without changing existing classic behavior. Names and placement make it easy to follow how the submit stage now owns the “keep in submit queue vs move to confirm” decision.

Also applies to: 38-40


408-425: Using filter_operations_for_preparation in Lander prepare task matches disposition semantics

Passing both submit_queue and confirm_queue into prepare::filter_operations_for_preparation lets the Lander prepare loop offload already‑submitted ops and queue Submit ones, while only handing true PreSubmit operations to process_batch. The manual‑retry cleanup in determine_operation_disposition plus this call ensure we don’t keep stale payload mappings hanging around.

rust/main/agents/relayer/src/msg/message_processor/tests/tests_common.rs (2)

20-21: Extending MockQueueOperation with destination makes tests more faithful

Adding a destination: HyperlaneDomain, plumbing it through new, and having with_first_prepare / with_manual_retry use new_test_domain("test") lets tests exercise destination‑aware logic without extra boilerplate. Returning &self.destination from destination_domain finally lines the mock up with the real trait, which is exactly what you want here.

Also applies to: 29-38, 41-53, 77-79


183-214: create_test_metrics mirrors production metrics layout cleanly

The create_test_metrics helper sets up gauges and counters with the same label shape MessageProcessorMetrics expects, and cloning ops_processed into the different phases keeps the test wiring simple while still realistic. Handy little utility for future tests poking at metrics behavior.

rust/main/agents/relayer/src/msg/message_processor/disposition.rs (2)

3-4: Adding Submit disposition and docs clarifies the operation lifecycle

Introducing the Submit variant and spelling out in the doc comment how PreSubmit/Submit/PostSubmit are interpreted makes the routing rules a lot easier to reason about. The import changes are minimal and keep all the relevant status types in one place.

Also applies to: 7-7, 10-17, 19-25


30-40: Disposition logic for payload status is reasonable and defensive

The function now gracefully falls back to PreSubmit on DB errors, missing/empty UUIDs, or payload‑status lookup failures, while mapping ReadyToSubmit/PendingInclusion/Mempool into Submit and Included/Finalized into PostSubmit. That matches how the prepare and submit stages are using it and avoids losing ops when the DB or entrypoint stumbles, at the cost of a harmless extra round of work.

Also applies to: 42-47, 49-56, 58-72

rust/main/agents/relayer/src/msg/message_processor/stage/prepare.rs (2)

7-8: filter_operations_for_preparation cleanly splits Pre/Submit/Post paths

Taking submit_queue alongside confirm_queue and switching to a two‑phase disposition+routing loop means PreSubmit ops go back to preparation while Submit ones stay in the submit queue with ReadyToSubmit and PostSubmit ones move straight to confirm. The comments match the behavior, and the use of the Confirm(AlreadySubmitted) status ties in nicely with the rest of the processor.

Also applies to: 15-21, 24-32, 41-63


70-88: Manual retry handling avoids stale payload linkage before disposition

Clearing the message‑to‑payload mapping when the status is Retry(ReprepareReason::Manual) ensures manual interventions don’t get stuck behind old payload state, and the warning on store failure keeps some visibility without changing behavior. Letting the shared operation_disposition_by_payload_status logic run after that keeps the rest of the story simple.

Copy link
Contributor

@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: 0

🧹 Nitpick comments (2)
rust/main/agents/relayer/src/msg/message_processor/disposition.rs (2)

89-97: Multi-payload behavior: consider logging or asserting when more than one UUID exists

You early‑return PreSubmit on None/empty and then blindly take payload_uuids[0], with a comment noting only a single payload per message is supported. If multiple UUIDs ever show up, that’s a bit of a swampy edge case that will be silently ignored. Optional: log when uuids.len() > 1 or assert that we only ever see one, so it’s easier to spot if assumptions change.


97-103: Entry-point RPC errors also mapped to PreSubmit – double-check desired behavior

Same as with the DB error path, any payload_status RPC failure hits PreSubmit. In the Submit stage that again means “caller should re‑prepare / re‑submit now”, which could be a bit aggressive if the failure is a transient RPC hiccup and the original tx is actually fine. If you’d rather “wait it out” for this case, mapping RPC failures to Submit (or a future explicit “retry later” disposition) might better match intent; if you’re comfortable re-prepping here, then this is good as-is.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e9c5570 and 81d0744.

📒 Files selected for processing (1)
  • rust/main/agents/relayer/src/msg/message_processor/disposition.rs (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
rust/main/agents/relayer/src/msg/message_processor/disposition.rs (1)
rust/main/agents/relayer/src/msg/message_processor/tests/tests_common.rs (1)
  • id (59-61)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (12)
  • GitHub Check: infra-test
  • GitHub Check: e2e-matrix (evm)
  • GitHub Check: e2e-matrix (sealevel)
  • GitHub Check: e2e-matrix (cosmosnative)
  • GitHub Check: e2e-matrix (radix)
  • GitHub Check: e2e-matrix (cosmwasm)
  • GitHub Check: e2e-matrix (starknet)
  • GitHub Check: yarn-install
  • GitHub Check: build-and-push-to-gcr
  • GitHub Check: lander-coverage
  • GitHub Check: lint-rs
  • GitHub Check: test-rs
🔇 Additional comments (3)
rust/main/agents/relayer/src/msg/message_processor/disposition.rs (3)

9-63: Enum docs read clearly and match the three-stage flow

The expanded docs make the pipeline behavior much less murky and clarify how the same disposition is interpreted in Prepare vs Submit. Nothing smells off in the variant semantics; naming plus comments feel sufficient now for multi-stage usage.


66-87: Confirm that treating DB errors as PreSubmit is intentional for Submit stage

Right now any failure to read payload UUIDs (retrieve_payload_uuids_by_message_id returning Err) causes a PreSubmit disposition, which in the Submit stage means “go ahead and re‑prepare / re‑submit”. That’s a reasonable fallback if duplicates are tolerated, but if a transient DB issue could lead to unnecessary re-prep or extra tx attempts, you might instead want to keep the op in the submit queue (or add a distinct “error/retry later” path).


105-118: Status → disposition mapping looks consistent with pipeline semantics

The mapping from PayloadStatus / TransactionStatus into PreSubmit / Submit / PostSubmit lines up with the docs: dropped/retry → PreSubmit, ready/pending/mempool → Submit, included/finalized → PostSubmit. Nothing funky here; this should give clear observability for where each op sits in the pipeline.

@yjamin
Copy link
Contributor

yjamin commented Nov 18, 2025

These changes will also affect classical submitter right? Its not only limited to lander or am I wrong?

@ameten
Copy link
Collaborator Author

ameten commented Nov 18, 2025

@yjamin, why do you think that this change impacts Classic submitter as well?

@yjamin
Copy link
Contributor

yjamin commented Nov 18, 2025

@yjamin, why do you think that this change impacts Classic submitter as well?

I don't know about the details, I just see that a lot of code has changed in the relayer and not in the lander. So I assumed that this code is shared between lander and classical as I would expect lander specific code to live in lander.

@ameten
Copy link
Collaborator Author

ameten commented Nov 18, 2025

I see what you mean, @yjamin. I have changed only prepare_lander_task and submit_lander_task in Message Processor. Tasks which are related to Classic submitter, like prepare_classic_task and submit_classic_task are not impacted. Does it help?

@yjamin, why do you think that this change impacts Classic submitter as well?

I don't know about the details, I just see that a lot of code has changed in the relayer and not in the lander. So I assumed that this code is shared between lander and classical as I would expect lander specific code to live in lander.

Copy link
Contributor

@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: 5

Caution

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

⚠️ Outside diff range comments (1)
rust/main/agents/relayer/src/msg/message_processor/stage/prepare/tests/tests_determine_operation_disposition.rs (1)

297-347: Function name doesn't match what it actually tests, mate.

The function is named test_determine_disposition_returns_presubmit_for_dropped_states, but it's actually verifying that dropped states return PostSubmitFailure, not PreSubmit. The comment and assertion are spot on—it's just the function name that's sending mixed signals.

Consider renaming it:

-async fn test_determine_disposition_returns_presubmit_for_dropped_states() {
-    // Test that dropped states return PostSubmitFailure disposition
-    // which causes the operation to be prepared with linkage removed
+async fn test_determine_disposition_returns_postsubmit_failure_for_dropped_states() {
+    // Test that dropped states return PostSubmitFailure disposition
+    // which causes the operation to be prepared with linkage removed
🧹 Nitpick comments (1)
rust/main/agents/relayer/src/msg/message_processor/disposition.rs (1)

19-27: Doc still mentions old PostSubmit variant

The stage docs still talk about a PostSubmit bucket, but the enum now splits that path into PostSubmitSuccess and PostSubmitFailure. Let’s tweak the wording so the comments line up with the actual variants, else future readers will be wandering the swamp looking for a type that no longer exists.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 81d0744 and 2580ca0.

📒 Files selected for processing (7)
  • rust/main/agents/relayer/src/msg/message_processor/disposition.rs (2 hunks)
  • rust/main/agents/relayer/src/msg/message_processor/disposition/tests.rs (9 hunks)
  • rust/main/agents/relayer/src/msg/message_processor/stage/prepare.rs (3 hunks)
  • rust/main/agents/relayer/src/msg/message_processor/stage/prepare/tests/tests_determine_operation_disposition.rs (8 hunks)
  • rust/main/agents/relayer/src/msg/message_processor/stage/prepare/tests/tests_filter_operations_for_preparation.rs (32 hunks)
  • rust/main/agents/relayer/src/msg/message_processor/stage/submit.rs (1 hunks)
  • rust/main/agents/relayer/src/msg/message_processor/stage/submit/tests.rs (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-11-20T12:20:42.663Z
Learnt from: yjamin
Repo: hyperlane-xyz/hyperlane-monorepo PR: 7414
File: rust/main/chains/hyperlane-aleo/src/provider/traits.rs:252-0
Timestamp: 2025-11-20T12:20:42.663Z
Learning: In rust/main/chains/hyperlane-aleo/src/provider/traits.rs, the `get_state_paths_for_commitments` and `get_state_paths_for_commitments_async` methods intentionally use `.unwrap_or_default()` to return an empty Vec on any error. This behavior matches SnarkVM's internal QueryTrait implementation and should not be changed to propagate errors.

Applied to files:

  • rust/main/agents/relayer/src/msg/message_processor/stage/prepare/tests/tests_determine_operation_disposition.rs
🧬 Code graph analysis (6)
rust/main/agents/relayer/src/msg/message_processor/stage/submit/tests.rs (2)
rust/main/agents/relayer/src/msg/message_processor/tests/tests_common.rs (5)
  • create_test_metrics (185-214)
  • create_test_queue (164-182)
  • new (33-39)
  • id (59-61)
  • with_first_prepare (41-44)
rust/main/agents/relayer/src/msg/message_processor/stage/submit.rs (1)
  • filter_operations_for_submit (38-84)
rust/main/agents/relayer/src/msg/message_processor/stage/submit.rs (2)
rust/main/agents/relayer/src/msg/message_processor/disposition.rs (1)
  • operation_disposition_by_payload_status (96-144)
rust/main/agents/relayer/src/msg/message_processor.rs (5)
  • confirm_op (712-737)
  • batch (466-466)
  • batch (805-811)
  • new (106-147)
  • new (991-1003)
rust/main/agents/relayer/src/msg/message_processor/disposition.rs (1)
rust/main/agents/relayer/src/msg/message_processor/tests/tests_common.rs (2)
  • id (59-61)
  • status (96-98)
rust/main/agents/relayer/src/msg/message_processor/stage/prepare.rs (1)
rust/main/agents/relayer/src/msg/message_processor/disposition.rs (1)
  • operation_disposition_by_payload_status (96-144)
rust/main/agents/relayer/src/msg/message_processor/stage/prepare/tests/tests_determine_operation_disposition.rs (3)
rust/main/agents/relayer/src/msg/message_processor/stage/prepare.rs (1)
  • determine_operation_disposition (98-114)
rust/main/agents/relayer/src/msg/message_processor/tests/tests_common.rs (2)
  • new (33-39)
  • with_first_prepare (41-44)
rust/main/hyperlane-core/src/chain.rs (1)
  • new_test_domain (333-341)
rust/main/agents/relayer/src/msg/message_processor/stage/prepare/tests/tests_filter_operations_for_preparation.rs (3)
rust/main/agents/relayer/src/msg/message_processor/tests/tests_common.rs (4)
  • create_test_queue (164-182)
  • new (33-39)
  • id (59-61)
  • with_first_prepare (41-44)
rust/main/agents/relayer/src/msg/message_processor/stage/prepare.rs (1)
  • filter_operations_for_preparation (32-77)
rust/main/hyperlane-core/src/chain.rs (1)
  • new_test_domain (333-341)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
  • GitHub Check: build-and-push-to-gcr
  • GitHub Check: e2e-matrix (sealevel)
  • GitHub Check: e2e-matrix (evm)
  • GitHub Check: e2e-matrix (cosmwasm)
  • GitHub Check: e2e-matrix (radix)
  • GitHub Check: e2e-matrix (starknet)
  • GitHub Check: e2e-matrix (cosmosnative)
  • GitHub Check: lint-rs
  • GitHub Check: lander-coverage
  • GitHub Check: test-rs
🔇 Additional comments (6)
rust/main/agents/relayer/src/msg/message_processor/disposition/tests.rs (1)

143-147: Tests line up with the new failure disposition

Nice to see the dropped-payload case now asserting PostSubmitFailure; that keeps the safety net tight around the new enum split.

rust/main/agents/relayer/src/msg/message_processor/stage/submit/tests.rs (1)

224-311: Great coverage across the submit routing paths

Appreciate how these cases walk through retries, drops, and finalized payloads—makes it a breeze to reason about the new stage wiring.

rust/main/agents/relayer/src/msg/message_processor/stage/prepare/tests/tests_filter_operations_for_preparation.rs (1)

420-461: Solid assertions on where each disposition lands

These checks on confirm vs submit queue lengths keep the prepare stage honest with the new Ready/Mempool paths. Nicely done.

rust/main/agents/relayer/src/msg/message_processor/stage/prepare.rs (3)

32-77: Nice routing logic here—clear as day.

The disposition-based routing in filter_operations_for_preparation handles all four cases cleanly. Sequential async processing could be a bottleneck with large batches, but for typical use cases, this should be just fine.


98-114: Solid decision point for routing operations.

The manual retry handling followed by delegation to operation_disposition_by_payload_status is clean. Documentation spells out exactly what happens for each disposition type.


135-144: Error handling keeps things moving even when the DB acts up.

Swallowing the error with a warning is the right call here, as documented. Transient DB issues shouldn't block message reprocessing.

@ameten ameten force-pushed the ameten/lander-tx-submission-observability branch from 2580ca0 to 0f7bcb5 Compare November 20, 2025 13:16
Copy link
Contributor

@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: 0

Caution

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

⚠️ Outside diff range comments (1)
rust/main/agents/relayer/src/msg/message_processor/disposition/tests.rs (1)

232-266: Update assertion messages to say PostSubmitSuccess instead of Confirm.

These three tests now assert OperationDisposition::PostSubmitSuccess, but the failure messages still say "Should return Confirm…", which can confuse future swamp‑dwellers reading test output.

Consider updating the strings to match the enum name (or say “PostSubmitSuccess / confirm stage”) to keep semantics clear.

Also applies to: 305-347, 461-495

♻️ Duplicate comments (1)
rust/main/agents/relayer/src/msg/message_processor/stage/prepare/tests/tests_determine_operation_disposition.rs (1)

134-165: Duplicate PayloadNotFoundPreSubmit coverage.

test_determine_disposition_returns_presubmit_when_payload_not_found and test_determine_disposition_returns_presubmit_for_entrypoint_error_payload_not_found both set up a payload UUID, have the entrypoint return LanderError::PayloadNotFound, and assert PreSubmit.

Unless there’s a subtle distinction you want to keep, you can probably drop or reshape one of these (e.g., cover multiple UUIDs or a different error) to avoid testing the same swamp twice.

Also applies to: 530-562

🧹 Nitpick comments (5)
rust/main/agents/relayer/src/msg/message_processor/stage/prepare/tests/tests_determine_operation_disposition.rs (2)

196-243: Align test name/comment with PostSubmitSuccess variant.

This test is now asserting OperationDisposition::PostSubmitSuccess, but both the function name (returns_postsubmit_for_various_transaction_states) and the inner comment still speak in terms of a generic “PostSubmit”.

Given we now have both PostSubmitSuccess and PostSubmitFailure, it’d be clearer to rename the test (and tweak the comment) to mention PostSubmitSuccess explicitly.


135-143: Broaden the log message in remove_linkage_between_payload_and_message.

The helper is documented for manual retries and PostSubmitFailure/reorg cases, but the warning string says “for manual operation” only. That’s a bit misleading once this runs for non‑manual PostSubmitFailure dispositions too.

Consider rewording the log to something like “Failed to remove payload UUID mapping for operation” so it matches all call sites.

rust/main/agents/relayer/src/msg/message_processor/disposition.rs (1)

9-30: Top‑level enum docs still reference a PostSubmit variant that no longer exists.

The stage‑specific comments talk about a generic PostSubmit handling in Prepare/Submit, but the enum has been split into PostSubmitSuccess and PostSubmitFailure, each with different behavior.

Might be worth rewriting that header comment to:

  • Refer explicitly to PostSubmitSuccess and PostSubmitFailure, and
  • Briefly explain how each maps to stages, instead of the old single “PostSubmit” story.

That’ll keep future ogres from scratching their heads when they read the docs.

Also applies to: 65-78

rust/main/agents/relayer/src/msg/message_processor/stage/prepare.rs (1)

135-143: Make the linkage‑removal warning message less “manual”-specific.

Same note as in the tests: this helper is used for manual retries and generic PostSubmitFailure cases, but the log text still says “for manual operation”.

Tweaking the message to something like “Failed to remove payload UUID mapping for operation” would better reflect all the paths that land here.

rust/main/agents/relayer/src/msg/message_processor/stage/prepare/tests/tests_filter_operations_for_preparation.rs (1)

22-1064: Consider extracting common mock setup patterns into helper functions.

There's quite a bit of repeated boilerplate across tests - creating queues, setting up mock DB expectations, configuring mock entrypoints. While the current approach is clear and explicit, helper functions could reduce duplication and make tests easier to maintain. For example:

fn setup_mock_db_with_payload(
    mock_db: &mut MockHyperlaneDb,
    message_id: H256,
    payload_uuid: UniqueIdentifier,
) {
    let payload_uuid_clone = payload_uuid.clone();
    mock_db
        .expect_retrieve_payload_uuids_by_message_id()
        .returning(move |id| {
            if *id == message_id {
                Ok(Some(vec![payload_uuid_clone.clone()]))
            } else {
                Ok(None)
            }
        });
}

This would make each test more focused on what makes it unique. But honestly, the current explicit approach ain't terrible either - sometimes seeing all the setup right there in the test makes it easier to understand what's going on.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2580ca0 and 0f7bcb5.

📒 Files selected for processing (7)
  • rust/main/agents/relayer/src/msg/message_processor/disposition.rs (2 hunks)
  • rust/main/agents/relayer/src/msg/message_processor/disposition/tests.rs (9 hunks)
  • rust/main/agents/relayer/src/msg/message_processor/stage/prepare.rs (3 hunks)
  • rust/main/agents/relayer/src/msg/message_processor/stage/prepare/tests/tests_determine_operation_disposition.rs (8 hunks)
  • rust/main/agents/relayer/src/msg/message_processor/stage/prepare/tests/tests_filter_operations_for_preparation.rs (32 hunks)
  • rust/main/agents/relayer/src/msg/message_processor/stage/submit.rs (1 hunks)
  • rust/main/agents/relayer/src/msg/message_processor/stage/submit/tests.rs (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • rust/main/agents/relayer/src/msg/message_processor/stage/submit.rs
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-11-20T12:20:42.663Z
Learnt from: yjamin
Repo: hyperlane-xyz/hyperlane-monorepo PR: 7414
File: rust/main/chains/hyperlane-aleo/src/provider/traits.rs:252-0
Timestamp: 2025-11-20T12:20:42.663Z
Learning: In rust/main/chains/hyperlane-aleo/src/provider/traits.rs, the `get_state_paths_for_commitments` and `get_state_paths_for_commitments_async` methods intentionally use `.unwrap_or_default()` to return an empty Vec on any error. This behavior matches SnarkVM's internal QueryTrait implementation and should not be changed to propagate errors.

Applied to files:

  • rust/main/agents/relayer/src/msg/message_processor/stage/prepare/tests/tests_determine_operation_disposition.rs
🧬 Code graph analysis (5)
rust/main/agents/relayer/src/msg/message_processor/stage/submit/tests.rs (2)
rust/main/agents/relayer/src/msg/message_processor/tests/tests_common.rs (5)
  • create_test_metrics (185-214)
  • create_test_queue (164-182)
  • new (33-39)
  • id (59-61)
  • with_first_prepare (41-44)
rust/main/agents/relayer/src/msg/message_processor/stage/submit.rs (1)
  • filter_operations_for_submit (38-84)
rust/main/agents/relayer/src/msg/message_processor/disposition.rs (1)
rust/main/agents/relayer/src/msg/message_processor/tests/tests_common.rs (2)
  • id (59-61)
  • status (96-98)
rust/main/agents/relayer/src/msg/message_processor/stage/prepare.rs (1)
rust/main/agents/relayer/src/msg/message_processor/disposition.rs (1)
  • operation_disposition_by_payload_status (96-144)
rust/main/agents/relayer/src/msg/message_processor/stage/prepare/tests/tests_filter_operations_for_preparation.rs (2)
rust/main/agents/relayer/src/msg/message_processor/tests/tests_common.rs (4)
  • create_test_queue (164-182)
  • new (33-39)
  • id (59-61)
  • with_first_prepare (41-44)
rust/main/agents/relayer/src/msg/message_processor/stage/prepare.rs (1)
  • filter_operations_for_preparation (32-77)
rust/main/agents/relayer/src/msg/message_processor/stage/prepare/tests/tests_determine_operation_disposition.rs (3)
rust/main/agents/relayer/src/msg/message_processor/stage/prepare.rs (1)
  • determine_operation_disposition (98-114)
rust/main/agents/relayer/src/msg/message_processor/tests/tests_common.rs (2)
  • new (33-39)
  • with_first_prepare (41-44)
rust/main/hyperlane-core/src/chain.rs (1)
  • new_test_domain (333-341)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
  • GitHub Check: build-and-push-to-gcr
  • GitHub Check: e2e-matrix (evm)
  • GitHub Check: e2e-matrix (radix)
  • GitHub Check: e2e-matrix (sealevel)
  • GitHub Check: e2e-matrix (cosmwasm)
  • GitHub Check: e2e-matrix (starknet)
  • GitHub Check: e2e-matrix (cosmosnative)
  • GitHub Check: lint-rs
  • GitHub Check: lander-coverage
  • GitHub Check: test-rs
🔇 Additional comments (10)
rust/main/agents/relayer/src/msg/message_processor/disposition/tests.rs (1)

112-495: Disposition mapping tests look aligned with the new 3‑stage pipeline.

The scenarios for Dropped/Retry, PendingInclusion, ReadyToSubmit, Mempool, Included, and Finalized all line up with PostSubmitFailure, Submit, and PostSubmitSuccess as implemented in operation_disposition_by_payload_status, and the “early return” cases (DB error / no UUIDs / entrypoint error) correctly stick to PreSubmit. Nothing smelly here.

rust/main/agents/relayer/src/msg/message_processor/stage/prepare/tests/tests_determine_operation_disposition.rs (1)

22-193: Manual vs non‑manual retry coverage looks solid.

The tests around manual retries (clearing linkage then falling back to PreSubmit) and non‑manual retries (e.g. ErrorSubmitting mapping to PostSubmitSuccess) match the determine_operation_disposition + operation_disposition_by_payload_status flow and exercise both DB‑failure and happy paths nicely. No dragons hiding in this part.

rust/main/agents/relayer/src/msg/message_processor/stage/submit/tests.rs (1)

19-938: Submit‑stage routing tests thoroughly cover the new dispositions.

The suite hits all the interesting branches—PreSubmit resubmission, Submit re‑queueing (ReadyToSubmit/PendingInclusion/Mempool), and PostSubmit{Success,Failure} flowing into the confirm queue—plus DB/entrypoint errors and multi‑payload/variant cases. Behavior matches filter_operations_for_submit and the disposition mapping cleanly; nothing obviously off here.

rust/main/agents/relayer/src/msg/message_processor/disposition.rs (1)

81-143: Status→disposition mapping and logging look correct and conservative.

The function safely falls back to PreSubmit on DB/entrypoint errors or missing UUIDs, and the mappings for all PayloadStatus/TransactionStatus variants line up with how the prepare and submit stages consume PreSubmit/Submit/PostSubmitSuccess/PostSubmitFailure. The added warn! logs include message ID and payload UUID, which should make debugging nice and muddy in the right ways.

rust/main/agents/relayer/src/msg/message_processor/stage/prepare.rs (1)

32-77: Prepare‑stage routing matches the new disposition semantics.

filter_operations_for_preparation and determine_operation_disposition hook together cleanly: manual retries clear linkage then drop into PreSubmit, Submit ops are funneled to the submit queue with ReadyToSubmit, finalized/included ops head to confirm with Confirm(AlreadySubmitted), and PostSubmitFailure clears linkage before handing the op back for re‑prep. That lines up with the intended three‑stage flow.

Also applies to: 98-114

rust/main/agents/relayer/src/msg/message_processor/stage/prepare/tests/tests_filter_operations_for_preparation.rs (5)

22-98: Tests correctly updated for new submit queue parameter.

The early tests (empty batch and manual retry) have been properly updated to include the submit_queue parameter and verify both queue states. The logic is sound - manual retry operations go to pre-submit, leaving both queues empty.


358-461: Well-structured mixed batch test validates new routing logic.

This test nicely demonstrates the three-way split: manual retry + not submitted → pre-submit, Finalized → confirm queue, PendingInclusion → submit queue. The assertions clearly verify each routing path.


509-615: PostSubmitFailure disposition correctly tested for dropped payloads and transactions.

Both tests properly validate that when payloads or transactions are dropped, the linkage is removed (empty UUID list stored) and operations return to pre-submit. The withf matchers on lines 529 and 581 ensure the removal logic is called correctly.


758-903: Solid coverage for new status routing paths.

These three focused tests validate that ReadyToSubmit and Mempool route to submit_queue, while Included routes to confirm_queue. Each test is simple and clearly demonstrates one routing path. Nice work on the test isolation.


905-1064: Comprehensive batch tests for Submit disposition variants.

These final tests validate that multiple operations with Submit disposition (PendingInclusion, ReadyToSubmit, Mempool) correctly route to the submit queue, both in homogeneous and heterogeneous batches. The coverage is thorough.

…or messages which payload and corresponding transactions are dropped
@ameten ameten force-pushed the ameten/lander-tx-submission-observability branch from 0f7bcb5 to 1b5361d Compare November 20, 2025 13:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: In Review

Development

Successfully merging this pull request may close these issues.

4 participants