Skip to content

Conversation

@bmuddha
Copy link
Collaborator

@bmuddha bmuddha commented Jan 2, 2026

Summary

  • Added fallible insert functionality to handle account commit failures
  • Transaction now fails if account commit operation encounters errors

Compatibility

  • No breaking changes

Testing

  • tests (tests updated in accounts-db and integration tests)

Checklist

  • docs updated (if needed)

Closes #797

Related to: #794 #795

Summary by CodeRabbit

  • New Features

    • Added batch account insertion and made account insertion report success/failure.
  • Bug Fixes

    • Increased log severity from warning to error for relevant failures.
  • Refactor

    • Account APIs now require explicit transaction management; transaction handling centralized.
  • Tests

    • Tests updated to assert insertions; some initialization paths intentionally ignore insertion errors to continue startup.
  • Chores

    • Updated workspace package version and aligned dependency revisions.

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

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 2, 2026

📝 Walkthrough

Walkthrough

This PR makes account insertion fallible and moves LMDB transaction management outward. Public insert_account now returns AccountsDbResult<()>; insert_batch was added for bulk writes. Several index methods now accept &mut RwTransaction and AccountsDbIndex exposes rwtxn(). Many call sites and tests were updated to use explicit transactions; however, numerous call sites were changed to explicitly ignore the new Result (let _ = ...). commit_accounts was refactored to use insert_batch and thread logs into failure handling.

Assessment against linked issues

Objective Addressed Explanation
Transactions fail when account commits fail (#797) commit_accounts and insert paths return results, but many call sites ignore errors, preventing atomic transaction failure.
Error handling is consistent across processor modules (#797) Multiple modules swallow insert_account errors via let _ = ..., causing inconsistent behavior.
Tests cover failure scenarios (#797) Tests updated for transactional signatures, but no new tests assert that transactions fail when account inserts fail.

Out-of-scope changes

Code Change Explanation
log_err macro severity changed to error (magicblock-accounts-db/src/error.rs) Logging-severity change unrelated to fallible-insert objective; does not affect transaction propagation.
Allocation derive made unconditional Clone/Copy (magicblock-accounts-db/src/storage.rs) Trait-derivation change is structural and not required by the fallible-insert objective.
Many call sites changed to ignore insert_account results (e.g., magicblock-api/src/magic_validator.rs, magicblock-processor/src/loader.rs, magicblock-processor/src/lib.rs, magicblock-processor/src/executor/callback.rs, test-kit/src/lib.rs) Silencing the Result contradicts the objective to propagate insert failures and undermines atomic failure behavior; this is outside the stated objective.

Suggested reviewers

  • thlorenz
  • GabrielePicco
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch bmuddha/accountsdb/fallible-inserts

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.

@github-actions
Copy link

github-actions bot commented Jan 2, 2026

Manual Deploy Available

You can trigger a manual deploy of this PR branch to testnet:

Deploy to Testnet 🚀

Alternative: Comment /deploy on this PR to trigger deployment directly.

⚠️ Note: Manual deploy requires authorization. Only authorized users can trigger deployments.

Comment updated automatically when the PR is synchronized.

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

Caution

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

⚠️ Outside diff range comments (6)
magicblock-api/src/magic_validator.rs (3)

281-282: Usage of .expect() in production code.

Per coding guidelines, .expect() in magicblock-* production code should be avoided. Consider returning an error or using a fallible pattern.

🔎 Proposed fix
-                .build()
-                .expect("failed to bulid async runtime for rpc service");
+                .build()
+                .map_err(|e| {
+                    error!("failed to build async runtime for rpc service: {e}");
+                    e
+                })?;

This would require changing the thread closure to handle errors appropriately, potentially by returning the error through a channel or using a panic with proper cleanup.


289-292: Usage of .expect() in production code.

The .expect() on ledger_path.parent() violates coding guidelines. While this path should always have a parent in practice, consider using a more defensive pattern.

🔎 Proposed fix
-            SchedulerDatabase::path(ledger.ledger_path().parent().expect(
-                "ledger_path didn't have a parent, should never happen",
-            ));
+            SchedulerDatabase::path(
+                ledger.ledger_path().parent().ok_or_else(|| {
+                    ApiError::InvalidConfiguration("ledger_path has no parent directory".into())
+                })?
+            );

300-305: Usage of .expect() in production code.

The .expect() on tasks_service.take() violates coding guidelines.

🔎 Proposed fix
             dispatch
                 .tasks_service
                 .take()
-                .expect("tasks_service should be initialized"),
+                .ok_or(ApiError::InvalidConfiguration(
+                    "tasks_service was not initialized".into()
+                ))?,
magicblock-processor/src/scheduler/state.rs (1)

121-133: Same issue: Rent sysvar insertion failure is silently ignored.

🔎 Proposed fix
         if !accountsdb.contains_account(&sysvar::rent::ID) {
             let account = self
                 .environment
                 .rent_collector
                 .as_ref()
                 .map(|rc| rc.get_rent())
                 .and_then(|rent| {
                     AccountSharedData::new_data(1, rent, owner).ok()
                 });
             if let Some(acc) = account {
-                let _ = accountsdb.insert_account(&sysvar::rent::ID, &acc);
+                if let Err(e) = accountsdb.insert_account(&sysvar::rent::ID, &acc) {
+                    log::error!("Failed to insert Rent sysvar: {e}");
+                }
             }
         }
magicblock-accounts-db/src/index/tests.rs (1)

67-70: Minor inconsistency in error message usage.

This transaction creation uses an inline error message while other locations use the INSERT_ACCOUNT_TXN_ERR constant. Consider using the constant for consistency.

🔎 Proposed fix
-    let txn = tenv
-        .env
-        .begin_rw_txn()
-        .expect("failed to start new RW transaction");
+    let txn = tenv.env.begin_rw_txn().expect(INSERT_ACCOUNT_TXN_ERR);
magicblock-processor/src/executor/processing.rs (1)

304-310: Address .unwrap() on RwLock::write() in production code.

The .unwrap() at line 308 on RwLock::write() can panic if the lock is poisoned (when a thread panics while holding the lock). This is a pre-existing issue that should be addressed with proper error handling rather than deferred to a follow-up.

📜 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 e9f100a and 2f0dfd3.

⛔ 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 (17)
  • Cargo.toml
  • magicblock-accounts-db/src/error.rs
  • magicblock-accounts-db/src/index.rs
  • magicblock-accounts-db/src/index/tests.rs
  • magicblock-accounts-db/src/lib.rs
  • magicblock-accounts-db/src/storage.rs
  • magicblock-accounts-db/src/tests.rs
  • magicblock-api/src/fund_account.rs
  • magicblock-api/src/magic_validator.rs
  • magicblock-processor/src/executor/callback.rs
  • magicblock-processor/src/executor/processing.rs
  • magicblock-processor/src/lib.rs
  • magicblock-processor/src/loader.rs
  • magicblock-processor/src/scheduler/state.rs
  • magicblock-processor/tests/replay.rs
  • test-integration/Cargo.toml
  • test-kit/src/lib.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-processor/src/executor/callback.rs
  • magicblock-processor/src/loader.rs
  • magicblock-accounts-db/src/storage.rs
  • magicblock-api/src/magic_validator.rs
  • magicblock-api/src/fund_account.rs
  • magicblock-accounts-db/src/error.rs
  • magicblock-processor/tests/replay.rs
  • magicblock-accounts-db/src/index.rs
  • magicblock-processor/src/lib.rs
  • magicblock-accounts-db/src/lib.rs
  • magicblock-processor/src/scheduler/state.rs
  • magicblock-accounts-db/src/index/tests.rs
  • magicblock-accounts-db/src/tests.rs
  • magicblock-processor/src/executor/processing.rs
{test-*,tools}/**

⚙️ CodeRabbit configuration file

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

Files:

  • test-kit/src/lib.rs
  • test-integration/Cargo.toml
🧠 Learnings (16)
📚 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-processor/src/executor/callback.rs
  • magicblock-processor/src/loader.rs
  • test-kit/src/lib.rs
  • magicblock-api/src/magic_validator.rs
  • magicblock-api/src/fund_account.rs
  • magicblock-processor/tests/replay.rs
  • magicblock-processor/src/lib.rs
  • magicblock-accounts-db/src/lib.rs
  • magicblock-processor/src/scheduler/state.rs
  • magicblock-accounts-db/src/index/tests.rs
  • magicblock-accounts-db/src/tests.rs
  • magicblock-processor/src/executor/processing.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-processor/src/executor/callback.rs
  • magicblock-processor/src/loader.rs
  • magicblock-api/src/fund_account.rs
  • magicblock-accounts-db/src/index.rs
  • magicblock-processor/src/lib.rs
  • magicblock-accounts-db/src/lib.rs
  • magicblock-processor/src/scheduler/state.rs
  • magicblock-accounts-db/src/index/tests.rs
  • magicblock-accounts-db/src/tests.rs
  • magicblock-processor/src/executor/processing.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-processor/src/executor/callback.rs
  • test-kit/src/lib.rs
  • magicblock-api/src/magic_validator.rs
  • magicblock-api/src/fund_account.rs
  • magicblock-processor/tests/replay.rs
  • magicblock-processor/src/lib.rs
  • magicblock-processor/src/scheduler/state.rs
  • magicblock-accounts-db/src/tests.rs
  • magicblock-processor/src/executor/processing.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-processor/src/executor/callback.rs
  • magicblock-processor/src/loader.rs
  • test-kit/src/lib.rs
  • magicblock-api/src/magic_validator.rs
  • magicblock-api/src/fund_account.rs
  • magicblock-processor/tests/replay.rs
  • magicblock-accounts-db/src/index.rs
  • magicblock-processor/src/lib.rs
  • magicblock-accounts-db/src/lib.rs
  • magicblock-processor/src/scheduler/state.rs
  • magicblock-processor/src/executor/processing.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-processor/src/executor/callback.rs
  • magicblock-processor/src/loader.rs
  • magicblock-processor/tests/replay.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-processor/src/executor/callback.rs
  • test-kit/src/lib.rs
  • magicblock-api/src/magic_validator.rs
  • magicblock-api/src/fund_account.rs
  • magicblock-processor/tests/replay.rs
  • magicblock-processor/src/lib.rs
  • magicblock-processor/src/scheduler/state.rs
  • magicblock-accounts-db/src/index/tests.rs
  • magicblock-accounts-db/src/tests.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-api/src/magic_validator.rs
  • magicblock-api/src/fund_account.rs
  • magicblock-processor/tests/replay.rs
  • magicblock-accounts-db/src/index.rs
  • magicblock-accounts-db/src/lib.rs
  • magicblock-accounts-db/src/index/tests.rs
  • magicblock-accounts-db/src/tests.rs
  • magicblock-processor/src/executor/processing.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-processor/tests/replay.rs
  • magicblock-accounts-db/src/index/tests.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:

  • Cargo.toml
  • test-integration/Cargo.toml
📚 Learning: 2025-11-24T08:45:11.164Z
Learnt from: bmuddha
Repo: magicblock-labs/magicblock-validator PR: 675
File: Cargo.toml:145-145
Timestamp: 2025-11-24T08:45:11.164Z
Learning: The reqwest dependency version 0.11 is intentionally used in the magicblock-validator project to maintain compatibility with the Solana client dependencies.

Applied to files:

  • Cargo.toml
📚 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-accounts-db/src/index.rs
  • magicblock-accounts-db/src/index/tests.rs
  • magicblock-processor/src/executor/processing.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-accounts-db/src/index.rs
  • magicblock-processor/src/executor/processing.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-accounts-db/src/lib.rs
  • magicblock-processor/src/scheduler/state.rs
  • magicblock-processor/src/executor/processing.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-processor/src/scheduler/state.rs
  • magicblock-processor/src/executor/processing.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:

  • test-integration/Cargo.toml
📚 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:

  • test-integration/Cargo.toml
🧬 Code graph analysis (4)
magicblock-processor/src/executor/callback.rs (2)
magicblock-accounts-db/src/index/tests.rs (1)
  • account (481-490)
magicblock-accounts-db/src/tests.rs (1)
  • account (667-669)
magicblock-accounts-db/src/index.rs (2)
magicblock-accounts-db/src/index/tests.rs (1)
  • allocation (466-480)
magicblock-accounts-db/src/storage.rs (1)
  • offset (184-190)
magicblock-accounts-db/src/index/tests.rs (1)
magicblock-accounts-db/src/index.rs (2)
  • ensure_correct_owner (264-294)
  • get_delloactions_count (427-433)
magicblock-accounts-db/src/tests.rs (1)
magicblock-accounts-db/src/index/tests.rs (1)
  • account (481-490)
🔇 Additional comments (27)
magicblock-accounts-db/src/error.rs (1)

27-33: LGTM!

Changing the log level from warn! to error! is appropriate since the log_err macro is specifically designed to handle error cases.

Cargo.toml (1)

41-41: LGTM!

Version bump to 0.5.2 appropriately accompanies the new fallible insert functionality.

test-kit/src/lib.rs (3)

182-182: LGTM!

Ignoring the insert_account result is acceptable in test utility code. The test-kit module is specifically for testing purposes.


207-207: LGTM!

Same reasoning - acceptable in test utilities.


340-342: LGTM!

Acceptable in test utility code.

magicblock-accounts-db/src/tests.rs (1)

56-57: LGTM!

All insert_account calls now properly handle the Result by using .expect() with descriptive messages. This is appropriate for test code and ensures tests fail fast with clear error messages if account insertion fails.

Also applies to: 100-101, 126-127, 152-153, 157-158, 163-164, 172-173, 178-179, 217-218, 221-222, 259-260, 278-279, 317-318, 326-327, 366-367, 409-410, 440-441, 463-464, 476-477, 490-491, 499-500, 513-514, 522-523, 546-547, 564-566, 597-598, 676-678

magicblock-processor/tests/replay.rs (1)

61-61: LGTM!

The result is intentionally ignored here as part of the test setup to simulate AccountsDb being behind the ledger. The surrounding comments clearly explain this design choice, which is appropriate for test code.

magicblock-accounts-db/src/storage.rs (1)

402-402: Clone/Copy derivation on Allocation is appropriate and safe.

The struct contains only NonNull<u8> (a non-owning pointer wrapper that implements Copy), Offset (u32), and Blocks (u32)—all Copy types. The struct doesn't own the memory it references and is returned by value in production code paths (alloc() and recycle() methods), making Copy a sensible optimization. No explicit .clone() calls exist in the codebase.

Note: The current code doesn't show evidence of cfg_attr(test, ...) on Allocation (unlike ExistingAllocation), so the claim about it being "previously test-only" cannot be confirmed from the available history.

test-integration/Cargo.toml (1)

82-82: LGTM!

The solana-account revision bump is consistent between the workspace dependency (line 82) and the patch entry (line 117), ensuring coherent version resolution across the project.

Also applies to: 117-117

magicblock-accounts-db/src/index/tests.rs (3)

12-14: LGTM!

Good practice to define a constant for the repeated error message, ensuring consistency across all test functions.


24-31: LGTM!

The transaction lifecycle is properly managed: begin transaction, perform operation with mutable reference, then commit. This pattern is consistently applied throughout the test.


274-306: LGTM!

The test correctly validates the recycling workflow across multiple transaction cycles, including the allocation split scenario where a larger deallocation is partially reused.

magicblock-processor/src/executor/processing.rs (4)

2-2: LGTM!

Import of AccountsDbResult aligns with the new fallible return type from commit_accounts.


79-95: LGTM!

Excellent implementation of the PR objective: transactions now properly fail when account commit operations encounter errors. The CommitCancelled error is appropriately used, and the error message is captured in the transaction logs for debugging purposes.


269-291: LGTM!

The commit_failed_transaction signature update properly supports passing log messages, enabling better error context in the ledger for debugging failed transactions.


343-357: LGTM!

The batch insert logic correctly:

  1. Filters accounts to only those that are dirty or privileged
  2. Uses the new insert_batch API for atomic batch operations
  3. Propagates errors via ? operator
  4. Short-circuits replay transactions after batch insert
  5. Sends account updates through the channel for non-replay scenarios
magicblock-accounts-db/src/lib.rs (7)

7-7: LGTM!

Import of RwTransaction and Transaction trait supports the new explicit transaction management pattern.


92-105: LGTM!

The lazy transaction initialization via the txn! macro is an elegant approach - it avoids creating a transaction when only Borrowed accounts without owner changes are being processed, while ensuring a single transaction is reused across multiple operations when needed.


112-127: LGTM!

Borrowed account handling correctly:

  1. Checks for owner change before initiating transaction
  2. Updates the index via ensure_correct_owner within the transaction
  3. Calls acc.commit() to finalize the atomic counter update for readers

128-184: LGTM!

Owned account path properly:

  1. Creates transaction early via txn!() macro
  2. Attempts allocation recycling before falling back to new allocation
  3. Updates the index atomically
  4. Handles deallocation bookkeeping
  5. Serializes account data to mmap
  6. Commits transaction only if one was created

The error propagation is correctly implemented throughout.


186-206: LGTM!

The insert_batch method reuses the same lazy transaction pattern and error handling approach. The break_error! macro provides clean error capture and loop termination.


304-308: LGTM!

Transaction commit is properly guarded - only commits if a transaction was actually created (i.e., if any operations needed it). This ensures efficiency for the common case of no-op batches.


295-303: The safety claim relies on undocumented behavior of the external solana-account crate.

The unsafe account.rollback() call assumes the rollback buffer is initialized by serialize_to_mmap(). However, this safety invariant is not documented in this codebase, and the external custom solana-account fork (rev 2246929) cannot be verified from this repository.

To address this:

  • Add a reference to the solana-account crate's documentation or source explaining the rollback buffer lifecycle, or
  • Document the safety invariant more explicitly, clarifying that serialize_to_mmap() initializes the rollback buffer as a postcondition, or
  • Consider safer alternatives to calling unsafe methods on external account types without local verification of their preconditions.
magicblock-accounts-db/src/index.rs (4)

166-200: LGTM!

The insert_account method correctly delegates transaction management to callers. All database operations use the provided txn reference, enabling atomic batch operations when multiple accounts need to be inserted together.


264-294: LGTM!

The ensure_correct_owner method properly uses the externally provided transaction for all operations, maintaining atomicity with other operations in the same transaction scope.


375-402: LGTM!

The try_recycle_allocation method correctly uses the provided transaction for cursor operations and allocation management. The split logic for oversized allocations is preserved and properly operates within the transaction.


434-438: LGTM!

The rwtxn() helper provides a clean public interface for callers to obtain write transactions, supporting the new explicit transaction management pattern.

@bmuddha bmuddha force-pushed the bmuddha/accountsdb/fallible-inserts branch from 4616fe7 to b4dffa5 Compare January 5, 2026 16:10
Copy link
Collaborator Author

bmuddha commented Jan 5, 2026

This stack of pull requests is managed by Graphite. Learn more about stacking.

@bmuddha bmuddha mentioned this pull request Jan 5, 2026
3 tasks
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

Fix all issues with AI Agents 🤖
In @magicblock-accounts-db/src/lib.rs:
- Around line 295-308: If txn.commit() fails we must perform the same rollback
of in-memory accounts that we do when earlier errors occurred; modify the end of
the commit routine (the block that currently calls txn.commit()? and then
Ok(())) to detect an Err from txn.commit(), run the existing rollback loop over
accounts.take(commited) and call unsafe { account.rollback() } for each
rolled-back account (preserving the safety comment), and then return the commit
error (Propagate it as Err). In short: replace the unconditional txn.commit()?
path with logic that on Err(e) executes the same rollback loop used when error
is Some and then returns Err(e), otherwise proceeds to Ok(()).
♻️ Duplicate comments (3)
magicblock-processor/src/executor/callback.rs (1)

39-39: Acknowledged: Safe to ignore on fresh AccountsDb.

Based on the maintainer's previous clarification, insertion failure is impossible on a fresh accountsdb for builtin accounts. Consider adding an inline comment to document this invariant for future maintainers:

// Safe to ignore: builtin account insertion cannot fail on fresh accountsdb
let _ = self.accountsdb.insert_account(program_id, &account);
magicblock-api/src/magic_validator.rs (1)

159-161: Acknowledged: Safe to ignore on fresh AccountsDb.

Based on the maintainer's previous clarification, genesis account insertion cannot fail on a fresh accountsdb. For future maintainability, consider adding a comment before the loop:

// Safe to ignore: genesis account insertion cannot fail on fresh accountsdb
for (pubkey, account) in genesis_config.accounts {
    let _ = accountsdb.insert_account(&pubkey, &account.into());
}
magicblock-api/src/fund_account.rs (1)

38-38: Error handling inconsistent with PR objectives.

The PR introduces fallible account inserts to "fail transaction if account commit failed," but these three call sites explicitly ignore insert_account errors with let _ =. This contradicts the stated objective of propagating commit failures.

While a past review comment indicates these error-handling issues (including .unwrap() calls on lines 46, 47, 81) will be addressed in #794, the explicit error ignoring introduced in this PR (lines 38, 48, 83-84) represents new technical debt.

Consider:

  1. Refactoring these functions to return Result and propagate errors to callers, or
  2. If these operations are truly infallible due to specific invariants (e.g., during validator initialization), document the justification explicitly.

Based on coding guidelines (production code under magicblock-* should not ignore errors without justification).

Also applies to: 48-48, 83-84

📜 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 4616fe7 and b4dffa5.

⛔ 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 (17)
  • Cargo.toml
  • magicblock-accounts-db/src/error.rs
  • magicblock-accounts-db/src/index.rs
  • magicblock-accounts-db/src/index/tests.rs
  • magicblock-accounts-db/src/lib.rs
  • magicblock-accounts-db/src/storage.rs
  • magicblock-accounts-db/src/tests.rs
  • magicblock-api/src/fund_account.rs
  • magicblock-api/src/magic_validator.rs
  • magicblock-processor/src/executor/callback.rs
  • magicblock-processor/src/executor/processing.rs
  • magicblock-processor/src/lib.rs
  • magicblock-processor/src/loader.rs
  • magicblock-processor/src/scheduler/state.rs
  • magicblock-processor/tests/replay.rs
  • test-integration/Cargo.toml
  • test-kit/src/lib.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-processor/src/lib.rs
  • magicblock-api/src/magic_validator.rs
  • magicblock-processor/tests/replay.rs
  • magicblock-accounts-db/src/error.rs
  • magicblock-processor/src/scheduler/state.rs
  • magicblock-accounts-db/src/storage.rs
  • magicblock-processor/src/executor/callback.rs
  • magicblock-accounts-db/src/tests.rs
  • magicblock-accounts-db/src/index.rs
  • magicblock-api/src/fund_account.rs
  • magicblock-accounts-db/src/index/tests.rs
  • magicblock-processor/src/executor/processing.rs
  • magicblock-processor/src/loader.rs
  • magicblock-accounts-db/src/lib.rs
{test-*,tools}/**

⚙️ CodeRabbit configuration file

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

Files:

  • test-kit/src/lib.rs
  • test-integration/Cargo.toml
🧠 Learnings (17)
📚 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-processor/src/lib.rs
  • magicblock-api/src/magic_validator.rs
  • magicblock-processor/tests/replay.rs
  • magicblock-processor/src/scheduler/state.rs
  • magicblock-processor/src/executor/callback.rs
  • magicblock-accounts-db/src/tests.rs
  • Cargo.toml
  • magicblock-api/src/fund_account.rs
  • test-kit/src/lib.rs
  • magicblock-accounts-db/src/index/tests.rs
  • magicblock-processor/src/executor/processing.rs
  • magicblock-processor/src/loader.rs
  • magicblock-accounts-db/src/lib.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-processor/src/lib.rs
  • magicblock-processor/tests/replay.rs
  • magicblock-processor/src/scheduler/state.rs
  • magicblock-processor/src/executor/callback.rs
  • magicblock-api/src/fund_account.rs
  • test-kit/src/lib.rs
  • magicblock-processor/src/executor/processing.rs
  • magicblock-processor/src/loader.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-processor/src/lib.rs
  • magicblock-api/src/magic_validator.rs
  • magicblock-processor/tests/replay.rs
  • magicblock-processor/src/scheduler/state.rs
  • magicblock-processor/src/executor/callback.rs
  • magicblock-accounts-db/src/tests.rs
  • magicblock-accounts-db/src/index.rs
  • magicblock-api/src/fund_account.rs
  • test-kit/src/lib.rs
  • magicblock-processor/src/executor/processing.rs
  • magicblock-processor/src/loader.rs
  • magicblock-accounts-db/src/lib.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-processor/src/lib.rs
  • magicblock-processor/src/scheduler/state.rs
  • magicblock-processor/src/executor/callback.rs
  • magicblock-accounts-db/src/tests.rs
  • magicblock-accounts-db/src/index.rs
  • magicblock-api/src/fund_account.rs
  • magicblock-accounts-db/src/index/tests.rs
  • magicblock-processor/src/executor/processing.rs
  • magicblock-processor/src/loader.rs
  • magicblock-accounts-db/src/lib.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-api/src/magic_validator.rs
  • magicblock-processor/tests/replay.rs
  • magicblock-processor/src/scheduler/state.rs
  • magicblock-processor/src/executor/callback.rs
  • magicblock-accounts-db/src/tests.rs
  • magicblock-accounts-db/src/index.rs
  • Cargo.toml
  • magicblock-api/src/fund_account.rs
  • test-kit/src/lib.rs
  • magicblock-accounts-db/src/index/tests.rs
  • magicblock-processor/src/executor/processing.rs
  • magicblock-processor/src/loader.rs
  • magicblock-accounts-db/src/lib.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-api/src/magic_validator.rs
  • magicblock-processor/tests/replay.rs
  • magicblock-processor/src/scheduler/state.rs
  • magicblock-processor/src/executor/callback.rs
  • magicblock-accounts-db/src/tests.rs
  • magicblock-api/src/fund_account.rs
  • test-kit/src/lib.rs
  • magicblock-accounts-db/src/index/tests.rs
  • magicblock-processor/src/loader.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-processor/tests/replay.rs
  • magicblock-processor/src/executor/callback.rs
  • magicblock-accounts-db/src/tests.rs
  • magicblock-api/src/fund_account.rs
  • test-kit/src/lib.rs
  • magicblock-processor/src/loader.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-processor/tests/replay.rs
  • magicblock-processor/src/scheduler/state.rs
  • magicblock-accounts-db/src/tests.rs
  • test-kit/src/lib.rs
  • magicblock-accounts-db/src/index/tests.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-processor/src/scheduler/state.rs
  • magicblock-processor/src/executor/processing.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-processor/src/scheduler/state.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/scheduler/state.rs
  • magicblock-processor/src/executor/processing.rs
  • magicblock-accounts-db/src/lib.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-accounts-db/src/index.rs
  • magicblock-processor/src/executor/processing.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-accounts-db/src/index.rs
  • magicblock-processor/src/executor/processing.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:

  • Cargo.toml
  • test-integration/Cargo.toml
📚 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:

  • Cargo.toml
  • test-integration/Cargo.toml
📚 Learning: 2025-11-24T08:45:11.164Z
Learnt from: bmuddha
Repo: magicblock-labs/magicblock-validator PR: 675
File: Cargo.toml:145-145
Timestamp: 2025-11-24T08:45:11.164Z
Learning: The reqwest dependency version 0.11 is intentionally used in the magicblock-validator project to maintain compatibility with the Solana client dependencies.

Applied to files:

  • Cargo.toml
📚 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:

  • test-integration/Cargo.toml
🧬 Code graph analysis (3)
magicblock-accounts-db/src/error.rs (2)
test-integration/test-tools/src/conversions.rs (1)
  • err (8-8)
magicblock-rpc-client/src/lib.rs (1)
  • error (201-203)
magicblock-accounts-db/src/index/tests.rs (1)
magicblock-accounts-db/src/index.rs (2)
  • ensure_correct_owner (264-294)
  • get_delloactions_count (427-433)
magicblock-accounts-db/src/lib.rs (1)
magicblock-accounts-db/src/index.rs (2)
  • insert_account (166-200)
  • rwtxn (436-438)
🔇 Additional comments (22)
magicblock-accounts-db/src/error.rs (1)

29-33: LGTM: Error severity elevation is appropriate.

Changing from log::warn! to log::error! correctly reflects the criticality of account operation failures, aligning with the PR's objective to surface and handle account commit errors explicitly.

test-kit/src/lib.rs (3)

182-182: LGTM!

Ignoring the insert_account Result in test helper code is acceptable and aligns with the project's testing patterns.


207-207: LGTM!

Ignoring the insert_account Result in test helper code is acceptable and consistent with the project's testing practices.


341-341: LGTM!

Ignoring the insert_account Result in test helper code is acceptable. The CommitableAccount::commit helper is designed for test convenience.

magicblock-accounts-db/src/storage.rs (1)

402-402: LGTM!

Making Allocation unconditionally Copy is a benign change that simplifies usage across the codebase, including in the transactional contexts introduced by this PR.

magicblock-processor/tests/replay.rs (1)

61-61: LGTM!

Ignoring the insert_account Result in test code is acceptable. This helper function deliberately manipulates account state to create test scenarios for replay validation.

magicblock-accounts-db/src/tests.rs (1)

56-57: LGTM! Appropriate error handling for test code.

All insert_account calls now use .expect("failed to insert account") to surface insertion failures as test failures. This is acceptable in test code and aligns with the PR's objective to make account commits fallible.

Also applies to: 100-101, 126-127, 152-153, 157-158, 163-164, 172-173, 178-179, 217-218, 221-222, 259-260, 278-279, 317-318, 326-327, 366-367, 409-410, 440-441, 463-464, 476-477, 490-491, 499-500, 513-514, 522-523, 546-547, 564-566, 597-598, 676-678

magicblock-accounts-db/src/index.rs (4)

166-200: LGTM! Transaction management refactored for caller control.

The insert_account method now accepts an explicit &mut RwTransaction parameter instead of creating an internal transaction. This architectural change:

  • Enables batch operations by allowing multiple insertions within a single transaction
  • Moves commit responsibility to the caller, supporting the PR's goal of fallible commits
  • Maintains consistency across related index operations

The changes align well with the PR objectives to make account commits fallible at the transaction level.


264-294: LGTM! Consistent transactional pattern.

The ensure_correct_owner method follows the same pattern as insert_account, accepting an explicit transaction parameter and delegating commit responsibility to the caller. This ensures ownership index updates can be part of larger atomic operations.


375-402: LGTM! Deallocation recycling now transactional.

The try_recycle_allocation method consistently applies the transactional pattern, ensuring allocation recycling can participate in larger atomic commit operations.


435-438: LGTM! Convenience helper for transaction initialization.

The new rwtxn() helper method provides a clean way for callers to obtain a read-write transaction when needed, supporting the outward transaction management pattern.

magicblock-processor/src/executor/processing.rs (3)

79-95: LGTM! Proper error propagation for commit failures.

The new error handling ensures that if commit_accounts fails, the transaction is properly marked as failed with TransactionError::CommitCancelled. This directly implements the PR's objective: "transactions now fail if account commit failed."

The error message is threaded into the logs for debugging, and the failure is:

  1. Persisted to the ledger via commit_failed_transaction
  2. Counted in failure metrics
  3. Sent back to the caller if awaiting

This ensures atomic failure semantics when account commits encounter errors.


269-291: LGTM! Enhanced failure logging.

Adding the logs: Option<Vec<String>> parameter to commit_failed_transaction enables better debugging by threading error messages into the ledger metadata. This improves observability for commit failures.


293-358: LGTM! Batch commit with proper error propagation.

The refactored commit_accounts method now:

  1. Returns AccountsDbResult<()> to propagate errors (line 299)
  2. Uses insert_batch for atomic multi-account persistence (line 346)
  3. Filters accounts to only commit dirty or privileged ones (lines 343-345)
  4. Short-circuits on replay to avoid redundant ledger writes (lines 347-349)
  5. Emits AccountWithSlot events after successful commit (lines 350-356)

This batch-oriented approach improves atomicity and performance while enabling proper error propagation, which aligns with the PR's goal of fallible account inserts.

test-integration/Cargo.toml (1)

82-82: Solana-account revision 2246929 is valid and compatible.

The solana-account dependency revision update from 57158728 to 2246929 has been confirmed. The new revision contains 5 commits including a feature addition for account state rollback and safety-related fixes. No breaking changes are present, and the changes align with transactional account handling improvements.

magicblock-accounts-db/src/lib.rs (4)

92-105: LGTM! Clean lazy transaction pattern.

The txn!() macro provides efficient lazy initialization of the LMDB write transaction, avoiding unnecessary transaction overhead when processing Borrowed accounts without owner changes.


139-156: Well-structured error handling for allocation recycling.

The pattern of matching NotFound to fall back to fresh allocation while propagating other errors is appropriate. The error logging at Line 153 correctly identifies this as a catastrophic scenario.


186-206: Clear error handling macro for batch operations.

The break_error! macro provides consistent error logging and exit from the processing loop. The Clone bound on the iterator is necessary for the rollback mechanism at Line 296.


171-183: Consider rollback behavior for single insert commit failure.

For Owned accounts, serialize_to_mmap (Line 172-177) executes before txn.commit() (Line 181). If commit fails, data is written to storage but not indexed—causing a storage leak. For Borrowed accounts with owner changes, acc.commit() is called before the transaction commits.

While less critical for single inserts, consider whether consistency guarantees require rollback here as well, especially given the atomic semantics introduced by this PR.

magicblock-accounts-db/src/index/tests.rs (3)

12-14: Good practice: centralized error message constant.

The INSERT_ACCOUNT_TXN_ERR constant improves test readability and maintainability by providing a consistent error message across all transaction creation points.


24-43: Test correctly adapted to transactional API.

The transaction lifecycle follows the expected pattern: begin transaction, perform operation with &mut txn, commit. Both the initial insert and reinsert paths are properly tested.


244-312: Comprehensive transaction lifecycle testing.

The test properly exercises multiple transaction cycles including allocation recycling, removal, and subsequent recycling. Each logical operation correctly uses its own transaction scope.

@bmuddha bmuddha added this pull request to the merge queue Jan 6, 2026
Merged via the queue into master with commit 0cafea5 Jan 6, 2026
19 checks passed
@bmuddha bmuddha deleted the bmuddha/accountsdb/fallible-inserts branch January 6, 2026 09:37
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.

feat: fallible account inserts

3 participants