Skip to content

Comments

perf/store: optimize updating existing accounts #1567

Open
drahnr wants to merge 11 commits intonextfrom
bernhard-do-not-load-full-account
Open

perf/store: optimize updating existing accounts #1567
drahnr wants to merge 11 commits intonextfrom
bernhard-do-not-load-full-account

Conversation

@drahnr
Copy link
Contributor

@drahnr drahnr commented Jan 22, 2026

Context

Currently applying a partial delta to an existing account requires loading the full account state
consisting of code, all storage map entries, all vault assets, which is very costly - we spend ~250ms on this per block (that's a lot!).

See #1538

What

Optimizes account delta updates by avoiding loading full Account objects from the database when only applying partial deltas.

Core changes

  • module crates/store/src/db/models/queries/accounts/delta.rs

    • fn select_account_state_for_delta() - fetches only nonce, code_commitment, storage_header, vault_root
    • fn select_vault_balances_by_faucet_ids() - fetches only specific vault balances being updated
    • fn apply_storage_delta_with_precomputed_roots() - updates the storage header using precomputed map roots
  • InnerForest::apply_block_updates now precomputes vault and storage map roots for each account update and passes them to
    Db::apply_block for partial delta updates.

  • fn upsert_accounts uses the optimized path for partial deltas via enum AccountStateForInsert with three variants:

    • ::Private - no public state
    • ::FullAccount - new account creation == "full-state delta"
    • ::PartialState - incremental update == "partial delta"
  • AccountRowInsert constructors: new_private(), new_from_account(), new_from_partial()

Biggest Change

We reverse the flow and update - we update the InnerForest now and track new roots, then using these in the DB storage header update. The downside is additional tackling.

@drahnr drahnr marked this pull request as draft January 22, 2026 08:36
@drahnr drahnr force-pushed the bernhard-do-not-load-full-account branch 3 times, most recently from 14dc3a6 to 5f11a29 Compare January 22, 2026 15:16
@drahnr drahnr requested a review from Copilot February 3, 2026 15:47
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR optimizes applying partial account deltas by avoiding loading full Account state (code bytes, all storage-map entries, all vault assets) during upsert_accounts, instead fetching only minimal state and computing updated headers/roots.

Changes:

  • Added an optimized delta-update module to query minimal account state and compute updated storage_header / vault_root.
  • Updated upsert_accounts to use an AccountStateForInsert enum to handle private, full-state, and partial-state inserts.
  • Added new tests covering the optimized delta path, private upserts, and full-state delta upserts.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
crates/store/src/db/models/queries/accounts/delta.rs New optimized queries + helpers for partial delta application (minimal state + root/header computation).
crates/store/src/db/models/queries/accounts/delta/tests.rs New tests for optimized partial delta update, private account upsert, and full-state delta upsert.
crates/store/src/db/models/queries/accounts.rs Integrates optimized partial-delta path into upsert_accounts; adds AccountRowInsert constructors.
alt_approach.txt Documents an alternative design (precompute roots in InnerForest).
CHANGELOG.md Adds a changelog entry for the performance improvement.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

storage_header: new_storage_header,
vault_root: new_vault_root,
};

Copy link

Copilot AI Feb 3, 2026

Choose a reason for hiding this comment

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

In the partial-delta path, the code no longer verifies that the derived minimal state (nonce/storage/vault/code commitment) is consistent with update.final_state_commitment(). Previously this was enforced by applying the delta to a full Account and checking AccountCommitmentsMismatch. Without an equivalent check here, it’s possible to persist an accounts row whose commitment does not match its stored nonce/storage_header/vault_root fields (especially given the new ad-hoc SMT computations). Please add a commitment verification using the minimal fields (or otherwise ensure consistency) and fail the update if it doesn’t match.

Suggested change
// Verify that the derived minimal state matches the expected final commitment.
// This mirrors the full-state delta path where we build a full `Account` and
// compare `account.commitment()` with `update.final_state_commitment()`.
let calculated_commitment = Account::commitment_from_minimal_state(
account_state.nonce,
account_state.code_commitment,
account_state.storage_header,
account_state.vault_root,
);
if calculated_commitment != update.final_state_commitment() {
return Err(DatabaseError::AccountCommitmentsMismatch {
calculated: calculated_commitment,
expected: update.final_state_commitment(),
});
}

Copilot uses AI. Check for mistakes.
@drahnr drahnr force-pushed the bernhard-do-not-load-full-account branch from 6b1b40a to a865ef0 Compare February 16, 2026 15:01
@drahnr drahnr force-pushed the bernhard-do-not-load-full-account branch from a865ef0 to 2c632b5 Compare February 16, 2026 15:48
@drahnr drahnr marked this pull request as ready for review February 16, 2026 16:45
@drahnr drahnr requested a review from Copilot February 16, 2026 18:08
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 11 out of 11 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

drahnr and others added 2 commits February 17, 2026 10:03
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@drahnr drahnr force-pushed the bernhard-do-not-load-full-account branch from 0a9e28b to faaad63 Compare February 23, 2026 12:55
@drahnr drahnr requested a review from sergerad February 24, 2026 19:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants