Skip to content

Conversation

@taco-paco
Copy link
Contributor

@taco-paco taco-paco commented Nov 21, 2025

Added patched errors report in SentCommit

Refactor

SingleStageExecutor & TwoStageExecutors to iterate and modify their own state to record erros the patched.
IntentExecutor now has method cleanup that can be explicitly awaited on(useful for tests) or offloaded on another task(useful for prod).

Patched errors trace also now checked in tests, which improves tests quality

Summary by CodeRabbit

  • New Features

    • Richer execution results surfaced: per-stage signatures, captured patched-errors, and optional error messages on sent commits.
    • New observability: metrics tracking scheduled intent counts and task/ALT preparation durations.
  • Bug Fixes

    • Improved error classification and recovery across commit/finalize flows; better logging and failure reporting for intent processing.
    • More robust cleanup and patching behavior during execution retries.
  • Tests

    • Expanded tests and helpers covering patched-error recovery and multi-stage execution paths.

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

feat: add metrics for task preparation & alt preparation
# Conflicts:
#	test-integration/test-committor-service/tests/test_intent_executor.rs
feat: trigger SentCommit on intent failure and failed retry
… feat/base-layer-ix/improve-executors

# Conflicts:
#	magicblock-accounts/src/scheduled_commits_processor.rs
#	test-integration/programs/flexi-counter/src/processor.rs
feat: SentCommit fails if underlying intent failed to execute on Base
fix: compilation
feat: trigger SentCommit on intent failure and failed retry
… feat/base-layer-ix/improve-executors

# Conflicts:
#	magicblock-accounts/src/scheduled_commits_processor.rs
#	programs/magicblock/src/schedule_transactions/process_scheduled_commit_sent.rs
#	test-integration/test-committor-service/tests/test_intent_executor.rs
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 21, 2025

Walkthrough

Introduces BroadcastedIntentExecutionResult with patched_errors, removes ExecutionOutputWrapper, makes IntentExecutor mutable with cleanup, refactors single-/two‑stage executors into stateful flows, consolidates error variants and signature accessors, updates consumers/tests and adds committor metrics.

Changes

Cohort / File(s) Summary
Execution result & broadcasts
magicblock-committor-service/src/intent_execution_manager/intent_execution_engine.rs, magicblock-committor-service/src/intent_execution_manager.rs, magicblock-committor-service/src/stubs/changeset_committor_stub.rs
Add BroadcastedIntentExecutionResult { inner, id, trigger_type, patched_errors }; remove ExecutionOutputWrapper re-export; broadcast flow constructs/sends new type; tests/mocks updated.
Accounts result consumption
magicblock-accounts/src/scheduled_commits_processor.rs, magicblock-committor-service/src/service_ext.rs
Consumers accept BroadcastedIntentExecutionResult; build_sent_commit/processing derive chain_signatures, error_message, and patched_errors from result; dispatcher uses result.id directly.
Intent executor API & lifecycle
magicblock-committor-service/src/intent_executor/mod.rs
Introduce IntentExecutionResult { inner, patched_errors }; IntentExecutor::execute now &mut self -> IntentExecutionResult; add cleanup(self) -> Result<(), BufferExecutionError>; executor holds junk and patched_errors.
Single-stage executor
magicblock-committor-service/src/intent_executor/single_stage_executor.rs
Make executor reference mutable, add transaction_strategy field; execute takes &mut self and committed_pubkeys, pushes cleanup/patches into inner.junk and inner.patched_errors; adjust patching signature.
Two-stage executor (stateful)
magicblock-committor-service/src/intent_executor/two_stage_executor.rs
Replace flat two-stage with stateful Initialized/Committed/Finalized and TwoStageExecutor<'a, T, F, S: Sealed>; add commit()/finalize() transitions; patch helpers accept inner.
Error consolidation & signatures
magicblock-committor-service/src/intent_executor/error.rs, magicblock-committor-service/src/transaction_preparator/error.rs, magicblock-committor-service/src/transaction_preparator/delivery_preparator.rs, magicblock-committor-service/src/intent_executor/task_info_fetcher.rs, magicblock-committor-service/src/tasks/task_builder.rs
Consolidate IntentExecutorError into commit/finalize composite variants carrying TransactionStrategyExecutionError and optional signatures; add signature() accessors on several error types; add UndelegationError variant and helpers.
Tasks & labeling
magicblock-committor-service/src/tasks/mod.rs, magicblock-committor-service/src/tasks/args_task.rs, magicblock-committor-service/src/tasks/buffer_task.rs, magicblock-committor-service/src/tasks/task_builder.rs
BaseTask now requires LabelValue; implement LabelValue for ArgsTask and BufferTask; TaskBuilderError::signature() added.
Transaction preparator API changes
magicblock-committor-service/src/transaction_preparator/mod.rs, magicblock-committor-service/src/transaction_preparator/delivery_preparator.rs
Rename error enum to DeliveryPreparatorError; cleanup/cleanup_for_strategy signatures use BufferExecutionError; add error signature() helpers.
Metrics
magicblock-metrics/src/metrics/mod.rs
Add committor metrics: COMMITTOR_INTENTS_COUNT, COMMITTOR_INTENT_TASK_PREPARATION_TIME, COMMITTOR_INTENT_ALT_PREPARATION_TIME and helper APIs to observe/inc.
Program & tests updates
programs/magicblock/src/schedule_transactions/process_scheduled_commit_sent.rs, test-integration/programs/flexi-counter/src/state.rs, test-integration/programs/flexi-counter/src/processor.rs, test-integration/test-committor-service/..., test-integration/.../utils/*
SentCommit gains error_message: Option<String> and patched_errors: Vec<String>; add FAIL_UNDELEGATION_LABEL/FAIL_UNDELEGATION_CODE; tests updated to pass optional label, use IntentExecutionResult/BroadcastedIntentExecutionResult, assert patched_errors and cleanup behavior; test helpers/signatures adjusted.

Sequence Diagram(s)

sequenceDiagram
    participant Scheduler as Commit Scheduler
    participant Executor as IntentExecutorImpl
    participant Single as SingleStageExecutor
    participant Two as TwoStageExecutor
    participant Broad as Broadcaster
    participant Consumer as ScheduledCommitsProcessor

    Scheduler->>Executor: schedule intent -> Executor.execute(&mut)
    Executor->>Single: SingleStageExecutor::execute(&mut)
    alt success (single)
        Single-->>Executor: Ok(ExecutionOutput::SingleStage)
    else patchable error / CPI-limit
        Single->>Executor: record junk & patched_error
        Single->>Two: initialize TwoStageExecutor (Initialized)
        Two->>Two: commit() -> Committed
        Two->>Two: finalize() -> Finalized
        Two-->>Executor: Ok(ExecutionOutput::TwoStage)
    end
    Executor->>Executor: cleanup(junk) via cleanup()
    Executor->>Broad: send BroadcastedIntentExecutionResult { inner, id, trigger_type, patched_errors }
    Broad->>Consumer: deliver BroadcastedIntentExecutionResult
    Consumer->>Consumer: build SentCommit from result (derive signatures, error_message, patched_errors)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Areas needing extra attention:

  • Two-stage executor state machine and sealed trait transitions (two_stage_executor.rs).
  • Error mapping and signature extraction across intent_executor/error.rs and delivery preparator errors.
  • Correct propagation and ownership of patched_errors (Arc/Vec) across broadcaster and consumers.
  • Mutable &mut self threading, cleanup lifecycle, and spawned-task interactions.

Possibly related PRs

Suggested reviewers

  • thlorenz
  • GabrielePicco
  • bmuddha

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 70.79% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 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 objective: adding patched errors reporting to SentCommit, which is the primary change across the codebase.
✨ 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 feat/base-layer-ix/improve-executors

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

Caution

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

⚠️ Outside diff range comments (5)
test-integration/test-committor-service/tests/test_intent_executor.rs (2)

329-395: Use of IntentExecutionResult and patched_errors in recovery tests is mostly solid; watch ordering assumptions

The recovery tests (test_commit_id_error_recovery, test_undelegation_error_recovery, test_action_error_recovery, test_commit_id_and_action_errors_recovery) all:

  • Call intent_executor.execute(...) and destructure IntentExecutionResult as:

    let IntentExecutionResult { inner: res, patched_errors } = res;

    so res becomes the inner Result<ExecutionOutput, TransactionStrategyExecutionError>, and patched_errors is the collected patch trace.

  • Assert:

    • res.is_ok() and matches!(res.unwrap(), ExecutionOutput::SingleStage(_)) (i.e., execution recovered to a single‑stage success).
    • patched_errors.len() matches the expected number of patches.
    • The patched error variants are what you expect (CommitIDError, UndelegationError, ActionsError).
  • Call intent_executor.cleanup().await and then verify on‑chain state and TableMania ref‑counts via verify / verify_committed_accounts_state / verify_table_mania_released.

This is a good pattern and uses the new IntentExecutionResult surface correctly.

One thing to consider: in test_commit_id_and_action_errors_recovery, you additionally assume a specific ordering of patches:

let mut iter = patched_errors.into_iter();
let commit_id_error = iter.next().unwrap();
let actions_error = iter.next().unwrap();

If patch order is not guaranteed as part of the public contract, you may want to relax this by e.g. collecting variants into a multiset and asserting on membership/counts rather than sequence, to avoid brittle tests when recovery logic is refactored but remains semantically equivalent.

If patch ordering is intended to be stable API, consider documenting that guarantee near the patched_errors definition; otherwise, loosening these tests will better tolerate future internal changes.

Also applies to: 396-449, 451-515, 517-596


598-683: Direct access to intent_executor.patched_errors is intentional but tightly couples tests to executor internals

In the two‑stage/CPI‑limit recovery tests:

  • test_cpi_limits_error_recovery uses single_stage_execution_flow and only checks the returned ExecutionOutput::TwoStage { .. } plus post‑cleanup state.

  • test_commit_id_actions_cpi_limit_errors_recovery additionally inspects the executor’s internal patched_errors via:

    let res = intent_executor
        .single_stage_execution_flow(...)
        .await;
    
    let patched_errors = mem::take(&mut intent_executor.patched_errors);
    assert!(res.is_ok());
    assert_eq!(patched_errors.len(), 3, "Only 3 patches expected");
    // then match CommitIDError, CpiLimitError, ActionsError

This makes sense given the current design, where single_stage_execution_flow itself doesn’t return an IntentExecutionResult but the executor tracks patched errors as state. Using mem::take to consume and reset that state is a clean way to avoid leaking patches between runs.

However, it does mean:

  • Tests rely on IntentExecutorImpl.patched_errors being a public field, similar to the documented pattern for SingleStageExecutor / TwoStageExecutor patched_errors. If that visibility ever changes, these tests will break. A small improvement would be to expose a method like drain_patched_errors() on the executor instead of touching the field directly. Based on learnings.
  • As with the single‑stage tests, you assert a specific ordering of the three patches (CommitID, CpiLimit, then Actions). If ordering is not part of the external contract, consider asserting only on the set of variants and the length.

Functionally, the cleanup and verification steps (verify, verify_buffers_cleaned_up with adjusted invalidated_keys, and TableMania checks) are coherent and match the intent of ensuring both commit‑related buffers and lookup tables are cleaned up after recovery.

If you’d like, I can sketch a drain_patched_errors(&mut self) -> Vec<TransactionStrategyExecutionError> helper on IntentExecutorImpl and update the tests to use it, to decouple them from the field layout.

Also applies to: 685-825

magicblock-committor-service/src/stubs/changeset_committor_stub.rs (1)

18-26: Stub result construction matches new broadcast type

The stub now constructs BroadcastedIntentExecutionResult with the right shape (id, trigger_type, inner: Ok(ExecutionOutput::TwoStage { .. }), and patched_errors), so consumers can transparently consume it like the real engine output. If you want to tighten style a bit, patched_errors: Arc::default() (or Arc::new(Vec::new())) would avoid an explicit vec![], but current code is functionally correct.

Also applies to: 190-208

magicblock-committor-service/src/intent_execution_manager/intent_execution_engine.rs (1)

268-317: execute() now integrates IntentExecutionResult, broadcasting, and async cleanup correctly

The updated execute wrapper awaits executor.execute(...) into an IntentExecutionResult, logs failures via result.inner.inspect_err, records metrics against &result.inner, wraps everything into BroadcastedIntentExecutionResult::new(...), and then spawns a background task that moves executor and awaits executor.cleanup(), logging any BufferExecutionError. This ensures callers always receive a fully‑populated broadcast (including patched_errors) while decoupling potentially heavy cleanup from the hot path, and still unblocking the scheduler via complete(&intent.inner) and dropping the semaphore permit at the end.

Also applies to: 322-357

magicblock-committor-service/src/intent_executor/two_stage_executor.rs (1)

143-178: Commit/finalize patching rules and new undelegation handling are consistent with task layout

  • patch_commit_strategy only patches CommitIDError and treats ActionsError / UndelegationError as unexpected in the commit phase, which matches the expectation that non‑commit tasks (actions/undelegations) should not appear in the commit‑only strategy produced by handle_cpi_limit_error.
  • patch_finalize_strategy correctly mirrors the single‑stage semantics by:
    • treating ActionsError as patchable via handle_actions_error,
    • adding UndelegationError as patchable via handle_undelegation_error,
    • and breaking for CommitIDError, CpiLimitError, and internal errors.
  • One small nit: the log message for CommitIDError in patch_finalize_strategy still says “two stage commit flow” even though this is the finalize stage; adjusting the wording would make logs clearer when debugging finalize vs commit issues.

Also applies to: 261-295

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f67482b and e01bc79.

📒 Files selected for processing (25)
  • magicblock-accounts/src/scheduled_commits_processor.rs (6 hunks)
  • magicblock-committor-service/src/intent_execution_manager.rs (1 hunks)
  • magicblock-committor-service/src/intent_execution_manager/intent_execution_engine.rs (16 hunks)
  • magicblock-committor-service/src/intent_executor/error.rs (6 hunks)
  • magicblock-committor-service/src/intent_executor/mod.rs (8 hunks)
  • magicblock-committor-service/src/intent_executor/single_stage_executor.rs (4 hunks)
  • magicblock-committor-service/src/intent_executor/task_info_fetcher.rs (2 hunks)
  • magicblock-committor-service/src/intent_executor/two_stage_executor.rs (6 hunks)
  • magicblock-committor-service/src/service_ext.rs (1 hunks)
  • magicblock-committor-service/src/stubs/changeset_committor_stub.rs (2 hunks)
  • magicblock-committor-service/src/tasks/args_task.rs (2 hunks)
  • magicblock-committor-service/src/tasks/buffer_task.rs (2 hunks)
  • magicblock-committor-service/src/tasks/mod.rs (2 hunks)
  • magicblock-committor-service/src/tasks/task_builder.rs (2 hunks)
  • magicblock-committor-service/src/transaction_preparator/delivery_preparator.rs (5 hunks)
  • magicblock-committor-service/src/transaction_preparator/error.rs (2 hunks)
  • magicblock-committor-service/src/transaction_preparator/mod.rs (3 hunks)
  • magicblock-metrics/src/metrics/mod.rs (5 hunks)
  • programs/magicblock/src/schedule_transactions/process_scheduled_commit_sent.rs (6 hunks)
  • test-integration/programs/flexi-counter/src/processor.rs (2 hunks)
  • test-integration/programs/flexi-counter/src/state.rs (1 hunks)
  • test-integration/test-committor-service/tests/test_intent_executor.rs (22 hunks)
  • test-integration/test-committor-service/tests/test_ix_commit_local.rs (2 hunks)
  • test-integration/test-committor-service/tests/utils/instructions.rs (1 hunks)
  • test-integration/test-committor-service/tests/utils/transactions.rs (2 hunks)
🧰 Additional context used
🧠 Learnings (13)
📓 Common learnings
Learnt from: taco-paco
Repo: magicblock-labs/magicblock-validator PR: 661
File: magicblock-committor-service/src/intent_executor/single_stage_executor.rs:20-28
Timestamp: 2025-11-21T10:22:07.492Z
Learning: In magicblock-committor-service's SingleStageExecutor and TwoStageExecutor (single_stage_executor.rs and two_stage_executor.rs), the fields transaction_strategy, junk, and patched_errors are intentionally public because these executors are designed to be used independently outside of the IntentExecutor scope, and callers need access to these execution reports for cleanup and error handling.
📚 Learning: 2025-11-19T09:34:37.917Z
Learnt from: thlorenz
Repo: magicblock-labs/magicblock-validator PR: 621
File: test-integration/test-chainlink/tests/ix_remote_account_provider.rs:62-63
Timestamp: 2025-11-19T09:34:37.917Z
Learning: In test-integration/test-chainlink/tests/ix_remote_account_provider.rs and similar test files, the `_fwd_rx` receiver returned by `init_remote_account_provider()` is intentionally kept alive (but unused) to prevent "receiver dropped" errors on the sender side. The pattern `let (remote_account_provider, _fwd_rx) = init_remote_account_provider().await;` should NOT be changed to `let (remote_account_provider, _) = ...` because dropping the receiver would cause send() operations to fail.

Applied to files:

  • test-integration/test-committor-service/tests/utils/transactions.rs
  • test-integration/test-committor-service/tests/utils/instructions.rs
  • test-integration/test-committor-service/tests/test_ix_commit_local.rs
  • test-integration/test-committor-service/tests/test_intent_executor.rs
  • magicblock-committor-service/src/intent_execution_manager/intent_execution_engine.rs
📚 Learning: 2025-10-14T09:56:14.047Z
Learnt from: taco-paco
Repo: magicblock-labs/magicblock-validator PR: 564
File: test-integration/programs/flexi-counter/src/processor/call_handler.rs:122-125
Timestamp: 2025-10-14T09:56:14.047Z
Learning: The file test-integration/programs/flexi-counter/src/processor/call_handler.rs contains a test smart contract used for integration testing, not production code.

Applied to files:

  • test-integration/test-committor-service/tests/utils/transactions.rs
  • magicblock-committor-service/src/tasks/args_task.rs
  • test-integration/test-committor-service/tests/test_ix_commit_local.rs
  • test-integration/programs/flexi-counter/src/processor.rs
  • test-integration/programs/flexi-counter/src/state.rs
  • test-integration/test-committor-service/tests/test_intent_executor.rs
📚 Learning: 2025-10-21T14:00:54.642Z
Learnt from: bmuddha
Repo: magicblock-labs/magicblock-validator PR: 578
File: magicblock-aperture/src/requests/websocket/account_subscribe.rs:18-27
Timestamp: 2025-10-21T14:00:54.642Z
Learning: In magicblock-aperture account_subscribe handler (src/requests/websocket/account_subscribe.rs), the RpcAccountInfoConfig fields data_slice, commitment, and min_context_slot are currently ignored—only encoding is applied. This is tracked as technical debt in issue #579: https://github.com/magicblock-labs/magicblock-validator/issues/579

Applied to files:

  • test-integration/test-committor-service/tests/utils/transactions.rs
  • test-integration/test-committor-service/tests/test_ix_commit_local.rs
📚 Learning: 2025-11-21T10:22:07.492Z
Learnt from: taco-paco
Repo: magicblock-labs/magicblock-validator PR: 661
File: magicblock-committor-service/src/intent_executor/single_stage_executor.rs:20-28
Timestamp: 2025-11-21T10:22:07.492Z
Learning: In magicblock-committor-service's SingleStageExecutor and TwoStageExecutor (single_stage_executor.rs and two_stage_executor.rs), the fields transaction_strategy, junk, and patched_errors are intentionally public because these executors are designed to be used independently outside of the IntentExecutor scope, and callers need access to these execution reports for cleanup and error handling.

Applied to files:

  • magicblock-committor-service/src/intent_executor/task_info_fetcher.rs
  • magicblock-committor-service/src/intent_execution_manager.rs
  • magicblock-committor-service/src/transaction_preparator/mod.rs
  • magicblock-committor-service/src/service_ext.rs
  • programs/magicblock/src/schedule_transactions/process_scheduled_commit_sent.rs
  • magicblock-committor-service/src/tasks/buffer_task.rs
  • magicblock-committor-service/src/stubs/changeset_committor_stub.rs
  • magicblock-committor-service/src/transaction_preparator/delivery_preparator.rs
  • magicblock-accounts/src/scheduled_commits_processor.rs
  • test-integration/test-committor-service/tests/test_intent_executor.rs
  • magicblock-committor-service/src/intent_executor/error.rs
  • magicblock-committor-service/src/intent_execution_manager/intent_execution_engine.rs
  • magicblock-committor-service/src/intent_executor/two_stage_executor.rs
  • magicblock-committor-service/src/intent_executor/single_stage_executor.rs
  • magicblock-metrics/src/metrics/mod.rs
  • magicblock-committor-service/src/intent_executor/mod.rs
📚 Learning: 2025-11-04T10:48:00.070Z
Learnt from: bmuddha
Repo: magicblock-labs/magicblock-validator PR: 589
File: magicblock-processor/src/scheduler/mod.rs:217-219
Timestamp: 2025-11-04T10:48:00.070Z
Learning: In magicblock-validator, the codebase uses a pattern where types containing non-Send/non-Sync fields (like Rc<RefCell<...>>) are marked with unsafe impl Send when they are guaranteed to be confined to a single thread through careful API design and thread spawning patterns.

Applied to files:

  • magicblock-committor-service/src/intent_execution_manager.rs
📚 Learning: 2025-11-07T14:20:31.457Z
Learnt from: thlorenz
Repo: magicblock-labs/magicblock-validator PR: 621
File: magicblock-chainlink/src/remote_account_provider/chain_pubsub_actor.rs:457-495
Timestamp: 2025-11-07T14:20:31.457Z
Learning: In magicblock-chainlink/src/remote_account_provider/chain_pubsub_client.rs, the unsubscribe closure returned by PubSubConnection::account_subscribe(...) resolves to () (unit), not a Result. Downstream code should not attempt to inspect an unsubscribe result and can optionally wrap it in a timeout to guard against hangs.

Applied to files:

  • magicblock-committor-service/src/service_ext.rs
📚 Learning: 2025-11-18T08:47:39.702Z
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 639
File: magicblock-chainlink/tests/04_redeleg_other_separate_slots.rs:158-165
Timestamp: 2025-11-18T08:47:39.702Z
Learning: In magicblock-chainlink tests involving compressed accounts, `set_remote_slot()` sets the slot of the `AccountSharedData`, while `compressed_account_shared_with_owner_and_slot()` sets the slot of the delegation record. These are two different fields and both calls are necessary.

Applied to files:

  • test-integration/test-committor-service/tests/test_ix_commit_local.rs
📚 Learning: 2025-11-07T13:20:13.793Z
Learnt from: bmuddha
Repo: magicblock-labs/magicblock-validator PR: 589
File: magicblock-processor/src/scheduler/coordinator.rs:227-238
Timestamp: 2025-11-07T13:20:13.793Z
Learning: In magicblock-processor's ExecutionCoordinator (scheduler/coordinator.rs), the `account_contention` HashMap intentionally does not call `shrink_to_fit()`. Maintaining slack capacity is beneficial for performance by avoiding frequent reallocations during high transaction throughput. As long as empty entries are removed from the map (which `clear_account_contention` does), the capacity overhead is acceptable.

Applied to files:

  • magicblock-committor-service/src/transaction_preparator/delivery_preparator.rs
📚 Learning: 2025-11-07T13:09:52.253Z
Learnt from: bmuddha
Repo: magicblock-labs/magicblock-validator PR: 589
File: test-kit/src/lib.rs:275-0
Timestamp: 2025-11-07T13:09:52.253Z
Learning: In test-kit, the transaction scheduler in ExecutionTestEnv is not expected to shut down during tests. Therefore, using `.unwrap()` in test helper methods like `schedule_transaction` is acceptable and will not cause issues in the test environment.

Applied to files:

  • magicblock-accounts/src/scheduled_commits_processor.rs
  • test-integration/test-committor-service/tests/test_intent_executor.rs
  • magicblock-committor-service/src/intent_execution_manager/intent_execution_engine.rs
  • magicblock-committor-service/src/intent_executor/single_stage_executor.rs
📚 Learning: 2025-11-04T10:53:50.922Z
Learnt from: bmuddha
Repo: magicblock-labs/magicblock-validator PR: 589
File: magicblock-processor/src/scheduler/locks.rs:110-122
Timestamp: 2025-11-04T10:53:50.922Z
Learning: In magicblock-processor, the TransactionScheduler runs in a single, dedicated thread and will always remain single-threaded. The `next_transaction_id()` function in scheduler/locks.rs uses `unsafe static mut` which is safe given this architectural guarantee.

Applied to files:

  • magicblock-accounts/src/scheduled_commits_processor.rs
  • magicblock-committor-service/src/intent_execution_manager/intent_execution_engine.rs
📚 Learning: 2025-11-12T09:46:27.553Z
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 614
File: magicblock-task-scheduler/src/db.rs:26-0
Timestamp: 2025-11-12T09:46:27.553Z
Learning: In magicblock-task-scheduler, task parameter validation (including ensuring iterations > 0 and enforcing minimum execution intervals) is performed in the Magic program (on-chain) before ScheduleTaskRequest instances reach the scheduler service. The From<&ScheduleTaskRequest> conversion in db.rs does not need additional validation because inputs are already validated at the program level.

Applied to files:

  • magicblock-committor-service/src/intent_executor/single_stage_executor.rs
  • magicblock-committor-service/src/intent_executor/mod.rs
📚 Learning: 2025-11-13T09:38:43.804Z
Learnt from: bmuddha
Repo: magicblock-labs/magicblock-validator PR: 589
File: magicblock-processor/src/scheduler/locks.rs:64-102
Timestamp: 2025-11-13T09:38:43.804Z
Learning: In magicblock-processor's TransactionScheduler (scheduler/mod.rs line 59), the executor count is clamped to MAX_SVM_EXECUTORS (63) at initialization time, and executor IDs are assigned sequentially from 0 to count-1. This architectural guarantee ensures that executor IDs used in the bitmask-based AccountLock (scheduler/locks.rs) will always be within valid bounds for bit shifting operations, making runtime bounds checks unnecessary.

Applied to files:

  • magicblock-committor-service/src/intent_executor/mod.rs
🧬 Code graph analysis (18)
test-integration/test-committor-service/tests/utils/transactions.rs (1)
test-integration/test-committor-service/tests/utils/instructions.rs (1)
  • init_account_and_delegate_ixs (20-51)
magicblock-committor-service/src/intent_executor/task_info_fetcher.rs (5)
magicblock-committor-service/src/intent_executor/error.rs (2)
  • signature (29-34)
  • signature (156-164)
magicblock-committor-service/src/tasks/task_builder.rs (1)
  • signature (211-216)
magicblock-committor-service/src/transaction_preparator/delivery_preparator.rs (2)
  • signature (551-556)
  • signature (568-573)
magicblock-committor-service/src/transaction_preparator/error.rs (1)
  • signature (20-25)
magicblock-rpc-client/src/lib.rs (1)
  • signature (82-90)
magicblock-committor-service/src/tasks/args_task.rs (3)
magicblock-committor-service/src/intent_executor/mod.rs (1)
  • value (75-83)
magicblock-committor-service/src/intent_executor/error.rs (2)
  • value (115-127)
  • value (242-250)
magicblock-committor-service/src/tasks/buffer_task.rs (1)
  • value (146-150)
magicblock-committor-service/src/tasks/task_builder.rs (2)
magicblock-committor-service/src/intent_executor/task_info_fetcher.rs (1)
  • signature (279-285)
magicblock-rpc-client/src/lib.rs (1)
  • signature (82-90)
programs/magicblock/src/schedule_transactions/process_scheduled_commit_sent.rs (1)
magicblock-committor-service/src/intent_executor/two_stage_executor.rs (1)
  • commit (69-134)
magicblock-committor-service/src/tasks/buffer_task.rs (3)
magicblock-committor-service/src/intent_executor/mod.rs (1)
  • value (75-83)
magicblock-committor-service/src/intent_executor/error.rs (2)
  • value (115-127)
  • value (242-250)
magicblock-committor-service/src/tasks/args_task.rs (1)
  • value (171-178)
test-integration/test-committor-service/tests/test_ix_commit_local.rs (1)
test-integration/test-committor-service/tests/utils/transactions.rs (1)
  • init_and_delegate_account_on_chain (127-224)
magicblock-committor-service/src/stubs/changeset_committor_stub.rs (1)
magicblock-committor-service/src/intent_execution_manager/intent_execution_engine.rs (3)
  • new (51-64)
  • new (105-122)
  • new (701-707)
magicblock-committor-service/src/transaction_preparator/delivery_preparator.rs (3)
magicblock-metrics/src/metrics/mod.rs (2)
  • observe_committor_intent_task_preparation_time (434-442)
  • observe_committor_intent_alt_preparation_time (444-446)
magicblock-committor-service/src/transaction_preparator/error.rs (1)
  • signature (20-25)
magicblock-rpc-client/src/lib.rs (2)
  • signature (82-90)
  • error (193-195)
magicblock-accounts/src/scheduled_commits_processor.rs (3)
magicblock-committor-service/src/intent_executor/mod.rs (1)
  • value (75-83)
magicblock-committor-service/src/intent_executor/error.rs (4)
  • value (115-127)
  • value (242-250)
  • signature (29-34)
  • signature (156-164)
magicblock-committor-service/src/intent_executor/two_stage_executor.rs (2)
  • commit (69-134)
  • finalize (188-252)
magicblock-committor-service/src/transaction_preparator/error.rs (1)
magicblock-committor-service/src/transaction_preparator/delivery_preparator.rs (2)
  • signature (551-556)
  • signature (568-573)
test-integration/test-committor-service/tests/test_intent_executor.rs (5)
magicblock-committor-service/src/intent_execution_manager/intent_execution_engine.rs (3)
  • new (51-64)
  • new (105-122)
  • new (701-707)
magicblock-committor-service/src/intent_executor/mod.rs (1)
  • new (124-138)
test-integration/programs/flexi-counter/src/state.rs (2)
  • pda (34-37)
  • new (16-22)
test-integration/test-tools/src/conversions.rs (1)
  • err (8-8)
test-integration/test-committor-service/tests/utils/transactions.rs (1)
  • init_and_delegate_account_on_chain (127-224)
magicblock-committor-service/src/intent_executor/error.rs (4)
magicblock-rpc-client/src/lib.rs (2)
  • error (193-195)
  • signature (82-90)
magicblock-committor-service/src/tasks/args_task.rs (2)
  • value (171-178)
  • task_type (147-154)
magicblock-committor-service/src/tasks/buffer_task.rs (2)
  • value (146-150)
  • task_type (123-127)
magicblock-committor-service/src/tasks/mod.rs (1)
  • task_type (90-90)
magicblock-committor-service/src/intent_execution_manager/intent_execution_engine.rs (4)
magicblock-rpc-client/src/lib.rs (1)
  • error (193-195)
magicblock-committor-service/src/intent_executor/mod.rs (5)
  • new (124-138)
  • None (904-904)
  • None (920-920)
  • cleanup (104-104)
  • cleanup (839-849)
magicblock-committor-service/src/transaction_preparator/delivery_preparator.rs (4)
  • new (50-60)
  • signature (551-556)
  • signature (568-573)
  • cleanup (438-500)
magicblock-committor-service/src/intent_executor/error.rs (2)
  • signature (29-34)
  • signature (156-164)
magicblock-committor-service/src/intent_executor/two_stage_executor.rs (2)
magicblock-committor-service/src/intent_executor/error.rs (4)
  • signature (29-34)
  • signature (156-164)
  • from_commit_execution_error (68-76)
  • from_finalize_execution_error (78-88)
magicblock-committor-service/src/intent_executor/mod.rs (3)
  • new (124-138)
  • cleanup (104-104)
  • cleanup (839-849)
magicblock-committor-service/src/intent_executor/single_stage_executor.rs (3)
magicblock-committor-service/src/intent_executor/mod.rs (5)
  • new (124-138)
  • execute (97-101)
  • execute (802-836)
  • cleanup (104-104)
  • cleanup (839-849)
magicblock-committor-service/src/intent_executor/two_stage_executor.rs (1)
  • new (55-67)
magicblock-committor-service/src/intent_executor/error.rs (1)
  • from_finalize_execution_error (78-88)
magicblock-metrics/src/metrics/mod.rs (3)
magicblock-committor-service/src/tasks/args_task.rs (2)
  • new (37-42)
  • task_type (147-154)
magicblock-committor-service/src/tasks/buffer_task.rs (2)
  • new (38-46)
  • task_type (123-127)
magicblock-committor-service/src/tasks/mod.rs (1)
  • task_type (90-90)
magicblock-committor-service/src/intent_executor/mod.rs (4)
magicblock-committor-service/src/intent_execution_manager/intent_execution_engine.rs (7)
  • execute (267-320)
  • execute (778-818)
  • cleanup (820-822)
  • new (51-64)
  • new (105-122)
  • new (701-707)
  • spawn (125-130)
magicblock-committor-service/src/intent_executor/single_stage_executor.rs (2)
  • execute (40-103)
  • new (30-38)
magicblock-committor-service/src/transaction_preparator/delivery_preparator.rs (2)
  • cleanup (438-500)
  • new (50-60)
magicblock-committor-service/src/intent_executor/two_stage_executor.rs (1)
  • new (55-67)
🔇 Additional comments (37)
magicblock-committor-service/src/intent_executor/task_info_fetcher.rs (2)

13-13: LGTM!

The import is necessary for the new signature() method and is correctly placed.


278-286: LGTM! Consistent with project-wide pattern.

The implementation correctly follows the established pattern for extracting signatures from error types across the codebase. All three error variants are properly handled, with delegation to the inner MagicBlockRpcClientError::signature() method when appropriate.

test-integration/programs/flexi-counter/src/state.rs (1)

12-13: LGTM! Test constants are well-defined.

These constants provide a clear mechanism for injecting undelegation failures in integration tests. The naming is descriptive and the values are appropriate for test scenarios.

Based on learnings

test-integration/programs/flexi-counter/src/processor.rs (1)

40-40: LGTM! Import additions are correct.

The new constants are properly imported from the state module to support the conditional undelegation failure logic.

programs/magicblock/src/schedule_transactions/process_scheduled_commit_sent.rs (5)

32-33: Good addition for error tracking.

The new fields appropriately capture execution diagnostics. The Option<String> for a terminal error and Vec<String> for intermediate patched errors provide clear semantics for consumers.


48-49: LGTM!

The printable struct correctly mirrors the new diagnostic fields from SentCommit.


77-78: LGTM!

The conversion correctly propagates the new diagnostic fields without unnecessary transformations.


222-229: LGTM!

The patched errors logging follows the same pattern as the chain signatures logging and provides clear diagnostics.


231-241: LGTM!

The error handling correctly returns a failure when an error message is present, otherwise succeeds. The ownership semantics are correct since commit is fully owned at this point.

magicblock-committor-service/src/tasks/task_builder.rs (1)

10-10: Expose TaskBuilderError.signature for upstream consumers

Forwarding signature() to the inner TaskInfoFetcherError in both variants is clean and keeps error reporting consistent with other components that already expose signatures. No issues with the new import or method.

Also applies to: 210-217

magicblock-metrics/src/metrics/mod.rs (1)

195-198: Committor intent metrics and helpers are wired consistently

The new counters/histograms and their helpers:

  • Use clear, stable metric names and reasonable bucket choices.
  • Are correctly registered in register().
  • Leverage LabelValue for task_type labeling, aligning with other committor metrics.

This should integrate cleanly with existing observability without behavior regressions.

Also applies to: 227-247, 281-288, 395-402, 434-446

magicblock-committor-service/src/tasks/buffer_task.rs (1)

3-3: BufferTask label integrates with task metrics

Implementing LabelValue for BufferTask and returning "buffer_commit" for the Commit variant matches the existing naming scheme and allows Buffer tasks to be used directly with the new preparation-time histograms. No issues.

Also applies to: 145-151

magicblock-committor-service/src/service_ext.rs (1)

94-104: Dispatcher now keyed directly by result id

Using execution_result.id as the key for pending_messages.remove aligns the dispatcher with the ScheduledBaseIntentWrapper.inner.id used on insertion and the new BroadcastedIntentExecutionResult shape. Listener lookup and delivery semantics remain the same.

magicblock-committor-service/src/tasks/args_task.rs (1)

2-2: ArgsTask LabelValue mapping matches task strategy taxonomy

The LabelValue impl mapping:

  • Commit → "args_commit"
  • BaseAction → "args_action"
  • Finalize → "args_finalize"
  • Undelegate → "args_undelegate"

is consistent with BufferTask’s "buffer_commit" and gives you fine-grained metric labels by task strategy and kind. Implementation is straightforward and side‑effect free.

Also applies to: 170-179

magicblock-committor-service/src/intent_execution_manager.rs (1)

7-7: Public API now centered on BroadcastedIntentExecutionResult

Restricting the public re-export to BroadcastedIntentExecutionResult matches the new execution flow and avoids leaking ExecutionOutputWrapper. Please ensure no external crates rely on importing ExecutionOutputWrapper via this module; the compiler will surface any such usages.

magicblock-committor-service/src/tasks/mod.rs (1)

13-13: BaseTask now requires LabelValue for metric labeling

Extending BaseTask to Send + Sync + DynClone + LabelValue is a clean way to ensure every task can provide a stable label string (e.g., for task_type histograms) without extra plumbing. Just confirm that any other BaseTask implementors also implement LabelValue; compile errors will highlight any misses.

Also applies to: 54-54

test-integration/test-committor-service/tests/test_ix_commit_local.rs (1)

113-119: init_and_delegate_account_on_chain call sites correctly updated with None label

Both helpers now pass None as the third argument, which keeps behavior identical to the old 2‑arg version (default label path) while aligning with the new API. No issues here.

Also applies to: 393-403

magicblock-committor-service/src/transaction_preparator/error.rs (1)

1-26: Error plumbing and signature() helper are consistent

Wrapping DeliveryPreparatorError in TransactionPreparatorError::DeliveryPreparationError and exposing fn signature(&self) -> Option<Signature> that delegates to the inner error keeps the error surface coherent and makes signature extraction straightforward. The From<TaskStrategistError> mapping into FailedToFitError and SignerError also looks correct.

No functional issues spotted here.

Also applies to: 28-35

test-integration/test-committor-service/tests/test_intent_executor.rs (2)

1-4: Label‑aware counter setup and new imports are wired correctly

  • Importing mem, FlexiCounterInstruction, FlexiCounter, and FAIL_UNDELEGATION_LABEL is justified by later usage (patched‑error inspection, failing undelegation actions, and CPI stress tests).
  • setup_counter(counter_bytes, label) cleanly forwards the optional label into init_and_delegate_account_on_chain(&counter_auth, counter_bytes, label) and then sets the owner to program_flexi_counter::id(), which aligns with how other helpers use that account.

This all looks consistent with the rest of the test helpers and the new label‑driven failure paths.

Also applies to: 16-22, 40-42, 917-924


112-161: New parsing tests correctly exercise labeled counters and updated setup

  • test_commit_id_error_parsing, test_undelegation_error_parsing, test_action_error_parsing, and test_cpi_limits_error_parsing all use the updated setup_counter(COUNTER_SIZE, ...) signature, passing None for the default path and Some(FAIL_UNDELEGATION_LABEL.to_string()) when an undelegation failure is desired.
  • Each test:
    • Ensures prepare_and_execute_strategy succeeds (outer preparation ok).
    • Asserts that the inner result is Err with the expected TransactionStrategyExecutionError variant.
    • Checks that the formatted error string contains a stable substring (EXPECTED_ERR_MSG), which is a good balance between precision and robustness.

The control flow and assertions are consistent across variants; no logical issues found.

Also applies to: 163-210, 224-225, 284-287

test-integration/test-committor-service/tests/utils/transactions.rs (1)

126-147: Label threading verified across all call sites

All 7 call sites of init_and_delegate_account_on_chain have been correctly updated to the new 3-argument signature:

  • 5 sites pass None (preserving default label behavior)
  • 1 site passes Some(FAIL_UNDELEGATION_LABEL.to_string()) (custom label)
  • 1 site passes the label variable (custom label)

The implementation and threading are correct. No issues found.

magicblock-committor-service/src/transaction_preparator/mod.rs (1)

13-17: Error handling verified; call site correctly uses try_join_all with BufferExecutionError

The trait and impl both correctly define cleanup_for_strategy to return DeliveryPreparatorResult<(), BufferExecutionError> (which is Result<(), BufferExecutionError>). The impl forwards to delivery_preparator.cleanup() which also returns the same type. At the call site in intent_executor/mod.rs:839, the cleanup method properly collects futures yielding Result<(), BufferExecutionError> and uses try_join_all() to handle them, which propagates the error type correctly. The error handling is type-safe and consistent throughout.

magicblock-committor-service/src/transaction_preparator/delivery_preparator.rs (3)

69-103: Task/ALT preparation metrics are correctly scoped

The new timers around prepare_task_handling_errors and prepare_lookup_tables are wrapped tightly around the awaited calls and stopped in all paths via local res bindings, so they should give accurate per-task and per-ALT timing without leaking. No behavioral change beyond metrics.


237-247: Double‑check safety of parallel buffer realloc transactions

initialize_buffer_account now sends the first chunk sequentially, then fires all remaining preparation_instructions in parallel via try_join_all. This is great for latency, but it assumes that the individual realloc chunks are independent enough that concurrent transactions (likely touching the same buffer PDA) won’t race on size/ownership or cause non‑deterministic failures at the runtime level. Please confirm that chunk_realloc_ixs guarantees such independence (or that later chunks are idempotent with respect to earlier ones); if not, this should remain sequential.


443-500: Error typing and signature propagation align with executor/cleanup flow

Changing cleanup to return DeliveryPreparatorResult<(), BufferExecutionError> and introducing DeliveryPreparatorError plus InternalError::signature() cleanly separate buffer‑level execution failures from higher‑level preparation failures, while still allowing callers and metrics to extract a Signature when available. This lines up with the IntentExecutor::cleanup contract and with TransactionPreparatorError::signature(), and keeps the error surface consistent across preparation and cleanup.

Also applies to: 550-577

magicblock-accounts/src/scheduled_commits_processor.rs (1)

210-243: SentCommit now correctly captures both primary and patched intent errors

The new flow that passes BroadcastedIntentExecutionResult through process_intent_result into build_sent_commit looks sound: you extract intent_id/trigger_type once in the loop, use result.as_ref().err() for an optional error_message, derive chain_signatures from either ExecutionOutput (success) or IntentExecutorError::signatures() (failure), and then log and stringify each result.patched_errors entry into the patched_errors field. This gives downstream consumers a complete picture of both the final error and all patched intermediate errors without dropping any data.

Also applies to: 272-321

magicblock-committor-service/src/intent_executor/error.rs (3)

48-65: Composite IntentExecutorError variants and signatures() are consistent with consumers

The new FailedToCommitError/FailedToFinalizeError variants plus the from_*_execution_error helpers cleanly wrap TransactionStrategyExecutionError while capturing commit/finalize signatures via error.signature(). The signatures() method then exposes a uniform (commit, finalize?) view across execution, preparation, and builder errors, which is exactly what ScheduledCommitsProcessor::build_sent_commit expects when reconstructing chain_signatures.

Also applies to: 67-112


241-251: Metrics labels now reflect semantic execution error classes

The metrics::LabelValue impl for TransactionStrategyExecutionError provides stable, semantically meaningful labels (actions_failed, commit_nonce_failed, cpi_limit_failed, undelegation_failed), and the IntentExecutorError label impl correctly delegates to the nested TransactionStrategyExecutionError where present, falling back to "failed" otherwise. This should give much clearer error distribution metrics without changing behavior.


130-143: Document and validate the task-instruction layout coupling in try_from_transaction_error

The review correctly identifies a fragile coupling in try_from_transaction_error (lines 169–238). The function assumes exactly two budget instructions precede task instructions and that the tasks array order matches instruction order. While the code is defensive and won't silently drop errors, it can map errors to the wrong variant if this invariant breaks.

Verified findings:

  • budget_instructions() returns [Instruction; 2] (tasks/utils.rs:135)
  • Instructions are concatenated as [budget_ixs, task_ixs] (tasks/utils.rs:98)
  • OFFSET=2 is correct and well-established
  • No tests validate that the tasks parameter corresponds to the instruction array
  • This mapping is used in production (intent_executor/mod.rs:721, delivery_preparator.rs:370)

Action required: Add a comment documenting the contract (that tasks must correspond to the per-task instructions in order), consider adding a test validating this invariant, or refactor to eliminate the implicit coupling (e.g., pass task indices alongside errors).

magicblock-committor-service/src/intent_execution_manager/intent_execution_engine.rs (2)

1-5: BroadcastedIntentExecutionResult cleanly exposes execution outcome and patched errors

Defining PatchedErrors = Vec<TransactionStrategyExecutionError> and wrapping IntentExecutionResult into BroadcastedIntentExecutionResult { inner: Result<ExecutionOutput, Arc<IntentExecutorError>>, id, trigger_type, patched_errors: Arc<PatchedErrors> } gives subscribers direct access to both the final outcome and the full list of patched errors. The Deref impl back to Result<ExecutionOutput, Arc<IntentExecutorError>> preserves existing ergonomics (is_ok, is_err, as_ref, etc.), so the public surface evolves without breaking callers.

Also applies to: 18-34, 40-73


328-345: Tests validate new broadcast shape and patched error reporting

The tests now assert that BroadcastedIntentExecutionResult carries the correct id, trigger_type, error type, and patched_errors content (including the exact error string), and that success paths under contention/high throughput still behave as expected. The failing MockIntentExecutor builds an IntentExecutionResult with a nested FailedToCommitError and a non‑empty patched_errors vector, which exercises both the error and patched‑error plumbing end‑to‑end.

Also applies to: 372-397, 440-497, 587-623

magicblock-committor-service/src/intent_executor/single_stage_executor.rs (1)

20-23: Single‑stage executor state, recursion, and new undelegation patching look coherent

  • Using &mut self plus a stored transaction_strategy and crate‑local inner nicely encodes the stateful loop without exposing internals beyond transaction_strategy (which matches the earlier intent to allow external callers to inspect/drive the strategy).
  • The recursion‑capped loop correctly distinguishes:
    • success → ExecutionOutput::SingleStage,
    • unpatchable errors / missing committed pubkeys / CPI‑limit / internal errors → immediate break,
    • patchable errors → inner.junk.push(cleanup) + inner.patched_errors.push(execution_err) on each retry.
  • The new UndelegationError arm in patch_strategy cleanly reuses IntentExecutorImpl::handle_undelegation_error, in line with how ActionsError and CommitIDError are already handled, and ensures the patched error is recorded once per retry.
  • Early return when committed_pubkeys is None preserves the previous behavior for intents that don’t commit accounts (standalone actions), which seems consistent with the existing assumptions around reset/patch flows.

Also applies to: 30-38, 40-103, 112-159

magicblock-committor-service/src/intent_executor/mod.rs (3)

86-91: IntentExecutionResult and executor state tracking align with the new broadcasting flow

  • Introducing IntentExecutionResult { inner, patched_errors } and making it the return type of IntentExecutor::execute cleanly separates user‑visible outcome from the internal patch trace while keeping type signatures straightforward.
  • Keeping junk and patched_errors as pub on IntentExecutorImpl preserves the ability to run the low‑level executors independently and inspect their state, while mem::take(&mut self.patched_errors) in execute guarantees per‑intent isolation of the patched error list.
  • The new cleanup(self) on the trait, backed by IntentExecutorImpl::cleanup, matches how intent_execution_engine now awaits cleanup asynchronously after broadcasting results and lets tests explicitly await cleanup when needed.

Also applies to: 93-105, 107-117, 124-137


273-323: Single‑stage → two‑stage fallback on CPI limit is handled correctly and records patches

  • The single_stage_execution_flow logic that:
    • runs the SingleStageExecutor,
    • special‑cases FailedToFinalizeError { err: CpiLimitError(..), .. } with committed pubkeys,
    • then splits via handle_cpi_limit_error, pushes the cleanup strategy into junk, records the CPI‑limit error into patched_errors, and continues in two_stage_execution_flow,
      ensures that:
    • you don’t persist or expose the transient single‑stage failure as the final result,
    • all cleanup and the fact that a CPI‑limit patch occurred are captured in the executor state and surfaced through IntentExecutionResult.
  • For all non‑CPI‑limit outcomes (including success), pushing the final transaction_strategy into junk before returning preserves the invariant that every strategy used for an intent eventually gets cleaned up.

838-849: Cleanup implementation matches how junk is accumulated

  • cleanup(mut self) iterates over self.junk and calls cleanup_for_strategy for each accumulated TransactionStrategy, then uses try_join_all to await them and collapse to Result<(), BufferExecutionError>.
  • This is consistent with how SingleStageExecutor and TwoStageExecutor both push per‑patch cleanup strategies and final strategies into junk, so all resources scheduled during patches and normal execution are eventually released.
magicblock-committor-service/src/intent_executor/two_stage_executor.rs (2)

22-47: Stateful TwoStageExecutor design and integration with executor state look solid

  • Splitting the two‑stage flow into Initialized, Committed, and Finalized states and threading them through TwoStageExecutor<'a, T, F, S: Sealed> gives a clear, type‑level encoding of the valid progression (new → commit → finalize).
  • commit and finalize both:
    • operate on self.state.*_strategy,
    • push per‑patch cleanup strategies into inner.junk,
    • on each successful patch, record the TransactionStrategyExecutionError into inner.patched_errors,
    • and, after the loop, always push the final commit/finalize strategy into inner.junk before mapping the last execution result into an IntentExecutorError.
  • This mirrors the single‑stage behavior while keeping the API safe and explicit for callers of the two‑stage path.

Also applies to: 48-67, 69-134


298-304: Sealed trait correctly restricts TwoStageExecutor state parameter

  • The private sealed module with a pub trait Sealed and impls only for Initialized, Committed, and Finalized ensures external code cannot introduce additional state types for TwoStageExecutor, while still allowing them to name and use the three provided states.
  • This is an idiomatic Rust sealing pattern and fits well with the stateful design here.

Comment on lines +475 to +502
/// Handles actions error, stripping away actions
/// Returns [`TransactionStrategy`] to be cleaned up
fn handle_undelegation_error(
&self,
strategy: &mut TransactionStrategy,
) -> TransactionStrategy {
let position = strategy
.optimized_tasks
.iter()
.position(|el| el.task_type() == TaskType::Undelegate);

if let Some(position) = position {
// Remove everything after undelegation including post undelegation actions
let removed_task =
strategy.optimized_tasks.drain(position..).collect();
let old_alts =
strategy.dummy_revaluate_alts(&self.authority.pubkey());
TransactionStrategy {
optimized_tasks: removed_task,
lookup_tables_keys: old_alts,
}
} else {
TransactionStrategy {
optimized_tasks: vec![],
lookup_tables_keys: vec![],
}
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Fix handle_undelegation_error documentation and clarify behavior

  • The doc comment still says “Handles actions error, stripping away actions”, but this helper now specifically handles undelegation by draining tasks from the first TaskType::Undelegate onward and returning them (plus old ALTs) as a cleanup TransactionStrategy.
  • It would be clearer to update the comment to describe undelegation semantics (e.g., “Handles undelegation error by removing tasks from the first undelegation onward and returning them for cleanup”), which also avoids confusion with handle_actions_error.
🤖 Prompt for AI Agents
In magicblock-committor-service/src/intent_executor/mod.rs around lines 475 to
502, the doc comment for handle_undelegation_error is inaccurate and vague;
update it to clearly state that this function handles undelegation errors by
finding the first TaskType::Undelegate, draining all tasks from that position
onward (including post-undelegation tasks), and returning those drained tasks
along with the previous lookup table keys as a TransactionStrategy for cleanup.
Keep the comment concise, mention that it returns the drained tasks and old ALTs
for cleanup, and avoid referencing generic "actions error" or conflating it with
handle_actions_error.

Comment on lines +19 to +20
/// Code emitted if Intent failed to execute on base chain
const INTENT_FAILED_CODE: u32 = 0x7461636F;
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Document the custom error code's purpose.

The constant INTENT_FAILED_CODE with value 0x7461636F should include a doc comment explaining when this error is returned and what it signifies. Custom error codes are more maintainable when their purpose is documented inline.

Apply this diff to add documentation:

+/// Error code returned when an intent execution failed on the base chain.
+/// This indicates the intent could not be successfully executed despite patching attempts.
 const INTENT_FAILED_CODE: u32 = 0x7461636F;

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In
programs/magicblock/src/schedule_transactions/process_scheduled_commit_sent.rs
around lines 19 to 20, the constant INTENT_FAILED_CODE lacks a doc comment; add
a concise Rust doc comment above the constant explaining when this custom error
code is returned (e.g., when an Intent failed to execute on the base chain
during scheduled commit processing), what it signifies (failure of intent
execution vs other errors), and any relevant context such as where callers
should map or handle it.

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: 2

Caution

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

⚠️ Outside diff range comments (1)
test-integration/test-committor-service/tests/test_ix_commit_local.rs (1)

519-530: Add assertions for patched_errors to improve test quality.

The PR description states "Patched errors trace is now checked in tests to improve test quality," but this test file doesn't validate patched_errors. Since line 530 accesses .inner.unwrap(), the outer wrapper likely contains patched error information that should be verified.

Consider adding assertions before unwrapping to validate the expected state of patched errors:

 for (execution_output, base_intent) in
     execution_outputs.into_iter().zip(base_intents.into_iter())
 {
+    // Verify no errors were patched in these test scenarios
+    assert!(
+        execution_output.patched_errors.is_empty(),
+        "Unexpected patched errors: {:?}",
+        execution_output.patched_errors
+    );
+    
     let execution_output = execution_output.inner.unwrap();

This validates a key feature introduced in this PR and prevents regressions where errors are silently patched in scenarios that should execute cleanly.

♻️ Duplicate comments (1)
magicblock-committor-service/src/intent_executor/mod.rs (1)

471-498: Fix handle_undelegation_error docstring and double-check no-undelegate path

The doc comment still says “Handles actions error, stripping away actions”, but this helper is specifically handling undelegation by draining tasks from the first TaskType::Undelegate onward and returning those drained tasks plus the old ALTs as a cleanup TransactionStrategy. It would be clearer to update the comment to describe the undelegation semantics explicitly and avoid conflation with handle_actions_error.

Also, when no TaskType::Undelegate is found, the function returns an entirely empty cleanup strategy (no tasks, no lookup table keys). That’s fine if all call sites guarantee at least one undelegation task when this helper is invoked; otherwise, it would silently skip ALT cleanup. Please sanity‑check that assumption and, if it’s not guaranteed, consider returning appropriate lookup table keys in this branch as well.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e01bc79 and d1f9a74.

📒 Files selected for processing (2)
  • magicblock-committor-service/src/intent_executor/mod.rs (8 hunks)
  • test-integration/test-committor-service/tests/test_ix_commit_local.rs (6 hunks)
🧰 Additional context used
🧠 Learnings (8)
📓 Common learnings
Learnt from: taco-paco
Repo: magicblock-labs/magicblock-validator PR: 661
File: magicblock-committor-service/src/intent_executor/single_stage_executor.rs:20-28
Timestamp: 2025-11-21T10:22:07.520Z
Learning: In magicblock-committor-service's SingleStageExecutor and TwoStageExecutor (single_stage_executor.rs and two_stage_executor.rs), the fields transaction_strategy, junk, and patched_errors are intentionally public because these executors are designed to be used independently outside of the IntentExecutor scope, and callers need access to these execution reports for cleanup and error handling.
📚 Learning: 2025-10-14T09:56:14.047Z
Learnt from: taco-paco
Repo: magicblock-labs/magicblock-validator PR: 564
File: test-integration/programs/flexi-counter/src/processor/call_handler.rs:122-125
Timestamp: 2025-10-14T09:56:14.047Z
Learning: The file test-integration/programs/flexi-counter/src/processor/call_handler.rs contains a test smart contract used for integration testing, not production code.

Applied to files:

  • test-integration/test-committor-service/tests/test_ix_commit_local.rs
📚 Learning: 2025-11-19T09:34:37.917Z
Learnt from: thlorenz
Repo: magicblock-labs/magicblock-validator PR: 621
File: test-integration/test-chainlink/tests/ix_remote_account_provider.rs:62-63
Timestamp: 2025-11-19T09:34:37.917Z
Learning: In test-integration/test-chainlink/tests/ix_remote_account_provider.rs and similar test files, the `_fwd_rx` receiver returned by `init_remote_account_provider()` is intentionally kept alive (but unused) to prevent "receiver dropped" errors on the sender side. The pattern `let (remote_account_provider, _fwd_rx) = init_remote_account_provider().await;` should NOT be changed to `let (remote_account_provider, _) = ...` because dropping the receiver would cause send() operations to fail.

Applied to files:

  • test-integration/test-committor-service/tests/test_ix_commit_local.rs
📚 Learning: 2025-10-21T14:00:54.642Z
Learnt from: bmuddha
Repo: magicblock-labs/magicblock-validator PR: 578
File: magicblock-aperture/src/requests/websocket/account_subscribe.rs:18-27
Timestamp: 2025-10-21T14:00:54.642Z
Learning: In magicblock-aperture account_subscribe handler (src/requests/websocket/account_subscribe.rs), the RpcAccountInfoConfig fields data_slice, commitment, and min_context_slot are currently ignored—only encoding is applied. This is tracked as technical debt in issue #579: https://github.com/magicblock-labs/magicblock-validator/issues/579

Applied to files:

  • test-integration/test-committor-service/tests/test_ix_commit_local.rs
📚 Learning: 2025-11-04T10:48:00.070Z
Learnt from: bmuddha
Repo: magicblock-labs/magicblock-validator PR: 589
File: magicblock-processor/src/scheduler/mod.rs:217-219
Timestamp: 2025-11-04T10:48:00.070Z
Learning: In magicblock-validator, the codebase uses a pattern where types containing non-Send/non-Sync fields (like Rc<RefCell<...>>) are marked with unsafe impl Send when they are guaranteed to be confined to a single thread through careful API design and thread spawning patterns.

Applied to files:

  • test-integration/test-committor-service/tests/test_ix_commit_local.rs
📚 Learning: 2025-11-21T10:22:07.520Z
Learnt from: taco-paco
Repo: magicblock-labs/magicblock-validator PR: 661
File: magicblock-committor-service/src/intent_executor/single_stage_executor.rs:20-28
Timestamp: 2025-11-21T10:22:07.520Z
Learning: In magicblock-committor-service's SingleStageExecutor and TwoStageExecutor (single_stage_executor.rs and two_stage_executor.rs), the fields transaction_strategy, junk, and patched_errors are intentionally public because these executors are designed to be used independently outside of the IntentExecutor scope, and callers need access to these execution reports for cleanup and error handling.

Applied to files:

  • test-integration/test-committor-service/tests/test_ix_commit_local.rs
  • magicblock-committor-service/src/intent_executor/mod.rs
📚 Learning: 2025-11-13T09:38:43.804Z
Learnt from: bmuddha
Repo: magicblock-labs/magicblock-validator PR: 589
File: magicblock-processor/src/scheduler/locks.rs:64-102
Timestamp: 2025-11-13T09:38:43.804Z
Learning: In magicblock-processor's TransactionScheduler (scheduler/mod.rs line 59), the executor count is clamped to MAX_SVM_EXECUTORS (63) at initialization time, and executor IDs are assigned sequentially from 0 to count-1. This architectural guarantee ensures that executor IDs used in the bitmask-based AccountLock (scheduler/locks.rs) will always be within valid bounds for bit shifting operations, making runtime bounds checks unnecessary.

Applied to files:

  • magicblock-committor-service/src/intent_executor/mod.rs
📚 Learning: 2025-11-12T09:46:27.553Z
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 614
File: magicblock-task-scheduler/src/db.rs:26-0
Timestamp: 2025-11-12T09:46:27.553Z
Learning: In magicblock-task-scheduler, task parameter validation (including ensuring iterations > 0 and enforcing minimum execution intervals) is performed in the Magic program (on-chain) before ScheduleTaskRequest instances reach the scheduler service. The From<&ScheduleTaskRequest> conversion in db.rs does not need additional validation because inputs are already validated at the program level.

Applied to files:

  • magicblock-committor-service/src/intent_executor/mod.rs
🧬 Code graph analysis (2)
test-integration/test-committor-service/tests/test_ix_commit_local.rs (1)
test-integration/test-committor-service/tests/utils/transactions.rs (1)
  • init_and_delegate_account_on_chain (127-224)
magicblock-committor-service/src/intent_executor/mod.rs (4)
magicblock-committor-service/src/intent_executor/single_stage_executor.rs (2)
  • execute (40-103)
  • new (30-38)
magicblock-committor-service/src/intent_execution_manager/intent_execution_engine.rs (7)
  • execute (267-320)
  • execute (778-818)
  • cleanup (820-822)
  • new (51-64)
  • new (105-122)
  • new (701-707)
  • spawn (125-130)
magicblock-committor-service/src/transaction_preparator/delivery_preparator.rs (2)
  • cleanup (438-500)
  • new (50-60)
magicblock-committor-service/src/intent_executor/two_stage_executor.rs (1)
  • new (55-67)
🔇 Additional comments (8)
test-integration/test-committor-service/tests/test_ix_commit_local.rs (2)

6-6: LGTM!

The new imports support the FlexiCounter serialization functionality added to improve test realism.

Also applies to: 30-30


116-117: LGTM!

The calls to init_and_delegate_account_on_chain correctly match the updated signature with the new label parameter set to None.

Also applies to: 406-411

magicblock-committor-service/src/intent_executor/mod.rs (6)

7-7: Imports updated consistently with new executor behavior

Adding mem, ControlFlow, Duration, narrowing the log import to trace/warn, and pulling in BufferExecutionError all line up with the new patched‑errors surface, retry flow, and cleanup API. No issues here.

Also applies to: 11-11, 54-54


86-105: IntentExecutionResult wrapper and trait surface look coherent

Wrapping the inner IntentExecutorResult<ExecutionOutput> plus patched_errors in IntentExecutionResult, switching execute to &mut self, and introducing async fn cleanup(self) give a clean, stateful lifecycle for executors (execute → inspect result/patched_errors → cleanup). The API shape is internally consistent and matches how the type is later consumed.


113-117: Public junk/patched_errors on IntentExecutorImpl are consistent with executor reporting

Exposing pub junk: Vec<TransactionStrategy> and pub patched_errors: Vec<TransactionStrategyExecutionError>, and initializing both to empty vectors in new(), aligns with the pattern where SingleStageExecutor/TwoStageExecutor publicly expose their execution reports so callers/tests can inspect and drive cleanup. This keeps the reporting surface uniform across the executor stack.

Based on learnings

Also applies to: 135-137


174-178: Stateful single-/two-stage flows and CPI-limit fallback look correct

Moving execute_inner, single_stage_execution_flow, and two_stage_execution_flow to &mut self and threading SingleStageExecutor::new(self, transaction_strategy) / TwoStageExecutor::new(self, ...) correctly centralizes mutation of junk and patched_errors inside IntentExecutorImpl. The CPI‑limit branch in single_stage_execution_flow:

  • Special‑cases FailedToFinalizeError::CpiLimitError only when committed_pubkeys.is_some(),
  • Splits the original strategy via handle_cpi_limit_error,
  • Pushes the cleanup strategy and patched error onto executor state,
  • Then continues via two_stage_execution_flow,

which matches the intended “retry as two‑stage with recorded cleanup + patched error trace” behavior. I don’t see obvious edge‑case gaps here.

Also applies to: 273-343


799-832: Executor execute wrapper cleanly exposes patched errors and offloads metrics

The updated execute implementation:

  • Resets the TaskInfoFetcher only when the result is an error or the intent is an undelegation, which matches the comment and avoids unnecessary resets.
  • Persists the inner IntentExecutorResult<ExecutionOutput> as before.
  • Uses Result::inspect to spawn intent_metrics on success, keeping RPC CU lookups off the hot path.
  • Constructs IntentExecutionResult while draining self.patched_errors with mem::take, ensuring each call returns only the patched‑error trace for that intent and doesn’t leak state across executions.

This wiring looks correct and matches how BroadcastedIntentExecutionResult::new later consumes the result.


834-845: cleanup(self) correctly centralizes junk cleanup

Consuming self in cleanup, iterating over self.junk, and running transaction_preparator.cleanup_for_strategy for each strategy via try_join_all is a good fit for the new lifecycle: callers can either await cleanup explicitly or offload it to a background task, and all outstanding cleanup strategies are handled in one place. Behavior here looks sound.

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: 2

♻️ Duplicate comments (2)
test-integration/test-committor-service/tests/test_ix_commit_local.rs (2)

117-128: Verify serialized size and consider more descriptive label.

The past review comment about potential truncation if serialized FlexiCounter exceeds bytes still applies here. Additionally, the hardcoded label "Counter" could be more descriptive for debugging purposes.

Consider making the label more descriptive:

 let counter = FlexiCounter {
-    label: "Counter".to_string(),
+    label: format!("Counter_{}B", bytes),
     updates: 0,
     count: 101,
 };

414-415: Consider using serialized FlexiCounter data for consistency.

As noted in the previous review comment, create_bundles still uses dummy zero data while commit_single_account (lines 121-128) now properly initializes with serialized FlexiCounter. This inconsistency should be addressed for improved test quality.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d1f9a74 and 927a357.

📒 Files selected for processing (1)
  • test-integration/test-committor-service/tests/test_ix_commit_local.rs (5 hunks)
🧰 Additional context used
🧠 Learnings (8)
📓 Common learnings
Learnt from: taco-paco
Repo: magicblock-labs/magicblock-validator PR: 661
File: magicblock-committor-service/src/intent_executor/single_stage_executor.rs:20-28
Timestamp: 2025-11-21T10:22:07.520Z
Learning: In magicblock-committor-service's SingleStageExecutor and TwoStageExecutor (single_stage_executor.rs and two_stage_executor.rs), the fields transaction_strategy, junk, and patched_errors are intentionally public because these executors are designed to be used independently outside of the IntentExecutor scope, and callers need access to these execution reports for cleanup and error handling.
📚 Learning: 2025-10-14T09:56:14.047Z
Learnt from: taco-paco
Repo: magicblock-labs/magicblock-validator PR: 564
File: test-integration/programs/flexi-counter/src/processor/call_handler.rs:122-125
Timestamp: 2025-10-14T09:56:14.047Z
Learning: The file test-integration/programs/flexi-counter/src/processor/call_handler.rs contains a test smart contract used for integration testing, not production code.

Applied to files:

  • test-integration/test-committor-service/tests/test_ix_commit_local.rs
📚 Learning: 2025-11-19T09:34:37.917Z
Learnt from: thlorenz
Repo: magicblock-labs/magicblock-validator PR: 621
File: test-integration/test-chainlink/tests/ix_remote_account_provider.rs:62-63
Timestamp: 2025-11-19T09:34:37.917Z
Learning: In test-integration/test-chainlink/tests/ix_remote_account_provider.rs and similar test files, the `_fwd_rx` receiver returned by `init_remote_account_provider()` is intentionally kept alive (but unused) to prevent "receiver dropped" errors on the sender side. The pattern `let (remote_account_provider, _fwd_rx) = init_remote_account_provider().await;` should NOT be changed to `let (remote_account_provider, _) = ...` because dropping the receiver would cause send() operations to fail.

Applied to files:

  • test-integration/test-committor-service/tests/test_ix_commit_local.rs
📚 Learning: 2025-10-21T14:00:54.642Z
Learnt from: bmuddha
Repo: magicblock-labs/magicblock-validator PR: 578
File: magicblock-aperture/src/requests/websocket/account_subscribe.rs:18-27
Timestamp: 2025-10-21T14:00:54.642Z
Learning: In magicblock-aperture account_subscribe handler (src/requests/websocket/account_subscribe.rs), the RpcAccountInfoConfig fields data_slice, commitment, and min_context_slot are currently ignored—only encoding is applied. This is tracked as technical debt in issue #579: https://github.com/magicblock-labs/magicblock-validator/issues/579

Applied to files:

  • test-integration/test-committor-service/tests/test_ix_commit_local.rs
📚 Learning: 2025-11-07T13:20:13.793Z
Learnt from: bmuddha
Repo: magicblock-labs/magicblock-validator PR: 589
File: magicblock-processor/src/scheduler/coordinator.rs:227-238
Timestamp: 2025-11-07T13:20:13.793Z
Learning: In magicblock-processor's ExecutionCoordinator (scheduler/coordinator.rs), the `account_contention` HashMap intentionally does not call `shrink_to_fit()`. Maintaining slack capacity is beneficial for performance by avoiding frequent reallocations during high transaction throughput. As long as empty entries are removed from the map (which `clear_account_contention` does), the capacity overhead is acceptable.

Applied to files:

  • test-integration/test-committor-service/tests/test_ix_commit_local.rs
📚 Learning: 2025-11-18T08:47:39.702Z
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 639
File: magicblock-chainlink/tests/04_redeleg_other_separate_slots.rs:158-165
Timestamp: 2025-11-18T08:47:39.702Z
Learning: In magicblock-chainlink tests involving compressed accounts, `set_remote_slot()` sets the slot of the `AccountSharedData`, while `compressed_account_shared_with_owner_and_slot()` sets the slot of the delegation record. These are two different fields and both calls are necessary.

Applied to files:

  • test-integration/test-committor-service/tests/test_ix_commit_local.rs
📚 Learning: 2025-10-21T13:06:38.900Z
Learnt from: bmuddha
Repo: magicblock-labs/magicblock-validator PR: 578
File: magicblock-aperture/src/requests/http/get_program_accounts.rs:17-25
Timestamp: 2025-10-21T13:06:38.900Z
Learning: The magicblock validator does not support ledger forking, so commitment-based state queries (processed/confirmed/finalized) are not applicable. RPC methods can safely ignore commitment and minContextSlot parameters from Solana RPC config objects.

Applied to files:

  • test-integration/test-committor-service/tests/test_ix_commit_local.rs
📚 Learning: 2025-11-21T10:22:07.520Z
Learnt from: taco-paco
Repo: magicblock-labs/magicblock-validator PR: 661
File: magicblock-committor-service/src/intent_executor/single_stage_executor.rs:20-28
Timestamp: 2025-11-21T10:22:07.520Z
Learning: In magicblock-committor-service's SingleStageExecutor and TwoStageExecutor (single_stage_executor.rs and two_stage_executor.rs), the fields transaction_strategy, junk, and patched_errors are intentionally public because these executors are designed to be used independently outside of the IntentExecutor scope, and callers need access to these execution reports for cleanup and error handling.

Applied to files:

  • test-integration/test-committor-service/tests/test_ix_commit_local.rs
🧬 Code graph analysis (1)
test-integration/test-committor-service/tests/test_ix_commit_local.rs (2)
test-integration/test-committor-service/tests/utils/transactions.rs (1)
  • init_and_delegate_account_on_chain (127-224)
test-integration/programs/flexi-counter/src/state.rs (2)
  • pda (34-37)
  • new (16-22)
🔇 Additional comments (2)
test-integration/test-committor-service/tests/test_ix_commit_local.rs (2)

407-412: LGTM!

The addition of the None argument for the label parameter is consistent with the function signature change in init_and_delegate_account_on_chain.


520-520: LGTM!

The change from collecting Result<Vec<_>, _> to Vec<_> correctly reflects the API refactoring where schedule_base_intents_waiting now returns Result<Vec<BroadcastedIntentExecutionResult>> instead of individual Results.

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