Skip to content

Conversation

@Dodecahedr0x
Copy link
Contributor

@Dodecahedr0x Dodecahedr0x commented Nov 18, 2025

Summary by CodeRabbit

  • New Features
    • End-to-end compressed delegation support: compressed commit/undelegate modes, Photon-backed compressed-account fetching, new compressed task and execution paths, and public client APIs for compressed flows.
  • Tests
    • Expanded unit and integration suites and new Photon mocks to validate compressed delegation scenarios and compressed account handling.
  • Chores
    • Workspace manifests updated; CI now installs Photon prerequisites, Node.js, and zk-compression CLI for integration runs.
  • Documentation
    • Compression configuration docs/examples added; aperture README trimmed.

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

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 18, 2025

📝 Walkthrough

Walkthrough

Adds compressed-account (Photon) support and a new workspace crate compressed-delegation-client. Threads a PhotonClient/PhotonIndexer generic through RemoteAccountProvider, Chainlink, FetchCloner, committor components, task builders, transaction preparation/execution, and metrics. Introduces PhotonClientImpl and PhotonClientMock, new compressed task variants and CompressedData flows, new error variants, instruction-builder helpers, updates to many Cargo manifests and configs, new constants and helper functions for compression/CDAs, and extensive tests and test-runner changes to exercise photon/compressed delegation paths.

Suggested reviewers

  • bmuddha
  • GabrielePicco

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: first compression iteration' is directly related to the main change: introducing compressed delegation account support throughout the codebase.
Docstring Coverage ✅ Passed Docstring coverage is 88.54% which is sufficient. The required threshold is 80.00%.

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

Caution

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

⚠️ Outside diff range comments (12)
magicblock-committor-program/src/instruction_builder/close_buffer.rs (1)

1-46: Revert new_with_bytes pattern to new_with_borsh; the refactor introduces unnecessary panic points.

All four instruction builders (realloc_buffer.rs, init_buffer.rs, write_buffer.rs, close_buffer.rs) changed from Instruction::new_with_borsh(program_id, &ix, accounts) to Instruction::new_with_bytes(program_id, &ix.try_to_vec().unwrap(), accounts).

Verification confirms new_with_borsh is not deprecated in current solana-program and remains active elsewhere in the codebase. The refactor:

  • Removes built-in error handling
  • Introduces .unwrap() panic points
  • Creates inconsistency with existing code patterns

Revert these four files to use new_with_borsh.

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

229-242: Consistent Instruction::new_with_bytes + Borsh pattern looks good, but consider avoiding bare unwrap()

The switch to Instruction::new_with_bytes plus borsh::to_vec(&FlexiCounterInstruction::...) is consistent and makes payload encoding uniform across all constructors. The only downside is the pervasive .unwrap(), which will panic on serialization failure and make client-side debugging harder.

Since these helpers run off-chain in tests, this is acceptable, but if you want a slightly safer pattern you could:

  • Use .expect("borsh serialization of FlexiCounterInstruction should never fail") to give clearer panic messages, or
  • Return a Result<Instruction, borsh::mayfail::Error> from the helpers and propagate errors explicitly.

Not a blocker—more of a polish consideration.

Also applies to: 244-265, 267-279, 281-303, 304-314, 316-343, 345-367, 369-386, 388-419, 421-463, 465-496, 498-518

test-integration/test-runner/bin/run_tests.rs (1)

244-301: Change cleanup calls to use cleanup_light_validator for Light validators.

Lines 275, 292, and 301 call cleanup_devnet_only(&mut devnet_validator), but the validator is started as ValidatorCluster::Light (line 246). The cleanup_devnet_only function only kills the process and runs generic validator cleanup; it does not execute the light test-validator --stop command that cleanup_light_validator provides.

This causes incomplete cleanup of Light validators. Update these three calls to:

cleanup_light_validator(&mut devnet_validator, "light");

This matches the pattern used in cleanup_validators_with_light and ensures the light validator is properly stopped.

magicblock-api/src/genesis_utils.rs (1)

107-113: Normalize AccountSharedData imports for consistency, but no functional issue identified

Based on code inspection, solana_account::AccountSharedData and solana_sdk::account::AccountSharedData are compatible types (the code compiles and the push at line 114–115 succeeds without casting). The concern in the review is valid from a consistency and clarity perspective but not a correctness issue.

The codebase currently mixes:

  • Bare AccountSharedData::new() (imported from solana_sdk::account) at lines 95, 99
  • Fully qualified solana_account::AccountSharedData::from() at line 107

This inconsistency makes the code harder to follow. The review's suggestion to pick one source of truth and use it consistently throughout the function is sound and improves readability going forward.

magicblock-chainlink/tests/utils/accounts.rs (1)

2-47: Align compressed helper with non‑compressed helper’s slot semantics

The compressed helper builds a plausible CompressedDelegationRecord and wraps it in an AccountSharedData, which is good for test fixtures. However, unlike account_shared_with_owner_and_slot, it never calls set_remote_slot(slot) on the resulting AccountSharedData; the slot argument is only stored as delegation_slot inside the record.

If your compressed‑account tests (or RemoteAccountProvider) rely on AccountSharedData::remote_slot for slot matching, this discrepancy could lead to subtle differences vs. the non‑compressed helper.

Consider aligning the behavior:

 pub fn compressed_account_shared_with_owner_and_slot(
@@
-) -> AccountSharedData {
+) -> AccountSharedData {
@@
-    let mut acc = Account::new(
+    let mut acc = Account::new(
         0,
         delegation_record_bytes.len(),
         &compressed_delegation_client::ID,
     );
     acc.data = delegation_record_bytes;
-    AccountSharedData::from(acc)
+    let mut acc_shared = AccountSharedData::from(acc);
+    acc_shared.set_remote_slot(slot);
+    acc_shared
 }

Or, if compressed accounts deliberately shouldn’t use remote_slot, it’d help to document that distinction in the helper’s comment or name.

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

1-15: Critical runtime panic: CompressedUndelegate instruction builder incomplete; reset_commit_id skips CompressedCommit

  • CompressedUndelegate instruction will panic at runtime (args_task.rs:110–125)

    • UndelegateBuilder::instruction() calls .expect() on payer, owner_program, system_program, and args (undelegate.rs:167–184).
    • Current builder only sets .delegated_account() and remaining accounts; all required fields are missing.
    • CompressedUndelegateTask struct lacks payer and system_program fields entirely, so they cannot be passed to the builder.
    • Either add these fields to CompressedUndelegateTask and populate them in task creation, or document why compressed undelegate does not require them.
    • The commented-out .owner_program() and .rent_reimbursement() are misleading (latter is not even a builder method); remove or clarify intent.
  • reset_commit_id does not handle CompressedCommit (args_task.rs:196–202)

    • CompressedCommitTask has a commit_id field that is used in instruction generation (line 75: update_nonce: value.commit_id).
    • Current implementation only matches Commit variant, leaving CompressedCommit unchanged.
    • Extend the match to also update CompressedCommitTask::commit_id for consistency.
magicblock-committor-service/src/transaction_preparator/delivery_preparator.rs (1)

61-90: Preserve TaskBuilderError context instead of collapsing to CompressedDataNotFound (lines 161-167)

The PreparationTask::Compressed branch discards the underlying error details by collapsing to a generic variant:

let Ok(compressed_data) =
    get_compressed_data(&delegated_account, photon_client).await
else {
    error!("Failed to get compressed data");
    return Err(InternalError::CompressedDataNotFound);
};

However, InternalError already has TaskBuilderError(#[from] TaskBuilderError), which preserves concrete error reasons (CompressedDataFetchError, MissingStateTrees, etc.). Use the propagation pattern instead:

let compressed_data = get_compressed_data(&delegated_account, photon_client)
    .await
    .map_err(InternalError::TaskBuilderError)?;

This retains full error context for debugging while eliminating unnecessary wrapping logic.

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

173-187: BufferPreparationTask logging may be overly verbose in hot paths

BufferPreparationTask::init_instruction now emits multiple debug! lines per call, including sizes and counts. This is useful while validating the new Chunks::struct_size(self.chunks.count()) usage, but if this path is hit frequently in production it will significantly increase log volume.

Once you’re confident in the sizing, consider either removing most of these logs or gating them behind a more specific target/feature flag so normal runs aren’t spammed. The struct_size call itself looks correct given Chunks::struct_size(count).

Also applies to: 189-201

magicblock-chainlink/src/chainlink/fetch_cloner.rs (3)

303-470: Compressed delegation handling in subscription path is mostly correct but lacks fallback logging

The new owned_by_compressed_delegation_program branch correctly:

  • Parses CompressedDelegationRecord from the fresh account data.
  • Falls back to re‑fetching via remote_account_provider.try_get when direct parsing fails.
  • Marks the account as compressed, sets owner/data/lamports from the record, and sets delegated only when authority == validator_pubkey.

Two improvements to consider:

  1. When both direct and Photon fetch parsing fail, we silently return None. Emitting at least a warn! in that case would make diagnosing bad compressed records easier.
  2. The fallback uses the data from the fetched account only to parse the record but still mutates the original subscription account. That’s probably fine, but if slots can differ you might want to pick the fresher of the two sources explicitly.

1750-1776: Buggy test assertions for compressed accounts (test_multiple_mixed_accounts_some_missing)

test_multiple_mixed_accounts_some_missing has contradictory expectations:

let cacc3 = provider.try_get(cpk3).await.unwrap();
assert_compressed_account!(cacc3, 777, 3);
assert!(!cacc3.is_found());

assert_compressed_account! already asserts is_found(), so the subsequent assert!(!cacc3.is_found()) will always fail. Additionally, since cpk3 is not part of the compressed_pubkeys passed into setup_with_mixed_accounts, it’s not clear that cpk3 should be found at all unless the mock is updated elsewhere.

Fixing the test likely means:

  • Keeping cacc3 as not found in the initial try_get_multi call, and
  • Either removing the final assert!(!cacc3.is_found()) (since the macro already asserts found) or changing the setup to actually add cpk3 to the Photon mock before expecting it to be found.

For example, the minimal change is:

-        let cacc3 = provider.try_get(cpk3).await.unwrap();
-        assert_compressed_account!(cacc3, 777, 3);
-        assert!(!cacc3.is_found());
+        let cacc3 = provider.try_get(cpk3).await.unwrap();
+        assert_compressed_account!(cacc3, 777, 3);

Also applies to: 1778-1815, 1817-1859


535-607: Compressed accounts have inconsistent lamports between subscription and fetch paths

The review comment is correct. The subscription path at line 460 calls account.set_lamports(delegation_record.lamports) for compressed accounts, but the fetch path at lines 746-775 processes compressed accounts without setting lamports.

The code locations match exactly:

  • Subscription path (lines ~455-461): Sets all four fields including set_lamports(delegation_record.lamports)
  • Fetch path (lines 746-775): Sets set_data and set_owner but omits set_lamports

The CompressedDelegationRecord struct has a pub lamports: u64 field available in both paths. This inconsistency means accounts will have different lamport values depending on whether they arrive via subscription updates or fetches, creating subtle state divergence in the bank.

The suggested fix is correct—add account.set_lamports(delegation_record.lamports); in the fetch path to align with the subscription path behavior.

magicblock-chainlink/src/remote_account_provider/mod.rs (1)

784-854: Fix type mismatch in join_all() result handling and remove unsafe unwraps

The three critical issues are confirmed:

  1. Type mismatch: JoinSet::join_all().await returns Vec<Result<FetchedRemoteAccounts, JoinError>>, but you're passing it directly to consolidate_fetched_remote_accounts() which expects Vec<FetchedRemoteAccounts>. This will not compile. You must map/filter join errors before consolidation, or unwrap and handle them properly.

  2. Unsafe unwraps in async helpers:

    • fetch_from_rpc (line 961): .await.unwrap().unwrap() panics on task failure or inner error instead of returning RemoteAccountProviderError::FailedFetchingAccounts
    • fetch_from_photon (line 1009): .await.unwrap() panics on any indexer error (already flagged with TODO comment)

    Both TODO comments acknowledge this. Replace with error propagation.

  3. Consolidation robustness: If join errors occur before consolidation, they are lost. Once you handle join errors properly, pass only successful results to consolidation and log/early-return if both sources fail.

At minimum: handle join errors before consolidation, replace unwraps with proper error returns, and surface failures through RemoteAccountProviderError.

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

811-819: Duplicate hardcoded PhotonIndexer initialization.

This is the second instance of hardcoded http://localhost:8784 in the codebase (first was in committor_processor.rs lines 54-57). This duplication reinforces the need to centralize PhotonIndexer configuration.

See the comment on committor_processor.rs lines 53-58 for the recommended centralization approach.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ded9c50 and a8cc1b8.

⛔ Files ignored due to path filters (26)
  • Cargo.lock is excluded by !**/*.lock
  • compressed-delegation-client/src/generated/accounts/compressed_delegation_record.rs is excluded by !**/generated/**
  • compressed-delegation-client/src/generated/accounts/mod.rs is excluded by !**/generated/**
  • compressed-delegation-client/src/generated/errors/mod.rs is excluded by !**/generated/**
  • compressed-delegation-client/src/generated/instructions/commit.rs is excluded by !**/generated/**
  • compressed-delegation-client/src/generated/instructions/delegate.rs is excluded by !**/generated/**
  • compressed-delegation-client/src/generated/instructions/delegate_compressed.rs is excluded by !**/generated/**
  • compressed-delegation-client/src/generated/instructions/finalize.rs is excluded by !**/generated/**
  • compressed-delegation-client/src/generated/instructions/mod.rs is excluded by !**/generated/**
  • compressed-delegation-client/src/generated/instructions/undelegate.rs is excluded by !**/generated/**
  • compressed-delegation-client/src/generated/instructions/undelegate_compressed.rs is excluded by !**/generated/**
  • compressed-delegation-client/src/generated/mod.rs is excluded by !**/generated/**
  • compressed-delegation-client/src/generated/programs.rs is excluded by !**/generated/**
  • compressed-delegation-client/src/generated/shared.rs is excluded by !**/generated/**
  • compressed-delegation-client/src/generated/types/commit_args.rs is excluded by !**/generated/**
  • compressed-delegation-client/src/generated/types/delegate_args.rs is excluded by !**/generated/**
  • compressed-delegation-client/src/generated/types/delegate_compressed_args.rs is excluded by !**/generated/**
  • compressed-delegation-client/src/generated/types/external_undelegate_args.rs is excluded by !**/generated/**
  • compressed-delegation-client/src/generated/types/finalize_args.rs is excluded by !**/generated/**
  • compressed-delegation-client/src/generated/types/mod.rs is excluded by !**/generated/**
  • compressed-delegation-client/src/generated/types/undelegate_args.rs is excluded by !**/generated/**
  • compressed-delegation-client/src/generated/types/undelegate_compressed_args.rs is excluded by !**/generated/**
  • magicblock-committor-program/bin/magicblock_committor_program.so is excluded by !**/*.so
  • test-integration/Cargo.lock is excluded by !**/*.lock
  • test-integration/programs/compressed_delegation/compressed_delegation.so is excluded by !**/*.so
  • test-integration/schedulecommit/elfs/dlp.so is excluded by !**/*.so
📒 Files selected for processing (106)
  • .github/workflows/ci-test-integration.yml (1 hunks)
  • Cargo.toml (6 hunks)
  • compressed-delegation-client/Cargo.toml (1 hunks)
  • compressed-delegation-client/src/lib.rs (1 hunks)
  • compressed-delegation-client/src/utils.rs (1 hunks)
  • configs/ephem-compression.toml (1 hunks)
  • magicblock-account-cloner/src/bpf_loader_v1.rs (2 hunks)
  • magicblock-account-cloner/src/lib.rs (1 hunks)
  • magicblock-accounts/src/scheduled_commits_processor.rs (2 hunks)
  • magicblock-aperture/README.md (0 hunks)
  • magicblock-aperture/src/state/mod.rs (2 hunks)
  • magicblock-api/Cargo.toml (1 hunks)
  • magicblock-api/src/genesis_utils.rs (1 hunks)
  • magicblock-api/src/magic_validator.rs (3 hunks)
  • magicblock-api/src/tickers.rs (1 hunks)
  • magicblock-chainlink/Cargo.toml (1 hunks)
  • magicblock-chainlink/src/chainlink/fetch_cloner.rs (19 hunks)
  • magicblock-chainlink/src/chainlink/mod.rs (8 hunks)
  • magicblock-chainlink/src/remote_account_provider/errors.rs (2 hunks)
  • magicblock-chainlink/src/remote_account_provider/mod.rs (21 hunks)
  • magicblock-chainlink/src/remote_account_provider/photon_client.rs (1 hunks)
  • magicblock-chainlink/src/remote_account_provider/remote_account.rs (4 hunks)
  • magicblock-chainlink/src/testing/mod.rs (2 hunks)
  • magicblock-chainlink/src/testing/photon_client_mock.rs (1 hunks)
  • magicblock-chainlink/src/testing/utils.rs (1 hunks)
  • magicblock-chainlink/tests/01_ensure-accounts.rs (3 hunks)
  • magicblock-chainlink/tests/03_deleg_after_sub.rs (2 hunks)
  • magicblock-chainlink/tests/04_redeleg_other_separate_slots.rs (2 hunks)
  • magicblock-chainlink/tests/05_redeleg_other_same_slot.rs (3 hunks)
  • magicblock-chainlink/tests/06_redeleg_us_separate_slots.rs (3 hunks)
  • magicblock-chainlink/tests/07_redeleg_us_same_slot.rs (3 hunks)
  • magicblock-chainlink/tests/utils/accounts.rs (2 hunks)
  • magicblock-chainlink/tests/utils/test_context.rs (4 hunks)
  • magicblock-committor-program/src/instruction_builder/close_buffer.rs (2 hunks)
  • magicblock-committor-program/src/instruction_builder/init_buffer.rs (2 hunks)
  • magicblock-committor-program/src/instruction_builder/realloc_buffer.rs (2 hunks)
  • magicblock-committor-program/src/instruction_builder/write_buffer.rs (2 hunks)
  • magicblock-committor-program/src/processor.rs (3 hunks)
  • magicblock-committor-program/src/state/changeset_chunks.rs (1 hunks)
  • magicblock-committor-program/src/state/chunks.rs (2 hunks)
  • magicblock-committor-service/Cargo.toml (1 hunks)
  • magicblock-committor-service/src/committor_processor.rs (3 hunks)
  • magicblock-committor-service/src/intent_execution_manager.rs (2 hunks)
  • magicblock-committor-service/src/intent_execution_manager/intent_execution_engine.rs (1 hunks)
  • magicblock-committor-service/src/intent_executor/mod.rs (19 hunks)
  • magicblock-committor-service/src/intent_executor/single_stage_executor.rs (4 hunks)
  • magicblock-committor-service/src/intent_executor/task_info_fetcher.rs (7 hunks)
  • magicblock-committor-service/src/intent_executor/two_stage_executor.rs (4 hunks)
  • magicblock-committor-service/src/tasks/args_task.rs (7 hunks)
  • magicblock-committor-service/src/tasks/buffer_task.rs (3 hunks)
  • magicblock-committor-service/src/tasks/mod.rs (7 hunks)
  • magicblock-committor-service/src/tasks/task_builder.rs (7 hunks)
  • magicblock-committor-service/src/tasks/task_strategist.rs (1 hunks)
  • magicblock-committor-service/src/transaction_preparator/delivery_preparator.rs (8 hunks)
  • magicblock-committor-service/src/transaction_preparator/mod.rs (4 hunks)
  • magicblock-core/Cargo.toml (2 hunks)
  • magicblock-core/src/compression/mod.rs (1 hunks)
  • magicblock-core/src/lib.rs (1 hunks)
  • magicblock-magic-program-api/src/instruction.rs (4 hunks)
  • magicblock-rpc-client/src/lib.rs (1 hunks)
  • programs/magicblock/Cargo.toml (1 hunks)
  • programs/magicblock/src/magic_context.rs (2 hunks)
  • programs/magicblock/src/magic_scheduled_base_intent.rs (8 hunks)
  • programs/magicblock/src/magicblock_processor.rs (2 hunks)
  • programs/magicblock/src/mutate_accounts/process_mutate_accounts.rs (3 hunks)
  • programs/magicblock/src/schedule_transactions/process_schedule_base_intent.rs (1 hunks)
  • programs/magicblock/src/schedule_transactions/process_schedule_commit.rs (2 hunks)
  • programs/magicblock/src/utils/instruction_utils.rs (3 hunks)
  • test-integration/Cargo.toml (3 hunks)
  • test-integration/configs/chainlink-conf.devnet.toml (1 hunks)
  • test-integration/configs/committor-conf.devnet.toml (1 hunks)
  • test-integration/notes-babur.md (1 hunks)
  • test-integration/programs/flexi-counter/Cargo.toml (1 hunks)
  • test-integration/programs/flexi-counter/src/instruction.rs (17 hunks)
  • test-integration/programs/flexi-counter/src/lib.rs (2 hunks)
  • test-integration/programs/flexi-counter/src/processor.rs (5 hunks)
  • test-integration/programs/flexi-counter/src/state.rs (1 hunks)
  • test-integration/programs/schedulecommit/src/api.rs (4 hunks)
  • test-integration/schedulecommit/test-security/Cargo.toml (1 hunks)
  • test-integration/schedulecommit/test-security/tests/utils/mod.rs (3 hunks)
  • test-integration/test-chainlink/Cargo.toml (2 hunks)
  • test-integration/test-chainlink/scripts/miniv2-json-from-so.js (1 hunks)
  • test-integration/test-chainlink/src/ixtest_context.rs (10 hunks)
  • test-integration/test-chainlink/src/programs.rs (1 hunks)
  • test-integration/test-chainlink/src/test_context.rs (4 hunks)
  • test-integration/test-chainlink/tests/ix_01_ensure-accounts.rs (1 hunks)
  • test-integration/test-chainlink/tests/ix_03_deleg_after_sub.rs (1 hunks)
  • test-integration/test-chainlink/tests/ix_06_redeleg_us_separate_slots.rs (1 hunks)
  • test-integration/test-chainlink/tests/ix_07_redeleg_us_same_slot.rs (1 hunks)
  • test-integration/test-chainlink/tests/ix_remote_account_provider.rs (2 hunks)
  • test-integration/test-committor-service/Cargo.toml (2 hunks)
  • test-integration/test-committor-service/tests/common.rs (6 hunks)
  • test-integration/test-committor-service/tests/test_delivery_preparator.rs (6 hunks)
  • test-integration/test-committor-service/tests/test_intent_executor.rs (12 hunks)
  • test-integration/test-committor-service/tests/test_ix_commit_local.rs (23 hunks)
  • test-integration/test-committor-service/tests/test_transaction_preparator.rs (5 hunks)
  • test-integration/test-committor-service/tests/utils/instructions.rs (3 hunks)
  • test-integration/test-committor-service/tests/utils/mod.rs (2 hunks)
  • test-integration/test-committor-service/tests/utils/transactions.rs (6 hunks)
  • test-integration/test-runner/bin/run_tests.rs (15 hunks)
  • test-integration/test-runner/src/cleanup.rs (1 hunks)
  • test-integration/test-runner/src/signal.rs (2 hunks)
  • test-integration/test-schedule-intent/tests/test_schedule_intents.rs (7 hunks)
  • test-integration/test-tools/Cargo.toml (1 hunks)
  • test-integration/test-tools/src/validator.rs (3 hunks)
  • test-kit/src/lib.rs (1 hunks)
💤 Files with no reviewable changes (1)
  • magicblock-aperture/README.md
🧰 Additional context used
🧠 Learnings (11)
📚 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-chainlink/src/remote_account_provider/errors.rs
  • magicblock-aperture/src/state/mod.rs
  • magicblock-accounts/src/scheduled_commits_processor.rs
  • magicblock-chainlink/tests/03_deleg_after_sub.rs
  • magicblock-chainlink/tests/06_redeleg_us_separate_slots.rs
  • test-integration/test-chainlink/tests/ix_03_deleg_after_sub.rs
  • magicblock-chainlink/src/remote_account_provider/photon_client.rs
  • magicblock-chainlink/tests/07_redeleg_us_same_slot.rs
  • magicblock-chainlink/src/testing/photon_client_mock.rs
  • magicblock-chainlink/tests/utils/test_context.rs
  • test-integration/test-chainlink/tests/ix_remote_account_provider.rs
  • test-integration/test-chainlink/src/test_context.rs
  • magicblock-chainlink/src/chainlink/mod.rs
  • magicblock-chainlink/src/chainlink/fetch_cloner.rs
  • magicblock-chainlink/src/remote_account_provider/remote_account.rs
  • test-integration/test-chainlink/src/ixtest_context.rs
  • magicblock-api/src/magic_validator.rs
  • magicblock-chainlink/src/remote_account_provider/mod.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-chainlink/tests/ix_01_ensure-accounts.rs
  • test-integration/programs/flexi-counter/src/lib.rs
  • test-integration/test-chainlink/tests/ix_06_redeleg_us_separate_slots.rs
  • test-integration/programs/flexi-counter/src/state.rs
  • test-integration/test-runner/bin/run_tests.rs
  • test-integration/test-chainlink/tests/ix_03_deleg_after_sub.rs
  • programs/magicblock/src/schedule_transactions/process_schedule_base_intent.rs
  • test-integration/programs/flexi-counter/src/instruction.rs
  • test-integration/test-committor-service/tests/utils/mod.rs
  • test-integration/test-committor-service/tests/utils/transactions.rs
  • test-integration/test-chainlink/tests/ix_07_redeleg_us_same_slot.rs
  • test-integration/programs/flexi-counter/src/processor.rs
  • test-integration/schedulecommit/test-security/tests/utils/mod.rs
  • test-integration/test-chainlink/src/ixtest_context.rs
  • test-integration/test-schedule-intent/tests/test_schedule_intents.rs
  • magicblock-chainlink/src/testing/mod.rs
  • test-integration/test-chainlink/src/programs.rs
  • test-integration/test-committor-service/tests/test_intent_executor.rs
  • test-integration/programs/flexi-counter/Cargo.toml
📚 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/notes-babur.md
  • magicblock-magic-program-api/src/instruction.rs
  • magicblock-api/src/tickers.rs
  • test-integration/test-chainlink/tests/ix_06_redeleg_us_separate_slots.rs
  • magicblock-chainlink/tests/utils/accounts.rs
  • magicblock-chainlink/tests/03_deleg_after_sub.rs
  • magicblock-chainlink/tests/06_redeleg_us_separate_slots.rs
  • programs/magicblock/Cargo.toml
  • programs/magicblock/src/mutate_accounts/process_mutate_accounts.rs
  • magicblock-chainlink/tests/04_redeleg_other_separate_slots.rs
  • test-integration/test-chainlink/tests/ix_03_deleg_after_sub.rs
  • magicblock-chainlink/tests/07_redeleg_us_same_slot.rs
  • programs/magicblock/src/magic_context.rs
  • magicblock-committor-service/src/tasks/task_builder.rs
  • magicblock-committor-program/src/processor.rs
  • magicblock-chainlink/tests/05_redeleg_other_same_slot.rs
  • magicblock-chainlink/tests/01_ensure-accounts.rs
  • test-integration/test-committor-service/tests/utils/transactions.rs
  • test-integration/test-committor-service/tests/utils/instructions.rs
  • test-integration/test-chainlink/tests/ix_07_redeleg_us_same_slot.rs
  • programs/magicblock/src/utils/instruction_utils.rs
  • programs/magicblock/src/schedule_transactions/process_schedule_commit.rs
  • magicblock-committor-service/src/intent_executor/task_info_fetcher.rs
  • magicblock-chainlink/src/chainlink/fetch_cloner.rs
  • magicblock-chainlink/src/remote_account_provider/remote_account.rs
  • test-integration/test-chainlink/src/ixtest_context.rs
  • magicblock-account-cloner/src/lib.rs
  • magicblock-api/src/magic_validator.rs
  • programs/magicblock/src/magic_scheduled_base_intent.rs
  • 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/notes-babur.md
  • magicblock-api/src/tickers.rs
  • programs/magicblock/src/magic_context.rs
  • magicblock-committor-program/src/processor.rs
  • programs/magicblock/src/magicblock_processor.rs
  • magicblock-committor-service/src/intent_executor/task_info_fetcher.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:

  • magicblock-api/src/tickers.rs
📚 Learning: 2025-11-07T18:19:48.996Z
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 614
File: test-integration/programs/schedulecommit/Cargo.toml:19-20
Timestamp: 2025-11-07T18:19:48.996Z
Learning: In Solana programs (crates depending on solana-program), the empty feature flags `custom-heap = []` and `custom-panic = []` are standard declarations required to avoid compiler warnings. These should not be flagged as unused features in Cargo.toml files for Solana program crates.

Applied to files:

  • programs/magicblock/Cargo.toml
  • magicblock-core/Cargo.toml
  • test-integration/test-chainlink/Cargo.toml
  • test-integration/programs/flexi-counter/Cargo.toml
📚 Learning: 2025-10-21T11:00:18.396Z
Learnt from: bmuddha
Repo: magicblock-labs/magicblock-validator PR: 578
File: magicblock-aperture/src/encoder.rs:176-187
Timestamp: 2025-10-21T11:00:18.396Z
Learning: In the magicblock validator, the current slot is always the root slot. The SlotEncoder in magicblock-aperture/src/encoder.rs correctly sets `root: slot` because there is no lag between current and root slots in this architecture.

Applied to files:

  • magicblock-chainlink/tests/01_ensure-accounts.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:

  • programs/magicblock/src/magicblock_processor.rs
  • magicblock-committor-service/src/committor_processor.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:

  • programs/magicblock/src/magicblock_processor.rs
  • test-integration/test-schedule-intent/tests/test_schedule_intents.rs
  • test-integration/test-committor-service/tests/test_intent_executor.rs
📚 Learning: 2025-10-26T16:53:29.820Z
Learnt from: thlorenz
Repo: magicblock-labs/magicblock-validator PR: 587
File: magicblock-chainlink/src/remote_account_provider/mod.rs:134-0
Timestamp: 2025-10-26T16:53:29.820Z
Learning: In magicblock-chainlink/src/remote_account_provider/mod.rs, the `Endpoint::separate_pubsub_url_and_api_key()` method uses `split_once("?api-key=")` because the api-key parameter is always the only query parameter right after `?`. No additional query parameter parsing is needed for this use case.

Applied to files:

  • test-integration/test-chainlink/tests/ix_remote_account_provider.rs
  • magicblock-api/src/magic_validator.rs
  • magicblock-chainlink/src/remote_account_provider/mod.rs
📚 Learning: 2025-10-26T08:49:31.543Z
Learnt from: taco-paco
Repo: magicblock-labs/magicblock-validator PR: 585
File: magicblock-committor-service/src/tasks/buffer_task.rs:111-115
Timestamp: 2025-10-26T08:49:31.543Z
Learning: In the magicblock-committor-service, compute units returned by the `compute_units()` method in task implementations (such as `BufferTask`, `ArgsTask`, etc.) represent the compute budget for a single task. Transactions can comprise multiple tasks, and the total compute budget for a transaction is computed as the sum of the compute units of all tasks included in that transaction.

Applied to files:

  • magicblock-committor-service/src/tasks/args_task.rs
  • magicblock-committor-service/src/intent_executor/mod.rs
🧬 Code graph analysis (44)
test-integration/test-chainlink/tests/ix_01_ensure-accounts.rs (3)
magicblock-chainlink/src/testing/utils.rs (1)
  • init_logger (51-59)
test-integration/test-chainlink/src/ixtest_context.rs (2)
  • init (101-106)
  • counter_pda (206-208)
magicblock-chainlink/src/remote_account_provider/remote_account.rs (1)
  • remote_slot (146-152)
magicblock-committor-service/src/intent_execution_manager.rs (1)
magicblock-committor-service/src/intent_executor/task_info_fetcher.rs (3)
  • Self (298-306)
  • Self (308-316)
  • new (63-75)
magicblock-committor-service/src/tasks/buffer_task.rs (3)
magicblock-committor-service/src/tasks/mod.rs (4)
  • is_compressed (99-99)
  • set_compressed_data (102-102)
  • get_compressed_data (105-105)
  • delegated_account (108-108)
magicblock-committor-service/src/tasks/args_task.rs (4)
  • is_compressed (243-250)
  • set_compressed_data (252-265)
  • get_compressed_data (267-280)
  • delegated_account (282-298)
magicblock-committor-service/src/tasks/task_builder.rs (1)
  • get_compressed_data (402-452)
magicblock-committor-service/src/intent_execution_manager/intent_execution_engine.rs (2)
magicblock-chainlink/src/chainlink/fetch_cloner.rs (5)
  • pubkeys (498-501)
  • pubkeys (509-512)
  • pubkeys (513-516)
  • pubkeys (1031-1034)
  • pubkeys (1036-1039)
magicblock-committor-service/src/intent_executor/task_info_fetcher.rs (2)
  • pubkeys (159-170)
  • pubkeys (216-219)
test-integration/test-chainlink/tests/ix_06_redeleg_us_separate_slots.rs (4)
magicblock-chainlink/src/testing/utils.rs (2)
  • init_logger (51-59)
  • sleep_ms (41-43)
test-integration/test-chainlink/src/ixtest_context.rs (2)
  • init (101-106)
  • counter_pda (206-208)
magicblock-chainlink/src/remote_account_provider/remote_account.rs (1)
  • remote_slot (146-152)
compressed-delegation-client/src/lib.rs (1)
  • id (61-63)
magicblock-chainlink/tests/03_deleg_after_sub.rs (2)
magicblock-chainlink/src/testing/rpc_client_mock.rs (2)
  • accounts (95-101)
  • slot (66-72)
magicblock-chainlink/tests/utils/accounts.rs (2)
  • compressed_account_shared_with_owner_and_slot (22-47)
  • account_shared_with_owner_and_slot (12-20)
magicblock-chainlink/tests/06_redeleg_us_separate_slots.rs (3)
magicblock-chainlink/src/testing/rpc_client_mock.rs (2)
  • accounts (95-101)
  • slot (66-72)
magicblock-chainlink/src/testing/accounts.rs (1)
  • account_shared_with_owner (4-10)
magicblock-chainlink/tests/utils/accounts.rs (2)
  • compressed_account_shared_with_owner_and_slot (22-47)
  • account_shared_with_owner_and_slot (12-20)
magicblock-core/src/compression/mod.rs (1)
test-integration/test-chainlink/src/ixtest_context.rs (1)
  • hashv_to_bn254_field_size_be_const_array (562-562)
test-integration/test-runner/bin/run_tests.rs (3)
test-integration/test-tools/src/validator.rs (4)
  • start_light_validator_with_config (130-221)
  • start_magic_block_validator_with_config (23-75)
  • start_test_validator_with_config (77-128)
  • cleanup (359-363)
test-integration/test-runner/src/cleanup.rs (3)
  • cleanup_devnet_only (21-24)
  • cleanup_light_validator (26-38)
  • cleanup_validators (3-10)
test-integration/test-runner/src/signal.rs (1)
  • wait_for_ctrlc (9-33)
programs/magicblock/src/mutate_accounts/process_mutate_accounts.rs (1)
magicblock-chainlink/src/remote_account_provider/remote_account.rs (1)
  • compressed (154-156)
magicblock-chainlink/tests/04_redeleg_other_separate_slots.rs (4)
magicblock-chainlink/src/testing/rpc_client_mock.rs (4)
  • accounts (95-101)
  • slot (66-72)
  • default (40-42)
  • default (246-248)
magicblock-chainlink/tests/utils/accounts.rs (3)
  • compressed_account_shared_with_owner_and_slot (22-47)
  • default (57-63)
  • account_shared_with_owner_and_slot (12-20)
magicblock-chainlink/src/testing/photon_client_mock.rs (1)
  • get_account (49-68)
magicblock-chainlink/src/testing/cloner_stub.rs (1)
  • get_account (41-45)
test-integration/test-chainlink/tests/ix_03_deleg_after_sub.rs (3)
magicblock-chainlink/src/testing/utils.rs (1)
  • init_logger (51-59)
test-integration/test-chainlink/src/ixtest_context.rs (2)
  • init (101-106)
  • counter_pda (206-208)
magicblock-chainlink/src/remote_account_provider/remote_account.rs (1)
  • remote_slot (146-152)
magicblock-chainlink/src/remote_account_provider/photon_client.rs (3)
magicblock-core/src/compression/mod.rs (1)
  • derive_cda_from_pda (10-22)
magicblock-chainlink/src/testing/photon_client_mock.rs (3)
  • new (26-30)
  • get_account (49-68)
  • get_multiple_accounts (70-87)
magicblock-chainlink/src/remote_account_provider/mod.rs (10)
  • new (212-256)
  • None (297-297)
  • None (1214-1214)
  • None (1259-1259)
  • None (1337-1337)
  • None (1537-1537)
  • pubkeys (510-514)
  • pubkeys (970-993)
  • pubkeys (1175-1178)
  • default (124-130)
magicblock-chainlink/tests/07_redeleg_us_same_slot.rs (4)
magicblock-chainlink/src/testing/rpc_client_mock.rs (4)
  • accounts (95-101)
  • slot (66-72)
  • default (40-42)
  • default (246-248)
magicblock-chainlink/src/testing/accounts.rs (1)
  • account_shared_with_owner (4-10)
magicblock-chainlink/src/testing/deleg.rs (1)
  • add_delegation_record_for (22-46)
magicblock-chainlink/tests/utils/accounts.rs (3)
  • compressed_account_shared_with_owner_and_slot (22-47)
  • default (57-63)
  • account_shared_with_owner_and_slot (12-20)
test-integration/test-committor-service/tests/test_delivery_preparator.rs (2)
test-integration/test-committor-service/tests/common.rs (3)
  • create_compressed_commit_task (185-212)
  • generate_random_bytes (158-163)
  • new (63-66)
test-integration/test-committor-service/tests/utils/transactions.rs (1)
  • init_and_delegate_compressed_account_on_chain (233-322)
test-integration/test-runner/src/signal.rs (1)
test-integration/test-runner/src/cleanup.rs (2)
  • cleanup_light_validator (26-38)
  • cleanup_validator (40-44)
magicblock-chainlink/src/testing/photon_client_mock.rs (2)
magicblock-core/src/compression/mod.rs (1)
  • derive_cda_from_pda (10-22)
magicblock-chainlink/src/remote_account_provider/photon_client.rs (5)
  • new (27-29)
  • get_account (38-42)
  • get_account (53-81)
  • get_multiple_accounts (44-48)
  • get_multiple_accounts (83-123)
magicblock-committor-service/src/tasks/task_builder.rs (4)
magicblock-committor-service/src/tasks/mod.rs (5)
  • instruction (68-68)
  • instruction (304-310)
  • get_compressed_data (105-105)
  • task_type (93-93)
  • is_compressed (99-99)
magicblock-committor-service/src/tasks/args_task.rs (5)
  • instruction (51-152)
  • new (42-47)
  • get_compressed_data (267-280)
  • task_type (216-228)
  • is_compressed (243-250)
magicblock-core/src/compression/mod.rs (1)
  • derive_cda_from_pda (10-22)
magicblock-committor-service/src/intent_execution_manager.rs (1)
  • new (36-71)
test-integration/programs/flexi-counter/src/instruction.rs (3)
compressed-delegation-client/src/generated/instructions/delegate_compressed.rs (8)
  • args (162-165)
  • args (430-433)
  • payer (123-126)
  • payer (386-392)
  • new (81-83)
  • new (119-121)
  • new (246-262)
  • new (372-384)
compressed-delegation-client/src/lib.rs (1)
  • id (61-63)
test-integration/programs/flexi-counter/src/state.rs (2)
  • pda (43-46)
  • new (25-31)
magicblock-chainlink/tests/utils/test_context.rs (2)
magicblock-chainlink/src/remote_account_provider/mod.rs (3)
  • rpc_client (1116-1118)
  • rpc_client (1129-1131)
  • new (212-256)
magicblock-chainlink/src/testing/photon_client_mock.rs (1)
  • new (26-30)
magicblock-committor-service/src/transaction_preparator/delivery_preparator.rs (5)
magicblock-committor-service/src/tasks/task_builder.rs (1)
  • get_compressed_data (402-452)
magicblock-committor-service/src/tasks/mod.rs (4)
  • get_compressed_data (105-105)
  • strategy (90-90)
  • cleanup_task (289-294)
  • delegated_account (108-108)
magicblock-committor-service/src/tasks/args_task.rs (4)
  • get_compressed_data (267-280)
  • strategy (212-214)
  • delegated_account (282-298)
  • from (36-38)
magicblock-committor-service/src/tasks/buffer_task.rs (3)
  • get_compressed_data (157-161)
  • strategy (121-123)
  • delegated_account (163-169)
magicblock-committor-service/src/utils.rs (1)
  • persist_status_update (6-22)
magicblock-chainlink/tests/05_redeleg_other_same_slot.rs (3)
magicblock-chainlink/src/testing/rpc_client_mock.rs (2)
  • accounts (95-101)
  • slot (66-72)
magicblock-chainlink/src/testing/accounts.rs (1)
  • account_shared_with_owner (4-10)
magicblock-chainlink/tests/utils/accounts.rs (1)
  • compressed_account_shared_with_owner_and_slot (22-47)
magicblock-chainlink/tests/01_ensure-accounts.rs (1)
magicblock-chainlink/tests/utils/accounts.rs (1)
  • compressed_account_shared_with_owner_and_slot (22-47)
programs/magicblock/src/magicblock_processor.rs (1)
programs/magicblock/src/schedule_transactions/process_schedule_commit.rs (2)
  • process_schedule_commit (33-39)
  • process_schedule_compressed_commit (41-47)
test-integration/test-committor-service/tests/utils/transactions.rs (2)
test-integration/test-committor-service/tests/utils/instructions.rs (2)
  • init_account_and_delegate_compressed_ixs (79-159)
  • init_account_and_delegate_ixs (48-77)
test-integration/test-committor-service/tests/utils/mod.rs (1)
  • sleep_millis (16-18)
test-integration/test-committor-service/tests/utils/instructions.rs (3)
magicblock-core/src/compression/mod.rs (1)
  • derive_cda_from_pda (10-22)
test-integration/programs/flexi-counter/src/instruction.rs (1)
  • create_delegate_compressed_ix (520-540)
test-integration/programs/flexi-counter/src/state.rs (1)
  • pda (43-46)
test-integration/test-committor-service/tests/common.rs (3)
magicblock-committor-service/src/tasks/args_task.rs (2)
  • instruction (51-152)
  • new (42-47)
magicblock-committor-service/src/intent_executor/task_info_fetcher.rs (1)
  • new (63-75)
magicblock-committor-service/src/intent_executor/mod.rs (1)
  • new (92-104)
magicblock-committor-service/src/committor_processor.rs (3)
magicblock-committor-service/src/intent_execution_manager.rs (1)
  • new (36-71)
magicblock-committor-service/src/intent_executor/task_info_fetcher.rs (1)
  • new (63-75)
magicblock-chainlink/src/remote_account_provider/photon_client.rs (1)
  • new (27-29)
test-integration/test-chainlink/tests/ix_07_redeleg_us_same_slot.rs (4)
magicblock-chainlink/src/testing/utils.rs (1)
  • init_logger (51-59)
test-integration/test-chainlink/src/ixtest_context.rs (2)
  • init (101-106)
  • counter_pda (206-208)
test-integration/test-chainlink/src/test_context.rs (1)
  • init (61-129)
magicblock-chainlink/src/remote_account_provider/remote_account.rs (1)
  • remote_slot (146-152)
magicblock-committor-service/src/tasks/args_task.rs (3)
magicblock-committor-service/src/tasks/buffer_task.rs (7)
  • new (38-46)
  • preparation_state (98-100)
  • is_compressed (146-148)
  • task_type (125-129)
  • set_compressed_data (150-155)
  • get_compressed_data (157-161)
  • delegated_account (163-169)
magicblock-committor-service/src/tasks/mod.rs (6)
  • preparation_state (77-77)
  • is_compressed (99-99)
  • task_type (93-93)
  • set_compressed_data (102-102)
  • get_compressed_data (105-105)
  • delegated_account (108-108)
magicblock-committor-service/src/tasks/task_builder.rs (1)
  • get_compressed_data (402-452)
test-integration/test-chainlink/src/test_context.rs (1)
magicblock-chainlink/src/chainlink/fetch_cloner.rs (1)
  • new (139-163)
programs/magicblock/src/schedule_transactions/process_schedule_commit.rs (2)
programs/magicblock/src/utils/instruction_utils.rs (1)
  • schedule_commit (33-40)
magicblock-chainlink/src/remote_account_provider/remote_account.rs (1)
  • compressed (154-156)
test-integration/programs/flexi-counter/src/processor.rs (3)
compressed-delegation-client/src/generated/instructions/delegate_compressed.rs (12)
  • args (162-165)
  • args (430-433)
  • new (81-83)
  • new (119-121)
  • new (246-262)
  • new (372-384)
  • payer (123-126)
  • payer (386-392)
  • invoke (264-266)
  • invoke (464-466)
  • delegated_account (128-134)
  • delegated_account (394-400)
test-integration/programs/flexi-counter/src/state.rs (4)
  • seeds (32-34)
  • seeds_with_bump (36-41)
  • new (25-31)
  • pda (43-46)
test-integration/programs/flexi-counter/src/utils/asserts.rs (1)
  • assert_keys_equal (7-19)
magicblock-committor-service/src/intent_executor/task_info_fetcher.rs (5)
magicblock-core/src/compression/mod.rs (1)
  • derive_cda_from_pda (10-22)
magicblock-chainlink/src/testing/photon_client_mock.rs (1)
  • new (26-30)
magicblock-committor-service/src/intent_execution_manager.rs (1)
  • new (36-71)
magicblock-chainlink/src/remote_account_provider/photon_client.rs (1)
  • new (27-29)
compressed-delegation-client/src/generated/accounts/compressed_delegation_record.rs (1)
  • fetch_compressed_delegation_record (59-68)
magicblock-chainlink/src/chainlink/fetch_cloner.rs (4)
magicblock-chainlink/src/remote_account_provider/photon_client.rs (1)
  • new (27-29)
magicblock-chainlink/src/remote_account_provider/mod.rs (6)
  • new (212-256)
  • None (297-297)
  • None (1214-1214)
  • None (1259-1259)
  • None (1337-1337)
  • None (1537-1537)
magicblock-chainlink/src/remote_account_provider/remote_account.rs (3)
  • account (189-211)
  • account_shared_data (122-128)
  • slot (212-224)
compressed-delegation-client/src/lib.rs (1)
  • id (61-63)
magicblock-chainlink/src/remote_account_provider/remote_account.rs (2)
compressed-delegation-client/src/generated/accounts/compressed_delegation_record.rs (1)
  • owner (158-160)
compressed-delegation-client/src/lib.rs (1)
  • id (61-63)
test-integration/test-chainlink/src/ixtest_context.rs (4)
magicblock-core/src/compression/mod.rs (2)
  • hashv_to_bn254_field_size_be_const_array (14-14)
  • derive_cda_from_pda (10-22)
magicblock-committor-service/src/tasks/args_task.rs (2)
  • instruction (51-152)
  • new (42-47)
test-integration/programs/flexi-counter/src/state.rs (3)
  • new (25-31)
  • seeds (32-34)
  • pda (43-46)
test-integration/programs/flexi-counter/src/instruction.rs (1)
  • create_delegate_compressed_ix (520-540)
test-integration/test-tools/src/validator.rs (2)
test-integration/test-runner/bin/run_tests.rs (1)
  • log_suffix (852-858)
test-integration/test-tools/src/toml_to_args.rs (2)
  • rpc_port_from_config (122-125)
  • config_to_args (59-120)
magicblock-committor-service/src/tasks/mod.rs (4)
magicblock-committor-service/src/tasks/args_task.rs (4)
  • is_compressed (243-250)
  • set_compressed_data (252-265)
  • get_compressed_data (267-280)
  • delegated_account (282-298)
magicblock-committor-service/src/tasks/buffer_task.rs (4)
  • is_compressed (146-148)
  • set_compressed_data (150-155)
  • get_compressed_data (157-161)
  • delegated_account (163-169)
magicblock-committor-service/src/tasks/task_builder.rs (1)
  • get_compressed_data (402-452)
magicblock-committor-program/src/state/chunks.rs (7)
  • struct_size (60-67)
  • chunks (219-219)
  • chunks (234-234)
  • count (126-128)
  • std (64-64)
  • std (66-66)
  • chunk_size (130-132)
test-integration/test-committor-service/tests/test_intent_executor.rs (2)
magicblock-committor-service/src/intent_executor/task_info_fetcher.rs (1)
  • new (63-75)
magicblock-committor-service/src/tasks/task_builder.rs (2)
  • finalize_tasks (56-60)
  • finalize_tasks (167-377)
programs/magicblock/src/magic_scheduled_base_intent.rs (1)
magicblock-committor-service/src/tasks/mod.rs (1)
  • is_compressed (99-99)
test-integration/test-committor-service/tests/test_ix_commit_local.rs (3)
magicblock-core/src/compression/mod.rs (1)
  • derive_cda_from_pda (10-22)
test-integration/test-committor-service/tests/utils/transactions.rs (1)
  • init_and_delegate_compressed_account_on_chain (233-322)
compressed-delegation-client/src/lib.rs (1)
  • id (61-63)
magicblock-chainlink/src/remote_account_provider/mod.rs (3)
magicblock-chainlink/src/chainlink/fetch_cloner.rs (3)
  • new (139-163)
  • None (283-283)
  • None (1603-1603)
magicblock-chainlink/src/remote_account_provider/photon_client.rs (2)
  • new (27-29)
  • new_from_url (30-33)
magicblock-chainlink/src/remote_account_provider/remote_account.rs (6)
  • slot (212-224)
  • data (72-78)
  • from_fresh_account (172-187)
  • source (225-232)
  • fresh_lamports (248-250)
  • fresh_data_len (252-254)
magicblock-committor-service/src/intent_executor/mod.rs (3)
magicblock-committor-service/src/tasks/task_builder.rs (7)
  • commit_tasks (48-53)
  • commit_tasks (70-164)
  • finalize_task (173-190)
  • accounts (105-108)
  • accounts (312-315)
  • finalize_tasks (56-60)
  • finalize_tasks (167-377)
magicblock-committor-service/src/intent_execution_manager.rs (1)
  • new (36-71)
magicblock-committor-service/src/intent_executor/task_info_fetcher.rs (5)
  • new (63-75)
  • pubkeys (159-170)
  • pubkeys (216-219)
  • fetch_rent_reimbursements (39-42)
  • fetch_rent_reimbursements (338-353)
🪛 LanguageTool
test-integration/notes-babur.md

[style] ~23-~23: In contexts where ‘if’ is followed by ‘or’, using ‘whether’ may be more appropriate (and formal).
Context: ....blocks.get(hash)`? - [x] we won't know if an account delegated to system program ...

(IF_WHETHER)


[grammar] ~25-~25: Ensure spelling is correct
Context: ... of those would fail (Gabriele) and the committor won't retry (Edwin) - [ ] LRU cache cap...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~36-~36: Ensure spelling is correct
Context: ...undelegate -> turn on subscription (via committor service) 4. Get update for 2. -> turn o...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[style] ~48-~48: This sentence contains multiple usages of the word “again”. Consider removing or replacing it.
Context: ...ates 5. We can now write to the account again and won't receive the undelegation upda...

(REPETITION_OF_AGAIN)


[style] ~83-~83: Who is ‘not sure’? Consider being more precise.
Context: ...pand --locked) ### Need Babur's Help Not sure why these fail (assume 0` return value...

(WHO_NOT_SURE)


[grammar] ~95-~95: Ensure spelling is correct
Context: ...add_ an Account to the test env which looses the delegated flag. Either we add th...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

🪛 markdownlint-cli2 (0.18.1)
test-integration/notes-babur.md

1-1: First line in a file should be a top-level heading

(MD041, first-line-heading, first-line-h1)


22-22: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


22-22: Unordered list indentation
Expected: 4; Actual: 6

(MD007, ul-indent)


128-128: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

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.

Review continued from previous batch...

GabrielePicco and others added 12 commits November 18, 2025 09:28
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Improvements**
* WebSocket communication now processes binary payloads in addition to
text payloads, expanding the range of supported data types for
transmission.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Old `DeliveryPreparator::send_ixs_with_retry` wasn't parsing any errors
and retrying blindly for specified `max_retries` times. This led to
Intents taking more time retrying errors it couldn't recover from.

Now we adapt error parsing from IntentExecutor. and not to duplicate
quite cumbersome error dispatches of `MagicBlockRpcClientError` a
generalized version that could be used from both `IntentExecutor` and
`DeliveryPreparator` is introduced.

See error explained in #590. We handle it by cleaning and then
reainitializing buffer. Due structure of `magicblock-committer-program`
reusing existing buffer is only possible if initialized buffer length is
equal to current account state, which isn't guaranteed at all but could
be a future optimization

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

* **New Features**
* Added a public utils module with a pluggable async retry framework
(send-with-retries), error mappers, and RPC error decision logic.
* Delivery preparator and intent executor now surface richer send
outcomes and mappers, exposing new public error types and APIs that can
carry optional signatures.

* **Bug Fixes**
* Improved error propagation and messages to include RPC context and
optional signatures across execution and retry flows.
* Centralized retry/error-mapping for more consistent prepare/delivery
behavior.

* **Tests**
* Added/updated integration tests for cleanup, re-prepare,
already-initialized, and adjusted error assertions.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

* **Chores**
* Optimized continuous integration pipeline with restructured test
execution workflow.
  * Enhanced build system efficiency for integration testing processes.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Luca Cillario <luca@magicblock.gg>
Co-authored-by: Thorsten Lorenz <thlorenz@gmx.de>
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Chores**
* Replaced workspace-wide dependencies with explicit version constraints
for underlying libraries to improve build consistency.
  * Preserved existing serde derive feature while pinning its version.
  * No changes to public APIs or exported behavior.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Refactor**
* Enhanced internal debugging capabilities across encoder types and
filter structures.
* Improved subscription lifecycle management through centralized
registration handling, replacing direct insertion patterns.

* **Chores**
* Updated type exports and visibility modifiers for subscription-related
infrastructure.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added per-intent execution timing histogram and async CU usage
reporting.
* Failure counters now include intent and error labels for richer
metrics.

* **Chores**
* Introduced labeled-value support for intent/outcome results so metrics
carry context.
* Metrics collection refactored to a dedicated flow invoked after
execution.

* **Bug Fixes**
* Improved execution failure log formatting and adjusted logging level
based on duration.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Chores**
* Enhanced RPC transaction configuration settings for improved
transaction retrieval and metrics calculation across transaction
processing paths.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Performance**
* Compaction now preserves account-modification data during cleanup to
avoid losing important account-related entries.
* Faster metadata access via column-count caching, reducing overhead
during storage operations.

* **Monitoring**
* Continuous metrics for ledger storage size, accounts storage size, and
account counts.
* New duration histogram for column-count measurements and
renamed/updated execution-time histogram for improved observability.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Refactor**
* Optimized ledger truncation process to execute asynchronously,
reducing blocking operations and improving system responsiveness during
maintenance operations.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
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: 30

Caution

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

⚠️ Outside diff range comments (12)
magicblock-api/src/tickers.rs (1)

105-105: Remove the stale #[allow(unused_variables)] attribute.

All function parameters (tick_duration, ledger, accountsdb, token) are now used in the implementation, so this attribute is no longer necessary.

Apply this diff:

-#[allow(unused_variables)]
 pub fn init_system_metrics_ticker(
magicblock-committor-service/src/transaction_preparator/delivery_preparator.rs (1)

507-517: Potential double-logging of cleanup errors.

Line 510 maps errors to InternalError, then line 511 inspects and logs them. If the caller also logs the returned error, this could result in duplicate error logs. Consider whether the inspect logging is necessary here, or document that callers should not log these errors again.

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

235-241: Apply the suggested diff to handle CompressedCommit in reset_commit_id.

Both CommitTask and CompressedCommitTask have identical commit_id: u64 fields (mod.rs:117-129). The current implementation only resets Commit variants, causing CompressedCommit reset calls to silently fail when invoked generically at the call site (intent_executor/mod.rs:393). This leaves invalid compressed commit tasks with stale IDs during error recovery.

 fn reset_commit_id(&mut self, commit_id: u64) {
-    let ArgsTaskType::Commit(commit_task) = &mut self.task_type else {
-        return;
-    };
-
-    commit_task.commit_id = commit_id;
+    match &mut self.task_type {
+        ArgsTaskType::Commit(commit_task) => {
+            commit_task.commit_id = commit_id;
+        }
+        ArgsTaskType::CompressedCommit(commit_task) => {
+            commit_task.commit_id = commit_id;
+        }
+        _ => {}
+    }
 }
programs/magicblock/src/schedule_transactions/process_schedule_commit.rs (1)

141-173: Undelegation branch only enforces writability, not delegated state – potential invariant leak

In this block, when opts.request_undelegation is true, you only enforce that the account is writable via get_writable_with_idx, and then you skip the delegated() check that’s enforced for the non‑undelegate path:

if opts.request_undelegation {
    // writable check...
    if !acc_writable { ... ReadonlyDataModified }
} else if !acc.borrow().delegated() {
    ... IllegalOwner
}

That means a caller can pass an arbitrary writable but non‑delegated account and still get it committed and “undelegated”, which looks inconsistent with the intent of the surrounding checks and with the comment that “we rely on invariant writable means delegated”. Since account metas are ultimately under user control, treating “writable ⇒ delegated” as a hard invariant here seems fragile.

I’d strongly recommend also asserting delegated() in the undelegation branch, so both flows enforce delegation, with undelegation adding the extra writability requirement. For example:

         {
-            if opts.request_undelegation {
+            let is_delegated = acc.borrow().delegated();
+
+            if opts.request_undelegation {
                 // Since we need to modify the account during undelegation, we expect it to be writable
                 // We rely on invariant "writable means delegated"
                 let acc_writable =
                     get_writable_with_idx(transaction_context, idx as u16)?;
                 if !acc_writable {
                     ic_msg!(
                         invoke_context,
                         "ScheduleCommit ERR: account {} is required to be writable in order to be undelegated",
                         acc_pubkey
                     );
                     return Err(InstructionError::ReadonlyDataModified);
                 }
-            } else if !acc.borrow().delegated() {
+                if !is_delegated {
+                    ic_msg!(
+                        invoke_context,
+                        "ScheduleCommit ERR: account {} is required to be delegated to the current validator, in order to be undelegated",
+                        acc_pubkey
+                    );
+                    return Err(InstructionError::IllegalOwner);
+                }
+            } else if !is_delegated {
                 ic_msg!(
                     invoke_context,
                     "ScheduleCommit ERR: account {} is required to be delegated to the current validator, in order to be committed",
                     acc_pubkey
                 );
                 return Err(InstructionError::IllegalOwner);
             };

This keeps behavior for the existing commit-only path intact, tightens the undelegation path to the same delegation requirement, and aligns better with the comment expectation. You may also want to add a negative test for “undelegate with writable but non‑delegated account” to lock this in.

programs/magicblock/src/schedule_transactions/process_schedule_commit_tests.rs (2)

88-143: Three-committee helper parametrization is useful; minor duplication could be reduced

Extending prepare_transaction_with_three_committees with is_delegated: (bool, bool, bool) is a good way to control per-committee delegation state for tests, and setting delegated on each AccountSharedData here centralizes the setup.

There’s some repeated boilerplate when constructing the three committee accounts that could be made less error-prone. For example:

-        {
-            let mut acc = AccountSharedData::new(0, 0, &program);
-            acc.set_delegated(is_delegated.0);
-            map.insert(committee_uno, acc);
-        }
-        {
-            let mut acc = AccountSharedData::new(0, 0, &program);
-            acc.set_delegated(is_delegated.1);
-            map.insert(committee_dos, acc);
-        }
-        {
-            let mut acc = AccountSharedData::new(0, 0, &program);
-            acc.set_delegated(is_delegated.2);
-            map.insert(committee_tres, acc);
-        }
+        for (committee, delegated) in [
+            (committee_uno, is_delegated.0),
+            (committee_dos, is_delegated.1),
+            (committee_tres, is_delegated.2),
+        ] {
+            let mut acc = AccountSharedData::new(0, 0, &program);
+            acc.set_delegated(delegated);
+            map.insert(committee, acc);
+        }

This keeps the three branches in lockstep and makes it harder to accidentally mismatch a committee/flag pairing in future refactors.


451-463: Callsites consistently passing (true, true, true); consider a named helper/constant

All updated callsites that rely on fully delegated committees now pass (true, true, true) into prepare_transaction_with_three_committees, which preserves previous semantics.

To improve readability and avoid magic tuples scattered around, consider a small helper or constant, e.g.:

const ALL_DELEGATED: (bool, bool, bool) = (true, true, true);

// ...
prepare_transaction_with_three_committees(&payer, None, ALL_DELEGATED);

or a dedicated helper like prepare_fully_delegated_transaction_with_three_committees(...) that wraps this pattern. That would make the intent clearer and reduce duplication.

Also applies to: 503-510, 563-575, 617-624, 707-715

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

60-84: Metrics wiring (ExecutionOutput label + CU tracking) and result persistence look good.

  • ExecutionOutput now implements metrics::LabelValue with clear "single_stage_succeeded"/"two_stage_succeeded" labels, aligning with how magicblock-metrics wraps Result values.
  • intent_metrics fetches transaction status with the executor’s commitment level, extracts compute_units_consumed, and records a single CU value (sum across stages for two-stage). Overflow handling on the i64 cast is bounded.
  • persist_result correctly adapts to the new IntentExecutorError shapes (two-field CommitIDError/ActionsError/CpiLimitError) while preserving the previous status semantics.

All of this is side-effect-only (logging/metrics) and doesn’t threaten the core execution paths.

If you want stronger guarantees around metrics visibility, you could consider logging a structured event when CU data is missing (currently swallowed as _ => {}) to help debug gaps in CU reporting.

Also applies to: 510-610, 713-770, 779-813


123-162: Compression guard in try_unite_tasks and test coverage are reasonable but could be expanded.

The early return in try_unite_tasks when any commit/finalize task is compressed prevents accidental unification of compressed flows into a single transaction, which is a sensible conservative choice and keeps the existing single-stage optimization strictly for non-compressed cases. The test_try_unite test still validates the happy path for uncompressed tasks.

You may eventually want a dedicated test that builds a compressed intent and asserts that try_unite_tasks returns Ok(None) to lock in this guard.

Also applies to: 221-239, 622-651, 861-899

magicblock-aperture/src/server/websocket/connection.rs (1)

98-157: Keep‑alive logic is sound; consider explicitly handling CLOSE frames

The new PING_PERIOD/MAX_INACTIVE_INTERVAL logic with a pinned next_ping future and rescheduling on inbound frames gives clear “ping every 30s, close after 60s of no inbound traffic” semantics, and updating last_activity plus resetting next_ping on every received frame is consistent. The change to let _ = self.report_failure(..).await; also avoids tearing down the connection when a parse‑error response cannot be delivered.

Two minor points to consider:

  • Frames with OpCode::Close are now treated as “non‑Text/Binary” and simply ignored (while still refreshing last_activity). That means a client‑initiated close will keep the connection alive until the idle timeout or a later I/O failure. You may want to special‑case OpCode::Close to send a close frame and break the loop to honor the WebSocket close handshake promptly.
  • If report_failure returns false (write failed), you currently continue the loop and rely on later I/O to fail. If you consider a failed error‑response write a terminal condition, you could break in that case to release resources earlier.
magicblock-ledger/src/store/api.rs (3)

1784-1918: Tests generally match new per-slot indexing, but one assertion uses an old res

The updated tests around get_confirmed_signatures_for_address nicely exercise the new per-slot index behavior and the added write_block calls align with how indices are derived from write_transaction_status.

There is, however, a small correctness bug in test_find_address_signatures_no_intra_slot_limits:

// No before/until
{
    let sigs = extract(
        store
            .get_confirmed_signatures_for_address(
                read_uno, slot_seis, None, None, 1000,
            )
            .unwrap()
            .infos,
    );
    assert!(!res.found_upper);
    assert_eq!(sigs, vec![/* ... */]);
}

Here res refers to the earlier let res = store.get_confirmed_signatures_for_address(read_cuatro, ...), so assert!(!res.found_upper) is asserting against the wrong call and does not validate the found_upper flag for the read_uno query at all.

You likely want:

-        {
-            let sigs = extract(
-                store
-                    .get_confirmed_signatures_for_address(
-                        read_uno, slot_seis, None, None, 1000,
-                    )
-                    .unwrap()
-                    .infos,
-            );
-            assert!(!res.found_upper);
-            assert_eq!(
-                sigs,
-                vec![
-                    (slot_seis, signature_seis),
-                    (slot_tres, signature_tres),
-                    (slot_dos, signature_dos),
-                    (slot_uno, signature_uno),
-                ]
-            );
-        }
+        {
+            let res = store
+                .get_confirmed_signatures_for_address(
+                    read_uno, slot_seis, None, None, 1000,
+                )
+                .unwrap();
+            let sigs = extract(res.infos.clone());
+            assert!(!res.found_upper);
+            assert_eq!(
+                sigs,
+                vec![
+                    (slot_seis, signature_seis),
+                    (slot_tres, signature_tres),
+                    (slot_dos, signature_dos),
+                    (slot_uno, signature_uno),
+                ]
+            );
+        }

The rest of the test adjustments (extra write_block calls, updated expected orderings and ranges) look consistent with the new indexing semantics.

Also applies to: 1958-1965, 2000-2013, 2088-2095, 2101-2133, 2166-2168


480-523: Fix required for same-slot before+until edge case that produces duplicates and wrong results

The review identifies a real bug with major impact. When both upper_limit_signature and lower_limit_signature refer to transactions in the same slot, the current three-phase logic fails:

Current behavior (lines 531-595 + 661-719):

  • Upper phase adds all signatures with tx_idx < upper_idx
  • Lower phase adds all signatures with tx_idx > lower_idx
  • Middle phase skipped because newest_slot = upper_slot - 1, making newest_slot > lower_slot false

This produces duplicates and includes out-of-range signatures. The test suite lacks coverage for this scenario—all dual-limit tests use different slots, leaving the same-slot case untested.

Required changes:

  • Add special-case handling for found_upper && found_lower && include_upper && include_lower && upper_slot == lower_slot
  • Fetch both upper_idx and lower_idx, assert lower_idx < upper_idx
  • Execute a single pass collecting only entries where lower_idx < tx_idx < upper_idx
  • Skip the existing upper- and lower-phase loops for this case
  • Add a unit test exercising same-slot before+until to prevent regression

1225-1323: Clear block_txn_indexes cache during slot truncation in delete_slot_range

The issue is confirmed: delete_slot_range (lines 1224–1324) properly removes all on-disk transaction data for the truncated slot range but leaves entries in the in-memory block_txn_indexes: HashCache<Slot, AtomicU32> cache uncleaned. This results in:

  • Persistent in-memory cache entries until natural HashCache eviction
  • If truncated slots are later rewritten, transaction indices resume from the old counter value rather than zero

The test test_truncate_slots verifies on-disk deletion but does not check in-memory cache state or test slot reuse scenarios. The suggested fix—iterating through the range and calling .remove() on the cache—is appropriate and safe:

     pub fn delete_slot_range(
         &self,
         from_slot: Slot,
         to_slot: Slot,
     ) -> LedgerResult<()> {
         self.set_lowest_cleanup_slot(to_slot);
+        // Best-effort cleanup of per-slot index counters for truncated slots.
+        for slot in from_slot..=to_slot {
+            let _ = self.block_txn_indexes.remove(&slot);
+        }
♻️ Duplicate comments (9)
programs/magicblock/src/utils/instruction_utils.rs (1)

61-95: Compressed commit helpers correctly mirror the existing pattern

The implementation correctly mirrors the existing schedule_commit helpers with the appropriate ScheduleCompressedCommit instruction variant and identical account metadata construction.

test-integration/programs/schedulecommit/src/api.rs (1)

28-32: Serialization pattern and error handling concerns remain.

The switch from Instruction::new_with_borsh to manual borsh::to_vec().unwrap() with Instruction::new_with_bytes introduces the same concerns raised in previous reviews: potential panics from .unwrap() and repeated serialization patterns across multiple instruction builders.

Also applies to: 86-90, 194-198, 218-227, 233-237

Cargo.toml (2)

96-100: Prefer pinning light-protocol deps by rev instead of mutable branch.

Lines 96–100 reference the light-protocol dependencies on the dode/sdk-v2-2 branch. Mutable branch references can cause non-reproducible builds over time if the branch is force-pushed or updated. Based on learnings, it's recommended to pin by a specific revision (rev) instead.

Once the dode/sdk-v2-2 branch is stable, convert to revision-pinned dependencies:

- light-client = { git = "https://github.com/magicblock-labs/light-protocol", branch = "dode/sdk-v2-2" }
- light-compressed-account = { git = "https://github.com/magicblock-labs/light-protocol", branch = "dode/sdk-v2-2" }
- light-hasher = { git = "https://github.com/magicblock-labs/light-protocol", branch = "dode/sdk-v2-2" }
- light-sdk = { git = "https://github.com/magicblock-labs/light-protocol", branch = "dode/sdk-v2-2" }
- light-sdk-types = { git = "https://github.com/magicblock-labs/light-protocol", branch = "dode/sdk-v2-2" }
+ light-client = { git = "https://github.com/magicblock-labs/light-protocol", rev = "<stable-commit-hash>" }
+ light-compressed-account = { git = "https://github.com/magicblock-labs/light-protocol", rev = "<stable-commit-hash>" }
+ light-hasher = { git = "https://github.com/magicblock-labs/light-protocol", rev = "<stable-commit-hash>" }
+ light-sdk = { git = "https://github.com/magicblock-labs/light-protocol", rev = "<stable-commit-hash>" }
+ light-sdk-types = { git = "https://github.com/magicblock-labs/light-protocol", rev = "<stable-commit-hash>" }

58-59: CRITICAL: Unresolved borsh version mismatch will cause build failures.

Lines 58–59 have an incompatible major version mismatch: borsh 0.10.4 and borsh-derive 1.5.1. These major versions are not compatible; borsh-derive 1.5.x expects borsh 1.x, and using 0.10.x alongside 1.5.x commonly produces duplicate/trait/crate-not-found errors during macro expansion.

Additionally, magicblock-api depends on borsh 1.5.3, fragmenting the workspace further.

Required fix: Align borsh and borsh-derive to the same major version across the entire workspace. Choose one path:

  • Option A (recommended for Solana 2.2): Use borsh 1.x series to align with modern ecosystem patterns.
  • Option B: Use borsh 0.10.x series and downgrade borsh-derive to 0.10.x.

Apply this diff to start (choose Option A or B):

- borsh = { version = "0.10.4" }
- borsh-derive = "1.5.1"
+ borsh = { version = "1.5.3" }
+ borsh-derive = "1.5.3"

Then update magicblock-api's Cargo.toml to match, and run cargo update to ensure the workspace resolves to a single borsh version. Verify the build succeeds before merging.

.github/workflows/ci-test-integration.yml (1)

33-40: Use stable zk-compression CLI version instead of prerelease.

Line 40 installs a prerelease version @lightprotocol/zk-compression-cli@0.27.1-alpha.2. The latest stable version is 0.27.0, which should be used in CI to avoid stability risks.

Update the npm install command to use the stable release:

-          npm i -g @lightprotocol/zk-compression-cli@0.27.1-alpha.2
+          npm i -g @lightprotocol/zk-compression-cli@0.27.0
magicblock-committor-service/src/intent_execution_manager/intent_execution_engine.rs (1)

782-788: Consider simplifying the closure pattern.

The addition of the _compressed parameter aligns with the broader compressed delegation support. The mock implementation correctly ignores this parameter.

As noted in a previous review, the closure pattern could be more concise:

-        Ok(pubkeys.iter().map(|pubkey| (*pubkey, 1)).collect())
+        Ok(pubkeys.iter().map(|&k| (k, 1)).collect())
programs/magicblock/src/schedule_transactions/process_schedule_commit.rs (1)

34-55: Wrapper split and shared schedule_commit core look good; consider documenting compressed

Refactoring into process_schedule_commit / process_schedule_compressed_commit wrappers with a shared schedule_commit(..., compressed: bool) keeps the branching localized and is an appropriate abstraction for the new compressed flow.

One follow-up: the bare compressed: bool is not self-describing for future callers. A short doc comment (either on schedule_commit or both wrappers) explaining what “compressed” means in terms of expected callers and behavior (compressed-asset commit workflow vs standard commit) would help avoid misuse.

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

345-367: Mixed compressed/non-compressed tasks are still treated as a single boolean flag.

handle_commit_id_error forwards a single compressed boolean to fetch_next_commit_ids based on strategy.optimized_tasks.iter().any(|task| task.is_compressed()), and there’s a TODO acknowledging mixed cases. This is the same concern previously raised: if a strategy ever contains both compressed and non-compressed tasks, this boolean conflates them and may fetch/assign incorrect commit IDs.

Even if current strategies are homogeneous, it would be safer to either assert homogeneity up front (and fail fast if violated) or extend fetch_next_commit_ids/strategy metadata to support per-task compression status.

programs/magicblock/src/magic_scheduled_base_intent.rs (1)

109-115: Document is_compressed on ScheduledBaseIntent

This new public helper is part of the external API surface and encodes an important semantic (“uses compressed account delegation”). Adding a short doc comment will make its behavior and implications clearer to callers, especially around when compressed variants are set and what they mean for downstream processing (e.g., Photon indexer vs. normal account fetch).

For example:

-    pub fn is_compressed(&self) -> bool {
+    /// Returns `true` if this base intent uses compressed account delegation.
+    ///
+    /// Compressed variants rely on the Photon indexer and compressed accounts
+    /// instead of standard Solana account fetching.
+    pub fn is_compressed(&self) -> bool {
         matches!(
             &self.base_intent,
             MagicBaseIntent::CompressedCommit(_)
                 | MagicBaseIntent::CompressedCommitAndUndelegate(_)
         )
     }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a8cc1b8 and 397b9b3.

⛔ Files ignored due to path filters (2)
  • Cargo.lock is excluded by !**/*.lock
  • test-integration/Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (70)
  • .github/workflows/ci-fmt.yml (1 hunks)
  • .github/workflows/ci-lint.yml (1 hunks)
  • .github/workflows/ci-test-integration.yml (2 hunks)
  • .github/workflows/ci-test-unit.yml (1 hunks)
  • .github/workflows/deploy-testnet-by-pr-comment.yml (1 hunks)
  • .github/workflows/publish-packages.yml (2 hunks)
  • .github/workflows/slack-notify.yml (1 hunks)
  • Cargo.toml (6 hunks)
  • Makefile (1 hunks)
  • magicblock-accounts/src/scheduled_commits_processor.rs (3 hunks)
  • magicblock-aperture/Cargo.toml (1 hunks)
  • magicblock-aperture/src/encoder.rs (6 hunks)
  • magicblock-aperture/src/requests/http/mod.rs (4 hunks)
  • magicblock-aperture/src/requests/http/send_transaction.rs (3 hunks)
  • magicblock-aperture/src/requests/http/simulate_transaction.rs (1 hunks)
  • magicblock-aperture/src/requests/mod.rs (1 hunks)
  • magicblock-aperture/src/requests/websocket/account_subscribe.rs (1 hunks)
  • magicblock-aperture/src/requests/websocket/log_subscribe.rs (1 hunks)
  • magicblock-aperture/src/requests/websocket/program_subscribe.rs (1 hunks)
  • magicblock-aperture/src/requests/websocket/slot_subscribe.rs (1 hunks)
  • magicblock-aperture/src/server/http/dispatch.rs (2 hunks)
  • magicblock-aperture/src/server/websocket/connection.rs (7 hunks)
  • magicblock-aperture/src/server/websocket/dispatch.rs (4 hunks)
  • magicblock-aperture/src/state/subscriptions.rs (9 hunks)
  • magicblock-aperture/src/utils.rs (1 hunks)
  • magicblock-aperture/tests/transactions.rs (2 hunks)
  • magicblock-api/src/tickers.rs (2 hunks)
  • magicblock-chainlink/src/chainlink/mod.rs (10 hunks)
  • magicblock-committor-service/src/intent_execution_manager/intent_execution_engine.rs (4 hunks)
  • magicblock-committor-service/src/intent_executor/error.rs (7 hunks)
  • magicblock-committor-service/src/intent_executor/mod.rs (22 hunks)
  • magicblock-committor-service/src/intent_executor/single_stage_executor.rs (7 hunks)
  • magicblock-committor-service/src/intent_executor/two_stage_executor.rs (6 hunks)
  • magicblock-committor-service/src/tasks/args_task.rs (7 hunks)
  • magicblock-committor-service/src/tasks/buffer_task.rs (4 hunks)
  • magicblock-committor-service/src/transaction_preparator/delivery_preparator.rs (10 hunks)
  • magicblock-committor-service/src/types.rs (2 hunks)
  • magicblock-ledger/Cargo.toml (1 hunks)
  • magicblock-ledger/src/database/columns.rs (2 hunks)
  • magicblock-ledger/src/database/compaction_filter.rs (1 hunks)
  • magicblock-ledger/src/database/ledger_column.rs (4 hunks)
  • magicblock-ledger/src/database/rocks_db.rs (2 hunks)
  • magicblock-ledger/src/ledger_truncator.rs (1 hunks)
  • magicblock-ledger/src/store/api.rs (22 hunks)
  • magicblock-ledger/src/store/utils.rs (1 hunks)
  • magicblock-ledger/tests/common.rs (1 hunks)
  • magicblock-ledger/tests/get_block.rs (1 hunks)
  • magicblock-ledger/tests/test_ledger_truncator.rs (4 hunks)
  • magicblock-magic-program-api/Cargo.toml (1 hunks)
  • magicblock-metrics/src/metrics/mod.rs (7 hunks)
  • magicblock-metrics/src/metrics/types.rs (1 hunks)
  • magicblock-processor/Cargo.toml (1 hunks)
  • magicblock-processor/src/executor/mod.rs (1 hunks)
  • magicblock-processor/src/executor/processing.rs (2 hunks)
  • magicblock-processor/src/scheduler.rs (1 hunks)
  • magicblock-rpc-client/src/lib.rs (3 hunks)
  • magicblock-rpc-client/src/utils.rs (1 hunks)
  • programs/magicblock/src/magic_scheduled_base_intent.rs (12 hunks)
  • programs/magicblock/src/mutate_accounts/account_mod_data.rs (1 hunks)
  • programs/magicblock/src/schedule_transactions/process_schedule_commit.rs (5 hunks)
  • programs/magicblock/src/schedule_transactions/process_schedule_commit_tests.rs (10 hunks)
  • programs/magicblock/src/utils/instruction_utils.rs (3 hunks)
  • test-integration/programs/schedulecommit/src/api.rs (6 hunks)
  • test-integration/programs/schedulecommit/src/lib.rs (2 hunks)
  • test-integration/schedulecommit/client/src/schedule_commit_context.rs (1 hunks)
  • test-integration/schedulecommit/test-scenarios/tests/01_commits.rs (2 hunks)
  • test-integration/test-chainlink/tests/ix_remote_account_provider.rs (4 hunks)
  • test-integration/test-cloning/tests/01_program-deploy.rs (1 hunks)
  • test-integration/test-committor-service/tests/test_delivery_preparator.rs (6 hunks)
  • test-integration/test-committor-service/tests/test_intent_executor.rs (15 hunks)
🧰 Additional context used
🧠 Learnings (15)
📚 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:

  • magicblock-ledger/Cargo.toml
  • programs/magicblock/src/mutate_accounts/account_mod_data.rs
  • test-integration/programs/schedulecommit/src/api.rs
  • magicblock-ledger/tests/common.rs
  • magicblock-aperture/src/requests/websocket/account_subscribe.rs
  • magicblock-aperture/src/requests/websocket/log_subscribe.rs
  • magicblock-aperture/src/encoder.rs
  • magicblock-aperture/src/requests/http/mod.rs
  • magicblock-aperture/src/requests/http/send_transaction.rs
  • magicblock-aperture/src/requests/websocket/slot_subscribe.rs
  • programs/magicblock/src/schedule_transactions/process_schedule_commit_tests.rs
  • programs/magicblock/src/schedule_transactions/process_schedule_commit.rs
  • magicblock-processor/src/executor/processing.rs
  • magicblock-ledger/src/store/api.rs
  • magicblock-aperture/src/state/subscriptions.rs
  • test-integration/test-chainlink/tests/ix_remote_account_provider.rs
  • magicblock-aperture/tests/transactions.rs
  • Cargo.toml
  • programs/magicblock/src/magic_scheduled_base_intent.rs
  • magicblock-aperture/src/server/websocket/dispatch.rs
  • programs/magicblock/src/utils/instruction_utils.rs
  • magicblock-committor-service/src/transaction_preparator/delivery_preparator.rs
  • magicblock-api/src/tickers.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:

  • programs/magicblock/src/mutate_accounts/account_mod_data.rs
  • magicblock-ledger/src/database/columns.rs
  • magicblock-ledger/src/ledger_truncator.rs
  • magicblock-processor/src/executor/mod.rs
  • magicblock-aperture/src/requests/http/mod.rs
  • programs/magicblock/src/schedule_transactions/process_schedule_commit_tests.rs
  • programs/magicblock/src/schedule_transactions/process_schedule_commit.rs
  • magicblock-processor/src/executor/processing.rs
  • magicblock-ledger/src/store/api.rs
  • magicblock-processor/src/scheduler.rs
  • magicblock-api/src/tickers.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/types.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:

  • test-integration/schedulecommit/test-scenarios/tests/01_commits.rs
  • magicblock-processor/src/executor/mod.rs
  • magicblock-aperture/src/requests/http/send_transaction.rs
  • programs/magicblock/src/schedule_transactions/process_schedule_commit_tests.rs
  • magicblock-committor-service/src/intent_execution_manager/intent_execution_engine.rs
  • magicblock-ledger/tests/get_block.rs
  • magicblock-processor/src/scheduler.rs
  • magicblock-aperture/tests/transactions.rs
  • magicblock-committor-service/src/intent_executor/single_stage_executor.rs
  • test-integration/test-committor-service/tests/test_intent_executor.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/schedulecommit/test-scenarios/tests/01_commits.rs
  • magicblock-ledger/tests/get_block.rs
  • magicblock-aperture/tests/transactions.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-accounts/src/scheduled_commits_processor.rs
  • magicblock-aperture/src/requests/websocket/account_subscribe.rs
  • magicblock-aperture/src/requests/websocket/log_subscribe.rs
  • magicblock-aperture/src/requests/websocket/slot_subscribe.rs
  • magicblock-processor/src/executor/processing.rs
  • magicblock-aperture/src/state/subscriptions.rs
  • test-integration/test-chainlink/tests/ix_remote_account_provider.rs
  • magicblock-aperture/src/requests/websocket/program_subscribe.rs
  • magicblock-aperture/src/server/websocket/dispatch.rs
  • magicblock-chainlink/src/chainlink/mod.rs
📚 Learning: 2025-10-28T13:15:42.706Z
Learnt from: bmuddha
Repo: magicblock-labs/magicblock-validator PR: 596
File: magicblock-processor/src/scheduler.rs:1-1
Timestamp: 2025-10-28T13:15:42.706Z
Learning: In magicblock-processor, transaction indexes were always set to 0 even before the changes in PR #596. The proper transaction indexing within slots will be addressed during the planned ledger rewrite.

Applied to files:

  • magicblock-ledger/tests/common.rs
  • magicblock-ledger/tests/test_ledger_truncator.rs
  • magicblock-processor/src/executor/mod.rs
  • magicblock-processor/src/executor/processing.rs
  • magicblock-ledger/tests/get_block.rs
  • magicblock-ledger/src/store/api.rs
  • magicblock-processor/src/scheduler.rs
📚 Learning: 2025-10-21T11:00:18.396Z
Learnt from: bmuddha
Repo: magicblock-labs/magicblock-validator PR: 578
File: magicblock-aperture/src/encoder.rs:176-187
Timestamp: 2025-10-21T11:00:18.396Z
Learning: In the magicblock validator, the current slot is always the root slot. The SlotEncoder in magicblock-aperture/src/encoder.rs correctly sets `root: slot` because there is no lag between current and root slots in this architecture.

Applied to files:

  • magicblock-ledger/tests/test_ledger_truncator.rs
  • magicblock-aperture/src/encoder.rs
  • magicblock-ledger/src/store/api.rs
  • magicblock-processor/src/scheduler.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-aperture/src/server/http/dispatch.rs
  • magicblock-processor/src/executor/mod.rs
  • magicblock-processor/src/scheduler.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-aperture/src/server/http/dispatch.rs
  • magicblock-processor/src/executor/mod.rs
  • magicblock-processor/src/executor/processing.rs
  • magicblock-processor/src/scheduler.rs
📚 Learning: 2025-10-21T10:34:59.140Z
Learnt from: bmuddha
Repo: magicblock-labs/magicblock-validator PR: 578
File: magicblock-accounts-db/src/lib.rs:63-72
Timestamp: 2025-10-21T10:34:59.140Z
Learning: In magicblock-validator, the AccountsDb "stop-the-world" synchronizer is managed at the processor/executor level, not at the AccountsDb API level. Transaction executors in magicblock-processor hold a read lock (sync.read()) for the duration of each slot and release it only at slot boundaries, ensuring all account writes happen under the read lock. Snapshot operations acquire a write lock, blocking until all executors release their read locks. This pattern ensures mutual exclusion between writes and snapshots without requiring read guards in AccountsDb write APIs.

Applied to files:

  • magicblock-processor/src/executor/mod.rs
  • magicblock-processor/src/executor/processing.rs
  • magicblock-processor/src/scheduler.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-processor/src/executor/mod.rs
  • magicblock-processor/src/executor/processing.rs
  • magicblock-processor/src/scheduler.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:

  • magicblock-aperture/Cargo.toml
  • magicblock-api/src/tickers.rs
📚 Learning: 2025-11-07T18:19:48.996Z
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 614
File: test-integration/programs/schedulecommit/Cargo.toml:19-20
Timestamp: 2025-11-07T18:19:48.996Z
Learning: In Solana programs (crates depending on solana-program), the empty feature flags `custom-heap = []` and `custom-panic = []` are standard declarations required to avoid compiler warnings. These should not be flagged as unused features in Cargo.toml files for Solana program crates.

Applied to files:

  • magicblock-magic-program-api/Cargo.toml
📚 Learning: 2025-10-26T08:49:31.543Z
Learnt from: taco-paco
Repo: magicblock-labs/magicblock-validator PR: 585
File: magicblock-committor-service/src/tasks/buffer_task.rs:111-115
Timestamp: 2025-10-26T08:49:31.543Z
Learning: In the magicblock-committor-service, compute units returned by the `compute_units()` method in task implementations (such as `BufferTask`, `ArgsTask`, etc.) represent the compute budget for a single task. Transactions can comprise multiple tasks, and the total compute budget for a transaction is computed as the sum of the compute units of all tasks included in that transaction.

Applied to files:

  • magicblock-committor-service/src/tasks/args_task.rs
  • magicblock-committor-service/src/tasks/buffer_task.rs
  • magicblock-committor-service/src/intent_executor/mod.rs
🧬 Code graph analysis (29)
magicblock-committor-service/src/types.rs (3)
magicblock-committor-service/src/intent_executor/mod.rs (1)
  • value (75-83)
magicblock-committor-service/src/intent_executor/error.rs (1)
  • value (105-112)
magicblock-metrics/src/metrics/types.rs (2)
  • value (73-73)
  • value (81-86)
test-integration/schedulecommit/test-scenarios/tests/01_commits.rs (3)
test-integration/programs/schedulecommit/src/api.rs (4)
  • delegate_account_cpi_instruction (58-91)
  • init_account_instruction (15-33)
  • pda_and_bump (263-267)
  • schedule_commit_cpi_instruction (104-122)
test-integration/test-tools/src/integration_test_context.rs (3)
  • signature (63-65)
  • try_new (113-115)
  • airdrop_chain (483-494)
test-integration/schedulecommit/test-scenarios/tests/utils/mod.rs (1)
  • extract_transaction_error (255-264)
magicblock-metrics/src/metrics/types.rs (3)
magicblock-committor-service/src/intent_executor/mod.rs (1)
  • value (75-83)
magicblock-committor-service/src/intent_executor/error.rs (1)
  • value (105-112)
magicblock-committor-service/src/types.rs (1)
  • value (23-29)
magicblock-ledger/src/ledger_truncator.rs (1)
magicblock-api/src/magic_validator.rs (1)
  • ledger (741-743)
magicblock-ledger/tests/test_ledger_truncator.rs (1)
magicblock-ledger/tests/common.rs (1)
  • write_dummy_transaction (25-47)
test-integration/test-committor-service/tests/test_delivery_preparator.rs (2)
test-integration/test-committor-service/tests/common.rs (4)
  • create_commit_task (166-182)
  • create_compressed_commit_task (185-212)
  • generate_random_bytes (158-163)
  • new (63-66)
test-integration/test-committor-service/tests/utils/transactions.rs (1)
  • init_and_delegate_compressed_account_on_chain (233-322)
magicblock-aperture/src/requests/http/mod.rs (1)
magicblock-aperture/src/requests/http/get_multiple_accounts.rs (1)
  • pubkeys (31-39)
magicblock-aperture/src/requests/http/send_transaction.rs (1)
magicblock-aperture/src/requests/mod.rs (1)
  • params (22-26)
magicblock-ledger/src/database/ledger_column.rs (1)
magicblock-ledger/src/database/columns.rs (9)
  • columns (105-117)
  • slot (131-131)
  • slot (181-183)
  • slot (249-251)
  • slot (329-331)
  • slot (404-406)
  • slot (503-505)
  • slot (577-579)
  • slot (649-651)
magicblock-ledger/src/database/compaction_filter.rs (1)
magicblock-ledger/src/database/columns.rs (10)
  • key (125-125)
  • key (170-174)
  • key (234-243)
  • key (318-323)
  • key (393-398)
  • key (495-497)
  • key (566-571)
  • key (641-643)
  • keep_all_on_compaction (132-134)
  • keep_all_on_compaction (659-661)
programs/magicblock/src/schedule_transactions/process_schedule_commit_tests.rs (3)
test-integration/programs/schedulecommit/src/lib.rs (1)
  • process_instruction (110-151)
programs/magicblock/src/test_utils/mod.rs (1)
  • process_instruction (44-61)
programs/magicblock/src/utils/instruction_utils.rs (1)
  • schedule_commit_instruction (43-59)
programs/magicblock/src/schedule_transactions/process_schedule_commit.rs (2)
programs/magicblock/src/utils/accounts.rs (1)
  • get_writable_with_idx (104-111)
magicblock-chainlink/src/remote_account_provider/remote_account.rs (1)
  • compressed (154-156)
magicblock-committor-service/src/tasks/args_task.rs (3)
magicblock-committor-service/src/tasks/buffer_task.rs (7)
  • new (38-46)
  • preparation_state (98-100)
  • is_compressed (146-148)
  • task_type (125-129)
  • set_compressed_data (150-155)
  • get_compressed_data (157-161)
  • delegated_account (163-169)
magicblock-committor-service/src/tasks/mod.rs (6)
  • preparation_state (77-77)
  • is_compressed (99-99)
  • task_type (93-93)
  • set_compressed_data (102-102)
  • get_compressed_data (105-105)
  • delegated_account (108-108)
magicblock-committor-service/src/tasks/task_builder.rs (1)
  • get_compressed_data (402-452)
magicblock-committor-service/src/intent_execution_manager/intent_execution_engine.rs (2)
magicblock-metrics/src/metrics/mod.rs (2)
  • observe_committor_intent_execution_time_histogram (383-391)
  • inc_committor_failed_intents_count (370-377)
programs/magicblock/src/magic_scheduled_base_intent.rs (2)
  • get_committed_pubkeys (97-99)
  • get_committed_pubkeys (198-202)
magicblock-ledger/tests/get_block.rs (1)
magicblock-ledger/tests/common.rs (1)
  • write_dummy_transaction (25-47)
magicblock-aperture/src/state/subscriptions.rs (3)
magicblock-aperture/src/server/websocket/dispatch.rs (1)
  • new (51-63)
magicblock-aperture/src/server/websocket/connection.rs (1)
  • new (66-84)
magicblock-aperture/src/state/mod.rs (1)
  • new (77-95)
magicblock-committor-service/src/tasks/buffer_task.rs (3)
magicblock-committor-service/src/tasks/args_task.rs (4)
  • is_compressed (243-250)
  • set_compressed_data (252-265)
  • get_compressed_data (267-280)
  • delegated_account (282-298)
magicblock-committor-service/src/tasks/mod.rs (4)
  • is_compressed (99-99)
  • set_compressed_data (102-102)
  • get_compressed_data (105-105)
  • delegated_account (108-108)
magicblock-committor-service/src/tasks/task_builder.rs (1)
  • get_compressed_data (402-452)
test-integration/test-chainlink/tests/ix_remote_account_provider.rs (3)
magicblock-chainlink/src/testing/utils.rs (2)
  • airdrop (24-27)
  • sleep_ms (41-43)
test-integration/test-chainlink/src/lib.rs (1)
  • sleep_ms (8-11)
magicblock-chainlink/src/remote_account_provider/remote_account.rs (1)
  • fresh_lamports (248-250)
programs/magicblock/src/magic_scheduled_base_intent.rs (2)
programs/magicblock/src/utils/accounts.rs (2)
  • get_writable_with_idx (104-111)
  • get_instruction_pubkey_with_idx (94-102)
magicblock-committor-service/src/tasks/mod.rs (1)
  • is_compressed (99-99)
magicblock-aperture/src/server/websocket/dispatch.rs (1)
magicblock-chainlink/src/remote_account_provider/chain_pubsub_actor.rs (1)
  • subscriptions (146-151)
programs/magicblock/src/utils/instruction_utils.rs (1)
programs/magicblock/src/schedule_task/process_schedule_task.rs (1)
  • pdas (203-214)
magicblock-rpc-client/src/utils.rs (4)
magicblock-rpc-client/src/lib.rs (3)
  • error (193-195)
  • signature (82-90)
  • from (228-230)
magicblock-committor-service/src/intent_executor/error.rs (4)
  • signature (29-34)
  • from (129-131)
  • from (215-220)
  • try_map (203-211)
magicblock-committor-service/src/intent_executor/mod.rs (4)
  • map (669-681)
  • decide_flow (683-692)
  • None (874-874)
  • None (894-894)
magicblock-committor-service/src/transaction_preparator/delivery_preparator.rs (4)
  • map (361-371)
  • decide_flow (373-382)
  • from (542-546)
  • try_map (333-349)
magicblock-chainlink/src/chainlink/mod.rs (2)
magicblock-chainlink/src/remote_account_provider/program_account.rs (1)
  • try_new (231-259)
magicblock-chainlink/src/remote_account_provider/remote_account.rs (1)
  • account (189-211)
magicblock-committor-service/src/transaction_preparator/delivery_preparator.rs (4)
magicblock-rpc-client/src/utils.rs (6)
  • decide_rpc_error_flow (176-201)
  • map_magicblock_client_error (93-141)
  • send_transaction_with_retries (34-71)
  • try_map (84-88)
  • map (13-13)
  • decide_flow (14-16)
magicblock-committor-service/src/tasks/mod.rs (6)
  • instruction (68-68)
  • instruction (304-310)
  • get_compressed_data (105-105)
  • chunks_pda (271-278)
  • chunks_pda (322-329)
  • write_instructions (243-260)
magicblock-committor-service/src/tasks/task_builder.rs (1)
  • get_compressed_data (402-452)
magicblock-committor-service/src/utils.rs (1)
  • persist_status_update (6-22)
test-integration/test-committor-service/tests/test_intent_executor.rs (2)
magicblock-committor-service/src/intent_executor/task_info_fetcher.rs (1)
  • new (63-75)
magicblock-committor-service/src/tasks/task_builder.rs (2)
  • finalize_tasks (56-60)
  • finalize_tasks (167-377)
magicblock-api/src/tickers.rs (1)
magicblock-metrics/src/metrics/mod.rs (4)
  • set_ledger_size (284-286)
  • set_accounts_size (339-341)
  • set_accounts_count (343-345)
  • observe_columns_count_duration (332-337)
magicblock-metrics/src/metrics/mod.rs (3)
magicblock-aperture/src/state/subscriptions.rs (2)
  • new (342-355)
  • new (410-413)
magicblock-metrics/src/metrics/types.rs (2)
  • value (73-73)
  • value (81-86)
magicblock-api/src/tickers.rs (1)
  • set_accounts_count (152-159)
magicblock-committor-service/src/intent_executor/mod.rs (7)
magicblock-rpc-client/src/lib.rs (4)
  • error (193-195)
  • signature (82-90)
  • new (235-237)
  • from (228-230)
magicblock-rpc-client/src/utils.rs (5)
  • decide_rpc_error_flow (176-201)
  • map_magicblock_client_error (93-141)
  • send_transaction_with_retries (34-71)
  • map (13-13)
  • decide_flow (14-16)
magicblock-committor-service/src/intent_executor/error.rs (4)
  • signature (29-34)
  • value (105-112)
  • from (129-131)
  • from (215-220)
magicblock-metrics/src/metrics/types.rs (2)
  • value (73-73)
  • value (81-86)
magicblock-committor-service/src/intent_executor/task_info_fetcher.rs (7)
  • Self (298-306)
  • Self (308-316)
  • new (63-75)
  • pubkeys (159-170)
  • pubkeys (216-219)
  • fetch_rent_reimbursements (39-42)
  • fetch_rent_reimbursements (338-353)
magicblock-committor-service/src/tasks/task_builder.rs (7)
  • commit_tasks (48-53)
  • commit_tasks (70-164)
  • finalize_task (173-190)
  • accounts (105-108)
  • accounts (312-315)
  • finalize_tasks (56-60)
  • finalize_tasks (167-377)
magicblock-committor-service/src/intent_execution_manager/intent_execution_engine.rs (4)
  • None (391-391)
  • new (78-95)
  • new (671-677)
  • fetch_rent_reimbursements (790-795)
magicblock-committor-service/src/intent_executor/error.rs (6)
magicblock-rpc-client/src/lib.rs (3)
  • error (193-195)
  • signature (82-90)
  • from (228-230)
magicblock-committor-service/src/intent_executor/mod.rs (1)
  • value (75-83)
magicblock-committor-service/src/types.rs (1)
  • value (23-29)
magicblock-metrics/src/metrics/types.rs (2)
  • value (73-73)
  • value (81-86)
magicblock-committor-service/src/transaction_preparator/delivery_preparator.rs (2)
  • from (542-546)
  • try_map (333-349)
magicblock-rpc-client/src/utils.rs (1)
  • try_map (84-88)
🪛 actionlint (1.7.8)
.github/workflows/ci-test-integration.yml

16-16: label "extra-large" is unknown. available labels are "windows-latest", "windows-latest-8-cores", "windows-2025", "windows-2022", "windows-11-arm", "ubuntu-latest", "ubuntu-latest-4-cores", "ubuntu-latest-8-cores", "ubuntu-latest-16-cores", "ubuntu-24.04", "ubuntu-24.04-arm", "ubuntu-22.04", "ubuntu-22.04-arm", "macos-latest", "macos-latest-xl", "macos-latest-xlarge", "macos-latest-large", "macos-26-xlarge", "macos-26", "macos-15-intel", "macos-15-xlarge", "macos-15-large", "macos-15", "macos-14-xl", "macos-14-xlarge", "macos-14-large", "macos-14", "macos-13-xl", "macos-13-xlarge", "macos-13-large", "macos-13", "self-hosted", "x64", "arm", "arm64", "linux", "macos", "windows". if it is a custom label for self-hosted runner, set list of labels in actionlint.yaml config file

(runner-label)


52-52: label "extra-large" is unknown. available labels are "windows-latest", "windows-latest-8-cores", "windows-2025", "windows-2022", "windows-11-arm", "ubuntu-latest", "ubuntu-latest-4-cores", "ubuntu-latest-8-cores", "ubuntu-latest-16-cores", "ubuntu-24.04", "ubuntu-24.04-arm", "ubuntu-22.04", "ubuntu-22.04-arm", "macos-latest", "macos-latest-xl", "macos-latest-xlarge", "macos-latest-large", "macos-26-xlarge", "macos-26", "macos-15-intel", "macos-15-xlarge", "macos-15-large", "macos-15", "macos-14-xl", "macos-14-xlarge", "macos-14-large", "macos-14", "macos-13-xl", "macos-13-xlarge", "macos-13-large", "macos-13", "self-hosted", "x64", "arm", "arm64", "linux", "macos", "windows". if it is a custom label for self-hosted runner, set list of labels in actionlint.yaml config file

(runner-label)

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

Caution

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

⚠️ Outside diff range comments (5)
magicblock-api/Cargo.toml (1)

13-13: Critical: Borsh version fragmentation in workspace.

Line 13 directly pins borsh = "1.5.3", but the workspace root (Cargo.toml line 58) specifies borsh = "0.10.4". This creates two incompatible borsh versions in the same workspace, breaking crate interoperability. Additionally, the workspace borsh-derive is 1.5.1, which doesn't match either version properly.

Required fix: Either align magicblock-api to use workspace borsh 0.10.4 (by changing line 13 to borsh = { workspace = true }), or align the entire workspace to borsh 1.5.x and update borsh-derive accordingly. Choose one major version series consistently across all files.

Also applies to: 18-18, 42-42

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

71-105: Compressed commit task construction moves accounts and can panic on fetch failure

In commit_tasks, the compressed branch has two problems:

  1. Ownership bugfor account in accounts { ... } moves accounts (a Vec<_>), so the subsequent accounts.iter().zip(compressed_results) will not compile.
  2. Panic on compressed data failurecompressed_results is a Vec<Result<CompressedData, TaskBuilderError>>, but you later do compressed_data.expect("Compressed commit task must be provided with compressed data"), which will panic instead of returning a TaskBuilderError when get_compressed_data fails.

Both should be handled by iterating over &accounts and propagating errors instead of panicking. For example:

-        let tasks = if compressed {
-            // For compressed accounts, prepare compression data
-            let photon_client = photon_client
-                .as_ref()
-                .ok_or(TaskBuilderError::PhotonClientNotFound)?;
-            let mut compressed_results = vec![];
-            for account in accounts {
-                compressed_results.push(
-                    get_compressed_data(&account.pubkey, photon_client).await,
-                );
-            }
-
-            accounts.iter().zip(compressed_results).map(|(account, compressed_data)| {
-                let commit_id = *commit_ids.get(&account.pubkey).expect("CommitIdFetcher provide commit ids for all listed pubkeys, or errors!");
-                let compressed_data = compressed_data.expect("Compressed commit task must be provided with compressed data");
-                let task = ArgsTaskType::CompressedCommit(CompressedCommitTask {
-                    commit_id,
-                    allow_undelegation,
-                    committed_account: account.clone(),
-                    compressed_data
-                });
-                Box::new(ArgsTask::new(task)) as Box<dyn BaseTask>
-            })
-            .collect()
-        } else {
+        let tasks = if compressed {
+            // For compressed accounts, prepare compression data
+            let photon_client = photon_client
+                .as_ref()
+                .ok_or(TaskBuilderError::PhotonClientNotFound)?;
+
+            let mut tasks: Vec<Box<dyn BaseTask>> =
+                Vec::with_capacity(accounts.len());
+            for account in &accounts {
+                let commit_id = *commit_ids.get(&account.pubkey).expect(
+                    "CommitIdFetcher provide commit ids for all listed pubkeys, or errors!",
+                );
+                let compressed_data =
+                    get_compressed_data(&account.pubkey, photon_client).await?;
+                let task = ArgsTaskType::CompressedCommit(CompressedCommitTask {
+                    commit_id,
+                    allow_undelegation,
+                    committed_account: account.clone(),
+                    compressed_data,
+                });
+                tasks.push(Box::new(ArgsTask::new(task)) as Box<dyn BaseTask>);
+            }
+            tasks
+        } else {
             accounts
                 .iter()
                 .map(|account| {
                     let commit_id =
                         *commit_ids.get(&account.pubkey).expect("CommitIdFetcher provide commit ids for all listed pubkeys, or errors!");
                     let task = ArgsTaskType::Commit(CommitTask {
                         commit_id,
                         allow_undelegation,
                         committed_account: account.clone(),
                     });
                     Box::new(ArgsTask::new(task)) as Box<dyn BaseTask>
                 })
                 .collect()
         };

This keeps accounts borrowed, avoids the move, and uses ? so compressed data fetch failures surface as TaskBuilderError instead of panicking.

Also applies to: 124-162


168-291: Finalize path silently downgrades compressed intents to non‑compressed finalize on fetch failure

In finalize_tasks:

  • process_commit’s compressed branches invoke get_compressed_data(...).await.ok(), turning Result<CompressedData, TaskBuilderError> into Option<CompressedData>.
  • finalize_task then receives compressed_data: Option<CompressedData> and falls back to the non‑compressed FinalizeTask when None.

This means a compressed commit intent will be finalized via the non‑compressed DLP instruction if compressed data fetch fails (or Photon is temporarily unavailable), which is likely inconsistent with how compressed delegations are supposed to be closed out, and it hides the root cause.

Consider one of the following:

  • Prefer strict behavior: propagate TaskBuilderError on get_compressed_data failure so compressed finalize fails loudly, aligning with the commit path, e.g.:
-                    let mut compressed_data = vec![];
-                    let photon_client = photon_client
-                        .as_ref()
-                        .ok_or(TaskBuilderError::PhotonClientNotFound)?;
-                    for account in committed_accounts {
-                        compressed_data.push(
-                            get_compressed_data(&account.pubkey, photon_client)
-                                .await
-                                .ok(),
-                        );
-                    }
-
-                    Ok(committed_accounts
-                        .iter()
-                        .zip(compressed_data)
-                        .map(|(account, compressed_data)| {
-                            finalize_task(account, compressed_data)
-                        })
-                        .collect())
+                    let photon_client = photon_client
+                        .as_ref()
+                        .ok_or(TaskBuilderError::PhotonClientNotFound)?;
+                    let mut tasks = Vec::with_capacity(committed_accounts.len());
+                    for account in committed_accounts {
+                        let compressed_data =
+                            get_compressed_data(&account.pubkey, photon_client)
+                                .await?;
+                        tasks.push(finalize_task(
+                            account,
+                            Some(compressed_data),
+                        ));
+                    }
+                    Ok(tasks)

…and similarly for the WithBaseActions branch.

  • Or, if downgrade is intentional: at least log/metric the failure when get_compressed_data returns Err, so operators can see when compressed paths are failing and being converted to non‑compressed finalize.

Right now the error is completely swallowed, which makes debugging and monitoring compressed flows hard and could mask real consistency issues.


381-455: get_compressed_data assumes non‑empty packed_tree_infos and can panic

get_compressed_data does good work surfacing most failure modes as TaskBuilderError, but:

let packed_tree_accounts = proof_result
    .pack_tree_infos(&mut remaining_accounts)
    .state_trees
    .ok_or(TaskBuilderError::MissingStateTrees)?;
let account_meta = CompressedAccountMeta {
    tree_info: packed_tree_accounts.packed_tree_infos[0],
    // ...
};

This will panic with an out‑of‑bounds access if packed_tree_infos is empty even when state_trees is Some(_). To keep failure modes consistent with the rest of the function, consider:

  • Checking packed_tree_accounts.packed_tree_infos.first() and returning a dedicated error (e.g., reusing MissingStateTrees or adding a more specific variant) instead of indexing blindly, or
  • At least adding a debug assertion and comment if the light‑client API guarantees at least one entry here.

That will avoid a hard panic in the face of unexpected or malformed proofs.

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

349-405: Use strategy.compressed instead of recomputing and clean up stale TODO

In handle_commit_id_error (and related helpers) you now track compressed on TransactionStrategy and propagate it:

let commit_ids = self
    .task_info_fetcher
    .fetch_next_commit_ids(
        committed_pubkeys,
        // TODO(dode): Handle cases where some tasks are compressed and some are not
        strategy
            .optimized_tasks
            .iter()
            .any(|task| task.is_compressed()),
    )
    .await?;
...
TransactionStrategy {
    optimized_tasks: to_cleanup,
    lookup_tables_keys: old_alts,
    compressed: strategy.compressed,
}

Given the new TaskStrategistError::InconsistentTaskCompression and the fact that TransactionStrategy already carries a compressed flag, mixed compressed/non‑compressed task sets should now be rejected earlier. Recomputing compression with .any(|task.is_compressed()) plus a TODO is both redundant and potentially misleading.

I’d suggest:

  • Replace the .any(|task.is_compressed()) with strategy.compressed, and
  • Remove or reword the TODO to reflect that inconsistent compression is now handled by TaskStrategist.
-        let commit_ids = self
-            .task_info_fetcher
-            .fetch_next_commit_ids(
-                committed_pubkeys,
-                // TODO(dode): Handle cases where some tasks are compressed and some are not
-                strategy
-                    .optimized_tasks
-                    .iter()
-                    .any(|task| task.is_compressed()),
-            )
+        let commit_ids = self
+            .task_info_fetcher
+            .fetch_next_commit_ids(committed_pubkeys, strategy.compressed)

Same comment applies to other places where you construct new TransactionStrategy values: keeping compressed: strategy.compressed is good; relying on the field everywhere will make the invariant clearer.

Also applies to: 423-427, 457-482

♻️ Duplicate comments (2)
magicblock-api/src/magic_validator.rs (1)

402-414: Hard‑coded compression endpoint now diverges from configured Photon URL

init_chainlink still pushes an Endpoint::Compression with a baked‑in "http://127.0.0.1:8784" URL, while init_committor_service now uses compression_config.photon_url and compression_config.api_key to construct the PhotonIndexer. This creates two problems:

  1. The Chainlink/remote‑account side may talk to a different Photon instance than the committor if compression.photon_url is not http://127.0.0.1:8784.
  2. The compression endpoint is still not configurable at all from this code path, and configs that set a remote Photon URL won’t affect Chainlink here.

Recommend:

  • Drive the compression endpoint URL (and auth, if needed) from the same CompressionConfig used for the committor, or from a shared constant derived from config, and
  • Ensure you don’t end up with divergent Photon endpoints between committor and Chainlink.

This also keeps the earlier concern about the hard‑coded URL applicable.

-        // TODO: @@@ HACK, make this configurable
-        endpoints.push(Endpoint::Compression {
-            url: "http://127.0.0.1:8784".to_string(),
-        });
+        // TODO: @@@ HACK, make this configurable
+        endpoints.push(Endpoint::Compression {
+            url: config.compression.photon_url.clone(),
+        });
test-integration/test-committor-service/tests/common.rs (1)

185-213: create_compressed_commit_task builds placeholder compressed data – ensure usage stays preparator-only

This helper intentionally sets compressed_delegation_record_bytes to vec![] and uses default CompressedAccountMeta/ValidityProof, relying on later preparation (e.g., via Photon-backed prepare_task) to populate real compressed delegation data. That’s fine for the current tests, but it would be invalid if any path tried to submit these tasks on-chain without running through the preparator first; consider documenting that expectation at the call sites or in the helper’s comment to prevent future misuse.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 397b9b3 and c9848de.

⛔ Files ignored due to path filters (2)
  • Cargo.lock is excluded by !**/*.lock
  • test-integration/Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (35)
  • Cargo.toml (6 hunks)
  • magicblock-api/Cargo.toml (2 hunks)
  • magicblock-api/src/magic_validator.rs (8 hunks)
  • magicblock-chainlink/src/testing/mod.rs (1 hunks)
  • magicblock-chainlink/tests/07_redeleg_us_same_slot.rs (2 hunks)
  • magicblock-committor-program/src/instruction_builder/close_buffer.rs (2 hunks)
  • magicblock-committor-program/src/instruction_builder/init_buffer.rs (2 hunks)
  • magicblock-committor-program/src/instruction_builder/realloc_buffer.rs (2 hunks)
  • magicblock-committor-program/src/instruction_builder/write_buffer.rs (2 hunks)
  • magicblock-committor-service/Cargo.toml (1 hunks)
  • magicblock-committor-service/src/committor_processor.rs (3 hunks)
  • magicblock-committor-service/src/intent_execution_manager.rs (2 hunks)
  • magicblock-committor-service/src/intent_execution_manager/intent_execution_engine.rs (4 hunks)
  • magicblock-committor-service/src/intent_executor/error.rs (7 hunks)
  • magicblock-committor-service/src/intent_executor/intent_executor_factory.rs (3 hunks)
  • magicblock-committor-service/src/intent_executor/mod.rs (28 hunks)
  • magicblock-committor-service/src/service.rs (5 hunks)
  • magicblock-committor-service/src/tasks/task_builder.rs (7 hunks)
  • magicblock-committor-service/src/tasks/task_strategist.rs (6 hunks)
  • magicblock-committor-service/src/transaction_preparator/error.rs (2 hunks)
  • magicblock-committor-service/src/types.rs (2 hunks)
  • magicblock-config/src/compression.rs (1 hunks)
  • magicblock-config/src/lib.rs (8 hunks)
  • magicblock-config/tests/fixtures/11_everything-defined.toml (1 hunks)
  • magicblock-config/tests/parse_config.rs (3 hunks)
  • magicblock-config/tests/read_config.rs (4 hunks)
  • programs/magicblock/src/magicblock_processor.rs (4 hunks)
  • programs/magicblock/src/mutate_accounts/process_mutate_accounts.rs (4 hunks)
  • programs/magicblock/src/utils/instruction_utils.rs (4 hunks)
  • test-integration/Cargo.toml (3 hunks)
  • test-integration/schedulecommit/test-scenarios/Cargo.toml (1 hunks)
  • test-integration/schedulecommit/test-scenarios/tests/01_commits.rs (2 hunks)
  • test-integration/test-committor-service/tests/common.rs (7 hunks)
  • test-integration/test-committor-service/tests/test_delivery_preparator.rs (8 hunks)
  • test-integration/test-committor-service/tests/test_intent_executor.rs (16 hunks)
🧰 Additional context used
🧠 Learnings (20)
📓 Common learnings
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.681Z
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.
📚 Learning: 2025-11-19T09:34:37.890Z
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.890Z
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:

  • magicblock-committor-program/src/instruction_builder/realloc_buffer.rs
  • magicblock-committor-program/src/instruction_builder/write_buffer.rs
  • magicblock-committor-program/src/instruction_builder/close_buffer.rs
  • magicblock-chainlink/tests/07_redeleg_us_same_slot.rs
  • magicblock-committor-program/src/instruction_builder/init_buffer.rs
  • test-integration/test-committor-service/tests/common.rs
  • magicblock-api/src/magic_validator.rs
  • test-integration/schedulecommit/test-scenarios/tests/01_commits.rs
  • test-integration/test-committor-service/tests/test_delivery_preparator.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-program/src/instruction_builder/realloc_buffer.rs
  • magicblock-committor-program/src/instruction_builder/close_buffer.rs
  • magicblock-chainlink/tests/07_redeleg_us_same_slot.rs
  • magicblock-committor-program/src/instruction_builder/init_buffer.rs
  • magicblock-api/src/magic_validator.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:

  • magicblock-committor-program/src/instruction_builder/realloc_buffer.rs
  • magicblock-committor-program/src/instruction_builder/write_buffer.rs
  • magicblock-committor-service/src/types.rs
  • magicblock-committor-program/src/instruction_builder/close_buffer.rs
  • magicblock-chainlink/tests/07_redeleg_us_same_slot.rs
  • magicblock-committor-program/src/instruction_builder/init_buffer.rs
  • magicblock-committor-service/src/tasks/task_builder.rs
  • test-integration/test-committor-service/tests/common.rs
  • Cargo.toml
  • programs/magicblock/src/mutate_accounts/process_mutate_accounts.rs
  • magicblock-api/src/magic_validator.rs
  • test-integration/schedulecommit/test-scenarios/tests/01_commits.rs
  • magicblock-api/Cargo.toml
  • test-integration/test-committor-service/tests/test_delivery_preparator.rs
  • magicblock-config/tests/parse_config.rs
  • magicblock-chainlink/src/testing/mod.rs
  • programs/magicblock/src/utils/instruction_utils.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-committor-program/src/instruction_builder/realloc_buffer.rs
  • magicblock-committor-service/src/intent_execution_manager/intent_execution_engine.rs
  • test-integration/schedulecommit/test-scenarios/tests/01_commits.rs
  • test-integration/test-committor-service/tests/test_intent_executor.rs
  • test-integration/test-committor-service/tests/test_delivery_preparator.rs
  • programs/magicblock/src/magicblock_processor.rs
📚 Learning: 2025-10-28T13:15:42.706Z
Learnt from: bmuddha
Repo: magicblock-labs/magicblock-validator PR: 596
File: magicblock-processor/src/scheduler.rs:1-1
Timestamp: 2025-10-28T13:15:42.706Z
Learning: In magicblock-processor, transaction indexes were always set to 0 even before the changes in PR #596. The proper transaction indexing within slots will be addressed during the planned ledger rewrite.

Applied to files:

  • magicblock-committor-program/src/instruction_builder/realloc_buffer.rs
  • magicblock-committor-program/src/instruction_builder/write_buffer.rs
  • magicblock-committor-program/src/instruction_builder/close_buffer.rs
  • magicblock-chainlink/tests/07_redeleg_us_same_slot.rs
  • magicblock-committor-program/src/instruction_builder/init_buffer.rs
  • Cargo.toml
  • magicblock-chainlink/src/testing/mod.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:

  • magicblock-committor-program/src/instruction_builder/realloc_buffer.rs
  • magicblock-committor-program/src/instruction_builder/write_buffer.rs
  • magicblock-committor-program/src/instruction_builder/close_buffer.rs
  • magicblock-chainlink/tests/07_redeleg_us_same_slot.rs
  • magicblock-committor-program/src/instruction_builder/init_buffer.rs
  • Cargo.toml
  • magicblock-config/tests/parse_config.rs
  • magicblock-chainlink/src/testing/mod.rs
📚 Learning: 2025-10-26T16:54:39.084Z
Learnt from: thlorenz
Repo: magicblock-labs/magicblock-validator PR: 587
File: test-manual/Cargo.toml:0-0
Timestamp: 2025-10-26T16:54:39.084Z
Learning: In the magicblock-validator repository, use git branch references (not commit hashes or tags) for the helius-laserstream dependency to allow automatic updates when the branch is pushed to.

Applied to files:

  • magicblock-committor-program/src/instruction_builder/realloc_buffer.rs
  • magicblock-committor-program/src/instruction_builder/write_buffer.rs
  • magicblock-committor-program/src/instruction_builder/close_buffer.rs
  • magicblock-chainlink/tests/07_redeleg_us_same_slot.rs
  • magicblock-committor-program/src/instruction_builder/init_buffer.rs
  • Cargo.toml
  • magicblock-chainlink/src/testing/mod.rs
📚 Learning: 2025-11-04T13:22:38.811Z
Learnt from: bmuddha
Repo: magicblock-labs/magicblock-validator PR: 589
File: magicblock-aperture/src/requests/http/get_fee_for_message.rs:25-31
Timestamp: 2025-11-04T13:22:38.811Z
Learning: In magicblock-aperture, request size validation (including limits on message size) is enforced at the request ingestion layer, before handlers like get_fee_for_message are invoked. Therefore, handlers do not need additional size guards on decoded data.

Applied to files:

  • magicblock-committor-program/src/instruction_builder/realloc_buffer.rs
  • magicblock-committor-program/src/instruction_builder/write_buffer.rs
  • magicblock-committor-program/src/instruction_builder/close_buffer.rs
  • magicblock-chainlink/tests/07_redeleg_us_same_slot.rs
  • magicblock-committor-program/src/instruction_builder/init_buffer.rs
  • Cargo.toml
  • magicblock-chainlink/src/testing/mod.rs
📚 Learning: 2025-10-21T11:00:18.396Z
Learnt from: bmuddha
Repo: magicblock-labs/magicblock-validator PR: 578
File: magicblock-aperture/src/encoder.rs:176-187
Timestamp: 2025-10-21T11:00:18.396Z
Learning: In the magicblock validator, the current slot is always the root slot. The SlotEncoder in magicblock-aperture/src/encoder.rs correctly sets `root: slot` because there is no lag between current and root slots in this architecture.

Applied to files:

  • magicblock-committor-program/src/instruction_builder/realloc_buffer.rs
  • magicblock-committor-program/src/instruction_builder/write_buffer.rs
  • magicblock-committor-program/src/instruction_builder/close_buffer.rs
  • magicblock-chainlink/tests/07_redeleg_us_same_slot.rs
  • magicblock-committor-program/src/instruction_builder/init_buffer.rs
  • magicblock-chainlink/src/testing/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-program/src/instruction_builder/realloc_buffer.rs
  • magicblock-committor-program/src/instruction_builder/write_buffer.rs
  • magicblock-committor-program/src/instruction_builder/close_buffer.rs
  • magicblock-committor-program/src/instruction_builder/init_buffer.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/types.rs
📚 Learning: 2025-11-18T08:47:39.681Z
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.681Z
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:

  • magicblock-chainlink/tests/07_redeleg_us_same_slot.rs
  • test-integration/test-committor-service/tests/common.rs
  • programs/magicblock/src/mutate_accounts/process_mutate_accounts.rs
  • magicblock-api/src/magic_validator.rs
  • test-integration/test-committor-service/tests/test_delivery_preparator.rs
  • programs/magicblock/src/utils/instruction_utils.rs
📚 Learning: 2025-10-21T10:34:59.140Z
Learnt from: bmuddha
Repo: magicblock-labs/magicblock-validator PR: 578
File: magicblock-accounts-db/src/lib.rs:63-72
Timestamp: 2025-10-21T10:34:59.140Z
Learning: In magicblock-validator, the AccountsDb "stop-the-world" synchronizer is managed at the processor/executor level, not at the AccountsDb API level. Transaction executors in magicblock-processor hold a read lock (sync.read()) for the duration of each slot and release it only at slot boundaries, ensuring all account writes happen under the read lock. Snapshot operations acquire a write lock, blocking until all executors release their read locks. This pattern ensures mutual exclusion between writes and snapshots without requiring read guards in AccountsDb write APIs.

Applied to files:

  • magicblock-chainlink/tests/07_redeleg_us_same_slot.rs
  • magicblock-chainlink/src/testing/mod.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/common.rs
  • test-integration/schedulecommit/test-scenarios/tests/01_commits.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:

  • programs/magicblock/src/mutate_accounts/process_mutate_accounts.rs
📚 Learning: 2025-10-26T16:53:29.820Z
Learnt from: thlorenz
Repo: magicblock-labs/magicblock-validator PR: 587
File: magicblock-chainlink/src/remote_account_provider/mod.rs:134-0
Timestamp: 2025-10-26T16:53:29.820Z
Learning: In magicblock-chainlink/src/remote_account_provider/mod.rs, the `Endpoint::separate_pubsub_url_and_api_key()` method uses `split_once("?api-key=")` because the api-key parameter is always the only query parameter right after `?`. No additional query parameter parsing is needed for this use case.

Applied to files:

  • magicblock-api/src/magic_validator.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-committor-service/src/committor_processor.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/committor_processor.rs
📚 Learning: 2025-10-26T08:49:31.543Z
Learnt from: taco-paco
Repo: magicblock-labs/magicblock-validator PR: 585
File: magicblock-committor-service/src/tasks/buffer_task.rs:111-115
Timestamp: 2025-10-26T08:49:31.543Z
Learning: In the magicblock-committor-service, compute units returned by the `compute_units()` method in task implementations (such as `BufferTask`, `ArgsTask`, etc.) represent the compute budget for a single task. Transactions can comprise multiple tasks, and the total compute budget for a transaction is computed as the sum of the compute units of all tasks included in that transaction.

Applied to files:

  • magicblock-committor-service/src/intent_executor/mod.rs
🧬 Code graph analysis (17)
magicblock-committor-service/src/intent_execution_manager.rs (2)
magicblock-committor-service/src/intent_executor/task_info_fetcher.rs (3)
  • Self (298-306)
  • Self (308-316)
  • new (63-75)
magicblock-committor-service/src/intent_executor/mod.rs (1)
  • new (111-125)
magicblock-committor-service/src/types.rs (3)
magicblock-committor-service/src/intent_executor/error.rs (1)
  • value (107-114)
magicblock-committor-service/src/intent_executor/mod.rs (1)
  • value (76-84)
magicblock-metrics/src/metrics/types.rs (2)
  • value (73-73)
  • value (81-86)
magicblock-config/src/lib.rs (1)
magicblock-config/src/compression.rs (1)
  • default (24-29)
magicblock-chainlink/tests/07_redeleg_us_same_slot.rs (2)
magicblock-chainlink/src/testing/rpc_client_mock.rs (2)
  • accounts (95-101)
  • slot (66-72)
magicblock-chainlink/tests/utils/accounts.rs (2)
  • compressed_account_shared_with_owner_and_slot (22-47)
  • account_shared_with_owner_and_slot (12-20)
magicblock-committor-service/src/tasks/task_builder.rs (6)
magicblock-committor-service/src/tasks/buffer_task.rs (5)
  • instruction (68-89)
  • new (38-46)
  • get_compressed_data (157-161)
  • task_type (125-129)
  • is_compressed (146-148)
magicblock-committor-service/src/tasks/args_task.rs (6)
  • instruction (51-152)
  • new (42-47)
  • get_compressed_data (267-280)
  • task_type (216-228)
  • is_compressed (243-250)
  • from (36-38)
magicblock-committor-service/src/tasks/mod.rs (5)
  • instruction (68-68)
  • instruction (304-310)
  • get_compressed_data (105-105)
  • task_type (93-93)
  • is_compressed (99-99)
magicblock-core/src/compression/mod.rs (1)
  • derive_cda_from_pda (10-22)
magicblock-committor-service/src/intent_executor/mod.rs (1)
  • new (111-125)
magicblock-committor-service/src/intent_executor/task_info_fetcher.rs (1)
  • new (63-75)
magicblock-committor-service/src/intent_executor/error.rs (5)
magicblock-rpc-client/src/lib.rs (3)
  • error (193-195)
  • from (228-230)
  • signature (82-90)
magicblock-committor-service/src/transaction_preparator/error.rs (1)
  • from (21-29)
magicblock-committor-service/src/transaction_preparator/delivery_preparator.rs (2)
  • from (542-546)
  • try_map (333-349)
magicblock-metrics/src/metrics/types.rs (2)
  • value (73-73)
  • value (81-86)
magicblock-rpc-client/src/utils.rs (1)
  • try_map (84-88)
test-integration/test-committor-service/tests/common.rs (5)
magicblock-committor-service/src/intent_executor/mod.rs (1)
  • new (111-125)
magicblock-committor-service/src/intent_execution_manager.rs (1)
  • new (36-72)
magicblock-committor-service/src/intent_executor/task_info_fetcher.rs (1)
  • new (63-75)
test-integration/test-committor-service/tests/test_delivery_preparator.rs (15)
  • None (53-53)
  • None (54-54)
  • None (126-126)
  • None (127-127)
  • None (210-210)
  • None (211-211)
  • None (251-251)
  • None (252-252)
  • None (292-292)
  • None (293-293)
  • None (361-361)
  • None (362-362)
  • None (462-462)
  • None (463-463)
  • None (548-548)
test-integration/test-committor-service/tests/test_intent_executor.rs (1)
  • None (148-148)
programs/magicblock/src/mutate_accounts/process_mutate_accounts.rs (1)
magicblock-chainlink/src/remote_account_provider/remote_account.rs (1)
  • compressed (154-156)
magicblock-committor-service/src/intent_execution_manager/intent_execution_engine.rs (2)
magicblock-metrics/src/metrics/mod.rs (2)
  • observe_committor_intent_execution_time_histogram (383-391)
  • inc_committor_failed_intents_count (370-377)
programs/magicblock/src/magic_scheduled_base_intent.rs (2)
  • get_committed_pubkeys (97-99)
  • get_committed_pubkeys (198-202)
magicblock-api/src/magic_validator.rs (2)
magicblock-chainlink/src/remote_account_provider/photon_client.rs (1)
  • new (27-29)
magicblock-chainlink/src/remote_account_provider/mod.rs (1)
  • new (212-256)
magicblock-committor-service/src/intent_executor/mod.rs (3)
magicblock-rpc-client/src/utils.rs (5)
  • decide_rpc_error_flow (176-201)
  • map_magicblock_client_error (93-141)
  • send_transaction_with_retries (34-71)
  • map (13-13)
  • decide_flow (14-16)
magicblock-committor-service/src/intent_executor/task_info_fetcher.rs (7)
  • Self (298-306)
  • Self (308-316)
  • new (63-75)
  • pubkeys (159-170)
  • pubkeys (216-219)
  • fetch_rent_reimbursements (39-42)
  • fetch_rent_reimbursements (338-353)
magicblock-committor-service/src/tasks/task_builder.rs (7)
  • commit_tasks (49-54)
  • commit_tasks (71-165)
  • finalize_task (174-191)
  • accounts (106-109)
  • accounts (313-316)
  • finalize_tasks (57-61)
  • finalize_tasks (168-378)
test-integration/schedulecommit/test-scenarios/tests/01_commits.rs (3)
test-integration/programs/schedulecommit/src/api.rs (4)
  • delegate_account_cpi_instruction (58-91)
  • init_account_instruction (15-33)
  • pda_and_bump (263-267)
  • schedule_commit_cpi_instruction (104-122)
test-integration/test-tools/src/integration_test_context.rs (3)
  • signature (63-65)
  • try_new (113-115)
  • airdrop_chain (483-494)
test-integration/schedulecommit/test-scenarios/tests/utils/mod.rs (1)
  • extract_transaction_error (255-264)
magicblock-config/src/compression.rs (2)
magicblock-config-macro/src/lib.rs (2)
  • clap_from_serde (153-163)
  • clap_prefix (44-58)
magicblock-config/src/lib.rs (3)
  • test_merge_with_default (203-291)
  • test_merge_default_with_non_default (294-381)
  • test_merge_non_default (384-552)
magicblock-committor-service/src/tasks/task_strategist.rs (2)
magicblock-committor-service/src/intent_executor/task_info_fetcher.rs (2)
  • Self (298-306)
  • Self (308-316)
magicblock-chainlink/src/remote_account_provider/remote_account.rs (1)
  • compressed (154-156)
test-integration/test-committor-service/tests/test_intent_executor.rs (3)
magicblock-committor-service/src/intent_executor/mod.rs (1)
  • new (111-125)
magicblock-committor-service/src/intent_execution_manager.rs (1)
  • new (36-72)
magicblock-committor-service/src/tasks/task_builder.rs (2)
  • finalize_tasks (57-61)
  • finalize_tasks (168-378)
test-integration/test-committor-service/tests/test_delivery_preparator.rs (3)
test-integration/test-committor-service/tests/common.rs (4)
  • create_commit_task (167-183)
  • create_compressed_commit_task (186-213)
  • generate_random_bytes (159-164)
  • new (63-66)
test-integration/test-committor-service/tests/utils/transactions.rs (1)
  • init_and_delegate_compressed_account_on_chain (233-322)
magicblock-committor-service/src/tasks/mod.rs (5)
  • cleanup_task (289-294)
  • buffer_pda (280-287)
  • buffer_pda (331-338)
  • chunks_pda (271-278)
  • chunks_pda (322-329)
programs/magicblock/src/magicblock_processor.rs (1)
programs/magicblock/src/schedule_transactions/process_schedule_commit.rs (2)
  • process_schedule_commit (34-40)
  • process_schedule_compressed_commit (42-48)

Comment on lines 141 to 151
let compressed_account = compressed_account_shared_with_owner_and_slot(
pubkey,
ctx.validator_pubkey,
program_pubkey,
slot,
);
photon_client.add_account(
pubkey,
compressed_account.clone().into(),
slot,
);
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 | 🟠 Major

Also set remote_slot on compressed accounts before adding to photon_client

In both the seeding and redelegation steps, the compressed delegation record’s delegation_slot is set via compressed_account_shared_with_owner_and_slot(...), but the AccountSharedData.remote_slot is left at its default. Per prior compressed-account tests, both fields should advance together so slot-based logic sees the update correctly. Based on learnings

-        let compressed_account = compressed_account_shared_with_owner_and_slot(
+        let mut compressed_account = compressed_account_shared_with_owner_and_slot(
             pubkey,
             ctx.validator_pubkey,
             program_pubkey,
             slot,
         );
-        photon_client.add_account(
+        compressed_account.set_remote_slot(slot);
+
+        photon_client.add_account(
             pubkey,
             compressed_account.clone().into(),
             slot,
         );
@@
-        let compressed_account = compressed_account_shared_with_owner_and_slot(
+        let mut compressed_account = compressed_account_shared_with_owner_and_slot(
             pubkey,
             ctx.validator_pubkey,
             program_pubkey,
             slot,
         );
-        photon_client.add_account(
+        compressed_account.set_remote_slot(slot);
+
+        photon_client.add_account(
             pubkey,
             compressed_account.clone().into(),
             slot,
         );

Also applies to: 178-188

🤖 Prompt for AI Agents
In magicblock-chainlink/tests/07_redeleg_us_same_slot.rs around lines 141-151
(and also apply the same change at 178-188), the compressed account is created
with the delegation_slot set but AccountSharedData.remote_slot is left at its
default; before calling photon_client.add_account, set the compressed account's
remote_slot to the same slot (i.e., assign remote_slot = slot or call the
account setter that updates remote_slot) so the remote_slot advances in tandem
with delegation_slot; do this in both the initial seeding block and the
redelegation block so slot-based logic observes the update correctly.

@@ -1,3 +1,4 @@
use borsh::BorshSerialize;
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

Write instruction serialization is correct; consider a small helper to dedupe pattern

The move to Instruction::new_with_bytes using ix.try_to_vec().expect(...) is consistent with the other builders and keeps semantics equivalent to the prior new_with_borsh path.

Given create_write_ix, create_close_ix, create_realloc_buffer_ix, and create_init_ix now all repeat the same new_with_bytes + try_to_vec().expect(...) sequence, you might consider a tiny helper like:

fn build_ix(
    program_id: Pubkey,
    ix: &impl BorshSerialize,
    accounts: Vec<AccountMeta>,
) -> Instruction {
    Instruction::new_with_bytes(
        program_id,
        &ix.try_to_vec()
            .expect("Serialization of instruction should never fail"),
        accounts,
    )
}

to reduce duplication and keep the panic message / serialization behavior centralized.

Also applies to: 51-56

🤖 Prompt for AI Agents
In magicblock-committor-program/src/instruction_builder/write_buffer.rs around
lines 1 and 51-56, multiple functions repeat the sequence
Instruction::new_with_bytes(..., &ix.try_to_vec().expect("Serialization of
instruction should never fail"), ...); extract that pattern into a small helper
(e.g., build_ix) that takes program_id, a reference to a BorshSerialize
instruction, and accounts, calls try_to_vec().expect(...) once, and returns
Instruction::new_with_bytes(...). Replace the repeated sequences in
create_write_ix, create_close_ix, create_realloc_buffer_ix, and create_init_ix
with calls to this helper so serialization behavior and panic message are
centralized.

executable: false,
data,
rent_epoch: u64::MAX,
rent_epoch: 0,
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 | 🟠 Major

🧩 Analysis chain

Verify authority account rent_epoch inconsistency.

The authority account assertion expects rent_epoch: 0, but other tests in this file expect rent_epoch: u64::MAX for the authority account (lines 440 and 551). Since the authority account is not being modified, its rent_epoch should remain at the value set by ensure_started_validator.

Run the following script to check the initialization behavior:


🏁 Script executed:

#!/bin/bash
# Description: Check ensure_started_validator and how it initializes authority rent_epoch

# Search for ensure_started_validator implementation
ast-grep --pattern 'fn ensure_started_validator($$$) {
  $$$
}'

# Search for authority account setup patterns
rg -n -A5 'ensure_started_validator'

Length of output: 8922


🏁 Script executed:

#!/bin/bash
# Check AccountSharedData::new implementation and default rent_epoch
rg -n -B2 -A10 'impl.*AccountSharedData' --type=rs

# Look at the specific assertions in the test file
rg -n -B5 -A5 'rent_epoch' programs/magicblock/src/mutate_accounts/process_mutate_accounts.rs

Length of output: 4779


🏁 Script executed:

#!/bin/bash
# Find test function definitions and their scope
rg -n 'fn test_' programs/magicblock/src/mutate_accounts/process_mutate_accounts.rs

# Look at the full test function containing line 360
sed -n '300,385p' programs/magicblock/src/mutate_accounts/process_mutate_accounts.rs

# Look at the full test function containing line 440
sed -n '385,475p' programs/magicblock/src/mutate_accounts/process_mutate_accounts.rs

# Look for any authority rent_epoch modifications
rg -n 'validator_authority_id\|authority.*rent_epoch' programs/magicblock/src/mutate_accounts/process_mutate_accounts.rs

Length of output: 5635


🏁 Script executed:

#!/bin/bash
# Get the full third test
sed -n '478,620p' programs/magicblock/src/mutate_accounts/process_mutate_accounts.rs

# Check if there's any code that sets authority rent_epoch to u64::MAX
rg -n 'set_rent_epoch.*MAX\|rent_epoch.*=.*MAX' programs/magicblock/src/mutate_accounts/

Length of output: 4581


🏁 Script executed:

#!/bin/bash
# Search for where rent_epoch might be modified to u64::MAX in the processor
rg -n 'u64::MAX' programs/magicblock/src/mutate_accounts/ -A2 -B2

# Look for process_instruction implementation
rg -n 'fn process_instruction' programs/magicblock/src/test_utils/mod.rs -A50 | head -100

Length of output: 5620


🏁 Script executed:

#!/bin/bash
# Search for the actual instruction processor implementation
find programs/magicblock/src -name "*.rs" -type f | xargs grep -l "process_mutate_accounts" | grep -v test

# Look for the mutate accounts processor code (not tests)
rg -n 'pub fn process_mutate_accounts' programs/magicblock/src/ -A 100 | head -150

Length of output: 161


🏁 Script executed:

#!/bin/bash
# Look at mod.rs for processor implementation
cat programs/magicblock/src/mutate_accounts/mod.rs

# Also check the file structure - get line counts
wc -l programs/magicblock/src/mutate_accounts/process_mutate_accounts.rs

Length of output: 282


🏁 Script executed:

#!/bin/bash
# View the processor implementation (first 300 lines)
sed -n '1,300p' programs/magicblock/src/mutate_accounts/process_mutate_accounts.rs

Length of output: 11114


Fix incorrect authority account rent_epoch assertions in tests.

The authority account is created identically in all three tests via ensure_started_validator() and is never modified by the processor. Therefore, all tests should expect the same rent_epoch value. Test test_mod_all_fields_of_one_account correctly asserts rent_epoch: 0, but test_mod_lamports_of_two_accounts (line 440) and test_mod_different_properties_of_four_accounts (line 551) incorrectly assert rent_epoch: u64::MAX. These should be changed to rent_epoch: 0 to match the actual authority account value set by ensure_started_validator().

🤖 Prompt for AI Agents
In programs/magicblock/src/mutate_accounts/process_mutate_accounts.rs around
lines 360, 440 and 551, the tests incorrectly expect different rent_epoch values
for the authority account; the authority is created by
ensure_started_validator() and never modified, so all tests should assert
rent_epoch: 0. Update the assertions in test_mod_lamports_of_two_accounts
(around line 440) and test_mod_different_properties_of_four_accounts (around
line 551) to use rent_epoch: 0 instead of rent_epoch: u64::MAX so they match
test_mod_all_fields_of_one_account and the actual account state.

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 (2)
magicblock-chainlink/src/remote_account_provider/mod.rs (2)

1235-1246: Use == 0 for unsigned integer zero-check in retry macro.

The condition remaining_retries <= 0 at line 1239 for a u64 is misleading since unsigned integers can never be negative. After the decrement, this effectively checks == 0, but the <= 0 reads as if negative values are possible.

🔎 Suggested fix
             macro_rules! retry {
                 ($msg:expr) => {{
                     trace!($msg);
                     remaining_retries -= 1;
-                    if remaining_retries <= 0 {
+                    if remaining_retries == 0 {
                         let err_msg = format!("Max retries {MAX_RETRIES} reached, giving up on fetching accounts: {pubkeys:?}");
                         notify_error(&err_msg);
                         return Err(RemoteAccountProviderError::FailedFetchingAccounts(err_msg));
                     }
                     tokio::time::sleep(Duration::from_millis(400)).await;
                     continue;
                 }};
             }

1200-1204: Consider adding explicit invariant comment for Mutex unwrap.

Line 1202 uses .unwrap() on fetching_accounts.lock(). Per coding guidelines, this should have proper error handling or explicit justification.

🔎 Suggested documentation
             let notify_error = |error_msg: &str| {
-                let mut fetching = fetching_accounts.lock().unwrap();
+                // INVARIANT: Mutex poisoning indicates a thread panicked while holding the lock,
+                // which is a critical bug. Panicking here is appropriate.
+                let mut fetching = fetching_accounts.lock().unwrap();
                 error!("{error_msg}");
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between db8d88b and c99cdbb.

⛔ Files ignored due to path filters (2)
  • Cargo.lock is excluded by !**/*.lock
  • test-integration/Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (2)
  • magicblock-chainlink/src/remote_account_provider/mod.rs
  • test-integration/test-chainlink/tests/ix_07_redeleg_us_same_slot.rs
🧰 Additional context used
📓 Path-based instructions (2)
{test-*,tools}/**

⚙️ CodeRabbit configuration file

Usage of .unwrap() or .expect() in test code is acceptable and may be treated as trivial.

Files:

  • test-integration/test-chainlink/tests/ix_07_redeleg_us_same_slot.rs
{magicblock-*,programs,storage-proto}/**

⚙️ CodeRabbit configuration file

{magicblock-*,programs,storage-proto}/**: Treat any usage of .unwrap() or .expect() in production Rust code as a MAJOR issue.
These should not be categorized as trivial or nit-level concerns.
Request proper error handling or explicit justification with invariants.

Files:

  • magicblock-chainlink/src/remote_account_provider/mod.rs
🧠 Learnings (17)
📓 Common learnings
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 639
File: test-integration/test-committor-service/tests/test_ix_commit_local.rs:867-881
Timestamp: 2025-12-03T09:33:48.707Z
Learning: Repo: magicblock-labs/magicblock-validator PR: 639
Context: test-integration/test-committor-service/tests/test_ix_commit_local.rs (ix_commit_local)
Learning: The PhotonIndexer used for compressed account fetches (get_compressed_account) has built‑in retry logic (defaults to ~10 attempts), so tests should not add separate retry loops around compressed fetches unless there’s a specific need.
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 639
File: test-integration/test-chainlink/tests/ix_01_ensure-accounts.rs:85-114
Timestamp: 2025-11-19T11:31:24.218Z
Learning: In the magicblock-validator codebase, compressed delegation records are never subscribed to by design. Tests for compressed delegation flows should focus on verifying that the delegated account (e.g., counter PDA) is cloned as delegated and not subscribed, but do not need to check for subscription to delegation-record-like PDAs in the compressed path because subscriptions to compressed delegation records never occur.
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 639
File: magicblock-committor-service/src/transaction_preparator/delivery_preparator.rs:172-193
Timestamp: 2025-11-26T13:27:46.702Z
Learning: The Photon indexer (PhotonIndexer from light-client) handles slot validation internally when an IndexerRpcConfig with a slot constraint is provided. Additional slot validation at the call site is not needed when fetching compressed data via get_compressed_data.
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.
📚 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-chainlink/tests/ix_07_redeleg_us_same_slot.rs
  • magicblock-chainlink/src/remote_account_provider/mod.rs
📚 Learning: 2025-12-03T09:33:48.707Z
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 639
File: test-integration/test-committor-service/tests/test_ix_commit_local.rs:867-881
Timestamp: 2025-12-03T09:33:48.707Z
Learning: Repo: magicblock-labs/magicblock-validator PR: 639
Context: test-integration/test-committor-service/tests/test_ix_commit_local.rs (ix_commit_local)
Learning: The PhotonIndexer used for compressed account fetches (get_compressed_account) has built‑in retry logic (defaults to ~10 attempts), so tests should not add separate retry loops around compressed fetches unless there’s a specific need.

Applied to files:

  • test-integration/test-chainlink/tests/ix_07_redeleg_us_same_slot.rs
  • magicblock-chainlink/src/remote_account_provider/mod.rs
📚 Learning: 2025-11-19T11:31:24.218Z
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 639
File: test-integration/test-chainlink/tests/ix_01_ensure-accounts.rs:85-114
Timestamp: 2025-11-19T11:31:24.218Z
Learning: In the magicblock-validator codebase, compressed delegation records are never subscribed to by design. Tests for compressed delegation flows should focus on verifying that the delegated account (e.g., counter PDA) is cloned as delegated and not subscribed, but do not need to check for subscription to delegation-record-like PDAs in the compressed path because subscriptions to compressed delegation records never occur.

Applied to files:

  • test-integration/test-chainlink/tests/ix_07_redeleg_us_same_slot.rs
  • magicblock-chainlink/src/remote_account_provider/mod.rs
📚 Learning: 2025-11-25T11:07:20.001Z
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 639
File: test-integration/programs/flexi-counter/src/processor.rs:643-680
Timestamp: 2025-11-25T11:07:20.001Z
Learning: In the compressed delegation architecture, ownership reassignment during undelegation is handled by the delegation program itself, not by the owner program's external undelegate handler. The external undelegate handler (e.g., `process_external_undelegate_compressed` in flexi-counter) is a callback for program-specific cleanup (restoring lamports and data) after the delegation program has already reassigned ownership back to the original owner stored in the CompressedDelegationRecord.

Applied to files:

  • test-integration/test-chainlink/tests/ix_07_redeleg_us_same_slot.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-chainlink/tests/ix_07_redeleg_us_same_slot.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-chainlink/tests/ix_07_redeleg_us_same_slot.rs
  • magicblock-chainlink/src/remote_account_provider/mod.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-chainlink/tests/ix_07_redeleg_us_same_slot.rs
  • magicblock-chainlink/src/remote_account_provider/mod.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:

  • test-integration/test-chainlink/tests/ix_07_redeleg_us_same_slot.rs
  • magicblock-chainlink/src/remote_account_provider/mod.rs
📚 Learning: 2025-12-17T12:46:36.207Z
Learnt from: GabrielePicco
Repo: magicblock-labs/magicblock-validator PR: 738
File: magicblock-chainlink/src/chainlink/fetch_cloner.rs:1109-1196
Timestamp: 2025-12-17T12:46:36.207Z
Learning: In magicblock-chainlink/src/chainlink/fetch_cloner.rs, eATA account subscriptions are intentionally NOT cancelled even when the eATA doesn't exist or delegation conversion fails. The subscriptions are kept active to watch for future creation or delegation of eATA accounts (per maintainer GabrielePicco).

Applied to files:

  • test-integration/test-chainlink/tests/ix_07_redeleg_us_same_slot.rs
  • magicblock-chainlink/src/remote_account_provider/mod.rs
📚 Learning: 2025-12-01T16:02:05.367Z
Learnt from: thlorenz
Repo: magicblock-labs/magicblock-validator PR: 703
File: magicblock-chainlink/src/submux/mod.rs:652-654
Timestamp: 2025-12-01T16:02:05.367Z
Learning: In magicblock-chainlink/src/submux/mod.rs, the subscribe_program method intentionally adds program_id to program_subs before attempting the subscription. This ensures that even if the initial subscription fails or only partially succeeds across clients, the reconnection logic will retry the subscription. This is a deliberate design pattern for resilience in the multi-client architecture and should not be "fixed" to remove entries on failure.

Applied to files:

  • test-integration/test-chainlink/tests/ix_07_redeleg_us_same_slot.rs
  • magicblock-chainlink/src/remote_account_provider/mod.rs
📚 Learning: 2025-12-03T09:36:01.527Z
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 639
File: magicblock-chainlink/src/remote_account_provider/mod.rs:1350-1353
Timestamp: 2025-12-03T09:36:01.527Z
Learning: Repo: magicblock-labs/magicblock-validator
File: magicblock-chainlink/src/remote_account_provider/mod.rs
Context: consolidate_fetched_remote_accounts
Learning: For unexpected result counts (>2), the project prefers logging an error and returning an empty Vec over panicking; acceptable during development per maintainer (Dodecahedr0x).

Applied to files:

  • magicblock-chainlink/src/remote_account_provider/mod.rs
📚 Learning: 2025-10-26T16:53:29.820Z
Learnt from: thlorenz
Repo: magicblock-labs/magicblock-validator PR: 587
File: magicblock-chainlink/src/remote_account_provider/mod.rs:134-0
Timestamp: 2025-10-26T16:53:29.820Z
Learning: In magicblock-chainlink/src/remote_account_provider/mod.rs, the `Endpoint::separate_pubsub_url_and_api_key()` method uses `split_once("?api-key=")` because the api-key parameter is always the only query parameter right after `?`. No additional query parameter parsing is needed for this use case.

Applied to files:

  • magicblock-chainlink/src/remote_account_provider/mod.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-chainlink/src/remote_account_provider/mod.rs
📚 Learning: 2025-11-21T11:03:26.756Z
Learnt from: thlorenz
Repo: magicblock-labs/magicblock-validator PR: 664
File: magicblock-chainlink/src/testing/mod.rs:342-370
Timestamp: 2025-11-21T11:03:26.756Z
Learning: In the magicblock-validator codebase, avoid leaving review comments that merely acknowledge code is correct or well-structured when there is no actionable suggestion, improvement, or issue to flag. Only comment when there is something specific to recommend, fix, or clarify.

Applied to files:

  • magicblock-chainlink/src/remote_account_provider/mod.rs
📚 Learning: 2025-11-26T13:27:46.702Z
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 639
File: magicblock-committor-service/src/transaction_preparator/delivery_preparator.rs:172-193
Timestamp: 2025-11-26T13:27:46.702Z
Learning: The Photon indexer (PhotonIndexer from light-client) handles slot validation internally when an IndexerRpcConfig with a slot constraint is provided. Additional slot validation at the call site is not needed when fetching compressed data via get_compressed_data.

Applied to files:

  • magicblock-chainlink/src/remote_account_provider/mod.rs
📚 Learning: 2025-11-21T13:56:03.885Z
Learnt from: snawaz
Repo: magicblock-labs/magicblock-validator PR: 575
File: test-integration/programs/schedulecommit/src/utils/mod.rs:71-71
Timestamp: 2025-11-21T13:56:03.885Z
Learning: In Solana programs (BPF runtime), defensive checked conversions to `usize` (e.g., `try_into()`) are unnecessary when casting from `u64`. Solana exclusively runs in 64-bit environments where `usize` is 64 bits, so truncation is not a concern and simple `as usize` casts are appropriate.

Applied to files:

  • magicblock-chainlink/src/remote_account_provider/mod.rs
🔇 Additional comments (4)
magicblock-chainlink/src/remote_account_provider/mod.rs (3)

982-1054: LGTM! Well-structured compressed account fetch with retry logic.

The async closure cleanly handles the compressed account fetch path:

  • Correctly checks for RPC accounts owned by compressed delegation program
  • Early returns Ok(None) when no compressed accounts need fetching
  • Properly validates photon_client availability
  • Implements retry loop with reasonable backoff (400ms)

The retry logic waiting for Photon to index compressed accounts aligns with the project's approach where PhotonIndexer has built-in retry logic. Based on learnings, this pattern is intentional.


1450-1530: LGTM! Consolidation logic handles all edge cases correctly.

The consolidation function properly:

  • Returns early for single-result cases
  • Prefers compressed accounts when both RPC and Photon find an account (with appropriate warning)
  • Falls back to RPC accounts on length mismatch
  • Returns empty vec for unexpected >2 results (acceptable per maintainer feedback)

The debug_assert! statements at lines 1488-1491 provide development-time validation without impacting release builds. Based on learnings, the error logging + empty vec return for >2 results is the preferred approach during development.


2245-2404: LGTM! Comprehensive test coverage for compressed account scenarios.

The new tests properly validate:

  • Multiple photon-only accounts (test_multiple_photon_accounts)
  • Mixed RPC + compressed accounts (test_multiple_mixed_accounts)
  • Missing accounts in both paths (test_multiple_mixed_accounts_some_missing)

The assertion macros (assert_compressed_account!, assert_regular_account!) make the tests readable and maintainable. The tests correctly verify RemoteAccountUpdateSource::Compressed vs Fetch tagging.

test-integration/test-chainlink/tests/ix_07_redeleg_us_same_slot.rs (1)

115-115: [No changes needed. AccountFetchOrigin::GetMultipleAccounts is the correct and consistent pattern across all compressed delegation tests in the codebase.]

Likely an incorrect or invalid review comment.

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 (3)
magicblock-chainlink/tests/05_redeleg_other_same_slot.rs (1)

94-94: Typo in comment.

-        // Then immediateljky delegate to other authority (simulating same slot operation)
+        // Then immediately delegate to other authority (simulating same slot operation)
magicblock-chainlink/src/remote_account_provider/mod.rs (1)

948-1199: Compressed metrics count all fetches when Photon is available, even if no compressed data was fetched

The fetch pipeline logic is correct, but the compressed metrics are misleading. When no accounts are owned by the compressed delegation program (compressed_accounts_count == 0), the closure returns Ok(None) and skips the fetch_from_photon call entirely. However, the metrics block still executes because it gates only on (*photon_client).is_some(), not on whether an actual compressed fetch occurred:

if (*photon_client).is_some() {
    inc_compressed_account_fetches_success(pubkeys.len() as u64);  // Always increments, even if no fetch happened
    inc_compressed_account_fetches_found(fetch_origin, compressed_found_count);
    inc_compressed_account_fetches_not_found(fetch_origin, compressed_not_found_count);
}

This means every fetch in a Photon-enabled setup counts toward compressed metrics, regardless of whether a Photon lookup was actually needed or performed. To reflect real Photon usage, gate the metrics block on compressed_found_count + compressed_not_found_count > 0 or on the presence of a FetchedRemoteAccounts::Compressed entry instead.

magicblock-chainlink/src/chainlink/fetch_cloner.rs (1)

1004-1045: Silently dropped compressed delegation records lack error visibility to callers

The bulk path silently omits accounts with unparseable compressed delegation records via filter_map, logging only an error:

let Ok(delegation_record) = CompressedDelegationRecord::try_from_slice(account.data())else {
    return None;
};

This differs from the non-compressed path (lines 1067–1091), where invalid records trigger ChainlinkError::InvalidDelegationRecord and abort the batch. The compressed path provides no way for callers to distinguish between accounts legitimately not found on-chain versus accounts found but unparseable—neither the account nor the error is recorded in FetchAndCloneResult. While subscriptions are correctly cancelled (since dropped accounts don't enter accounts_to_clone), the silent skip hides data integrity issues.

Consider either treating parse failures as hard errors or adding an invalid_records field to FetchAndCloneResult so callers can detect and react to malformed compressed delegation records.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8874b7d and bc83bef.

📒 Files selected for processing (11)
  • magicblock-chainlink/src/chainlink/fetch_cloner.rs
  • magicblock-chainlink/src/remote_account_provider/mod.rs
  • magicblock-chainlink/tests/01_ensure-accounts.rs
  • magicblock-chainlink/tests/04_redeleg_other_separate_slots.rs
  • magicblock-chainlink/tests/05_redeleg_other_same_slot.rs
  • magicblock-magic-program-api/src/instruction.rs
  • test-integration/configs/committor-conf.devnet.toml
  • test-integration/programs/schedulecommit/src/lib.rs
  • test-integration/programs/schedulecommit/src/magicblock_program.rs
  • test-integration/test-chainlink/tests/ix_07_redeleg_us_same_slot.rs
  • test-integration/test-tools/src/integration_test_context.rs
💤 Files with no reviewable changes (2)
  • test-integration/programs/schedulecommit/src/lib.rs
  • test-integration/programs/schedulecommit/src/magicblock_program.rs
🧰 Additional context used
📓 Path-based instructions (2)
{magicblock-*,programs,storage-proto}/**

⚙️ CodeRabbit configuration file

{magicblock-*,programs,storage-proto}/**: Treat any usage of .unwrap() or .expect() in production Rust code as a MAJOR issue.
These should not be categorized as trivial or nit-level concerns.
Request proper error handling or explicit justification with invariants.

Files:

  • magicblock-chainlink/tests/04_redeleg_other_separate_slots.rs
  • magicblock-magic-program-api/src/instruction.rs
  • magicblock-chainlink/tests/05_redeleg_other_same_slot.rs
  • magicblock-chainlink/tests/01_ensure-accounts.rs
  • magicblock-chainlink/src/remote_account_provider/mod.rs
  • magicblock-chainlink/src/chainlink/fetch_cloner.rs
{test-*,tools}/**

⚙️ CodeRabbit configuration file

Usage of .unwrap() or .expect() in test code is acceptable and may be treated as trivial.

Files:

  • test-integration/test-chainlink/tests/ix_07_redeleg_us_same_slot.rs
  • test-integration/test-tools/src/integration_test_context.rs
  • test-integration/configs/committor-conf.devnet.toml
🧠 Learnings (19)
📓 Common learnings
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 639
File: test-integration/test-committor-service/tests/test_ix_commit_local.rs:867-881
Timestamp: 2025-12-03T09:33:48.707Z
Learning: Repo: magicblock-labs/magicblock-validator PR: 639
Context: test-integration/test-committor-service/tests/test_ix_commit_local.rs (ix_commit_local)
Learning: The PhotonIndexer used for compressed account fetches (get_compressed_account) has built‑in retry logic (defaults to ~10 attempts), so tests should not add separate retry loops around compressed fetches unless there’s a specific need.
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 639
File: test-integration/test-chainlink/tests/ix_01_ensure-accounts.rs:85-114
Timestamp: 2025-11-19T11:31:24.218Z
Learning: In the magicblock-validator codebase, compressed delegation records are never subscribed to by design. Tests for compressed delegation flows should focus on verifying that the delegated account (e.g., counter PDA) is cloned as delegated and not subscribed, but do not need to check for subscription to delegation-record-like PDAs in the compressed path because subscriptions to compressed delegation records never occur.
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.
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 639
File: magicblock-committor-service/src/transaction_preparator/delivery_preparator.rs:172-193
Timestamp: 2025-11-26T13:27:46.702Z
Learning: The Photon indexer (PhotonIndexer from light-client) handles slot validation internally when an IndexerRpcConfig with a slot constraint is provided. Additional slot validation at the call site is not needed when fetching compressed data via get_compressed_data.
📚 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:

  • magicblock-chainlink/tests/04_redeleg_other_separate_slots.rs
  • test-integration/test-chainlink/tests/ix_07_redeleg_us_same_slot.rs
  • magicblock-magic-program-api/src/instruction.rs
  • magicblock-chainlink/tests/05_redeleg_other_same_slot.rs
  • magicblock-chainlink/tests/01_ensure-accounts.rs
  • magicblock-chainlink/src/remote_account_provider/mod.rs
  • magicblock-chainlink/src/chainlink/fetch_cloner.rs
📚 Learning: 2025-11-19T11:31:24.218Z
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 639
File: test-integration/test-chainlink/tests/ix_01_ensure-accounts.rs:85-114
Timestamp: 2025-11-19T11:31:24.218Z
Learning: In the magicblock-validator codebase, compressed delegation records are never subscribed to by design. Tests for compressed delegation flows should focus on verifying that the delegated account (e.g., counter PDA) is cloned as delegated and not subscribed, but do not need to check for subscription to delegation-record-like PDAs in the compressed path because subscriptions to compressed delegation records never occur.

Applied to files:

  • magicblock-chainlink/tests/04_redeleg_other_separate_slots.rs
  • test-integration/test-chainlink/tests/ix_07_redeleg_us_same_slot.rs
  • magicblock-chainlink/tests/05_redeleg_other_same_slot.rs
  • magicblock-chainlink/tests/01_ensure-accounts.rs
  • magicblock-chainlink/src/remote_account_provider/mod.rs
  • magicblock-chainlink/src/chainlink/fetch_cloner.rs
📚 Learning: 2025-12-03T09:33:48.707Z
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 639
File: test-integration/test-committor-service/tests/test_ix_commit_local.rs:867-881
Timestamp: 2025-12-03T09:33:48.707Z
Learning: Repo: magicblock-labs/magicblock-validator PR: 639
Context: test-integration/test-committor-service/tests/test_ix_commit_local.rs (ix_commit_local)
Learning: The PhotonIndexer used for compressed account fetches (get_compressed_account) has built‑in retry logic (defaults to ~10 attempts), so tests should not add separate retry loops around compressed fetches unless there’s a specific need.

Applied to files:

  • magicblock-chainlink/tests/04_redeleg_other_separate_slots.rs
  • test-integration/test-chainlink/tests/ix_07_redeleg_us_same_slot.rs
  • magicblock-chainlink/tests/05_redeleg_other_same_slot.rs
  • magicblock-chainlink/tests/01_ensure-accounts.rs
  • magicblock-chainlink/src/remote_account_provider/mod.rs
  • magicblock-chainlink/src/chainlink/fetch_cloner.rs
📚 Learning: 2025-11-25T11:07:20.001Z
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 639
File: test-integration/programs/flexi-counter/src/processor.rs:643-680
Timestamp: 2025-11-25T11:07:20.001Z
Learning: In the compressed delegation architecture, ownership reassignment during undelegation is handled by the delegation program itself, not by the owner program's external undelegate handler. The external undelegate handler (e.g., `process_external_undelegate_compressed` in flexi-counter) is a callback for program-specific cleanup (restoring lamports and data) after the delegation program has already reassigned ownership back to the original owner stored in the CompressedDelegationRecord.

Applied to files:

  • magicblock-chainlink/tests/04_redeleg_other_separate_slots.rs
  • test-integration/test-chainlink/tests/ix_07_redeleg_us_same_slot.rs
  • magicblock-chainlink/tests/05_redeleg_other_same_slot.rs
  • magicblock-chainlink/tests/01_ensure-accounts.rs
  • magicblock-chainlink/src/chainlink/fetch_cloner.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:

  • magicblock-chainlink/tests/04_redeleg_other_separate_slots.rs
  • test-integration/test-chainlink/tests/ix_07_redeleg_us_same_slot.rs
  • magicblock-magic-program-api/src/instruction.rs
  • magicblock-chainlink/tests/05_redeleg_other_same_slot.rs
  • magicblock-chainlink/tests/01_ensure-accounts.rs
  • magicblock-chainlink/src/remote_account_provider/mod.rs
  • magicblock-chainlink/src/chainlink/fetch_cloner.rs
📚 Learning: 2025-12-03T09:36:01.527Z
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 639
File: magicblock-chainlink/src/remote_account_provider/mod.rs:1350-1353
Timestamp: 2025-12-03T09:36:01.527Z
Learning: Repo: magicblock-labs/magicblock-validator
File: magicblock-chainlink/src/remote_account_provider/mod.rs
Context: consolidate_fetched_remote_accounts
Learning: For unexpected result counts (>2), the project prefers logging an error and returning an empty Vec over panicking; acceptable during development per maintainer (Dodecahedr0x).

Applied to files:

  • magicblock-chainlink/tests/04_redeleg_other_separate_slots.rs
  • test-integration/test-chainlink/tests/ix_07_redeleg_us_same_slot.rs
  • magicblock-chainlink/tests/05_redeleg_other_same_slot.rs
  • magicblock-chainlink/tests/01_ensure-accounts.rs
  • magicblock-chainlink/src/remote_account_provider/mod.rs
  • magicblock-chainlink/src/chainlink/fetch_cloner.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:

  • magicblock-chainlink/tests/04_redeleg_other_separate_slots.rs
  • test-integration/test-chainlink/tests/ix_07_redeleg_us_same_slot.rs
  • magicblock-chainlink/tests/05_redeleg_other_same_slot.rs
  • magicblock-chainlink/tests/01_ensure-accounts.rs
  • magicblock-chainlink/src/remote_account_provider/mod.rs
  • magicblock-chainlink/src/chainlink/fetch_cloner.rs
📚 Learning: 2025-10-21T11:00:18.396Z
Learnt from: bmuddha
Repo: magicblock-labs/magicblock-validator PR: 578
File: magicblock-aperture/src/encoder.rs:176-187
Timestamp: 2025-10-21T11:00:18.396Z
Learning: In the magicblock validator, the current slot is always the root slot. The SlotEncoder in magicblock-aperture/src/encoder.rs correctly sets `root: slot` because there is no lag between current and root slots in this architecture.

Applied to files:

  • magicblock-chainlink/tests/04_redeleg_other_separate_slots.rs
  • magicblock-chainlink/tests/01_ensure-accounts.rs
📚 Learning: 2025-11-26T13:27:46.702Z
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 639
File: magicblock-committor-service/src/transaction_preparator/delivery_preparator.rs:172-193
Timestamp: 2025-11-26T13:27:46.702Z
Learning: The Photon indexer (PhotonIndexer from light-client) handles slot validation internally when an IndexerRpcConfig with a slot constraint is provided. Additional slot validation at the call site is not needed when fetching compressed data via get_compressed_data.

Applied to files:

  • magicblock-chainlink/tests/04_redeleg_other_separate_slots.rs
  • magicblock-chainlink/src/remote_account_provider/mod.rs
📚 Learning: 2025-12-17T12:46:36.207Z
Learnt from: GabrielePicco
Repo: magicblock-labs/magicblock-validator PR: 738
File: magicblock-chainlink/src/chainlink/fetch_cloner.rs:1109-1196
Timestamp: 2025-12-17T12:46:36.207Z
Learning: In magicblock-chainlink/src/chainlink/fetch_cloner.rs, eATA account subscriptions are intentionally NOT cancelled even when the eATA doesn't exist or delegation conversion fails. The subscriptions are kept active to watch for future creation or delegation of eATA accounts (per maintainer GabrielePicco).

Applied to files:

  • magicblock-chainlink/tests/04_redeleg_other_separate_slots.rs
  • test-integration/test-chainlink/tests/ix_07_redeleg_us_same_slot.rs
  • magicblock-chainlink/tests/05_redeleg_other_same_slot.rs
  • magicblock-chainlink/tests/01_ensure-accounts.rs
  • magicblock-chainlink/src/remote_account_provider/mod.rs
  • magicblock-chainlink/src/chainlink/fetch_cloner.rs
📚 Learning: 2025-12-01T16:02:05.367Z
Learnt from: thlorenz
Repo: magicblock-labs/magicblock-validator PR: 703
File: magicblock-chainlink/src/submux/mod.rs:652-654
Timestamp: 2025-12-01T16:02:05.367Z
Learning: In magicblock-chainlink/src/submux/mod.rs, the subscribe_program method intentionally adds program_id to program_subs before attempting the subscription. This ensures that even if the initial subscription fails or only partially succeeds across clients, the reconnection logic will retry the subscription. This is a deliberate design pattern for resilience in the multi-client architecture and should not be "fixed" to remove entries on failure.

Applied to files:

  • magicblock-chainlink/tests/04_redeleg_other_separate_slots.rs
  • test-integration/test-chainlink/tests/ix_07_redeleg_us_same_slot.rs
  • magicblock-chainlink/tests/05_redeleg_other_same_slot.rs
  • magicblock-chainlink/src/remote_account_provider/mod.rs
  • magicblock-chainlink/src/chainlink/fetch_cloner.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:

  • test-integration/test-chainlink/tests/ix_07_redeleg_us_same_slot.rs
  • magicblock-chainlink/src/remote_account_provider/mod.rs
  • magicblock-chainlink/src/chainlink/fetch_cloner.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-chainlink/tests/ix_07_redeleg_us_same_slot.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:

  • test-integration/test-tools/src/integration_test_context.rs
  • magicblock-chainlink/src/remote_account_provider/mod.rs
📚 Learning: 2025-10-26T16:53:29.820Z
Learnt from: thlorenz
Repo: magicblock-labs/magicblock-validator PR: 587
File: magicblock-chainlink/src/remote_account_provider/mod.rs:134-0
Timestamp: 2025-10-26T16:53:29.820Z
Learning: In magicblock-chainlink/src/remote_account_provider/mod.rs, the `Endpoint::separate_pubsub_url_and_api_key()` method uses `split_once("?api-key=")` because the api-key parameter is always the only query parameter right after `?`. No additional query parameter parsing is needed for this use case.

Applied to files:

  • magicblock-chainlink/src/remote_account_provider/mod.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-chainlink/src/remote_account_provider/mod.rs
📚 Learning: 2025-11-21T13:56:03.885Z
Learnt from: snawaz
Repo: magicblock-labs/magicblock-validator PR: 575
File: test-integration/programs/schedulecommit/src/utils/mod.rs:71-71
Timestamp: 2025-11-21T13:56:03.885Z
Learning: In Solana programs (BPF runtime), defensive checked conversions to `usize` (e.g., `try_into()`) are unnecessary when casting from `u64`. Solana exclusively runs in 64-bit environments where `usize` is 64 bits, so truncation is not a concern and simple `as usize` casts are appropriate.

Applied to files:

  • magicblock-chainlink/src/remote_account_provider/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-chainlink/src/remote_account_provider/mod.rs
🧬 Code graph analysis (3)
test-integration/test-chainlink/tests/ix_07_redeleg_us_same_slot.rs (3)
test-integration/test-chainlink/src/ixtest_context.rs (1)
  • counter_pda (203-205)
test-integration/test-chainlink/src/lib.rs (1)
  • sleep_ms (8-11)
compressed-delegation-client/src/lib.rs (1)
  • id (61-63)
magicblock-chainlink/tests/05_redeleg_other_same_slot.rs (4)
magicblock-chainlink/src/testing/accounts.rs (1)
  • account_shared_with_owner (4-10)
magicblock-chainlink/src/testing/deleg.rs (1)
  • add_delegation_record_for (22-46)
magicblock-chainlink/src/testing/utils.rs (1)
  • init_logger (58-66)
magicblock-chainlink/tests/utils/accounts.rs (3)
  • account_shared_with_owner_and_slot (11-19)
  • compressed_account_shared_with_owner_and_slot (21-48)
  • default (58-64)
magicblock-chainlink/tests/01_ensure-accounts.rs (1)
magicblock-chainlink/tests/utils/accounts.rs (1)
  • compressed_account_shared_with_owner_and_slot (21-48)
🔇 Additional comments (19)
test-integration/test-tools/src/integration_test_context.rs (1)

729-738: LGTM! Improved test diagnostics.

The addition of a custom failure message to the assert! macro improves debuggability by displaying the actual result when the assertion fails. The underlying logic remains correct and unchanged.

magicblock-chainlink/tests/05_redeleg_other_same_slot.rs (3)

11-25: LGTM!

Import style is now consistent, and the new compressed account utilities are properly imported alongside the existing helpers.


126-156: LGTM!

The compressed account initialization with the explanatory comment and the assertion pattern (only checking pubkey, not delegation record) correctly align with the compressed delegation design where delegation records are never subscribed. Based on learnings.


158-205: LGTM!

The compressed redelegation flow correctly:

  1. Forces undelegation and triggers subscription
  2. Updates Photon with new delegation to other_authority
  3. Simulates the subscription update via send_and_receive_account_update
  4. Verifies the account is marked as undelegated (since delegated to another authority)

The assertion with timeout (line 198) properly guards against flaky test failures.

test-integration/test-chainlink/tests/ix_07_redeleg_us_same_slot.rs (3)

91-106: LGTM! Test setup correctly mirrors non-compressed flow.

The test setup properly initializes the context and delegates the counter account using the compressed path. The omission of deleg_record_pubkey (compared to the non-compressed test at line 29) is correct, as compressed delegation records are not subscribed to by design.


107-133: LGTM! First verification block correctly implements compressed flow.

The sleep after ensure_accounts (line 120) addresses the previous review concern. The subscription check correctly validates only the counter_pda without checking a delegation record, which aligns with the compressed delegation design where delegation records are never subscribed. Based on learnings, compressed delegation records are not tracked via subscription by design.


135-157: LGTM! Second verification block correctly validates same-slot redelegate.

The undelegate/redelegate flow properly uses the compressed-specific methods and maintains consistent assertions with the first verification block. The sleep after undelegation allows for pubsub updates to propagate before re-verification.

test-integration/configs/committor-conf.devnet.toml (1)

32-34: Configuration is correct. The compressed delegation program binary exists at the specified path (../programs/compressed_delegation/compressed_delegation.so relative to the config file), and the program ID DEL2rPzhFaS5qzo8XY9ZNxSzuunWueySq3p2dxJfwPbT is consistently referenced throughout the codebase in compressed-delegation-client.

magicblock-chainlink/tests/01_ensure-accounts.rs (2)

20-20: LGTM!

The import of compressed_account_shared_with_owner_and_slot is necessary for the new compressed delegation tests and follows the existing import pattern.


465-494: LGTM!

The test correctly validates that an undelegated compressed account is cloned as undelegated and subscribed, following the expected behavior for accounts without delegation.

magicblock-chainlink/tests/04_redeleg_other_separate_slots.rs (4)

21-21: LGTM!

The import addition is necessary for the compressed account test variant and follows the existing import patterns.


133-182: LGTM! Correct compressed delegation setup.

The test correctly implements the compressed delegation flow:

  • Line 165's set_remote_slot(slot) call is necessary (sets AccountSharedData slot, distinct from the delegation record slot set by the helper)
  • Line 181 correctly verifies only the account pubkey is not subscribed, consistent with the design that compressed delegation records are never subscribed to
  • The test properly uses photon_client for compressed account storage and verifies the expected cloning behavior

Based on learnings, the implementation correctly distinguishes between the two slot fields and follows compressed delegation subscription patterns.


184-210: LGTM! Undelegation flow correctly implemented.

The compressed undelegation sequence correctly mirrors the non-compressed test logic and properly verifies:

  • Forced undelegation prevents writes while undelegating
  • Commit and undelegation properly updates account state
  • Final state correctly shows account cloned as undelegated and subscribed (without delegation record, per compressed flow design)

212-252: LGTM! Redelegation flow correctly adapted for compressed accounts.

The compressed redelegation sequence is well-implemented:

  • Correctly creates compressed delegation record for other_authority via compressed_account_shared_with_owner_and_slot and stores in photon client
  • Uses send_and_receive_account_update to simulate the delegation update notification (appropriate for compressed flow vs the programmatic delegate_existing_account_to() used in non-compressed tests)
  • Line 237's descriptive assertion message is good practice
  • Final state verification correctly shows account cloned as undelegated with subscription active (no delegation record subscription per compressed design)
magicblock-magic-program-api/src/instruction.rs (2)

110-140: Compressed schedule instruction variants mirror existing API; watch ABI consumers

These variants mirror ScheduleCommit / ScheduleCommitAndUndelegate semantics with compressed-specific docs and account layout, which looks correct. Since MagicBlockInstruction is serialized (bincode/serde) and shared between on-chain program and off-chain clients, ensure all consumers are upgraded in lockstep so older nodes don’t fail to decode when these new variants appear.


149-172: compressed flags extend account modification structs consistently

Adding compressed: Option<bool> alongside delegated/confined keeps the tri-state “no change vs true vs false” pattern and preserves struct layout. From a type/serde perspective this is fine; just verify producers set it only when compressed delegation semantics actually apply.

magicblock-chainlink/src/chainlink/fetch_cloner.rs (2)

417-587: Compressed delegation subscription handling matches bulk semantics

The new owned_by_compressed_delegation_program branch correctly derives state from CompressedDelegationRecord: it marks accounts as compressed, rewrites lamports/owner/data, and sets the delegated flag based on authority, while returning a synthesized DelegationRecord so delegated_to_other and undelegation checks keep working. The fallback to try_get when direct deserialization fails is a reasonable recovery path and keeps subscription and bulk behavior aligned.


1476-1531: Compressed undelegating accounts correctly skip RPC-based refresh

The new in_bank.compressed() branch in should_refresh_undelegating_in_bank_account short-circuits refresh for compressed undelegations and avoids fetching delegation records for them, which matches the compressed delegation design where the delegation program itself handles ownership reassignment during undelegate, and owner programs only perform local cleanup. This behavior looks correct. Based on learnings, compressed undelegations should not go through the standard refresh path.

magicblock-chainlink/src/remote_account_provider/mod.rs (1)

100-141: PhotonClient generic integration in RemoteAccountProvider is coherent

Threading P: PhotonClient through RemoteAccountProvider, storing photon_client: Option<P>, and updating try_from_urls_and_config / try_from_clients_and_mode / new / try_new_from_endpoints is consistent. The default impls use PhotonClientImpl, while tests correctly instantiate None::<PhotonClientImpl> or Some(PhotonClientMock), so type signatures and lifecycle wiring look sound.

Also applies to: 162-205, 207-235, 320-377, 379-461

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

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bc83bef and ead02e3.

⛔ Files ignored due to path filters (1)
  • programs/elfs/guinea.so is excluded by !**/*.so
📒 Files selected for processing (5)
  • magicblock-chainlink/tests/01_ensure-accounts.rs
  • magicblock-committor-service/src/pubkeys_provider.rs
  • magicblock-committor-service/src/tasks/task_builder.rs
  • programs/magicblock/src/magic_scheduled_base_intent.rs
  • test-integration/test-committor-service/tests/test_intent_executor.rs
🧰 Additional context used
📓 Path-based instructions (2)
{magicblock-*,programs,storage-proto}/**

⚙️ CodeRabbit configuration file

{magicblock-*,programs,storage-proto}/**: Treat any usage of .unwrap() or .expect() in production Rust code as a MAJOR issue.
These should not be categorized as trivial or nit-level concerns.
Request proper error handling or explicit justification with invariants.

Files:

  • magicblock-committor-service/src/pubkeys_provider.rs
  • magicblock-chainlink/tests/01_ensure-accounts.rs
  • programs/magicblock/src/magic_scheduled_base_intent.rs
  • magicblock-committor-service/src/tasks/task_builder.rs
{test-*,tools}/**

⚙️ CodeRabbit configuration file

Usage of .unwrap() or .expect() in test code is acceptable and may be treated as trivial.

Files:

  • test-integration/test-committor-service/tests/test_intent_executor.rs
🧠 Learnings (17)
📓 Common learnings
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 639
File: test-integration/test-committor-service/tests/test_ix_commit_local.rs:867-881
Timestamp: 2025-12-03T09:33:48.707Z
Learning: Repo: magicblock-labs/magicblock-validator PR: 639
Context: test-integration/test-committor-service/tests/test_ix_commit_local.rs (ix_commit_local)
Learning: The PhotonIndexer used for compressed account fetches (get_compressed_account) has built‑in retry logic (defaults to ~10 attempts), so tests should not add separate retry loops around compressed fetches unless there’s a specific need.
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 639
File: test-integration/test-chainlink/tests/ix_01_ensure-accounts.rs:85-114
Timestamp: 2025-11-19T11:31:24.218Z
Learning: In the magicblock-validator codebase, compressed delegation records are never subscribed to by design. Tests for compressed delegation flows should focus on verifying that the delegated account (e.g., counter PDA) is cloned as delegated and not subscribed, but do not need to check for subscription to delegation-record-like PDAs in the compressed path because subscriptions to compressed delegation records never occur.
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.
📚 Learning: 2025-12-03T09:36:01.527Z
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 639
File: magicblock-chainlink/src/remote_account_provider/mod.rs:1350-1353
Timestamp: 2025-12-03T09:36:01.527Z
Learning: Repo: magicblock-labs/magicblock-validator
File: magicblock-chainlink/src/remote_account_provider/mod.rs
Context: consolidate_fetched_remote_accounts
Learning: For unexpected result counts (>2), the project prefers logging an error and returning an empty Vec over panicking; acceptable during development per maintainer (Dodecahedr0x).

Applied to files:

  • magicblock-committor-service/src/pubkeys_provider.rs
  • magicblock-chainlink/tests/01_ensure-accounts.rs
  • test-integration/test-committor-service/tests/test_intent_executor.rs
  • programs/magicblock/src/magic_scheduled_base_intent.rs
  • magicblock-committor-service/src/tasks/task_builder.rs
📚 Learning: 2025-11-19T11:31:24.218Z
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 639
File: test-integration/test-chainlink/tests/ix_01_ensure-accounts.rs:85-114
Timestamp: 2025-11-19T11:31:24.218Z
Learning: In the magicblock-validator codebase, compressed delegation records are never subscribed to by design. Tests for compressed delegation flows should focus on verifying that the delegated account (e.g., counter PDA) is cloned as delegated and not subscribed, but do not need to check for subscription to delegation-record-like PDAs in the compressed path because subscriptions to compressed delegation records never occur.

Applied to files:

  • magicblock-committor-service/src/pubkeys_provider.rs
  • magicblock-chainlink/tests/01_ensure-accounts.rs
  • programs/magicblock/src/magic_scheduled_base_intent.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:

  • magicblock-chainlink/tests/01_ensure-accounts.rs
  • programs/magicblock/src/magic_scheduled_base_intent.rs
📚 Learning: 2025-12-03T09:33:48.707Z
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 639
File: test-integration/test-committor-service/tests/test_ix_commit_local.rs:867-881
Timestamp: 2025-12-03T09:33:48.707Z
Learning: Repo: magicblock-labs/magicblock-validator PR: 639
Context: test-integration/test-committor-service/tests/test_ix_commit_local.rs (ix_commit_local)
Learning: The PhotonIndexer used for compressed account fetches (get_compressed_account) has built‑in retry logic (defaults to ~10 attempts), so tests should not add separate retry loops around compressed fetches unless there’s a specific need.

Applied to files:

  • magicblock-chainlink/tests/01_ensure-accounts.rs
  • test-integration/test-committor-service/tests/test_intent_executor.rs
  • programs/magicblock/src/magic_scheduled_base_intent.rs
  • magicblock-committor-service/src/tasks/task_builder.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:

  • magicblock-chainlink/tests/01_ensure-accounts.rs
  • programs/magicblock/src/magic_scheduled_base_intent.rs
  • magicblock-committor-service/src/tasks/task_builder.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:

  • magicblock-chainlink/tests/01_ensure-accounts.rs
  • programs/magicblock/src/magic_scheduled_base_intent.rs
  • magicblock-committor-service/src/tasks/task_builder.rs
📚 Learning: 2025-11-25T11:07:20.001Z
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 639
File: test-integration/programs/flexi-counter/src/processor.rs:643-680
Timestamp: 2025-11-25T11:07:20.001Z
Learning: In the compressed delegation architecture, ownership reassignment during undelegation is handled by the delegation program itself, not by the owner program's external undelegate handler. The external undelegate handler (e.g., `process_external_undelegate_compressed` in flexi-counter) is a callback for program-specific cleanup (restoring lamports and data) after the delegation program has already reassigned ownership back to the original owner stored in the CompressedDelegationRecord.

Applied to files:

  • magicblock-chainlink/tests/01_ensure-accounts.rs
📚 Learning: 2025-12-17T12:46:36.207Z
Learnt from: GabrielePicco
Repo: magicblock-labs/magicblock-validator PR: 738
File: magicblock-chainlink/src/chainlink/fetch_cloner.rs:1109-1196
Timestamp: 2025-12-17T12:46:36.207Z
Learning: In magicblock-chainlink/src/chainlink/fetch_cloner.rs, eATA account subscriptions are intentionally NOT cancelled even when the eATA doesn't exist or delegation conversion fails. The subscriptions are kept active to watch for future creation or delegation of eATA accounts (per maintainer GabrielePicco).

Applied to files:

  • magicblock-chainlink/tests/01_ensure-accounts.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-chainlink/tests/01_ensure-accounts.rs
  • magicblock-committor-service/src/tasks/task_builder.rs
📚 Learning: 2025-12-01T16:02:05.367Z
Learnt from: thlorenz
Repo: magicblock-labs/magicblock-validator PR: 703
File: magicblock-chainlink/src/submux/mod.rs:652-654
Timestamp: 2025-12-01T16:02:05.367Z
Learning: In magicblock-chainlink/src/submux/mod.rs, the subscribe_program method intentionally adds program_id to program_subs before attempting the subscription. This ensures that even if the initial subscription fails or only partially succeeds across clients, the reconnection logic will retry the subscription. This is a deliberate design pattern for resilience in the multi-client architecture and should not be "fixed" to remove entries on failure.

Applied to files:

  • magicblock-chainlink/tests/01_ensure-accounts.rs
📚 Learning: 2025-10-21T11:00:18.396Z
Learnt from: bmuddha
Repo: magicblock-labs/magicblock-validator PR: 578
File: magicblock-aperture/src/encoder.rs:176-187
Timestamp: 2025-10-21T11:00:18.396Z
Learning: In the magicblock validator, the current slot is always the root slot. The SlotEncoder in magicblock-aperture/src/encoder.rs correctly sets `root: slot` because there is no lag between current and root slots in this architecture.

Applied to files:

  • magicblock-chainlink/tests/01_ensure-accounts.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_intent_executor.rs
  • programs/magicblock/src/magic_scheduled_base_intent.rs
  • magicblock-committor-service/src/tasks/task_builder.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:

  • test-integration/test-committor-service/tests/test_intent_executor.rs
📚 Learning: 2025-11-21T11:03:26.756Z
Learnt from: thlorenz
Repo: magicblock-labs/magicblock-validator PR: 664
File: magicblock-chainlink/src/testing/mod.rs:342-370
Timestamp: 2025-11-21T11:03:26.756Z
Learning: In the magicblock-validator codebase, avoid leaving review comments that merely acknowledge code is correct or well-structured when there is no actionable suggestion, improvement, or issue to flag. Only comment when there is something specific to recommend, fix, or clarify.

Applied to files:

  • programs/magicblock/src/magic_scheduled_base_intent.rs
📚 Learning: 2025-11-20T08:57:07.217Z
Learnt from: thlorenz
Repo: magicblock-labs/magicblock-validator PR: 650
File: magicblock-chainlink/src/submux/subscription_task.rs:13-99
Timestamp: 2025-11-20T08:57:07.217Z
Learning: In the magicblock-validator repository, avoid posting review comments that merely confirm code is correct or matches intended behavior without providing actionable feedback, suggestions for improvement, or identifying potential issues. Such confirmatory comments are considered unhelpful noise by the maintainers.

Applied to files:

  • programs/magicblock/src/magic_scheduled_base_intent.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/tasks/task_builder.rs
🧬 Code graph analysis (1)
test-integration/test-committor-service/tests/test_intent_executor.rs (3)
magicblock-committor-service/src/intent_executor/mod.rs (1)
  • new (126-142)
test-integration/test-committor-service/tests/test_transaction_preparator.rs (1)
  • None (62-62)
test-integration/test-committor-service/tests/test_delivery_preparator.rs (15)
  • None (54-54)
  • None (55-55)
  • None (125-125)
  • None (126-126)
  • None (207-207)
  • None (208-208)
  • None (249-249)
  • None (250-250)
  • None (291-291)
  • None (292-292)
  • None (359-359)
  • None (360-360)
  • None (461-461)
  • None (462-462)
  • None (552-552)
🔇 Additional comments (10)
magicblock-chainlink/tests/01_ensure-accounts.rs (2)

367-410: LGTM! Compressed delegation test correctly validates the "delegated to us" scenario.

The test properly sets up a compressed delegation record delegated to the validator, verifies it's cloned as delegated with the correct owner, and confirms it's NOT subscribed—aligning with the design that compressed delegation records are never subscribed. The previous review concerns about missing parameters and owner verification have been addressed.


416-494: LGTM! Compressed delegation tests correctly validate "delegated to other" and "undelegated" scenarios.

Both tests follow the correct patterns:

  • test_compressed_delegation_record_delegated_to_other properly verifies that an account delegated to another authority is cloned as undelegated and subscribed (with owner verification).
  • test_compressed_account_undelegated correctly tests an empty/undelegated compressed record, expecting undelegated clone and subscription.

The previous review concerns about missing parameters and owner verification have been addressed in these tests as well.

magicblock-committor-service/src/pubkeys_provider.rs (3)

54-68: LGTM: Logging maintains observability.

The trace logging correctly includes the compressed delegation program alongside other program IDs, maintaining consistency and visibility into which programs are being used.


73-73: LGTM: Correct inclusion in common pubkeys.

The compressed delegation program is properly added to the common pubkeys set, ensuring it's available for all process/finalize transactions alongside other program IDs.


48-48: Compressed-delegation-client integration is correctly implemented.

The crate is properly configured as a workspace member with valid workspace dependency declarations in magicblock-committor-service/Cargo.toml. The compressed_delegation_client::id() function usage follows the established pattern used for other program IDs (e.g., dlp::id(), magicblock_committor_program::id()), and the program ID is correctly registered in the common pubkeys set.

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

15-15: LGTM! PhotonIndexer properly integrated into test infrastructure.

The PhotonIndexer is correctly threaded through the test environment setup:

  • Imported from light-client
  • Passed to CacheTaskInfoFetcher constructor
  • Passed to IntentExecutorImpl constructor

This enables the test infrastructure to support both RPC and Photon-based execution paths.

Also applies to: 88-91, 102-102


138-155: LGTM! Appropriate use of None for photon_client in non-compressed tests.

These error recovery tests don't exercise compressed account flows, so passing None for the photon_client parameter is correct. The tests focus on:

  • Commit ID error parsing and recovery
  • Undelegation error parsing and recovery
  • Action error parsing and recovery
  • CPI limit error parsing and recovery

All of which operate on standard delegated accounts, not compressed accounts.

Also applies to: 199-204, 258-264, 320-327


275-280: LGTM! Improved assertion message for better debugging.

The enhanced assertion now displays both the actual and expected error messages when the test fails, making it easier to diagnose issues:

assert!(
    execution_err.to_string().contains(EXPECTED_ERR_MSG),
    "{} != {}",
    execution_err.to_string(),
    EXPECTED_ERR_MSG
);

This is a useful improvement for test maintainability.


363-367: LGTM! Correct usage of fetch_next_commit_ids for test setup.

These calls invalidate the commit nonce cache to force CommitIDError scenarios in the error recovery tests. This is a valid test setup pattern to exercise the error recovery logic.

Also applies to: 551-555, 755-758


979-994: LGTM! TaskBuilderImpl calls correctly updated with photon_client parameter.

The helper function properly passes the photon_client parameter to both commit_tasks and finalize_tasks:

  • &None::<Arc<PhotonIndexer>> is passed since these tests don't use compressed accounts
  • Both async calls are properly awaited and unwrapped
  • Aligns with the updated TaskBuilderImpl API

The changes maintain the existing test behavior while supporting the new PhotonIndexer infrastructure.

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

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2590179 and 8ed4fea.

📒 Files selected for processing (2)
  • magicblock-committor-service/src/tasks/task_builder.rs
  • test-integration/test-chainlink/src/ixtest_context.rs
🧰 Additional context used
📓 Path-based instructions (2)
{test-*,tools}/**

⚙️ CodeRabbit configuration file

Usage of .unwrap() or .expect() in test code is acceptable and may be treated as trivial.

Files:

  • test-integration/test-chainlink/src/ixtest_context.rs
{magicblock-*,programs,storage-proto}/**

⚙️ CodeRabbit configuration file

{magicblock-*,programs,storage-proto}/**: Treat any usage of .unwrap() or .expect() in production Rust code as a MAJOR issue.
These should not be categorized as trivial or nit-level concerns.
Request proper error handling or explicit justification with invariants.

Files:

  • magicblock-committor-service/src/tasks/task_builder.rs
🧠 Learnings (17)
📓 Common learnings
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 639
File: test-integration/test-committor-service/tests/test_ix_commit_local.rs:867-881
Timestamp: 2025-12-03T09:33:48.707Z
Learning: Repo: magicblock-labs/magicblock-validator PR: 639
Context: test-integration/test-committor-service/tests/test_ix_commit_local.rs (ix_commit_local)
Learning: The PhotonIndexer used for compressed account fetches (get_compressed_account) has built‑in retry logic (defaults to ~10 attempts), so tests should not add separate retry loops around compressed fetches unless there’s a specific need.
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 639
File: test-integration/test-chainlink/tests/ix_01_ensure-accounts.rs:85-114
Timestamp: 2025-11-19T11:31:24.218Z
Learning: In the magicblock-validator codebase, compressed delegation records are never subscribed to by design. Tests for compressed delegation flows should focus on verifying that the delegated account (e.g., counter PDA) is cloned as delegated and not subscribed, but do not need to check for subscription to delegation-record-like PDAs in the compressed path because subscriptions to compressed delegation records never occur.
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.
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 639
File: magicblock-committor-service/src/transaction_preparator/delivery_preparator.rs:172-193
Timestamp: 2025-11-26T13:27:46.702Z
Learning: The Photon indexer (PhotonIndexer from light-client) handles slot validation internally when an IndexerRpcConfig with a slot constraint is provided. Additional slot validation at the call site is not needed when fetching compressed data via get_compressed_data.
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
📚 Learning: 2025-12-03T09:33:48.707Z
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 639
File: test-integration/test-committor-service/tests/test_ix_commit_local.rs:867-881
Timestamp: 2025-12-03T09:33:48.707Z
Learning: Repo: magicblock-labs/magicblock-validator PR: 639
Context: test-integration/test-committor-service/tests/test_ix_commit_local.rs (ix_commit_local)
Learning: The PhotonIndexer used for compressed account fetches (get_compressed_account) has built‑in retry logic (defaults to ~10 attempts), so tests should not add separate retry loops around compressed fetches unless there’s a specific need.

Applied to files:

  • test-integration/test-chainlink/src/ixtest_context.rs
  • magicblock-committor-service/src/tasks/task_builder.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-chainlink/src/ixtest_context.rs
  • magicblock-committor-service/src/tasks/task_builder.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-chainlink/src/ixtest_context.rs
📚 Learning: 2025-12-03T09:36:01.527Z
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 639
File: magicblock-chainlink/src/remote_account_provider/mod.rs:1350-1353
Timestamp: 2025-12-03T09:36:01.527Z
Learning: Repo: magicblock-labs/magicblock-validator
File: magicblock-chainlink/src/remote_account_provider/mod.rs
Context: consolidate_fetched_remote_accounts
Learning: For unexpected result counts (>2), the project prefers logging an error and returning an empty Vec over panicking; acceptable during development per maintainer (Dodecahedr0x).

Applied to files:

  • test-integration/test-chainlink/src/ixtest_context.rs
  • magicblock-committor-service/src/tasks/task_builder.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-chainlink/src/ixtest_context.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-chainlink/src/ixtest_context.rs
  • magicblock-committor-service/src/tasks/task_builder.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:

  • test-integration/test-chainlink/src/ixtest_context.rs
  • magicblock-committor-service/src/tasks/task_builder.rs
📚 Learning: 2025-11-19T11:31:24.218Z
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 639
File: test-integration/test-chainlink/tests/ix_01_ensure-accounts.rs:85-114
Timestamp: 2025-11-19T11:31:24.218Z
Learning: In the magicblock-validator codebase, compressed delegation records are never subscribed to by design. Tests for compressed delegation flows should focus on verifying that the delegated account (e.g., counter PDA) is cloned as delegated and not subscribed, but do not need to check for subscription to delegation-record-like PDAs in the compressed path because subscriptions to compressed delegation records never occur.

Applied to files:

  • test-integration/test-chainlink/src/ixtest_context.rs
📚 Learning: 2025-10-28T13:15:42.706Z
Learnt from: bmuddha
Repo: magicblock-labs/magicblock-validator PR: 596
File: magicblock-processor/src/scheduler.rs:1-1
Timestamp: 2025-10-28T13:15:42.706Z
Learning: In magicblock-processor, transaction indexes were always set to 0 even before the changes in PR #596. The proper transaction indexing within slots will be addressed during the planned ledger rewrite.

Applied to files:

  • test-integration/test-chainlink/src/ixtest_context.rs
📚 Learning: 2025-11-19T12:55:48.931Z
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 639
File: test-integration/test-tools/src/validator.rs:193-197
Timestamp: 2025-11-19T12:55:48.931Z
Learning: In the magicblock-validator codebase, when constructing arguments for the light CLI test validator in start_light_validator_with_config (test-integration/test-tools/src/validator.rs), the shlex::split approach is necessary because the light CLI does not handle whitespaces properly in validator arguments. The string concatenation + shlex parsing pattern should not be refactored to direct argument construction in this specific case.

Applied to files:

  • test-integration/test-chainlink/src/ixtest_context.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:

  • test-integration/test-chainlink/src/ixtest_context.rs
📚 Learning: 2025-11-25T11:07:20.001Z
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 639
File: test-integration/programs/flexi-counter/src/processor.rs:643-680
Timestamp: 2025-11-25T11:07:20.001Z
Learning: In the compressed delegation architecture, ownership reassignment during undelegation is handled by the delegation program itself, not by the owner program's external undelegate handler. The external undelegate handler (e.g., `process_external_undelegate_compressed` in flexi-counter) is a callback for program-specific cleanup (restoring lamports and data) after the delegation program has already reassigned ownership back to the original owner stored in the CompressedDelegationRecord.

Applied to files:

  • test-integration/test-chainlink/src/ixtest_context.rs
📚 Learning: 2025-11-24T14:21:00.996Z
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 639
File: Cargo.toml:58-58
Timestamp: 2025-11-24T14:21:00.996Z
Learning: In the magicblock-validator codebase, magicblock-api/Cargo.toml intentionally uses borsh = "1.5.3" (instead of the workspace version 0.10.4) because it needs to deserialize types from the magic-domain-program external dependency, which requires borsh 1.5.x compatibility. This is an intentional exception for interoperability with the magic domain program.

Applied to files:

  • test-integration/test-chainlink/src/ixtest_context.rs
📚 Learning: 2025-12-01T16:02:05.367Z
Learnt from: thlorenz
Repo: magicblock-labs/magicblock-validator PR: 703
File: magicblock-chainlink/src/submux/mod.rs:652-654
Timestamp: 2025-12-01T16:02:05.367Z
Learning: In magicblock-chainlink/src/submux/mod.rs, the subscribe_program method intentionally adds program_id to program_subs before attempting the subscription. This ensures that even if the initial subscription fails or only partially succeeds across clients, the reconnection logic will retry the subscription. This is a deliberate design pattern for resilience in the multi-client architecture and should not be "fixed" to remove entries on failure.

Applied to files:

  • test-integration/test-chainlink/src/ixtest_context.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/tasks/task_builder.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:

  • magicblock-committor-service/src/tasks/task_builder.rs
🧬 Code graph analysis (2)
test-integration/test-chainlink/src/ixtest_context.rs (5)
compressed-delegation-client/src/generated/instructions/undelegate_compressed.rs (2)
  • instruction (23-28)
  • instruction (135-150)
compressed-delegation-client/src/generated/instructions/delegate_compressed.rs (2)
  • instruction (29-34)
  • instruction (185-209)
magicblock-core/src/compression/mod.rs (1)
  • derive_cda_from_pda (14-26)
magicblock-chainlink/src/remote_account_provider/chain_pubsub_client.rs (3)
  • url (63-65)
  • new (53-61)
  • new (391-404)
test-integration/programs/flexi-counter/src/state.rs (1)
  • pda (45-48)
magicblock-committor-service/src/tasks/task_builder.rs (2)
magicblock-committor-service/src/tasks/args_task.rs (3)
  • instruction (72-192)
  • get_compressed_data (322-335)
  • from (44-46)
magicblock-core/src/compression/mod.rs (1)
  • derive_cda_from_pda (14-26)
🔇 Additional comments (12)
test-integration/test-chainlink/src/ixtest_context.rs (5)

3-60: LGTM!

The imports and type alias changes correctly integrate PhotonIndexer and compressed-delegation types. The IxtestChainlink type alias properly includes PhotonClientImpl as the new generic parameter.


62-190: LGTM!

The IxtestContext struct correctly adds the photon_indexer field and properly wires it through initialization. The Endpoint::Compression configuration and PhotonIndexer instantiation are correctly integrated into all code paths.


773-782: LGTM!

The get_packed_accounts helper correctly encapsulates the common pattern of creating PackedAccounts with system accounts, reducing duplication across the compressed delegation methods.


784-801: LGTM!

The helper correctly abstracts the fetch-account-and-proof pattern. Per coding guidelines, .unwrap() is acceptable in test code. Based on learnings, PhotonIndexer already has built-in retry logic (~10 attempts), so no additional retry handling is needed.


454-458: Address queue and tree indices are intentionally identical in test setup.

Both address_queue_pubkey_index and address_merkle_tree_pubkey_index are set to the same value across test utilities, with state_queue_pubkey_index computed separately. This pattern is consistent in both test-chainlink and test-committor-service test files. If this intentionally reflects your Light Protocol test configuration (where address tree and queue are the same account), it's acceptable—just verify this matches your deployment expectations.

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

4-16: LGTM: Clean imports for compressed account support.

The new imports for light_client, light_sdk, and related types are well-organized and appropriate for the compressed data workflow. The logging import supports proper observability.


40-47: LGTM: CompressedData struct is well-defined.

The struct correctly encapsulates all necessary data for compressed operations: hash, serialized record bytes, remaining accounts, metadata, and validity proof. The derives are appropriate for the use case.


49-65: LGTM: Trait signatures correctly extended for compressed support.

The addition of optional PhotonIndexer parameter to both commit_tasks and finalize_tasks enables the compressed workflow while maintaining backward compatibility for non-compressed paths.


191-253: LGTM: Compressed commit path with proper error handling and parallelization.

The implementation correctly:

  • Validates photon_client presence with structured error (PhotonClientNotFound)
  • Uses ok_or(TaskBuilderError::MissingCommitId(...)) instead of .expect() for commit_id lookup (previous review addressed)
  • Parallelizes compressed data fetching using FuturesUnordered for performance
  • Propagates all errors properly via ?

309-337: LGTM: Efficient parallel compressed data fetching in finalize flow.

The get_compressed_data_for_accounts helper correctly:

  • Validates photon_client presence before attempting fetches
  • Uses FuturesUnordered for concurrent fetching (addressing previous performance suggestion)
  • Returns vec![None; ...] for non-compressed path, avoiding unnecessary allocations
  • Propagates errors properly via try_collect()

482-521: LGTM: Comprehensive error handling for compressed workflow.

The error enum additions properly cover all failure modes in the compressed path:

  • CompressedDataFetchError for indexer issues
  • LightSdkError for SDK-level failures
  • MissingStateTrees, MissingAddress, MissingCompressedData for validation failures
  • PhotonClientNotFound for configuration issues
  • MissingCommitId(Pubkey) for lookup failures with context

The signature() method correctly returns None for all new variants since these aren't transaction-related errors.


525-581: LGTM: Robust compressed data fetching with proper error handling.

The function correctly addresses all previous review concerns:

  • Lines 557-561: Uses .first().copied().ok_or() to safely extract tree_info, preventing panic on empty packed_tree_infos vector
  • Line 577: Removed unnecessary .clone() on to_account_metas().0 since it's already owned
  • All error paths use map_err or ok_or to produce structured TaskBuilderError variants
  • No .unwrap() or .expect() calls

The flow correctly derives the CDA, fetches the compressed account and validity proof, packs the tree info, and constructs the CompressedData for downstream task consumption.

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)
magicblock-committor-service/src/transaction_preparator/mod.rs (1)

103-124: Replace .expect() with proper error propagation.

Line 120 uses .expect() which violates the project's coding guidelines for production Rust code in magicblock-* paths. Although the comment states the possibility was "checked above," the prior check at lines 91-99 only validates with dummy lookup tables—the actual lookup tables returned from prepare_for_delivery may differ, making this expectation potentially invalid.

As per coding guidelines, .expect() in production code is a MAJOR issue.

🔎 Proposed fix
-        let message = TransactionUtils::assemble_tasks_tx(
-            authority,
-            &tx_strategy.optimized_tasks,
-            self.compute_budget_config.compute_unit_price,
-            &lookup_tables,
-        )
-        .expect("Possibility to assemble checked above")
-        .message;
+        let message = TransactionUtils::assemble_tasks_tx(
+            authority,
+            &tx_strategy.optimized_tasks,
+            self.compute_budget_config.compute_unit_price,
+            &lookup_tables,
+        )?
+        .message;

This requires updating the return type or error conversion, but provides proper error handling instead of panicking.

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

192-216: Log errors when fetching commit transaction slot.

The closure at lines 197-216 silently discards RPC errors via .ok() but only logs on success (line 211). Any RPC failure collapses to None without visibility. Additionally, line 211 logs the entire transaction object which is verbose—consider logging just the slot.

🔎 Proposed fix
         let commit_slot_fn: CommitSlotFn = Arc::new(move || {
             let rpc_client = rpc_client.clone();
             Box::pin(async move {
-                rpc_client
+                match rpc_client
                     .get_transaction(
                         &sig,
                         Some(RpcTransactionConfig {
                             commitment: Some(CommitmentConfig::confirmed()),
                             max_supported_transaction_version: Some(0),
                             ..Default::default()
                         }),
                     )
                     .await
-                    .map(|tx| {
-                        info!("Commit slot for tx {:?}", tx);
-                        tx.slot
-                    })
-                    .ok()
+                {
+                    Ok(tx) => {
+                        info!("Commit slot: {}", tx.slot);
+                        Some(tx.slot)
+                    }
+                    Err(err) => {
+                        warn!("Failed to fetch commit transaction slot for {}: {}", sig, err);
+                        None
+                    }
+                }
             })
         });
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b9fa057 and 7583af3.

📒 Files selected for processing (5)
  • magicblock-committor-service/src/intent_executor/mod.rs
  • magicblock-committor-service/src/intent_executor/two_stage_executor.rs
  • magicblock-committor-service/src/transaction_preparator/delivery_preparator.rs
  • magicblock-committor-service/src/transaction_preparator/mod.rs
  • test-integration/test-committor-service/tests/test_ix_commit_local.rs
🧰 Additional context used
📓 Path-based instructions (2)
{magicblock-*,programs,storage-proto}/**

⚙️ CodeRabbit configuration file

{magicblock-*,programs,storage-proto}/**: Treat any usage of .unwrap() or .expect() in production Rust code as a MAJOR issue.
These should not be categorized as trivial or nit-level concerns.
Request proper error handling or explicit justification with invariants.

Files:

  • magicblock-committor-service/src/transaction_preparator/mod.rs
  • magicblock-committor-service/src/intent_executor/two_stage_executor.rs
  • magicblock-committor-service/src/transaction_preparator/delivery_preparator.rs
  • magicblock-committor-service/src/intent_executor/mod.rs
{test-*,tools}/**

⚙️ CodeRabbit configuration file

Usage of .unwrap() or .expect() in test code is acceptable and may be treated as trivial.

Files:

  • test-integration/test-committor-service/tests/test_ix_commit_local.rs
🧠 Learnings (20)
📓 Common learnings
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 639
File: test-integration/test-committor-service/tests/test_ix_commit_local.rs:867-881
Timestamp: 2025-12-03T09:33:48.707Z
Learning: Repo: magicblock-labs/magicblock-validator PR: 639
Context: test-integration/test-committor-service/tests/test_ix_commit_local.rs (ix_commit_local)
Learning: The PhotonIndexer used for compressed account fetches (get_compressed_account) has built‑in retry logic (defaults to ~10 attempts), so tests should not add separate retry loops around compressed fetches unless there’s a specific need.
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 639
File: test-integration/test-chainlink/tests/ix_01_ensure-accounts.rs:85-114
Timestamp: 2025-11-19T11:31:24.218Z
Learning: In the magicblock-validator codebase, compressed delegation records are never subscribed to by design. Tests for compressed delegation flows should focus on verifying that the delegated account (e.g., counter PDA) is cloned as delegated and not subscribed, but do not need to check for subscription to delegation-record-like PDAs in the compressed path because subscriptions to compressed delegation records never occur.
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.
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 639
File: magicblock-committor-service/src/transaction_preparator/delivery_preparator.rs:172-193
Timestamp: 2025-11-26T13:27:46.702Z
Learning: The Photon indexer (PhotonIndexer from light-client) handles slot validation internally when an IndexerRpcConfig with a slot constraint is provided. Additional slot validation at the call site is not needed when fetching compressed data via get_compressed_data.
📚 Learning: 2025-12-03T09:33:48.707Z
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 639
File: test-integration/test-committor-service/tests/test_ix_commit_local.rs:867-881
Timestamp: 2025-12-03T09:33:48.707Z
Learning: Repo: magicblock-labs/magicblock-validator PR: 639
Context: test-integration/test-committor-service/tests/test_ix_commit_local.rs (ix_commit_local)
Learning: The PhotonIndexer used for compressed account fetches (get_compressed_account) has built‑in retry logic (defaults to ~10 attempts), so tests should not add separate retry loops around compressed fetches unless there’s a specific need.

Applied to files:

  • magicblock-committor-service/src/transaction_preparator/mod.rs
  • magicblock-committor-service/src/intent_executor/two_stage_executor.rs
  • magicblock-committor-service/src/transaction_preparator/delivery_preparator.rs
  • test-integration/test-committor-service/tests/test_ix_commit_local.rs
  • magicblock-committor-service/src/intent_executor/mod.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:

  • magicblock-committor-service/src/transaction_preparator/mod.rs
  • magicblock-committor-service/src/intent_executor/two_stage_executor.rs
  • magicblock-committor-service/src/transaction_preparator/delivery_preparator.rs
  • test-integration/test-committor-service/tests/test_ix_commit_local.rs
  • magicblock-committor-service/src/intent_executor/mod.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:

  • magicblock-committor-service/src/intent_executor/two_stage_executor.rs
  • magicblock-committor-service/src/transaction_preparator/delivery_preparator.rs
  • test-integration/test-committor-service/tests/test_ix_commit_local.rs
  • magicblock-committor-service/src/intent_executor/mod.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/intent_executor/two_stage_executor.rs
  • test-integration/test-committor-service/tests/test_ix_commit_local.rs
  • magicblock-committor-service/src/intent_executor/mod.rs
📚 Learning: 2025-10-28T13:15:42.706Z
Learnt from: bmuddha
Repo: magicblock-labs/magicblock-validator PR: 596
File: magicblock-processor/src/scheduler.rs:1-1
Timestamp: 2025-10-28T13:15:42.706Z
Learning: In magicblock-processor, transaction indexes were always set to 0 even before the changes in PR #596. The proper transaction indexing within slots will be addressed during the planned ledger rewrite.

Applied to files:

  • magicblock-committor-service/src/transaction_preparator/delivery_preparator.rs
📚 Learning: 2025-11-26T13:27:46.702Z
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 639
File: magicblock-committor-service/src/transaction_preparator/delivery_preparator.rs:172-193
Timestamp: 2025-11-26T13:27:46.702Z
Learning: The Photon indexer (PhotonIndexer from light-client) handles slot validation internally when an IndexerRpcConfig with a slot constraint is provided. Additional slot validation at the call site is not needed when fetching compressed data via get_compressed_data.

Applied to files:

  • magicblock-committor-service/src/transaction_preparator/delivery_preparator.rs
  • 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:

  • magicblock-committor-service/src/transaction_preparator/delivery_preparator.rs
  • 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:

  • magicblock-committor-service/src/transaction_preparator/delivery_preparator.rs
📚 Learning: 2025-10-21T11:00:18.396Z
Learnt from: bmuddha
Repo: magicblock-labs/magicblock-validator PR: 578
File: magicblock-aperture/src/encoder.rs:176-187
Timestamp: 2025-10-21T11:00:18.396Z
Learning: In the magicblock validator, the current slot is always the root slot. The SlotEncoder in magicblock-aperture/src/encoder.rs correctly sets `root: slot` because there is no lag between current and root slots in this architecture.

Applied to files:

  • magicblock-committor-service/src/transaction_preparator/delivery_preparator.rs
📚 Learning: 2025-11-20T08:57:07.217Z
Learnt from: thlorenz
Repo: magicblock-labs/magicblock-validator PR: 650
File: magicblock-chainlink/src/submux/subscription_task.rs:13-99
Timestamp: 2025-11-20T08:57:07.217Z
Learning: In the magicblock-validator repository, avoid posting review comments that merely confirm code is correct or matches intended behavior without providing actionable feedback, suggestions for improvement, or identifying potential issues. Such confirmatory comments are considered unhelpful noise by the maintainers.

Applied to files:

  • magicblock-committor-service/src/transaction_preparator/delivery_preparator.rs
  • magicblock-committor-service/src/intent_executor/mod.rs
📚 Learning: 2025-11-21T11:03:26.756Z
Learnt from: thlorenz
Repo: magicblock-labs/magicblock-validator PR: 664
File: magicblock-chainlink/src/testing/mod.rs:342-370
Timestamp: 2025-11-21T11:03:26.756Z
Learning: In the magicblock-validator codebase, avoid leaving review comments that merely acknowledge code is correct or well-structured when there is no actionable suggestion, improvement, or issue to flag. Only comment when there is something specific to recommend, fix, or clarify.

Applied to files:

  • magicblock-committor-service/src/transaction_preparator/delivery_preparator.rs
  • magicblock-committor-service/src/intent_executor/mod.rs
📚 Learning: 2025-12-03T09:36:01.527Z
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 639
File: magicblock-chainlink/src/remote_account_provider/mod.rs:1350-1353
Timestamp: 2025-12-03T09:36:01.527Z
Learning: Repo: magicblock-labs/magicblock-validator
File: magicblock-chainlink/src/remote_account_provider/mod.rs
Context: consolidate_fetched_remote_accounts
Learning: For unexpected result counts (>2), the project prefers logging an error and returning an empty Vec over panicking; acceptable during development per maintainer (Dodecahedr0x).

Applied to files:

  • magicblock-committor-service/src/transaction_preparator/delivery_preparator.rs
  • test-integration/test-committor-service/tests/test_ix_commit_local.rs
  • magicblock-committor-service/src/intent_executor/mod.rs
📚 Learning: 2025-11-19T11:31:24.218Z
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 639
File: test-integration/test-chainlink/tests/ix_01_ensure-accounts.rs:85-114
Timestamp: 2025-11-19T11:31:24.218Z
Learning: In the magicblock-validator codebase, compressed delegation records are never subscribed to by design. Tests for compressed delegation flows should focus on verifying that the delegated account (e.g., counter PDA) is cloned as delegated and not subscribed, but do not need to check for subscription to delegation-record-like PDAs in the compressed path because subscriptions to compressed delegation records never occur.

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-25T11:07:20.001Z
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 639
File: test-integration/programs/flexi-counter/src/processor.rs:643-680
Timestamp: 2025-11-25T11:07:20.001Z
Learning: In the compressed delegation architecture, ownership reassignment during undelegation is handled by the delegation program itself, not by the owner program's external undelegate handler. The external undelegate handler (e.g., `process_external_undelegate_compressed` in flexi-counter) is a callback for program-specific cleanup (restoring lamports and data) after the delegation program has already reassigned ownership back to the original owner stored in the CompressedDelegationRecord.

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
  • magicblock-committor-service/src/intent_executor/mod.rs
📚 Learning: 2025-12-01T16:02:05.367Z
Learnt from: thlorenz
Repo: magicblock-labs/magicblock-validator PR: 703
File: magicblock-chainlink/src/submux/mod.rs:652-654
Timestamp: 2025-12-01T16:02:05.367Z
Learning: In magicblock-chainlink/src/submux/mod.rs, the subscribe_program method intentionally adds program_id to program_subs before attempting the subscription. This ensures that even if the initial subscription fails or only partially succeeds across clients, the reconnection logic will retry the subscription. This is a deliberate design pattern for resilience in the multi-client architecture and should not be "fixed" to remove entries on failure.

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-24T14:21:00.996Z
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 639
File: Cargo.toml:58-58
Timestamp: 2025-11-24T14:21:00.996Z
Learning: In the magicblock-validator codebase, magicblock-api/Cargo.toml intentionally uses borsh = "1.5.3" (instead of the workspace version 0.10.4) because it needs to deserialize types from the magic-domain-program external dependency, which requires borsh 1.5.x compatibility. This is an intentional exception for interoperability with the magic domain program.

Applied to files:

  • test-integration/test-committor-service/tests/test_ix_commit_local.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:

  • 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 (3)
magicblock-committor-service/src/transaction_preparator/delivery_preparator.rs (3)
magicblock-committor-service/src/tasks/task_builder.rs (1)
  • get_compressed_data (525-581)
magicblock-committor-service/src/tasks/buffer_task.rs (4)
  • get_compressed_data (171-175)
  • strategy (135-137)
  • delegated_account (177-183)
  • from (72-78)
magicblock-committor-service/src/intent_executor/two_stage_executor.rs (1)
  • None (86-86)
test-integration/test-committor-service/tests/test_ix_commit_local.rs (5)
magicblock-core/src/compression/mod.rs (1)
  • derive_cda_from_pda (14-26)
magicblock-committor-service/src/service.rs (1)
  • try_start (265-294)
magicblock-committor-service/src/tasks/buffer_task.rs (1)
  • is_compressed (160-162)
magicblock-committor-service/src/tasks/mod.rs (1)
  • is_compressed (103-103)
compressed-delegation-client/src/lib.rs (1)
  • id (61-63)
magicblock-committor-service/src/intent_executor/mod.rs (2)
magicblock-committor-service/src/intent_executor/task_info_fetcher.rs (2)
  • Self (314-322)
  • Self (324-332)
magicblock-committor-service/src/tasks/task_builder.rs (2)
  • finalize_tasks (60-64)
  • finalize_tasks (259-479)
🔇 Additional comments (26)
test-integration/test-committor-service/tests/test_ix_commit_local.rs (8)

8-11: LGTM!

The new imports for compressed account support are well-organized and correctly bring in the necessary types from the light-client indexer and compressed delegation client.


58-63: LGTM!

The CommitAccountMode enum cleanly captures the four test mode combinations and follows Rust naming conventions.


184-200: LGTM!

The explicit match arms for CommitAccountMode variants are now used, addressing the previous review feedback about replacing the wildcard pattern. This provides compile-time safety for future enum additions.


619-628: LGTM!

The expected strategy count is now correctly set to 5 commits for the 5 compressed accounts, addressing the previous review feedback.


697-738: LGTM!

The create_bundles function is well-structured with clean branching logic for compressed vs. regular account initialization. The async spawning pattern is appropriate for parallel account creation.


767-771: LGTM!

Good use of the matches! macro for checking compressed variants - this is idiomatic Rust and maintains clarity.


928-964: LGTM!

The compressed account validation logic correctly:

  1. Validates the on-chain "shell" account has owner compressed_delegation_client::ID with empty data
  2. Derives the CDA address and fetches the compressed account from the Photon indexer
  3. Validates the compressed account data against expectations

Based on learnings, the PhotonIndexer has built-in retry logic (~10 attempts), so the absence of explicit retry loops here is intentional and correct.


1115-1163: LGTM!

The validate_compressed_account function correctly:

  1. Parses the CompressedDelegationRecord from the compressed account data
  2. Validates lamports, data, and owner against expectations
  3. Logs the actual compared values (data.lamports, data.owner) in trace messages

This addresses the previous review feedback about inconsistent logging.

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

1-24: LGTM - Import updates for PhotonIndexer integration.

The new imports properly support the PhotonIndexer and CommitSlotFn threading through the transaction preparation flow.


29-49: LGTM - Trait signature extended for compressed account support.

The prepare_for_strategy signature now accepts photon_client and commit_slot_fn parameters to enable compressed data fetching during task preparation. The lifetime annotation 'a is correctly applied to support the async closure.

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

1-22: LGTM - Import updates for commit slot functionality.

The imports properly support the new CommitSlotFn mechanism and RPC transaction configuration.


71-134: LGTM - Commit phase passes None for commit_slot_fn.

During the commit phase, there's no prior commit to reference, so passing None::<CommitSlotFn> is semantically correct.


218-279: LGTM - Finalize loop properly threads commit_slot_fn.

The finalize execution loop correctly passes the cloned commit_slot_fn to enable slot-aware data fetching for compressed accounts.

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

63-65: LGTM - Type aliases for async commit slot function.

The BoxFut and CommitSlotFn type aliases properly encapsulate the async slot-fetching capability with correct lifetime bounds and thread-safety constraints (Send + Sync).


114-148: LGTM - PhotonIndexer field added to executor.

The photon_client: Option<Arc<PhotonIndexer>> field is properly integrated into IntentExecutorImpl and initialized in the constructor, addressing the earlier concern about hard-coded localhost instances.


170-196: LGTM - Single-stage flow threads photon_client.

The commit_tasks call now properly receives &self.photon_client to support compressed account handling in standalone actions.


198-246: LGTM - Two-stage task building threads photon_client.

Both commit_tasks and finalize_tasks futures correctly receive the photon client reference for compressed data support.


334-378: Acknowledge existing TODO for mixed compression handling.

The TODO at line 338 correctly flags the gap where mixed compressed/non-compressed tasks in a single strategy aren't properly handled. The current .any() approach treats the entire strategy as compressed if any task is compressed, which may cause incorrect commit ID fetching for non-compressed tasks.

This was flagged in a prior review and marked as addressed—verify the intended handling is documented or tracked.


563-575: LGTM - Error handling extended for compression-related failures.

The new InconsistentTaskCompression error variant is properly handled in persist_result, mapping to CommitStatus::Failed which is appropriate for this configuration error.


635-665: LGTM - prepare_and_execute_strategy properly threads new parameters.

The function now accepts commit_slot_fn and passes both it and photon_client to prepare_for_strategy, enabling the full compressed-data flow.

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

1-42: LGTM - Import updates for compressed data support.

The imports properly support PhotonIndexer, IndexerRpcConfig, CommitSlotFn, and the new task types (BufferPreparationTask, PreparationTask).


63-107: LGTM - prepare_for_delivery extended for photon context.

The signature now accepts photon_client and commit_slot_fn, which are correctly cloned and threaded into per-task preparation via the async closure.


109-205: LGTM - Task preparation handles Buffer and Compressed variants.

The new match structure properly separates:

  • Buffer path (lines 125-166): Maintains existing buffer initialization, chunk writing, and status persistence with proper state transitions.
  • Compressed path (lines 167-201): Fetches fresh compressed data from the indexer with slot-aware configuration, includes proper error handling with contextual logging.

The error handling at lines 193-198 addresses the prior review feedback about preserving error context. Based on learnings, Photon handles slot validation internally, so the IndexerRpcConfig usage is correct.


207-266: LGTM - Error recovery properly threads photon context.

The prepare_task_handling_errors function correctly:

  1. Passes commit_slot_fn.clone() to handle the lifetime properly
  2. Handles AccountAlreadyInitializedError with cleanup and retry
  3. Threads photon context through the retry path

268-335: LGTM - Buffer functions updated to accept BufferPreparationTask.

The parameter type change from generic PreparationTask to BufferPreparationTask improves type safety and clarifies the expected input for buffer-specific operations.


620-648: LGTM - Error variants properly distinguish failure modes.

New variants added:

  • CompressedDataNotFound - for missing compressed data
  • DelegatedAccountNotFound - when task lacks delegated account
  • PhotonClientNotFound - when photon client is required but absent
  • TaskBuilderError - wraps upstream builder errors
  • TransactionCreationError/TransactionSigningError - for transaction construction failures

These provide clear error categorization for debugging compressed flows.

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

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7583af3 and fd609e6.

⛔ Files ignored due to path filters (2)
  • Cargo.lock is excluded by !**/*.lock
  • test-integration/Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (3)
  • config.example.toml
  • magicblock-chainlink/src/chainlink/fetch_cloner.rs
  • magicblock-committor-service/src/tasks/task_builder.rs
🧰 Additional context used
📓 Path-based instructions (1)
{magicblock-*,programs,storage-proto}/**

⚙️ CodeRabbit configuration file

{magicblock-*,programs,storage-proto}/**: Treat any usage of .unwrap() or .expect() in production Rust code as a MAJOR issue.
These should not be categorized as trivial or nit-level concerns.
Request proper error handling or explicit justification with invariants.

Files:

  • magicblock-committor-service/src/tasks/task_builder.rs
  • magicblock-chainlink/src/chainlink/fetch_cloner.rs
🧠 Learnings (13)
📓 Common learnings
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 639
File: test-integration/test-committor-service/tests/test_ix_commit_local.rs:867-881
Timestamp: 2025-12-03T09:33:48.707Z
Learning: Repo: magicblock-labs/magicblock-validator PR: 639
Context: test-integration/test-committor-service/tests/test_ix_commit_local.rs (ix_commit_local)
Learning: The PhotonIndexer used for compressed account fetches (get_compressed_account) has built‑in retry logic (defaults to ~10 attempts), so tests should not add separate retry loops around compressed fetches unless there’s a specific need.
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 639
File: test-integration/test-chainlink/tests/ix_01_ensure-accounts.rs:85-114
Timestamp: 2025-11-19T11:31:24.218Z
Learning: In the magicblock-validator codebase, compressed delegation records are never subscribed to by design. Tests for compressed delegation flows should focus on verifying that the delegated account (e.g., counter PDA) is cloned as delegated and not subscribed, but do not need to check for subscription to delegation-record-like PDAs in the compressed path because subscriptions to compressed delegation records never occur.
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.
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 639
File: magicblock-committor-service/src/transaction_preparator/delivery_preparator.rs:172-193
Timestamp: 2025-11-26T13:27:46.702Z
Learning: The Photon indexer (PhotonIndexer from light-client) handles slot validation internally when an IndexerRpcConfig with a slot constraint is provided. Additional slot validation at the call site is not needed when fetching compressed data via get_compressed_data.
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
📚 Learning: 2025-12-03T09:33:48.707Z
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 639
File: test-integration/test-committor-service/tests/test_ix_commit_local.rs:867-881
Timestamp: 2025-12-03T09:33:48.707Z
Learning: Repo: magicblock-labs/magicblock-validator PR: 639
Context: test-integration/test-committor-service/tests/test_ix_commit_local.rs (ix_commit_local)
Learning: The PhotonIndexer used for compressed account fetches (get_compressed_account) has built‑in retry logic (defaults to ~10 attempts), so tests should not add separate retry loops around compressed fetches unless there’s a specific need.

Applied to files:

  • magicblock-committor-service/src/tasks/task_builder.rs
  • magicblock-chainlink/src/chainlink/fetch_cloner.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:

  • magicblock-committor-service/src/tasks/task_builder.rs
  • magicblock-chainlink/src/chainlink/fetch_cloner.rs
📚 Learning: 2025-12-03T09:36:01.527Z
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 639
File: magicblock-chainlink/src/remote_account_provider/mod.rs:1350-1353
Timestamp: 2025-12-03T09:36:01.527Z
Learning: Repo: magicblock-labs/magicblock-validator
File: magicblock-chainlink/src/remote_account_provider/mod.rs
Context: consolidate_fetched_remote_accounts
Learning: For unexpected result counts (>2), the project prefers logging an error and returning an empty Vec over panicking; acceptable during development per maintainer (Dodecahedr0x).

Applied to files:

  • magicblock-committor-service/src/tasks/task_builder.rs
  • magicblock-chainlink/src/chainlink/fetch_cloner.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/tasks/task_builder.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:

  • magicblock-committor-service/src/tasks/task_builder.rs
  • magicblock-chainlink/src/chainlink/fetch_cloner.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/tasks/task_builder.rs
  • magicblock-chainlink/src/chainlink/fetch_cloner.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:

  • magicblock-committor-service/src/tasks/task_builder.rs
📚 Learning: 2025-12-17T12:46:36.207Z
Learnt from: GabrielePicco
Repo: magicblock-labs/magicblock-validator PR: 738
File: magicblock-chainlink/src/chainlink/fetch_cloner.rs:1109-1196
Timestamp: 2025-12-17T12:46:36.207Z
Learning: In magicblock-chainlink/src/chainlink/fetch_cloner.rs, eATA account subscriptions are intentionally NOT cancelled even when the eATA doesn't exist or delegation conversion fails. The subscriptions are kept active to watch for future creation or delegation of eATA accounts (per maintainer GabrielePicco).

Applied to files:

  • magicblock-chainlink/src/chainlink/fetch_cloner.rs
📚 Learning: 2025-11-19T11:31:24.218Z
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 639
File: test-integration/test-chainlink/tests/ix_01_ensure-accounts.rs:85-114
Timestamp: 2025-11-19T11:31:24.218Z
Learning: In the magicblock-validator codebase, compressed delegation records are never subscribed to by design. Tests for compressed delegation flows should focus on verifying that the delegated account (e.g., counter PDA) is cloned as delegated and not subscribed, but do not need to check for subscription to delegation-record-like PDAs in the compressed path because subscriptions to compressed delegation records never occur.

Applied to files:

  • magicblock-chainlink/src/chainlink/fetch_cloner.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:

  • magicblock-chainlink/src/chainlink/fetch_cloner.rs
📚 Learning: 2025-12-01T16:02:05.367Z
Learnt from: thlorenz
Repo: magicblock-labs/magicblock-validator PR: 703
File: magicblock-chainlink/src/submux/mod.rs:652-654
Timestamp: 2025-12-01T16:02:05.367Z
Learning: In magicblock-chainlink/src/submux/mod.rs, the subscribe_program method intentionally adds program_id to program_subs before attempting the subscription. This ensures that even if the initial subscription fails or only partially succeeds across clients, the reconnection logic will retry the subscription. This is a deliberate design pattern for resilience in the multi-client architecture and should not be "fixed" to remove entries on failure.

Applied to files:

  • magicblock-chainlink/src/chainlink/fetch_cloner.rs
📚 Learning: 2025-11-25T11:07:20.001Z
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 639
File: test-integration/programs/flexi-counter/src/processor.rs:643-680
Timestamp: 2025-11-25T11:07:20.001Z
Learning: In the compressed delegation architecture, ownership reassignment during undelegation is handled by the delegation program itself, not by the owner program's external undelegate handler. The external undelegate handler (e.g., `process_external_undelegate_compressed` in flexi-counter) is a callback for program-specific cleanup (restoring lamports and data) after the delegation program has already reassigned ownership back to the original owner stored in the CompressedDelegationRecord.

Applied to files:

  • magicblock-chainlink/src/chainlink/fetch_cloner.rs
🧬 Code graph analysis (1)
magicblock-chainlink/src/chainlink/fetch_cloner.rs (2)
magicblock-chainlink/src/remote_account_provider/photon_client.rs (1)
  • new (29-31)
compressed-delegation-client/src/lib.rs (1)
  • id (61-63)
🔇 Additional comments (10)
magicblock-committor-service/src/tasks/task_builder.rs (8)

1-38: Imports look well-organized.

The imports are properly structured with external dependencies followed by local module imports. The duplicate import issue from previous reviews has been addressed.


40-47: Data structure is well-defined.

The CompressedData struct appropriately encapsulates all necessary compressed account information for task processing.


49-65: Trait API cleanly extends for compression support.

The optional PhotonIndexer parameter enables compressed paths without breaking existing non-compressed flows.


67-109: Commit task creation logic is correct.

The threshold-based decision between CommitDiff and Commit tasks is well-implemented, with appropriate fallback when base account is unavailable.


111-256: Commit tasks implementation is well-structured.

Good improvements from previous reviews:

  • Proper error propagation with ok_or(TaskBuilderError::MissingCommitId) instead of .expect()
  • Concurrent compressed data fetching with FuturesUnordered and try_collect
  • Clean separation between compressed and non-compressed paths

258-479: Finalize tasks implementation addresses previous feedback well.

Key improvements:

  • get_compressed_data_for_accounts now uses FuturesUnordered for concurrent fetching
  • Consistent error handling via ? propagation throughout
  • TODO at lines 451-460 properly documents the compressed undelegate limitation with issue reference

The separation of helpers (finalize_task, undelegate_task, get_compressed_data_for_accounts, process_commit) improves readability and maintainability.


482-521: Error handling is comprehensive.

The TaskBuilderError enum properly covers all compression-related failure modes including:

  • MissingCommitId (replaces previous .expect() usage)
  • Distinct errors for state trees, address, and data availability
  • Proper source attribution with #[source] for error chaining

525-581: Compressed data fetching is robust.

All previous review concerns have been addressed:

  • Line 557-561: Safe extraction with .first().copied().ok_or() prevents panic on empty packed_tree_infos
  • Line 577: Removed unnecessary .clone() on owned Vec
  • Consistent error propagation via map_err and ?
magicblock-chainlink/src/chainlink/fetch_cloner.rs (2)

1105-1142: Compressed delegation handling in bulk fetch path looks correct.

The logic correctly deserializes the CompressedDelegationRecord, sets all necessary fields (compressed, lamports, owner, data, delegated), and properly calculates delegated_to_other by checking for both validator_pubkey and Pubkey::default() (confined accounts).

This addresses the previously flagged issues about missing lamports/compressed flag and delegated_to_other field.


574-582: Track commit frequency limitation for compressed delegation.

The TODO comment indicates that commit_frequency_ms is not supported for compressed delegation records. This limitation means that compressed delegated accounts always use a commit frequency of 0, which might not match the intended behavior.

Would you like me to open an issue to track implementing commit frequency support for compressed delegation records, or help implement this feature?

⛔ Skipped due to learnings
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 639
File: test-integration/test-chainlink/tests/ix_01_ensure-accounts.rs:85-114
Timestamp: 2025-11-19T11:31:24.218Z
Learning: In the magicblock-validator codebase, compressed delegation records are never subscribed to by design. Tests for compressed delegation flows should focus on verifying that the delegated account (e.g., counter PDA) is cloned as delegated and not subscribed, but do not need to check for subscription to delegation-record-like PDAs in the compressed path because subscriptions to compressed delegation records never occur.
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 639
File: test-integration/test-committor-service/tests/test_ix_commit_local.rs:867-881
Timestamp: 2025-12-03T09:33:48.707Z
Learning: Repo: magicblock-labs/magicblock-validator PR: 639
Context: test-integration/test-committor-service/tests/test_ix_commit_local.rs (ix_commit_local)
Learning: The PhotonIndexer used for compressed account fetches (get_compressed_account) has built‑in retry logic (defaults to ~10 attempts), so tests should not add separate retry loops around compressed fetches unless there’s a specific need.
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
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 639
File: test-integration/programs/flexi-counter/src/processor.rs:643-680
Timestamp: 2025-11-25T11:07:20.001Z
Learning: In the compressed delegation architecture, ownership reassignment during undelegation is handled by the delegation program itself, not by the owner program's external undelegate handler. The external undelegate handler (e.g., `process_external_undelegate_compressed` in flexi-counter) is a callback for program-specific cleanup (restoring lamports and data) after the delegation program has already reassigned ownership back to the original owner stored in the CompressedDelegationRecord.

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 (3)
magicblock-chainlink/src/chainlink/fetch_cloner.rs (3)

1879-1879: MAJOR: Avoid .unwrap() in production code paths.

The .unwrap() here assumes the vector always has exactly 2 elements, but if this invariant is violated, the entire validator could panic. Even with the safety comment, this violates the coding guideline requiring proper error handling in production code.

🔎 Proposed fix
                 .await
-                // SAFETY: we always get two results here
-                .map(|mut accs| {
-                    let acc_last = accs.pop().unwrap();
-                    let acc_first = accs.pop().unwrap();
+                .and_then(|mut accs| {
+                    if accs.len() != 2 {
+                        return Err(ChainlinkError::ProgramAccountResolutionsFailed(
+                            format!("Expected 2 accounts, got {}", accs.len())
+                        ).into());
+                    }
+                    let acc_last = accs.pop().expect("checked len");
+                    let acc_first = accs.pop().expect("checked len");
                     (acc_first, acc_last)
                 })
-                .map_err(ChainlinkError::from)
-                .and_then(|(acc, deleg)| {
+                .and_then(|(acc, deleg)| {

As per coding guidelines.


2728-2728: MAJOR: Replace .expect() on lock poisoning with proper error handling.

The .expect() here will panic the entire validator if the lock is poisoned. Lock poisoning should be handled gracefully by returning an error result rather than crashing the process.

🔎 Proposed fix
         {
-            let mut pending = self
-                .pending_requests
-                .lock()
-                .expect("pending_requests lock poisoned");
+            let mut pending = self.pending_requests.lock().map_err(|_| {
+                ChainlinkError::Other(
+                    "Failed to acquire pending_requests lock (poisoned)".into(),
+                )
+            })?;

As per coding guidelines. Note that this requires propagating the error from this code block. Similar fix needed at line 2783.


2783-2783: MAJOR: Replace .expect() on lock poisoning with proper error handling.

Same issue as line 2728 - panicking on lock poisoning will crash the validator. This should return an error instead.

🔎 Proposed fix
         {
-            let mut pending = self
-                .pending_requests
-                .lock()
-                .expect("pending_requests lock poisoned");
+            let mut pending = self.pending_requests.lock().map_err(|_| {
+                ChainlinkError::Other(
+                    "Failed to acquire pending_requests lock (poisoned)".into(),
+                )
+            })?;

As per coding guidelines.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fd609e6 and 65ba648.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (2)
  • config.example.toml
  • magicblock-chainlink/src/chainlink/fetch_cloner.rs
🧰 Additional context used
📓 Path-based instructions (1)
{magicblock-*,programs,storage-proto}/**

⚙️ CodeRabbit configuration file

{magicblock-*,programs,storage-proto}/**: Treat any usage of .unwrap() or .expect() in production Rust code as a MAJOR issue.
These should not be categorized as trivial or nit-level concerns.
Request proper error handling or explicit justification with invariants.

Files:

  • magicblock-chainlink/src/chainlink/fetch_cloner.rs
🧠 Learnings (12)
📓 Common learnings
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 639
File: test-integration/test-committor-service/tests/test_ix_commit_local.rs:867-881
Timestamp: 2025-12-03T09:33:48.707Z
Learning: Repo: magicblock-labs/magicblock-validator PR: 639
Context: test-integration/test-committor-service/tests/test_ix_commit_local.rs (ix_commit_local)
Learning: The PhotonIndexer used for compressed account fetches (get_compressed_account) has built‑in retry logic (defaults to ~10 attempts), so tests should not add separate retry loops around compressed fetches unless there’s a specific need.
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 639
File: test-integration/test-chainlink/tests/ix_01_ensure-accounts.rs:85-114
Timestamp: 2025-11-19T11:31:24.218Z
Learning: In the magicblock-validator codebase, compressed delegation records are never subscribed to by design. Tests for compressed delegation flows should focus on verifying that the delegated account (e.g., counter PDA) is cloned as delegated and not subscribed, but do not need to check for subscription to delegation-record-like PDAs in the compressed path because subscriptions to compressed delegation records never occur.
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.
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 639
File: magicblock-committor-service/src/transaction_preparator/delivery_preparator.rs:172-193
Timestamp: 2025-11-26T13:27:46.702Z
Learning: The Photon indexer (PhotonIndexer from light-client) handles slot validation internally when an IndexerRpcConfig with a slot constraint is provided. Additional slot validation at the call site is not needed when fetching compressed data via get_compressed_data.
📚 Learning: 2025-12-03T09:33:48.707Z
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 639
File: test-integration/test-committor-service/tests/test_ix_commit_local.rs:867-881
Timestamp: 2025-12-03T09:33:48.707Z
Learning: Repo: magicblock-labs/magicblock-validator PR: 639
Context: test-integration/test-committor-service/tests/test_ix_commit_local.rs (ix_commit_local)
Learning: The PhotonIndexer used for compressed account fetches (get_compressed_account) has built‑in retry logic (defaults to ~10 attempts), so tests should not add separate retry loops around compressed fetches unless there’s a specific need.

Applied to files:

  • magicblock-chainlink/src/chainlink/fetch_cloner.rs
📚 Learning: 2025-12-17T12:46:36.207Z
Learnt from: GabrielePicco
Repo: magicblock-labs/magicblock-validator PR: 738
File: magicblock-chainlink/src/chainlink/fetch_cloner.rs:1109-1196
Timestamp: 2025-12-17T12:46:36.207Z
Learning: In magicblock-chainlink/src/chainlink/fetch_cloner.rs, eATA account subscriptions are intentionally NOT cancelled even when the eATA doesn't exist or delegation conversion fails. The subscriptions are kept active to watch for future creation or delegation of eATA accounts (per maintainer GabrielePicco).

Applied to files:

  • magicblock-chainlink/src/chainlink/fetch_cloner.rs
📚 Learning: 2025-12-03T09:36:01.527Z
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 639
File: magicblock-chainlink/src/remote_account_provider/mod.rs:1350-1353
Timestamp: 2025-12-03T09:36:01.527Z
Learning: Repo: magicblock-labs/magicblock-validator
File: magicblock-chainlink/src/remote_account_provider/mod.rs
Context: consolidate_fetched_remote_accounts
Learning: For unexpected result counts (>2), the project prefers logging an error and returning an empty Vec over panicking; acceptable during development per maintainer (Dodecahedr0x).

Applied to files:

  • magicblock-chainlink/src/chainlink/fetch_cloner.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:

  • magicblock-chainlink/src/chainlink/fetch_cloner.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:

  • magicblock-chainlink/src/chainlink/fetch_cloner.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-chainlink/src/chainlink/fetch_cloner.rs
📚 Learning: 2025-11-19T11:31:24.218Z
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 639
File: test-integration/test-chainlink/tests/ix_01_ensure-accounts.rs:85-114
Timestamp: 2025-11-19T11:31:24.218Z
Learning: In the magicblock-validator codebase, compressed delegation records are never subscribed to by design. Tests for compressed delegation flows should focus on verifying that the delegated account (e.g., counter PDA) is cloned as delegated and not subscribed, but do not need to check for subscription to delegation-record-like PDAs in the compressed path because subscriptions to compressed delegation records never occur.

Applied to files:

  • magicblock-chainlink/src/chainlink/fetch_cloner.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:

  • magicblock-chainlink/src/chainlink/fetch_cloner.rs
📚 Learning: 2025-12-01T16:02:05.367Z
Learnt from: thlorenz
Repo: magicblock-labs/magicblock-validator PR: 703
File: magicblock-chainlink/src/submux/mod.rs:652-654
Timestamp: 2025-12-01T16:02:05.367Z
Learning: In magicblock-chainlink/src/submux/mod.rs, the subscribe_program method intentionally adds program_id to program_subs before attempting the subscription. This ensures that even if the initial subscription fails or only partially succeeds across clients, the reconnection logic will retry the subscription. This is a deliberate design pattern for resilience in the multi-client architecture and should not be "fixed" to remove entries on failure.

Applied to files:

  • magicblock-chainlink/src/chainlink/fetch_cloner.rs
📚 Learning: 2025-11-25T11:07:20.001Z
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 639
File: test-integration/programs/flexi-counter/src/processor.rs:643-680
Timestamp: 2025-11-25T11:07:20.001Z
Learning: In the compressed delegation architecture, ownership reassignment during undelegation is handled by the delegation program itself, not by the owner program's external undelegate handler. The external undelegate handler (e.g., `process_external_undelegate_compressed` in flexi-counter) is a callback for program-specific cleanup (restoring lamports and data) after the delegation program has already reassigned ownership back to the original owner stored in the CompressedDelegationRecord.

Applied to files:

  • magicblock-chainlink/src/chainlink/fetch_cloner.rs
📚 Learning: 2025-12-15T20:32:57.435Z
Learnt from: thlorenz
Repo: magicblock-labs/magicblock-validator PR: 746
File: magicblock-config/src/tests.rs:680-703
Timestamp: 2025-12-15T20:32:57.435Z
Learning: In the magicblock-validator repository, gRPC remotes do not support URL aliases (mainnet, devnet, local) like RPC and WebSocket remotes do. The resolve_url function passes gRPC URLs through as-is without alias resolution.

Applied to files:

  • config.example.toml
🧬 Code graph analysis (1)
magicblock-chainlink/src/chainlink/fetch_cloner.rs (2)
magicblock-chainlink/src/remote_account_provider/photon_client.rs (1)
  • new (29-31)
compressed-delegation-client/src/lib.rs (1)
  • id (61-63)
🔇 Additional comments (4)
config.example.toml (2)

61-65: LGTM: Formatting improvement for remotes array.

The multi-line format with trailing commas improves readability and makes version control diffs cleaner when adding or removing remote endpoints.


233-246: LGTM: Compression configuration section is well-structured.

The new [compression] section appropriately introduces optional Photon indexer configuration fields. The fields are correctly commented out as examples, environment variable naming follows the established pattern, and the documentation is consistent with other sections in the config file. This aligns well with the PR's objective of adding compressed-account support.

magicblock-chainlink/src/chainlink/fetch_cloner.rs (2)

574-575: Track the TODO for compressed delegation commit frequency support.

The TODO comment indicates that commit frequency is not yet supported for compressed delegation records. This converts the record with commit_frequency_ms: 0, which may not reflect the actual desired behavior.

Consider opening an issue to track this limitation and determine if commit frequency support should be added for compressed delegation records, or if the current behavior (always using 0) is intentional and acceptable.


1587-1590: LGTM: Compressed account handling in undelegation refresh.

Correctly short-circuits the delegation record fetch for compressed accounts, since compressed delegation records are stored inline with the account data rather than in a separate PDA.

Based on learnings.

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

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 65ba648 and 9ae7d20.

📒 Files selected for processing (1)
  • magicblock-chainlink/src/chainlink/fetch_cloner.rs
🧰 Additional context used
📓 Path-based instructions (1)
{magicblock-*,programs,storage-proto}/**

⚙️ CodeRabbit configuration file

{magicblock-*,programs,storage-proto}/**: Treat any usage of .unwrap() or .expect() in production Rust code as a MAJOR issue.
These should not be categorized as trivial or nit-level concerns.
Request proper error handling or explicit justification with invariants.

Files:

  • magicblock-chainlink/src/chainlink/fetch_cloner.rs
🧠 Learnings (11)
📓 Common learnings
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 639
File: test-integration/test-committor-service/tests/test_ix_commit_local.rs:867-881
Timestamp: 2025-12-03T09:33:48.707Z
Learning: Repo: magicblock-labs/magicblock-validator PR: 639
Context: test-integration/test-committor-service/tests/test_ix_commit_local.rs (ix_commit_local)
Learning: The PhotonIndexer used for compressed account fetches (get_compressed_account) has built‑in retry logic (defaults to ~10 attempts), so tests should not add separate retry loops around compressed fetches unless there’s a specific need.
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 639
File: test-integration/test-chainlink/tests/ix_01_ensure-accounts.rs:85-114
Timestamp: 2025-11-19T11:31:24.218Z
Learning: In the magicblock-validator codebase, compressed delegation records are never subscribed to by design. Tests for compressed delegation flows should focus on verifying that the delegated account (e.g., counter PDA) is cloned as delegated and not subscribed, but do not need to check for subscription to delegation-record-like PDAs in the compressed path because subscriptions to compressed delegation records never occur.
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.
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 639
File: magicblock-committor-service/src/transaction_preparator/delivery_preparator.rs:172-193
Timestamp: 2025-11-26T13:27:46.702Z
Learning: The Photon indexer (PhotonIndexer from light-client) handles slot validation internally when an IndexerRpcConfig with a slot constraint is provided. Additional slot validation at the call site is not needed when fetching compressed data via get_compressed_data.
📚 Learning: 2025-12-03T09:33:48.707Z
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 639
File: test-integration/test-committor-service/tests/test_ix_commit_local.rs:867-881
Timestamp: 2025-12-03T09:33:48.707Z
Learning: Repo: magicblock-labs/magicblock-validator PR: 639
Context: test-integration/test-committor-service/tests/test_ix_commit_local.rs (ix_commit_local)
Learning: The PhotonIndexer used for compressed account fetches (get_compressed_account) has built‑in retry logic (defaults to ~10 attempts), so tests should not add separate retry loops around compressed fetches unless there’s a specific need.

Applied to files:

  • magicblock-chainlink/src/chainlink/fetch_cloner.rs
📚 Learning: 2025-12-17T12:46:36.207Z
Learnt from: GabrielePicco
Repo: magicblock-labs/magicblock-validator PR: 738
File: magicblock-chainlink/src/chainlink/fetch_cloner.rs:1109-1196
Timestamp: 2025-12-17T12:46:36.207Z
Learning: In magicblock-chainlink/src/chainlink/fetch_cloner.rs, eATA account subscriptions are intentionally NOT cancelled even when the eATA doesn't exist or delegation conversion fails. The subscriptions are kept active to watch for future creation or delegation of eATA accounts (per maintainer GabrielePicco).

Applied to files:

  • magicblock-chainlink/src/chainlink/fetch_cloner.rs
📚 Learning: 2025-12-03T09:36:01.527Z
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 639
File: magicblock-chainlink/src/remote_account_provider/mod.rs:1350-1353
Timestamp: 2025-12-03T09:36:01.527Z
Learning: Repo: magicblock-labs/magicblock-validator
File: magicblock-chainlink/src/remote_account_provider/mod.rs
Context: consolidate_fetched_remote_accounts
Learning: For unexpected result counts (>2), the project prefers logging an error and returning an empty Vec over panicking; acceptable during development per maintainer (Dodecahedr0x).

Applied to files:

  • magicblock-chainlink/src/chainlink/fetch_cloner.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:

  • magicblock-chainlink/src/chainlink/fetch_cloner.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:

  • magicblock-chainlink/src/chainlink/fetch_cloner.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-chainlink/src/chainlink/fetch_cloner.rs
📚 Learning: 2025-11-19T11:31:24.218Z
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 639
File: test-integration/test-chainlink/tests/ix_01_ensure-accounts.rs:85-114
Timestamp: 2025-11-19T11:31:24.218Z
Learning: In the magicblock-validator codebase, compressed delegation records are never subscribed to by design. Tests for compressed delegation flows should focus on verifying that the delegated account (e.g., counter PDA) is cloned as delegated and not subscribed, but do not need to check for subscription to delegation-record-like PDAs in the compressed path because subscriptions to compressed delegation records never occur.

Applied to files:

  • magicblock-chainlink/src/chainlink/fetch_cloner.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:

  • magicblock-chainlink/src/chainlink/fetch_cloner.rs
📚 Learning: 2025-12-01T16:02:05.367Z
Learnt from: thlorenz
Repo: magicblock-labs/magicblock-validator PR: 703
File: magicblock-chainlink/src/submux/mod.rs:652-654
Timestamp: 2025-12-01T16:02:05.367Z
Learning: In magicblock-chainlink/src/submux/mod.rs, the subscribe_program method intentionally adds program_id to program_subs before attempting the subscription. This ensures that even if the initial subscription fails or only partially succeeds across clients, the reconnection logic will retry the subscription. This is a deliberate design pattern for resilience in the multi-client architecture and should not be "fixed" to remove entries on failure.

Applied to files:

  • magicblock-chainlink/src/chainlink/fetch_cloner.rs
📚 Learning: 2025-11-25T11:07:20.001Z
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 639
File: test-integration/programs/flexi-counter/src/processor.rs:643-680
Timestamp: 2025-11-25T11:07:20.001Z
Learning: In the compressed delegation architecture, ownership reassignment during undelegation is handled by the delegation program itself, not by the owner program's external undelegate handler. The external undelegate handler (e.g., `process_external_undelegate_compressed` in flexi-counter) is a callback for program-specific cleanup (restoring lamports and data) after the delegation program has already reassigned ownership back to the original owner stored in the CompressedDelegationRecord.

Applied to files:

  • magicblock-chainlink/src/chainlink/fetch_cloner.rs
🧬 Code graph analysis (1)
magicblock-chainlink/src/chainlink/fetch_cloner.rs (4)
magicblock-chainlink/src/remote_account_provider/photon_client.rs (1)
  • new (29-31)
magicblock-chainlink/src/remote_account_provider/mod.rs (1)
  • new (323-377)
compressed-delegation-client/src/lib.rs (1)
  • id (61-63)
magicblock-chainlink/src/chainlink/account_still_undelegating_on_chain.rs (1)
  • account_still_undelegating_on_chain (22-89)
🔇 Additional comments (6)
magicblock-chainlink/src/chainlink/fetch_cloner.rs (6)

11-12: LGTM: Generic PhotonClient parameter properly threaded.

The addition of the P: PhotonClient generic parameter and related imports is correctly implemented. The type signatures properly propagate the constraint through FetchCloner, RemoteAccountProvider, and impl blocks.

Also applies to: 25-25, 42-42, 56-83, 152-158


574-584: Documented limitation: commit_frequency_ms not supported for compressed delegation.

The TODO comment notes that commit_frequency_ms is set to 0 for compressed delegation records. This is acceptable as documented technical debt, but verify that downstream code handles 0 commit frequency correctly or has appropriate defaults.


1105-1142: LGTM: Compressed delegation bulk fetch correctly mirrors subscription path.

The bulk fetch logic for compressed delegation accounts properly:

  • Deserializes CompressedDelegationRecord from account data
  • Sets compressed(true), lamports, owner, data from the record
  • Determines delegation status based on authority comparison
  • Computes delegated_to_other for accounts delegated to other validators
  • Handles errors appropriately by filtering out unparseable records

This matches the subscription path behavior (lines 565-573) and addresses previous review feedback about propagating delegated_to_other.


1587-1623: LGTM: Compressed account undelegation refresh correctly skips delegation record fetch.

For compressed accounts, the code correctly returns RefreshDecision::Yes immediately without fetching a delegation record. This is appropriate because compressed delegation records are embedded in the account data itself, not stored separately.

For non-compressed delegated accounts, the existing logic is preserved: fetch the delegation record and check if undelegation is complete on-chain.


2132-2139: LGTM: Helper function signature correctly updated for PhotonClient generic.

The cancel_subs helper function signature is properly updated to include the P: PhotonClient constraint and accept Arc<RemoteAccountProvider<T, U, P>>. The implementation logic remains unchanged.


2225-2405: LGTM: Test infrastructure correctly updated for PhotonClient generic.

The test infrastructure changes properly thread the PhotonClientMock type through:

  • Type aliases (TestFetchClonerResult)
  • Test context structures (FetcherTestCtx)
  • Helper functions (setup, init_fetch_cloner)
  • RemoteAccountProvider::new() calls with None::<PhotonClientMock>

These changes enable testing both compressed and non-compressed delegation flows with appropriate mock implementations.

Comment on lines +536 to +562
} else if owned_by_compressed_delegation_program {
// If the account is compressed, the delegation record is in the account itself
let delegation_record =
match CompressedDelegationRecord::try_from_slice(
account.data(),
) {
Ok(delegation_record) => Some(delegation_record),
Err(_err) => {
debug!("The account's data did not contain a valid compressed delegation record, fetching...");
if let Some(acc) = self
.remote_account_provider
.try_get(pubkey, AccountFetchOrigin::GetAccount)
.await
.map(|acc| acc.fresh_account().cloned())
.ok()
.flatten()
{
CompressedDelegationRecord::try_from_slice(
acc.data(),
)
.ok()
} else {
error!("Failed to parse compressed delegation record for {pubkey} directly from the data.");
None
}
}
};
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

Minor: Improve error context in compressed delegation record fallback path.

When direct parsing of the compressed delegation record fails (line 543), the error is discarded without logging. Later, if the fallback fetch succeeds but parsing still fails, the error message at line 558 says "Failed to parse" without indicating whether the issue was the fetch or the parse.

Consider:

  1. Log the initial parse error at debug level for troubleshooting
  2. Distinguish between fetch failures and parse failures in the error message
🔎 Suggested refinement
                 let delegation_record =
                     match CompressedDelegationRecord::try_from_slice(
                         account.data(),
                     ) {
                         Ok(delegation_record) => Some(delegation_record),
-                        Err(_err) => {
-                            debug!("The account's data did not contain a valid compressed delegation record, fetching...");
+                        Err(err) => {
+                            debug!("Failed to parse compressed delegation record directly: {err}. Fetching fresh account...");
                             if let Some(acc) = self
                                 .remote_account_provider
                                 .try_get(pubkey, AccountFetchOrigin::GetAccount)
                                 .await
                                 .map(|acc| acc.fresh_account().cloned())
                                 .ok()
                                 .flatten()
                             {
                                 CompressedDelegationRecord::try_from_slice(
                                     acc.data(),
                                 )
                                 .ok()
                             } else {
-                                error!("Failed to parse compressed delegation record for {pubkey} directly from the data.");
+                                error!("Failed to fetch or parse compressed delegation record for {pubkey}.");
                                 None
                             }
                         }
                     };
🤖 Prompt for AI Agents
In magicblock-chainlink/src/chainlink/fetch_cloner.rs around lines 536 to 562,
the initial CompressedDelegationRecord::try_from_slice parse error is discarded
and later error messaging doesn't differentiate between a remote fetch failure
and a parse failure; update the block to capture and debug-log the first parse
Err, then when attempting the remote fetch capture its result and if parsing the
fetched data fails log an error stating "fetched account parsed failed for
{pubkey}: {parse_err}", and if the remote fetch itself fails log "remote fetch
failed for {pubkey}: {fetch_err}"; ensure both parse errors use .to_string() or
Debug formatting and use debug for non-fatal parse details and error for final
failures so callers can distinguish fetch vs parse causes.

Comment on lines +1129 to +1133
let delegated_to_other = if delegation_record.authority.eq(&self.validator_pubkey) || delegation_record.authority.eq(&Pubkey::default()) {
None
} else {
Some(delegation_record.authority)
};
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

Optional: Consider reusing delegation authority check logic.

The inline logic for computing delegated_to_other duplicates the pattern in get_delegated_to_other (lines 747-756). While this works correctly, extracting a small helper function could reduce duplication and ensure consistency.

This is a minor maintainability suggestion and was noted in a previous review comment.

Based on past review comments.

🤖 Prompt for AI Agents
In magicblock-chainlink/src/chainlink/fetch_cloner.rs around lines 1129 to 1133,
the inline computation of delegated_to_other duplicates the delegation-authority
check already implemented in get_delegated_to_other (lines 747-756); refactor to
reuse that logic by either calling the existing get_delegated_to_other with the
delegation_record and self.validator_pubkey here or extract the shared check
into a small private helper used by both sites so the semantics remain identical
and you avoid duplicated code.

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.