-
Couldn't load subscription status.
- Fork 18
feat: Add ScheduleCommitDiffAndUndelegate to efficiently commit changes in delegated accounts
#575
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
This stack of pull requests is managed by Graphite. Learn more about stacking. |
WalkthroughThis PR introduces a diff-based commit flow across the magicblock codebase, adding new instruction variants and enum cases for handling commits with account state diffs. It updates dependency sources from git-based to local paths, adds comprehensive order-book support to test integration, and threads a Changes
Sequence DiagramsequenceDiagram
participant User
participant Committor as Committor Service
participant TaskBuilder
participant Processor as Magicblock Processor
User->>Committor: Send base intent (commit_diff flag)
Committor->>TaskBuilder: Extract commit_diff from intent
alt commit_diff = true
TaskBuilder->>TaskBuilder: Create CommitDiff(CommitTask)
Note over TaskBuilder: ArgsTaskType::CommitDiff variant
else commit_diff = false
TaskBuilder->>TaskBuilder: Create Commit(CommitTask)
Note over TaskBuilder: ArgsTaskType::Commit variant
end
TaskBuilder->>Processor: Build instruction
alt CommitDiff path
Processor->>Processor: Fetch account via RPC<br/>Compute diff with compute_diff()
Processor->>Processor: request_diff: true
Processor->>Processor: Create StandaloneDiff(accounts)
else Commit path
Processor->>Processor: request_diff: false
Processor->>Processor: Create Standalone(accounts)
end
Processor->>Processor: Emit commit_diff in SentCommit
User->>User: Receive SentCommit with commit_diff flag
Estimated code review effort🎯 4 (Complex) | ⏱️ ~50 minutes Areas requiring extra attention:
Possibly related issues
Possibly related PRs
Suggested reviewers
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
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. Comment |
249b1aa to
2f0555f
Compare
0151da0 to
5c25e73
Compare
MagicBlockInstruction::ScheduleCommitDiffAndUndelegate to efficiently commit changes in delegated accounts
MagicBlockInstruction::ScheduleCommitDiffAndUndelegate to efficiently commit changes in delegated accountsScheduleCommitDiffAndUndelegate to efficiently commit changes in delegated accounts
5c25e73 to
2ae750b
Compare
…ntly commit changes in delegated accounts
2ae750b to
725f72c
Compare
Manual Deploy AvailableYou can trigger a manual deploy of this PR branch to testnet: Alternative: Comment
Comment updated automatically when the PR is synchronized. |
725f72c to
e5c5e15
Compare
ScheduleCommitDiffAndUndelegate to efficiently commit changes in delegated accountsScheduleCommitDiffAndUndelegate to efficiently commit changes in delegated accounts
ScheduleCommitDiffAndUndelegate to efficiently commit changes in delegated accountsScheduleCommitDiffAndUndelegate to efficiently commit changes in delegated accounts
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 29
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/tasks/args_task.rs (1)
229-237: reset_commit_id ignores CommitDiff—update both variants.Commit IDs must update for Commit and CommitDiff.
Apply:
- let ArgsTaskType::Commit(commit_task) = &mut self.task_type else { - log::error!("reset_commit_id"); - return; - }; - - commit_task.commit_id = commit_id; + match &mut self.task_type { + ArgsTaskType::Commit(task) | ArgsTaskType::CommitDiff(task) => { + task.commit_id = commit_id; + } + _ => {} + }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
⛔ Files ignored due to path filters (2)
Cargo.lockis excluded by!**/*.locktest-integration/Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (28)
Cargo.toml(1 hunks)magicblock-accounts/src/scheduled_commits_processor.rs(3 hunks)magicblock-committor-service/src/tasks/args_task.rs(6 hunks)magicblock-committor-service/src/tasks/mod.rs(1 hunks)magicblock-committor-service/src/tasks/task_builder.rs(3 hunks)magicblock-committor-service/src/tasks/task_visitors/persistor_visitor.rs(1 hunks)magicblock-magic-program-api/src/instruction.rs(1 hunks)magicblock-rpc-client/src/lib.rs(1 hunks)programs/magicblock/src/magic_scheduled_base_intent.rs(7 hunks)programs/magicblock/src/magicblock_processor.rs(4 hunks)programs/magicblock/src/schedule_transactions/process_schedule_commit.rs(2 hunks)programs/magicblock/src/schedule_transactions/process_scheduled_commit_sent.rs(5 hunks)test-integration/Cargo.toml(2 hunks)test-integration/programs/schedulecommit-security/src/lib.rs(2 hunks)test-integration/programs/schedulecommit/src/api.rs(5 hunks)test-integration/programs/schedulecommit/src/lib.rs(9 hunks)test-integration/programs/schedulecommit/src/order_book.rs(1 hunks)test-integration/programs/schedulecommit/src/utils/mod.rs(3 hunks)test-integration/schedulecommit/client/src/schedule_commit_context.rs(6 hunks)test-integration/schedulecommit/client/src/verify.rs(2 hunks)test-integration/schedulecommit/test-scenarios/Cargo.toml(1 hunks)test-integration/schedulecommit/test-scenarios/tests/01_commits.rs(2 hunks)test-integration/schedulecommit/test-scenarios/tests/02_commit_and_undelegate.rs(4 hunks)test-integration/schedulecommit/test-scenarios/tests/03_commits_fee_payer.rs(1 hunks)test-integration/schedulecommit/test-scenarios/tests/utils/mod.rs(1 hunks)test-integration/test-ledger-restore/tests/08_commit_update.rs(2 hunks)test-integration/test-tools/src/integration_test_context.rs(2 hunks)test-integration/test-tools/src/scheduled_commits.rs(3 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-10-26T08:49:31.543Z
Learnt from: taco-paco
PR: magicblock-labs/magicblock-validator#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
🧬 Code graph analysis (15)
test-integration/test-ledger-restore/tests/08_commit_update.rs (1)
test-integration/test-ledger-restore/src/lib.rs (1)
setup_validator_with_local_remote(97-119)
test-integration/schedulecommit/test-scenarios/tests/03_commits_fee_payer.rs (3)
test-integration/programs/schedulecommit/src/api.rs (1)
schedule_commit_with_payer_cpi_instruction(214-232)test-integration/schedulecommit/test-scenarios/tests/utils/mod.rs (3)
assert_two_committees_were_committed(68-91)get_context_with_delegated_committees(16-35)assert_feepayer_was_committed(94-113)test-integration/schedulecommit/client/src/verify.rs (1)
fetch_and_verify_commit_result_from_logs(7-14)
test-integration/programs/schedulecommit-security/src/lib.rs (1)
test-integration/schedulecommit/test-security/tests/01_invocations.rs (1)
create_schedule_commit_ix(41-66)
magicblock-committor-service/src/tasks/args_task.rs (4)
magicblock-committor-service/src/tasks/mod.rs (2)
instruction(66-66)instruction(249-255)magicblock-committor-service/src/tasks/buffer_task.rs (2)
instruction(65-86)new(37-45)magicblock-committor-service/src/config.rs (1)
local(29-35)magicblock-accounts/src/scheduled_commits_processor.rs (2)
new(66-90)new(420-436)
programs/magicblock/src/magicblock_processor.rs (3)
magicblock-committor-service/src/tasks/args_task.rs (1)
instruction(58-160)programs/magicblock/src/schedule_transactions/process_schedule_commit.rs (1)
process_schedule_commit(34-259)magicblock-committor-program/src/state/changeset.rs (1)
request_undelegation(230-232)
test-integration/schedulecommit/test-scenarios/tests/02_commit_and_undelegate.rs (4)
test-integration/programs/schedulecommit/src/api.rs (4)
schedule_commit_and_undelegate_cpi_instruction(234-252)schedule_commit_and_undelegate_cpi_with_mod_after_instruction(287-311)schedule_commit_diff_instruction_for_order_book(193-212)update_order_book_instruction(175-191)test-integration/schedulecommit/test-scenarios/tests/utils/mod.rs (3)
get_context_with_delegated_committees(16-35)assert_one_committee_was_committed(41-65)assert_one_committee_account_was_undelegated_on_chain(190-196)test-integration/schedulecommit/client/src/schedule_commit_context.rs (3)
committees(205-209)ephem_blockhash(322-324)ephem_client(318-320)test-integration/schedulecommit/client/src/verify.rs (1)
fetch_and_verify_order_book_commit_result_from_logs(16-23)
test-integration/programs/schedulecommit/src/api.rs (2)
test-integration/programs/schedulecommit/src/order_book.rs (1)
new(85-94)test-integration/programs/flexi-counter/src/state.rs (1)
pda(32-35)
test-integration/schedulecommit/client/src/verify.rs (2)
test-integration/test-ledger-restore/tests/08_commit_update.rs (1)
ctx(90-91)test-integration/schedulecommit/test-security/tests/01_invocations.rs (1)
ctx(145-146)
magicblock-committor-service/src/tasks/task_builder.rs (2)
magicblock-accounts/src/scheduled_commits_processor.rs (2)
new(66-90)new(420-436)magicblock-committor-service/src/tasks/args_task.rs (1)
new(49-54)
test-integration/programs/schedulecommit/src/lib.rs (2)
test-integration/programs/schedulecommit/src/utils/mod.rs (3)
assert_is_signer(30-44)assert_keys_equal(16-28)allocate_account_and_assign_owner(58-106)test-integration/programs/schedulecommit/src/order_book.rs (1)
new(85-94)
programs/magicblock/src/schedule_transactions/process_schedule_commit.rs (2)
magicblock-committor-service/src/tasks/task_builder.rs (1)
committed_accounts(153-156)test-integration/test-committor-service/tests/test_ix_commit_local.rs (1)
base_intent(544-549)
test-integration/schedulecommit/client/src/schedule_commit_context.rs (1)
test-integration/programs/schedulecommit/src/api.rs (3)
init_order_book_instruction(36-54)init_payer_escrow(77-98)init_account_instruction(16-34)
programs/magicblock/src/magic_scheduled_base_intent.rs (1)
magicblock-committor-service/src/tasks/task_builder.rs (1)
committed_accounts(153-156)
test-integration/schedulecommit/test-scenarios/tests/utils/mod.rs (3)
test-integration/test-ledger-restore/tests/08_commit_update.rs (1)
ctx(90-91)test-integration/schedulecommit/test-security/tests/01_invocations.rs (1)
ctx(145-146)test-integration/schedulecommit/client/src/schedule_commit_context.rs (3)
try_new(72-74)ncommittees(102-121)try_new_random_keys(66-71)
test-integration/schedulecommit/test-scenarios/tests/01_commits.rs (1)
test-integration/schedulecommit/test-scenarios/tests/utils/mod.rs (1)
get_context_with_delegated_committees(16-35)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: run_make_ci_format
- GitHub Check: run_make_ci_test
- GitHub Check: run_make_ci_lint
- GitHub Check: run_make_ci_test
🔇 Additional comments (34)
test-integration/test-ledger-restore/tests/08_commit_update.rs (1)
55-55: LGTM! Correctly updated to match new function signature.Both call sites properly destructure the new 3-tuple return value. The
_tmpdirbinding is necessary to keep theTempDiralive throughout the function scope, preventing premature cleanup of the temporary directory while the validator is still using it.Also applies to: 170-170
test-integration/programs/schedulecommit/src/utils/mod.rs (2)
53-53: LGTM: Type alignment with Solana API.Changing
sizetou64aligns with Solana'ssystem_instruction::allocateAPI, which expects au64parameter. This improves type consistency and eliminates the need for type conversions downstream.
70-90: LGTM: Clean implementation with helpful debugging.The changes correctly handle the type conversion:
- Line 71: The cast to
usizeis necessary forRent::minimum_balanceand is safe given Solana's practical account size limits.- Lines 75-80: The debug log provides useful visibility into lamport requirements during account allocation.
- Line 90: Passing
sizedirectly asu64tosystem_instruction::allocateis cleaner and aligns with the API signature.test-integration/programs/schedulecommit-security/src/lib.rs (2)
2-2: LGTM: Import addition is correct.The
CommitPolicyimport is necessary for the API change on line 149.
143-150: No action required—the two CPI paths use intentionally different APIs.The review comment's concern about consistency is based on a false premise. The code uses two fundamentally different functions from different modules:
- Path 1 (
schedule_commit_cpi_instruction): A local program API wrapper with a fixed, simplified interface- Path 2 (
create_schedule_commit_ix): An external SDK function with extended configuration options includingCommitPolicyThese are not parallel implementations requiring symmetry. The
schedule_commit_cpi_instructionfunction does not supportCommitPolicyby design—it wraps commit scheduling with hardcoded policy defaults. AddingCommitPolicy::UseFullBytestocreate_schedule_commit_ixis the correct change and requires no corresponding update toschedule_commit_cpi_instruction.Likely an incorrect or invalid review comment.
test-integration/test-tools/src/integration_test_context.rs (1)
167-171: Transaction version configuration is correct and environment-aware.The conditional logic properly handles two distinct RPC endpoints:
- Chain (Solana devnet):
max_supported_transaction_version: Some(0)with 50 retries to handle devnet's known quirk of sometimes returning version responses instead of transaction metadata (noted at line 160-161).- Ephemeral (local validator):
Noneto use default behavior on a controlled, local environment without such quirks.Git history confirms this change is part of the current PR (commit 4c75d78). The code is correctly differentiated for each environment. No changes needed.
test-integration/test-tools/src/scheduled_commits.rs (1)
182-213: LGTM! Clear hierarchical naming for log variables.The renaming from
ephem_logs/chain_logstoephem_logs_l1/ephem_logs_l2improves clarity by establishing a consistent naming convention that reflects the two-level log retrieval hierarchy.magicblock-committor-service/src/tasks/task_visitors/persistor_visitor.rs (1)
29-33: LGTM: CommitDiff included in strategy persistence.Cleanly broadens Commit to CommitDiff without changing strategy semantics.
programs/magicblock/src/schedule_transactions/process_schedule_commit.rs (2)
224-230: Diff-aware commit routing is correct; keep logs concise.Choosing StandaloneDiff when request_diff is true is right. Consider demoting the "StandaloneDiff" ic_msg to debug in production builds to reduce log noise.
Also applies to: 233-238
29-32: All call sites properly initialize request_diff—no corrections needed.Verification confirms that every
process_schedule_commit()invocation explicitly sets bothrequest_undelegationandrequest_difffields. All three instruction paths (ScheduleCommit,ScheduleCommitAndUndelegate,ScheduleCommitDiffAndUndelegate) pass values forrequest_diff, withScheduleCommitDiffAndUndelegatecorrectly setting it totrueto trigger theCommitType::StandaloneDiffpath. No uninitialized defaults are used, and no silent routing to full-state commits can occur.programs/magicblock/src/schedule_transactions/process_scheduled_commit_sent.rs (1)
29-30: LGTM: commit_diff added end-to-end with safe logging.Field is carried into printable form and logged only as a flag. Tests initialize the new field.
Also applies to: 44-45, 71-73, 215-217, 254-255
magicblock-committor-service/src/tasks/args_task.rs (1)
197-205: Calibrate compute units for CommitDiff based on diff size.Fixed 65_000 may be inaccurate. Once diff is precomputed, scale CU by diff length/segments or add headroom to avoid CU errors.
Based on learnings
programs/magicblock/src/magicblock_processor.rs (3)
2-2: LGTM: import added is correct.
51-54: ScheduleCommit: explicit request_diff=false is correct.
90-99: New ScheduleCommitDiffAndUndelegate path correctly flips request_diff=true.magicblock-committor-service/src/tasks/task_builder.rs (1)
96-105: Per-account Commit vs CommitDiff task selection is correct.programs/magicblock/src/magic_scheduled_base_intent.rs (6)
104-107: ScheduledBaseIntent::is_commit_diff added — OK.
155-164: MagicBaseIntent::is_commit_diff added — OK.
448-454: CommitType::is_commit_diff implementation — OK.
456-463: Getters updated for StandaloneDiff — OK.Also applies to: 465-473
475-487: is_empty handles StandaloneDiff — OK.
317-323: StandaloneDiff variant already exists and is actively used in the codebase.The review's concern assumes
StandaloneDiffis a new addition that will shift bincode discriminants. However, the variant is already present inprocess_schedule_commit.rs(lines 225–226), indicating it exists before this PR or is not new.If
StandaloneDiffwas already committed to the codebase:
- The bincode discriminant shift already happened (or never was a concern).
- The review comment's warning is outdated or misguided.
If the snippet shows the final state (post-changes) and
StandaloneDiffwas genuinely added in this PR:
- Verify the diff shows it was inserted between existing variants (which would shift discriminants).
- If it was appended after existing variants, discriminants remain stable and no migration is needed.
Critical finding: No backwards compatibility tests, no versioning code, and no serde external tagging exist. If persisted state truly exists and the variant order changed, this is a risk. However, the evidence suggests
StandaloneDiffis not new.Action for developer: Confirm in the PR diff that you are not reordering existing enum variants. If appending new variants after existing ones, bincode compatibility is safe. If inserting between existing variants, migration is required.
test-integration/schedulecommit/test-scenarios/Cargo.toml (1)
19-20: LGTM!The addition of
randandborshas workspace dev-dependencies appropriately supports the new order-book test scenarios introduced in this PR.test-integration/schedulecommit/test-scenarios/tests/01_commits.rs (1)
30-31: LGTM!The addition of deterministic seed
b"magic_schedule_commit"improves test reproducibility by ensuring consistent PDA derivation across test runs.test-integration/schedulecommit/test-scenarios/tests/utils/mod.rs (2)
16-35: LGTM!The seed parameter enables deterministic test context initialization, and explicitly driving the
init_committeesanddelegate_committeesworkflow steps with debug logging improves test clarity and observability.
41-47: LGTM!Making
assert_one_committee_was_committedgeneric over typeTwith appropriate trait bounds enables reuse across different account types (MainAccount, OrderBookOwned, etc.) while maintaining type safety.test-integration/schedulecommit/test-scenarios/tests/03_commits_fee_payer.rs (2)
23-80: LGTM!The test properly validates that attempting to commit a fee payer without escrowing lamports fails with the expected "DoesNotHaveEscrowAccount" error. The test structure and assertions are appropriate.
83-135: LGTM!The test correctly validates the happy path where fee payer commits succeed when lamports are properly escrowed. The verification flow and assertions comprehensively check that both committees and the fee payer were committed and synchronized.
test-integration/schedulecommit/test-scenarios/tests/02_commit_and_undelegate.rs (3)
55-56: LGTM!The addition of deterministic seed
b"magic_schedule_commit"ensures reproducible test behavior across runs.
110-164: LGTM!The
commit_and_undelegate_order_book_accounthelper follows the established pattern of other commit helpers in this file, properly constructing the update and schedule-commit-diff instructions sequence.
244-312: Excellent reproducibility design for randomized testing.The test demonstrates best practices for randomized testing:
- Prints the RNG seed for reproducibility
- Includes the seed in assertion failure messages
- Uses seeded RNG (StdRng) for deterministic behavior given a seed
This allows failures to be reproduced by rerunning with the printed seed value.
One optional enhancement: consider adding a way to override the seed via environment variable for easier failure reproduction:
let rng_seed = std::env::var("TEST_RNG_SEED") .ok() .and_then(|s| s.parse::<u64>().ok()) .unwrap_or_else(|| OsRng.next_u64());test-integration/programs/schedulecommit/src/lib.rs (1)
561-571: Use commit_diff for undelegate path; this looks correct.The diff-based commit is invoked when
undelegateis true; good alignment with the new optimization.Please confirm tests cover both diff and full-commit paths (with/without
undelegate).test-integration/programs/schedulecommit/src/order_book.rs (1)
101-116: Bounds/capacity logic is good; but relies on header being valid.Once header init is fixed in
process_init_order_book, these helpers are fine for basic growth semantics.Ensure tests cover:
- Non-zero existing asks/bids followed by additional inserts (to exercise prefix/suffix behavior).
- Capacity exhaustion returning
None.Also applies to: 118-138, 163-184
test-integration/schedulecommit/client/src/schedule_commit_context.rs (1)
260-267: Seed semantics are correct and consistently applied across the codebase.The verification shows that
delegate_account_cpi_instruction()explicitly branches on two supported canonical seeds:
b"magic_schedule_commit"→ScheduleCommitInstruction::DelegateCpib"order_book"→ScheduleCommitInstruction::DelegateOrderBookAll test utilities and callers supply only these supported seeds. The
delegate_committees()function at lines 260-267 correctly passes&self.user_seed, and all constructors receive only canonical seeds from test callers. PDA derivation and instruction creation use consistent seed semantics.
| "no-entrypoint", | ||
| ] } | ||
| magicblock-aperture = { path = "./magicblock-aperture" } | ||
| magicblock-delegation-program = { path="../delegation-program", features = ["no-entrypoint"] } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
Verify CI/CD compatibility with local path dependency.
Switching from a git-based dependency to a local path (../delegation-program) may break builds in CI/CD environments, Docker containers, or for external contributors where this path doesn't exist.
Run the following script to verify this change doesn't break CI workflows:
Additionally, consider whether this local path change is intended only for development or should be committed. If this is meant for local testing only, it might be better to use a [patch] section or document setup requirements.
🏁 Script executed:
#!/bin/bash
# Check if delegation-program path exists relative to workspace root
if [ -d "../delegation-program" ]; then
echo "✓ Path ../delegation-program exists"
else
echo "✗ Path ../delegation-program does not exist"
echo "This will break builds in environments without this local checkout"
fi
# Check CI configuration for dependency setup
fd -t f 'ci\.yml|workflow' .github/Length of output: 110
Now I need to investigate the repository structure to understand where delegation-program should be located and how the workspace is organized.
🏁 Script executed:
#!/bin/bash
# Find all Cargo.toml files to understand the workspace structure
echo "=== Locating Cargo.toml files ==="
fd -t f 'Cargo\.toml$' | head -20
echo ""
echo "=== Looking for delegation-program directory ==="
fd -t d 'delegation-program$'
echo ""
echo "=== Checking Cargo.toml location context (parent directories) ==="
# Show what the file refers to relative to itself
cat Cargo.toml | grep -A 5 -B 5 'magicblock-delegation-program'Length of output: 1473
I need to check the CI/CD configuration and understand the context of this change better.
🏁 Script executed:
#!/bin/bash
# Check CI/CD workflows
echo "=== CI/CD Workflows ==="
find .github/workflows -type f -name '*.yml' -o -name '*.yaml' 2>/dev/null | while read f; do
echo "--- File: $f ---"
head -30 "$f"
echo ""
done
echo ""
echo "=== Checking git status and recent changes ==="
git log -n 5 --oneline Cargo.toml 2>/dev/null || echo "Git history unavailable"
echo ""
echo "=== Git diff for Cargo.toml (if available) ==="
git diff Cargo.toml 2>/dev/null | head -50 || echo "No git diff available"
echo ""
echo "=== Checking for README or setup documentation ==="
fd -t f 'README|SETUP|CONTRIBUTING' -x head -20 {} \; 2>/dev/null | head -50Length of output: 9108
CI/CD will fail with this uncommitted path dependency. The path ../delegation-program does not exist, and no workflows configure it.
The verified facts:
- The
../delegation-programpath does not exist anywhere in the repository or parent directories - All CI workflows checkout only the current repository (magicblock-validator) to a subdirectory
- No workflows include checkout of parent directories or sibling repositories
- No
.cargo/configor[patch]workarounds are configured - The change is already committed (no git diff output)
When CI/CD runs cargo build, it will fail with a "path does not exist" error. This breaks:
- All unit test workflows (ci-test-unit.yml)
- All integration test workflows (ci-test-integration.yml)
- All format/lint checks (ci-fmt.yml, ci-lint.yml)
- Deployment pipelines
Fix required: Either use a [patch] section in the root Cargo.toml, switch back to git-based dependency with proper access configuration, or ensure the delegation-program is included as a workspace member or checked out at the expected path in CI workflows.
🤖 Prompt for AI Agents
In Cargo.toml around line 112 the dependency magicblock-delegation-program is
declared with path="../delegation-program" which does not exist in CI; replace
the broken path dependency by either (A) making delegation-program a workspace
member at the correct relative path and committing it, (B) changing the
dependency to a git-based dependency (git = "https://.../delegation-program.git"
and appropriate tag/commit) so CI can fetch it, or (C) add a [patch.crates-io]
override that points to a published crate or a committed local path, or update
CI workflows to checkout the sibling repository into ../delegation-program
before cargo build; pick one approach and update Cargo.toml and CI accordingly
so cargo build can resolve the dependency.
| intent_sent_transaction: Transaction, | ||
| requested_undelegation: bool, | ||
| commit_diff: bool, | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Commit-diff flag propagation wired—add a unit test.
Storing intent.is_commit_diff() in ScheduledBaseIntentMeta and emitting it in SentCommit looks correct. Add a test that schedules a diff intent and asserts SentCommit.commit_diff == true to prevent regressions.
Also applies to: 435-435, 347-347
🤖 Prompt for AI Agents
In magicblock-accounts/src/scheduled_commits_processor.rs around lines 347, 417
and 435, the new commit-diff flag propagation logic lacks a unit test; add a
test that creates/schedules an intent with intent.is_commit_diff() == true, runs
the scheduling/processing path (mirroring how ScheduledBaseIntentMeta is
populated and SentCommit is emitted), then fetches the produced SentCommit and
asserts that SentCommit.commit_diff == true to lock in the behavior and prevent
regressions.
| ArgsTaskType::CommitDiff(value) => { | ||
| let chain_config = | ||
| ChainConfig::local(ComputeBudgetConfig::new(1_000_000)); | ||
|
|
||
| let rpc_client = RpcClient::new_with_commitment( | ||
| chain_config.rpc_uri.to_string(), | ||
| CommitmentConfig { | ||
| commitment: chain_config.commitment, | ||
| }, | ||
| ); | ||
|
|
||
| let account = match rpc_client | ||
| .get_account(&value.committed_account.pubkey) | ||
| { | ||
| Ok(account) => account, | ||
| Err(e) => { | ||
| log::warn!("Fallback to commit_state and send full-bytes, as rpc failed to fetch the delegated-account from base chain: {}", e); | ||
| let args = CommitStateArgs { | ||
| nonce: value.commit_id, | ||
| lamports: value.committed_account.account.lamports, | ||
| data: value.committed_account.account.data.clone(), | ||
| allow_undelegation: value.allow_undelegation, | ||
| }; | ||
| return dlp::instruction_builder::commit_state( | ||
| *validator, | ||
| value.committed_account.pubkey, | ||
| value.committed_account.account.owner, | ||
| args, | ||
| ); | ||
| } | ||
| }; | ||
|
|
||
| let args = CommitDiffArgs { | ||
| nonce: value.commit_id, | ||
| lamports: value.committed_account.account.lamports, | ||
| diff: compute_diff( | ||
| account.data(), | ||
| value.committed_account.account.data(), | ||
| ), | ||
| allow_undelegation: value.allow_undelegation, | ||
| }; | ||
| log::warn!("DIFF computed: {:?}", args.diff); | ||
| dlp::instruction_builder::commit_diff( | ||
| *validator, | ||
| value.committed_account.pubkey, | ||
| value.committed_account.account.owner, | ||
| args, | ||
| ) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do not perform network I/O inside instruction(); precompute/cache diff.
instruction() now does RPC and compute_diff each call. This is risky and expensive:
- instruction() may be called multiple times (e.g., via involved_accounts), multiplying RPC calls.
- TOCTOU: base-chain account can change between diff calc and submit.
- Coupling to network hinders testing and determinism.
Refactor: compute diff at task construction (e.g., in task_builder), store it in the task, and make instruction() pure. Alternatively, cache the diff inside the task on first call.
| let chain_config = | ||
| ChainConfig::local(ComputeBudgetConfig::new(1_000_000)); | ||
|
|
||
| let rpc_client = RpcClient::new_with_commitment( | ||
| chain_config.rpc_uri.to_string(), | ||
| CommitmentConfig { | ||
| commitment: chain_config.commitment, | ||
| }, | ||
| ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hard-coded ChainConfig::local/Processed—use injected config.
Using ChainConfig::local(...) and Processed commitment bakes in localhost RPC and a weak commitment level. Thread a real ChainConfig (and/or RpcClient handle) from the service layer instead.
🤖 Prompt for AI Agents
In magicblock-committor-service/src/tasks/args_task.rs around lines 75–83, the
code currently constructs a hard-coded ChainConfig::local(...) and builds an
RpcClient with a Processed commitment; instead, accept a ChainConfig (or an
RpcClient) injected from the service layer via the function/struct constructor,
remove the ChainConfig::local call, and construct or reuse the RpcClient from
that injected config (or use the provided RpcClient directly). Ensure you thread
the real chain_config into this module (or pass an Arc<RpcClient>), use the
configured rpc_uri and commitment from that injected config, and update
signatures/initialization sites accordingly so no localhost/Processed values are
baked in here.
| let account = match rpc_client | ||
| .get_account(&value.committed_account.pubkey) | ||
| { | ||
| Ok(account) => account, | ||
| Err(e) => { | ||
| log::warn!("Fallback to commit_state and send full-bytes, as rpc failed to fetch the delegated-account from base chain: {}", e); | ||
| let args = CommitStateArgs { | ||
| nonce: value.commit_id, | ||
| lamports: value.committed_account.account.lamports, | ||
| data: value.committed_account.account.data.clone(), | ||
| allow_undelegation: value.allow_undelegation, | ||
| }; | ||
| return dlp::instruction_builder::commit_state( | ||
| *validator, | ||
| value.committed_account.pubkey, | ||
| value.committed_account.account.owner, | ||
| args, | ||
| ); | ||
| } | ||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick | 🔵 Trivial
Improve fallback logging context.
Include commit_id and account pubkey in the fallback log to aid triage; keep level at info/warn as appropriate.
🤖 Prompt for AI Agents
In magicblock-committor-service/src/tasks/args_task.rs around lines 85 to 104,
the fallback log that triggers when rpc_client.get_account fails lacks
contextual identifiers; update the log message to include the commit id
(value.commit_id) and the committed account pubkey
(value.committed_account.pubkey) so triage is easier, keeping the same warning
level; e.g. expand the log::warn! call to include both values with clear text
like "commit_id={} pubkey={}" and the existing error, ensuring any Display/Debug
formatting used matches the types.
| let mut ixs = vec![ | ||
| ComputeBudgetInstruction::set_compute_unit_limit(1_400_000), | ||
| ComputeBudgetInstruction::set_compute_unit_price(10_000), | ||
| ]; | ||
| if self.user_seed == b"magic_schedule_commit" { | ||
| ixs.extend(self.committees.iter().map(|(player, committee)| { | ||
| init_account_instruction( | ||
| self.payer_chain.pubkey(), | ||
| player.pubkey(), | ||
| *committee, | ||
| ) | ||
| }) | ||
| .collect::<Vec<_>>(); | ||
| })); | ||
| } else { | ||
| ixs.extend(self.committees.iter().map( | ||
| |(book_manager, committee)| { | ||
| init_order_book_instruction( | ||
| self.payer_chain.pubkey(), | ||
| book_manager.pubkey(), | ||
| *committee, | ||
| ) | ||
| }, | ||
| )); | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Guard the branch with explicit seed validation.
Avoid silent misconfiguration: if user_seed is not one of the known seeds, initialization will fail later. Validate early.
- if self.user_seed == b"magic_schedule_commit" {
+ if self.user_seed == b"magic_schedule_commit" {
// Init MainAccount PDAs
ixs.extend(self.committees.iter().map(|(player, committee)| {
init_account_instruction(
self.payer_chain.pubkey(),
player.pubkey(),
*committee,
)
}));
- } else {
+ } else if self.user_seed == b"order_book" {
// Init OrderBook PDAs
ixs.extend(self.committees.iter().map(
|(book_manager, committee)| {
init_order_book_instruction(
self.payer_chain.pubkey(),
book_manager.pubkey(),
*committee,
)
},
));
+ } else {
+ return Err(anyhow::anyhow!("Unsupported user_seed; expected b\"magic_schedule_commit\" or b\"order_book\""));
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| let mut ixs = vec![ | |
| ComputeBudgetInstruction::set_compute_unit_limit(1_400_000), | |
| ComputeBudgetInstruction::set_compute_unit_price(10_000), | |
| ]; | |
| if self.user_seed == b"magic_schedule_commit" { | |
| ixs.extend(self.committees.iter().map(|(player, committee)| { | |
| init_account_instruction( | |
| self.payer_chain.pubkey(), | |
| player.pubkey(), | |
| *committee, | |
| ) | |
| }) | |
| .collect::<Vec<_>>(); | |
| })); | |
| } else { | |
| ixs.extend(self.committees.iter().map( | |
| |(book_manager, committee)| { | |
| init_order_book_instruction( | |
| self.payer_chain.pubkey(), | |
| book_manager.pubkey(), | |
| *committee, | |
| ) | |
| }, | |
| )); | |
| let mut ixs = vec![ | |
| ComputeBudgetInstruction::set_compute_unit_limit(1_400_000), | |
| ComputeBudgetInstruction::set_compute_unit_price(10_000), | |
| ]; | |
| if self.user_seed == b"magic_schedule_commit" { | |
| ixs.extend(self.committees.iter().map(|(player, committee)| { | |
| init_account_instruction( | |
| self.payer_chain.pubkey(), | |
| player.pubkey(), | |
| *committee, | |
| ) | |
| })); | |
| } else if self.user_seed == b"order_book" { | |
| ixs.extend(self.committees.iter().map( | |
| |(book_manager, committee)| { | |
| init_order_book_instruction( | |
| self.payer_chain.pubkey(), | |
| book_manager.pubkey(), | |
| *committee, | |
| ) | |
| }, | |
| )); | |
| } else { | |
| return Err(anyhow::anyhow!("Unsupported user_seed; expected b\"magic_schedule_commit\" or b\"order_book\"")); | |
| } |
🤖 Prompt for AI Agents
In test-integration/schedulecommit/client/src/schedule_commit_context.rs around
lines 166 to 188, the current branch selection based on self.user_seed only
handles the "magic_schedule_commit" case and an implicit else, which can hide
misconfiguration; add an explicit validation of self.user_seed against the known
allowed seeds (e.g., "magic_schedule_commit" and the expected order-book seed)
and fail fast with a clear error/Result return if the seed is unrecognized.
Replace the implicit else with an explicit match or if/else-if chain that
handles each valid seed path and returns Err or panics with a descriptive
message when an unknown seed is provided so initialization does not proceed
silently with an invalid configuration.
| pub fn fetch_and_verify_order_book_commit_result_from_logs( | ||
| ctx: &ScheduleCommitTestContext, | ||
| sig: Signature, | ||
| ) -> ScheduledCommitResult<OrderBookOwned> { | ||
| let res = ctx.fetch_schedule_commit_result(sig).unwrap(); | ||
| res.confirm_commit_transactions_on_chain(ctx).unwrap(); | ||
| res | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick | 🔵 Trivial
Consider eliminating code duplication with a generic implementation.
The new fetch_and_verify_order_book_commit_result_from_logs function duplicates the logic of fetch_and_verify_commit_result_from_logs but with a different type parameter. Since both functions call the same underlying generic fetch_schedule_commit_result, they could be unified.
Consider making the verification function generic:
-pub fn fetch_and_verify_commit_result_from_logs(
+pub fn fetch_and_verify_commit_result_from_logs<T>(
ctx: &ScheduleCommitTestContext,
sig: Signature,
-) -> ScheduledCommitResult<MainAccount> {
+) -> ScheduledCommitResult<T>
+where
+ T: borsh::BorshDeserialize,
+{
let res = ctx.fetch_schedule_commit_result(sig).unwrap();
res.confirm_commit_transactions_on_chain(ctx).unwrap();
res
}
-
-pub fn fetch_and_verify_order_book_commit_result_from_logs(
- ctx: &ScheduleCommitTestContext,
- sig: Signature,
-) -> ScheduledCommitResult<OrderBookOwned> {
- let res = ctx.fetch_schedule_commit_result(sig).unwrap();
- res.confirm_commit_transactions_on_chain(ctx).unwrap();
- res
-}Then call sites would use turbofish syntax: fetch_and_verify_commit_result_from_logs::<MainAccount>(&ctx, sig) or fetch_and_verify_commit_result_from_logs::<OrderBookOwned>(&ctx, sig).
Committable suggestion skipped: line range outside the PR's diff.
| let rpc_client = | ||
| rpc_client.expect("rpc_client for [{}] does not exist"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix the format placeholder in the error message.
The expect message contains a format placeholder [{}] but it's not being formatted with the label parameter. This will cause the error message to literally print "rpc_client for [{}] does not exist" instead of showing which client is missing.
Apply this diff to fix the error message:
- let rpc_client =
- rpc_client.expect("rpc_client for [{}] does not exist");
+ let rpc_client = rpc_client.unwrap_or_else(|| {
+ panic!("rpc_client for [{}] does not exist", label)
+ });Alternatively, if you prefer a simpler approach:
- let rpc_client =
- rpc_client.expect("rpc_client for [{}] does not exist");
+ let rpc_client = rpc_client
+ .unwrap_or_else(|| panic!("rpc_client for [{}] does not exist", label));📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| let rpc_client = | |
| rpc_client.expect("rpc_client for [{}] does not exist"); | |
| let rpc_client = rpc_client.unwrap_or_else(|| { | |
| panic!("rpc_client for [{}] does not exist", label) | |
| }); |
🤖 Prompt for AI Agents
In test-integration/test-tools/src/integration_test_context.rs around lines
157-158, the expect call uses a format placeholder "[{}]" but never formats it
with the label, so the panic message prints the placeholder literally; fix by
passing a formatted string to expect that injects the label (e.g., produce the
message using format! with the label) so the error shows which rpc_client is
missing.
| println!("Ephem Logs level-1: {:#?}", ephem_logs_l1); | ||
|
|
||
| // 2. Find chain commit signatures | ||
| let chain_logs = self | ||
| let ephem_logs_l2 = self | ||
| .fetch_ephemeral_logs(scheduled_commmit_sent_sig) | ||
| .with_context(|| { | ||
| format!( | ||
| "Logs {:#?}\nScheduled commit sent sig {:?}", | ||
| ephem_logs, scheduled_commmit_sent_sig | ||
| ephem_logs_l1, scheduled_commmit_sent_sig | ||
| ) | ||
| })?; | ||
|
|
||
| println!("Ephem Logs level-2: {:#?}", ephem_logs_l2); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick | 🔵 Trivial
Consider verbosity of debug output.
The println! statements with {:#?} pretty-printing could produce very verbose output, especially if the log arrays are large. While acceptable for test tooling, this may clutter test output and make it harder to identify actual test failures.
Consider either:
- Making these conditional via an environment variable (e.g.,
MAGICBLOCK_DEBUG_LOGS) - Using a more compact format, or
- Confirming this is temporary debugging code to be removed before merge
🤖 Prompt for AI Agents
In test-integration/test-tools/src/scheduled_commits.rs around lines 198 to 210,
the pretty-printed println! calls produce very verbose output; update them so
debug logging is conditional on an environment variable (e.g.,
MAGICBLOCK_DEBUG_LOGS) or use a compact debug format instead: check the env var
once and only print when enabled, or replace {:#?} with {:?} (or truncate/limit
the output) to reduce verbosity; ensure behavior is clearly documented in a
comment and confirm whether these prints should be removed before merging.
| for sig in sigs.iter() { | ||
| self.dump_chain_logs(sig.clone()); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick | 🔵 Trivial
🧩 Analysis chain
Remove unnecessary clone() on Copy type.
Signature implements the Copy trait, so calling .clone() is redundant. The signature is automatically copied when passed to the function.
Apply this diff to remove the unnecessary clone:
for sig in sigs.iter() {
- self.dump_chain_logs(sig.clone());
+ self.dump_chain_logs(*sig);
}Verify dump_chain_logs method exists.
Ensure that the dump_chain_logs method is implemented on IntegrationTestContext.
🏁 Script executed:
#!/bin/bash
# Description: Verify dump_chain_logs method exists on IntegrationTestContext
# Search for dump_chain_logs method definition
ast-grep --pattern $'impl $_ IntegrationTestContext $_ {
$$$
fn dump_chain_logs($$$) {
$$$
}
$$$
}'
# Also search with rg as fallback
rg -n 'fn dump_chain_logs' --type rust -A 3Length of output: 446
---
🏁 Script executed:
```shell
#!/bin/bash
# Find Signature import and usage in scheduled_commits.rs
rg -n 'use.*Signature|from.*Signature' test-integration/test-tools/src/scheduled_commits.rs
# Also check the imports at top of file
head -20 test-integration/test-tools/src/scheduled_commits.rs
# Search for Signature type definition or references to Copy implementation
rg -n 'Signature' test-integration/test-tools/src/scheduled_commits.rs -B2 -A2
Length of output: 2245
---
🌐 Web query:
```web
solana_sdk Signature Copy trait implementation
💡 Result:
Yes — solana_sdk::signature::Signature implements the Copy trait (also Clone, Debug, Default, etc.). [1]
Sources
- solana-sdk Signature docs (trait list showing Copy). [1]
Remove unnecessary clone() on Copy type.
Signature from solana_sdk implements the Copy trait, so calling .clone() is redundant. Use dereferencing instead:
for sig in sigs.iter() {
- self.dump_chain_logs(sig.clone());
+ self.dump_chain_logs(*sig);
}🤖 Prompt for AI Agents
In test-integration/test-tools/src/scheduled_commits.rs around lines 233 to 235,
remove the unnecessary .clone() call on Signature (a Copy type) when iterating
sigs; replace self.dump_chain_logs(sig.clone()) with self.dump_chain_logs(*sig)
(or pass sig directly if you change iteration to consume values) so you use
dereferencing instead of cloning.

This PR does the following things:
MagicBlockInstruction::ScheduleCommitDiffAndUndelegatethat is very similar to the existingScheduleCommitAndUndelegateexcept that it invokesCommitDiffinstruction in the delegation-program.args, notbufferaccount.OrderBookaccount (10 KB). I initially wanted to try a few MB, but realized currently that’s not possible yet.CommitDiffwas invoked (in the delegation-program) with onlydiff len = 286whereasdata len = 10240(see first screenshot).diff len = 8(encoding the size of account on ER and the number of offset-pairs), and logs a warning (see second screenshot).Summary by CodeRabbit
Release Notes
New Features
Improvements
Tests