Skip to content

Implement the new table balances logic to client runner#2320

Merged
findolor merged 18 commits intomainfrom
local-db-apply-post-batch
Dec 2, 2025
Merged

Implement the new table balances logic to client runner#2320
findolor merged 18 commits intomainfrom
local-db-apply-post-batch

Conversation

@findolor
Copy link
Copy Markdown
Collaborator

@findolor findolor commented Nov 17, 2025

Chained PR

Motivation

Now that we have the new vault balances tables, we can implement the logic that will insert to these tables during the client-runner process.

We need to:

  1. Have a way to create additional SQL statements in the apply pipeline
  2. Bundle these new statements together with what we have in the default pipeline implementation and execute
  3. Make sure we only insert the new tables in the client

Solution

  • Extend the bootstrap configuration with deployment block so we can call the upsert vault balances logic during bootstrapping phase
    • crates/common/src/local_db/pipeline/adapters/bootstrap.rs
  • Extend the apply pipeline with build_post_batch function. The default implementation for this is an empty batch list, but the client will provide sql statements for the vault balance changes
    • crates/common/src/local_db/pipeline/adapters/apply.rs
  • Remove the default apply pipeline struct and implement the default logic directly in the pipeline trait
  • Create the client implementation for the apply pipeline and use that in the client runner
    • crates/common/src/raindex_client/local_db/pipeline/apply.rs
  • Add new tests and update existing ones

Checks

By submitting this for review, I'm confirming I've done the following:

  • made this PR as small as possible
  • unit-tested any new functionality
  • linked any relevant issues or PRs
  • included screenshots (if this involves a front-end change)

Summary by CodeRabbit

  • New Features

    • Added post-batch hooks for custom pipeline actions and automatic vault-balance refreshes during indexing and bootstrap.
    • Bootstrap configuration now accepts a deployment block to scope initial balance refreshes.
    • Introduced client-specific apply adapter to enable client-targeted post-processing.
  • Refactor

    • Pipeline now carries explicit start/target block windows for more precise, two-phase batch construction and persistence.

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

@findolor findolor requested review from 0xgleb and hardyjosh November 17, 2025 15:13
@findolor findolor self-assigned this Nov 17, 2025
@findolor findolor added this to the LocalDB Implementation milestone Nov 17, 2025
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Nov 17, 2025

Walkthrough

Refactors the local_db pipeline to introduce an ApplyPipeline trait with an ApplyPipelineTargetInfo (start_block/target_block), adds a build_post_batch hook, passes deployment_block through BootstrapConfig, and implements ClientApplyAdapter to emit post-batch vault-balance upserts.

Changes

Cohort / File(s) Summary
Apply pipeline core
crates/common/src/local_db/pipeline/adapters/apply.rs, crates/common/src/local_db/pipeline/mod.rs
Add public ApplyPipeline trait (required build_batch, default build_post_batch/persist/export_dump), add ApplyPipelineTargetInfo (ob_id, start_block, target_block, hash), and refactor DefaultApplyPipeline to implement the trait. Remove older re-exports in pipeline mod.
Engine & runner wiring
crates/common/src/local_db/pipeline/engine.rs, crates/cli/src/commands/local_db/pipeline/runner/mod.rs, crates/common/src/local_db/pipeline/runner/environment.rs, crates/common/src/local_db/pipeline/runner/environment.rs
Engine now calls build_batch then build_post_batch and extends the batch before persist/export; test stubs updated to implement new build_post_batch; ApplyPipeline import paths adjusted.
Bootstrap config
crates/cli/src/commands/local_db/pipeline/bootstrap.rs, crates/common/src/local_db/pipeline/adapters/bootstrap.rs
Add deployment_block field to BootstrapConfig (CLI: u32, common: u64) and pass deployment_block through bootstrap flow and tests.
Client apply adapter & module
crates/common/src/raindex_client/local_db/pipeline/apply.rs, crates/common/src/raindex_client/local_db/pipeline/mod.rs
Add ClientApplyAdapter implementing ApplyPipeline::build_post_batch to upsert vault balances for [start_block..target_block]; new apply module exported.
Client runner/bootstrap wiring
crates/common/src/raindex_client/local_db/pipeline/bootstrap.rs, crates/common/src/raindex_client/local_db/pipeline/runner/environment.rs, crates/common/src/raindex_client/local_db/pipeline/runner/mod.rs, crates/common/src/raindex_client/local_db/pipeline/runner/scheduler.rs
Replace DefaultApplyPipeline with ClientApplyAdapter in environment/runner/specializations; add refresh_running_vault_balances call in bootstrap flow; update imports and tests.

Sequence Diagram(s)

sequenceDiagram
    participant Engine
    participant Apply as ApplyPipeline
    participant Default as DefaultApplyPipeline
    participant Client as ClientApplyAdapter
    participant DB

    Engine->>Apply: build_batch(target_info, logs, events, tokens, upserts)
    Apply->>Default: default build_batch() (or impl)
    Default-->>Engine: primary SqlStatementBatch

    Engine->>Apply: build_post_batch(target_info)
    alt DefaultApplyPipeline (default)
        Apply-->>Engine: empty SqlStatementBatch
    else ClientApplyAdapter
        Apply->>Client: build_post_batch(target_info)
        alt start_block ≤ target_block
            Client->>Client: upsert_vault_balances_batch(ob_id, start, target)
            Client-->>Engine: vault-balance SqlStatementBatch
        else start_block > target_block
            Client-->>Engine: empty SqlStatementBatch
        end
    end

    Engine->>Engine: extend primary batch with post_batch
    Engine->>Apply: persist(db, combined_batch)
    Apply->>DB: execute batch inside transaction
    DB-->>Apply: execution result
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

  • Focus review areas:
    • crates/common/src/local_db/pipeline/adapters/apply.rs — trait design, default implementations, and target-info semantics.
    • crates/common/src/local_db/pipeline/engine.rs — two-phase batch composition and persist/export changes.
    • crates/common/src/raindex_client/local_db/pipeline/apply.rs — conditional vault-balance upsert logic and SQL correctness.
    • Cross-module consistency for deployment_block type and propagation (CLI vs common types) and tests.

Possibly related PRs

Suggested reviewers

  • hardyjosh
  • 0xgleb

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 70.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Implement the new table balances logic to client runner' accurately describes the primary change in the PR: introducing vault balances table insertion logic into the client runner via the new apply pipeline post-batch mechanism.
✨ 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 local-db-apply-post-batch

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f04a8fe and 9dda788.

📒 Files selected for processing (7)
  • crates/cli/src/commands/local_db/pipeline/runner/mod.rs (4 hunks)
  • crates/common/src/local_db/pipeline/adapters/apply.rs (23 hunks)
  • crates/common/src/local_db/pipeline/engine.rs (7 hunks)
  • crates/common/src/local_db/pipeline/mod.rs (1 hunks)
  • crates/common/src/local_db/pipeline/runner/environment.rs (3 hunks)
  • crates/common/src/raindex_client/local_db/pipeline/runner/mod.rs (4 hunks)
  • crates/common/src/raindex_client/local_db/pipeline/runner/scheduler.rs (2 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
crates/**/*.rs

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

crates/**/*.rs: For Rust crates in crates/*, run lints using nix develop -c cargo clippy --workspace --all-targets --all-features -D warnings
For Rust crates in crates/*, run tests using nix develop -c cargo test --workspace or --package <crate>

Files:

  • crates/common/src/raindex_client/local_db/pipeline/runner/scheduler.rs
  • crates/common/src/raindex_client/local_db/pipeline/runner/mod.rs
  • crates/common/src/local_db/pipeline/mod.rs
  • crates/common/src/local_db/pipeline/adapters/apply.rs
  • crates/common/src/local_db/pipeline/engine.rs
  • crates/common/src/local_db/pipeline/runner/environment.rs
  • crates/cli/src/commands/local_db/pipeline/runner/mod.rs
**/crates/**

📄 CodeRabbit inference engine (AGENTS.md)

Rust workspace organized as crates/* with subdirectories: cli, common, bindings, js_api, quote, subgraph, settings, math, integration_tests

Files:

  • crates/common/src/raindex_client/local_db/pipeline/runner/scheduler.rs
  • crates/common/src/raindex_client/local_db/pipeline/runner/mod.rs
  • crates/common/src/local_db/pipeline/mod.rs
  • crates/common/src/local_db/pipeline/adapters/apply.rs
  • crates/common/src/local_db/pipeline/engine.rs
  • crates/common/src/local_db/pipeline/runner/environment.rs
  • crates/cli/src/commands/local_db/pipeline/runner/mod.rs
**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

**/*.rs: Rust: format code with nix develop -c cargo fmt --all
Rust: lint with nix develop -c rainix-rs-static (preconfigured flags included)
Rust: crates and modules use snake_case; types use PascalCase

Files:

  • crates/common/src/raindex_client/local_db/pipeline/runner/scheduler.rs
  • crates/common/src/raindex_client/local_db/pipeline/runner/mod.rs
  • crates/common/src/local_db/pipeline/mod.rs
  • crates/common/src/local_db/pipeline/adapters/apply.rs
  • crates/common/src/local_db/pipeline/engine.rs
  • crates/common/src/local_db/pipeline/runner/environment.rs
  • crates/cli/src/commands/local_db/pipeline/runner/mod.rs
🧠 Learnings (9)
📓 Common learnings
Learnt from: rouzwelt
Repo: rainlanguage/rain.orderbook PR: 0
File: :0-0
Timestamp: 2025-05-21T21:24:53.708Z
Learning: For PR #1884 in rainlanguage/rain.orderbook, provide a separate comment after each review with PR size statistics in the format: `TOTAL=number ADDITIONS=number DELETIONS=number`, excluding lock files like package-lock.json and cargo.lock.
Learnt from: rouzwelt
Repo: rainlanguage/rain.orderbook PR: 0
File: :0-0
Timestamp: 2025-05-21T21:24:53.708Z
Learning: For PR #1884 in rainlanguage/rain.orderbook, provide a separate comment after each review with PR size statistics in the format: `TOTAL=number ADDITIONS=number DELETIONS=number`, excluding lock files like package-lock.json and cargo.lock.
Learnt from: rouzwelt
Repo: rainlanguage/rain.orderbook PR: 0
File: :0-0
Timestamp: 2025-05-21T21:24:53.708Z
Learning: For PR #1884 in rainlanguage/rain.orderbook, provide a separate comment after each review with PR size statistics in the format: `TOTAL=number ADDITIONS=number DELETIONS=number`, excluding lock files like package-lock.json and cargo.lock.
Learnt from: rouzwelt
Repo: rainlanguage/rain.orderbook PR: 0
File: :0-0
Timestamp: 2025-05-21T21:24:53.708Z
Learning: For PR #1884 in rainlanguage/rain.orderbook, provide a separate comment after each review with PR size statistics in the format: `TOTAL=number ADDITIONS=number DELETIONS=number`, excluding lock files like package-lock.json and cargo.lock.
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 1994
File: crates/common/src/raindex_client/vaults.rs:282-292
Timestamp: 2025-07-15T08:01:38.534Z
Learning: In the rainlanguage/rain.orderbook codebase, findolor prefers to avoid concurrency optimizations like using `futures::future::try_join_all` for parallel processing of balance changes, considering such optimizations "not that critical at the moment" when the performance impact is minimal.
Learnt from: rouzwelt
Repo: rainlanguage/rain.orderbook PR: 0
File: :0-0
Timestamp: 2025-05-21T21:25:47.873Z
Learning: After each new commit review for rainlanguage/rain.orderbook repository, generate a PR size report in a separate comment with the format: "TOTAL=number ADDITIONS=number DELETIONS=number". This report should exclude irrelevant files such as lock files (e.g., package-lock.json, cargo.lock).
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 2145
File: crates/common/src/raindex_client/local_db/query/create_tables/query.sql:71-72
Timestamp: 2025-10-06T11:44:07.888Z
Learning: The local DB feature in the rain.orderbook codebase is not live yet (as of PR #2145), so schema migrations for existing databases are not required when modifying table structures in `crates/common/src/raindex_client/local_db/query/create_tables/query.sql`.
Learnt from: rouzwelt
Repo: rainlanguage/rain.orderbook PR: 0
File: :0-0
Timestamp: 2025-05-21T21:26:31.566Z
Learning: For PR #1884 and future PRs in rainlanguage/rain.orderbook repository, provide PR size reports in a separate comment with ONLY the exact format "TOTAL=number\nADDITIONS=number\nDELETIONS=number", without any additional text or explanation. Reports should exclude irrelevant files such as lock files (package-lock.json, yarn.lock, pnpm-lock.yaml, cargo.lock).
Learnt from: rouzwelt
Repo: rainlanguage/rain.orderbook PR: 0
File: :0-0
Timestamp: 2025-05-21T22:14:22.646Z
Learning: For PR #1884 in rainlanguage/rain.orderbook, I must consistently report the PR size after EVERY new commit in the exact format "TOTAL=number\nADDITIONS=number\nDELETIONS=number" without any formatting blocks. The report must exclude lock files (package-lock.json, yarn.lock, pnpm-lock.yaml, cargo.lock) and can be included either as part of the review or as a separate comment.
Learnt from: rouzwelt
Repo: rainlanguage/rain.orderbook PR: 0
File: :0-0
Timestamp: 2025-05-21T22:14:22.646Z
Learning: For PR #1884 in rainlanguage/rain.orderbook, I must consistently report the PR size after EVERY new commit in the exact format "TOTAL=number\nADDITIONS=number\nDELETIONS=number" without any additional text or formatting blocks. The report must exclude lock files (package-lock.json, yarn.lock, pnpm-lock.yaml, cargo.lock) and can be included either as part of the review or as a separate comment.
📚 Learning: 2025-10-06T11:13:29.956Z
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 2123
File: crates/common/src/raindex_client/local_db/mod.rs:23-29
Timestamp: 2025-10-06T11:13:29.956Z
Learning: In `crates/common/src/raindex_client/local_db/mod.rs`, the `Default` implementation for `LocalDb` that creates an RPC client pointing to `http://localhost:4444` is acceptable because the RPC client must be explicitly configured before actual usage in production scenarios.

Applied to files:

  • crates/common/src/raindex_client/local_db/pipeline/runner/scheduler.rs
  • crates/common/src/raindex_client/local_db/pipeline/runner/mod.rs
  • crates/common/src/local_db/pipeline/runner/environment.rs
  • crates/cli/src/commands/local_db/pipeline/runner/mod.rs
📚 Learning: 2025-10-06T14:41:41.909Z
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 2159
File: crates/cli/src/commands/local_db/sync/runner/mod.rs:52-113
Timestamp: 2025-10-06T14:41:41.909Z
Learning: The local DB sync CLI command (crates/cli/src/commands/local_db/sync/) is designed for CI-only usage, and simple println! statements are preferred over structured logging for status messages.

Applied to files:

  • crates/common/src/raindex_client/local_db/pipeline/runner/mod.rs
  • crates/common/src/local_db/pipeline/engine.rs
  • crates/common/src/local_db/pipeline/runner/environment.rs
📚 Learning: 2025-10-14T07:51:55.148Z
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 2202
File: crates/common/src/raindex_client/local_db/sync.rs:33-34
Timestamp: 2025-10-14T07:51:55.148Z
Learning: In `crates/common/src/raindex_client/local_db/sync.rs`, the hard-coded `DEFAULT_SYNC_CHAIN_ID` constant (set to `SUPPORTED_LOCAL_DB_CHAINS[0]`) will be replaced with proper chain ID handling in downstream PRs as part of the multi-network/orderbook implementation.

Applied to files:

  • crates/common/src/local_db/pipeline/adapters/apply.rs
  • crates/common/src/local_db/pipeline/runner/environment.rs
  • crates/cli/src/commands/local_db/pipeline/runner/mod.rs
📚 Learning: 2025-05-27T06:16:12.195Z
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 1874
File: tauri-app/src-tauri/src/transaction_status.rs:87-114
Timestamp: 2025-05-27T06:16:12.195Z
Learning: In tauri-app/src-tauri/src/transaction_status.rs, testing one WriteTransactionStatus variant (like PendingPrepare) is sufficient for the update_status_and_emit method since all variants follow the same code path through the From<WriteTransactionStatus<T>> implementation.

Applied to files:

  • crates/common/src/local_db/pipeline/adapters/apply.rs
📚 Learning: 2025-09-24T10:54:42.060Z
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 2163
File: crates/cli/src/commands/order/calldata.rs:47-48
Timestamp: 2025-09-24T10:54:42.060Z
Learning: In crates/cli/src/commands/order/calldata.rs, the config_deployment variable is used both as a parameter to AddOrderArgs::new_from_deployment() and later to extract RPC information, requiring the clone() to maintain access after ownership transfer.

Applied to files:

  • crates/common/src/local_db/pipeline/engine.rs
📚 Learning: 2025-11-04T09:20:06.368Z
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 2292
File: crates/settings/src/remote/manifest.rs:35-44
Timestamp: 2025-11-04T09:20:06.368Z
Learning: In the rain.orderbook codebase, manifest version validation happens during parsing in crates/settings/src/local_db_manifest.rs. The parse_manifest_header function validates both manifest_version against MANIFEST_VERSION and db_schema_version against DB_SCHEMA_VERSION constants, failing with YamlError if either doesn't match. This means fetch_manifest calls will fail before returning if versions are incompatible, making cross-URL version consistency checks unnecessary in fetch_multiple_manifests.

Applied to files:

  • crates/common/src/local_db/pipeline/runner/environment.rs
  • crates/cli/src/commands/local_db/pipeline/runner/mod.rs
📚 Learning: 2025-10-06T13:03:35.337Z
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 2146
File: crates/cli/src/commands/local_db/README.md:22-106
Timestamp: 2025-10-06T13:03:35.337Z
Learning: In the rain.orderbook repository, `cargo run` commands work without the `--` separator (e.g., `cargo run local-db fetch-events` works directly). Do not suggest adding `--` before CLI arguments in cargo run examples for this repository.

Applied to files:

  • crates/common/src/local_db/pipeline/runner/environment.rs
📚 Learning: 2025-10-18T10:38:41.273Z
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 2237
File: crates/common/src/raindex_client/local_db/sync.rs:79-89
Timestamp: 2025-10-18T10:38:41.273Z
Learning: In `crates/common/src/raindex_client/local_db/sync.rs`, the sync_database method currently only supports indexing a single orderbook per chain ID, which is why `.first()` is used to select the orderbook configuration. Multi-orderbook support per chain ID is planned for future PRs.

Applied to files:

  • crates/common/src/local_db/pipeline/runner/environment.rs
  • crates/cli/src/commands/local_db/pipeline/runner/mod.rs
🧬 Code graph analysis (3)
crates/common/src/local_db/pipeline/mod.rs (1)
crates/common/src/raindex_client/local_db/query/fetch_erc20_tokens_by_addresses.rs (1)
  • fetch_erc20_tokens_by_addresses (6-16)
crates/common/src/local_db/pipeline/adapters/apply.rs (1)
crates/common/src/local_db/query/sql_statement_batch.rs (3)
  • ensure_transaction (38-53)
  • is_transaction (30-35)
  • len (65-67)
crates/cli/src/commands/local_db/pipeline/runner/mod.rs (2)
crates/common/src/local_db/pipeline/adapters/apply.rs (2)
  • build_post_batch (94-99)
  • new (131-133)
crates/common/src/raindex_client/local_db/pipeline/apply.rs (1)
  • build_post_batch (14-27)
🔇 Additional comments (26)
crates/common/src/local_db/pipeline/mod.rs (1)

17-19: LGTM!

The import cleanup removing SqlStatementBatch aligns with moving ApplyPipeline (and its batch construction logic) to adapters::apply. The module now cleanly aggregates the remaining pipeline traits.

crates/cli/src/commands/local_db/pipeline/runner/mod.rs (2)

15-15: LGTM!

Import path correctly updated to reflect ApplyPipeline relocation to adapters::apply.


666-671: LGTM!

Test stub correctly implements the new build_post_batch method with an empty batch return, which is appropriate for test scenarios that don't need vault balance upserts.

crates/common/src/local_db/pipeline/runner/environment.rs (2)

3-6: LGTM!

Import paths correctly updated to reflect the ApplyPipeline trait relocation to adapters::apply.


389-414: LGTM!

The StubApply test implementation correctly uses the updated build_batch signature with ApplyPipelineTargetInfo and relies on the trait's default build_post_batch implementation, which returns an empty batch. This is appropriate for test scenarios.

crates/common/src/raindex_client/local_db/pipeline/runner/scheduler.rs (2)

4-7: LGTM!

Import changes correctly replace DefaultApplyPipeline with ClientApplyAdapter.


23-31: LGTM!

The DefaultClientRunner type alias correctly uses ClientApplyAdapter, which implements the build_post_batch hook to call upsert_vault_balances_batch. This ensures vault balance insertion occurs only in the client runner as specified in the PR objectives.

crates/common/src/local_db/pipeline/engine.rs (6)

1-3: LGTM!

Import paths correctly updated to use ApplyPipeline and ApplyPipelineTargetInfo from adapters::apply.


106-121: LGTM!

ApplyPipelineTargetInfo now correctly includes both start_block and target_block, providing the necessary context for build_post_batch to conditionally generate vault balance upserts when the window is valid.


156-159: LGTM!

BootstrapConfig now includes deployment_block, enabling the bootstrap phase to have access to deployment information for vault balance logic during bootstrapping.


304-321: LGTM!

The two-phase batch construction is well-implemented:

  1. build_batch creates the primary SQL batch
  2. build_post_batch generates additional statements (vault balance upserts in the client)
  3. batch.extend(post_batch) combines them before persistence

This design cleanly separates core apply logic from client-specific post-processing.


1006-1014: LGTM!

The MockApply test implementation correctly adds build_post_batch returning an empty batch, which is appropriate for test scenarios that don't need vault balance logic.


1625-1636: LGTM!

Test assertions correctly validate the new BootstrapConfig structure, verifying that deployment_block, block_number_threshold, and latest_block are properly propagated from SyncInputs.

crates/common/src/raindex_client/local_db/pipeline/runner/mod.rs (3)

5-27: Import reorganization looks correct.

The imports have been properly reorganized to:

  1. Import ApplyPipeline trait from the new adapters::apply module path (line 7)
  2. Add ClientApplyAdapter import for the client-specific implementation (line 24)

This aligns with the PR objective of implementing client-specific apply pipeline logic while keeping the trait definition in the adapters module.


170-185: Client runner now uses the client-specific apply adapter.

The ClientRunner specialization correctly switches from DefaultApplyPipeline to ClientApplyAdapter at line 176. This enables the client runner to use the build_post_batch hook for vault balance upserts as described in the PR objectives.


187-201: Test imports updated to new module paths.

The test module correctly imports ApplyPipelineTargetInfo from the new location at adapters::apply (line 193). The test infrastructure will properly exercise the new trait-based apply pipeline.

crates/common/src/local_db/pipeline/adapters/apply.rs (10)

26-40: Well-documented trait responsibilities.

The trait documentation clearly separates concrete responsibilities (batch building, watermark updates) from policy concerns (dump export). The ?Send bound on the async trait is appropriate for browser/WASM compatibility.


41-89: Default build_batch implementation is comprehensive.

The implementation:

  1. Builds a decimals map from existing rows and upserts (lines 53-61)
  2. Constructs SQL in correct order: raw events → token upserts → decoded events → watermark (lines 64-86)
  3. Returns the batch without transaction wrapping (caller's responsibility via persist)

The logic correctly gives precedence to upsert decimals over existing rows due to HashMap insertion order.


91-99: build_post_batch hook enables client-specific extensions.

The empty default implementation allows ClientApplyAdapter to override and inject vault balance upsert statements. This design cleanly separates core batch logic from client-specific concerns.


101-109: persist correctly ensures transactional semantics.

Using ensure_transaction() (line 107) guarantees the batch is wrapped with BEGIN/COMMIT if not already. Per the external snippet, ensure_transaction checks for existing transaction markers before wrapping, preventing double-wrapping.


111-124: export_dump no-op hook for environment-specific behavior.

This follows the same pattern as build_post_batch, allowing producer environments to override while keeping browser as no-op. The design is consistent.


126-137: DefaultApplyPipeline provides baseline behavior.

The unit struct with empty trait impl inherits all default methods. The const fn new() is appropriate for a zero-sized type.


149-160: Test helper build_target_info correctly initializes struct.

The helper function properly constructs ApplyPipelineTargetInfo with the sample hash constant, enabling consistent test assertions.


255-295: build_batch_contains_watermark test validates transactional wrapping.

The test at lines 283-286 correctly verifies that ensure_transaction() produces a valid transaction by calling is_transaction(). This is a good integration check for the batch/transaction flow.


340-355: empty_work_window_only_watermark test verifies minimal batch.

The test confirms that an empty work window produces only the watermark statement (line 351 expects exactly 1 statement). This validates the "no-op cycle" behavior where only progress tracking is persisted.


18-24: start_block field is actively used for vault balance upsert queries.

The ApplyPipelineTargetInfo struct's start_block field is used in ClientApplyAdapter::build_post_batch() to query vault balance changes within the computed block range. It's passed to upsert_vault_balances_batch() which filters balance change events, and is also checked against target_block to detect no-op sync cycles.


Comment @coderabbitai help to get the list of available commands and usage tips.

@findolor
Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Nov 17, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Base automatically changed from local-db-balance-tables to main December 2, 2025 05:43
@findolor findolor merged commit f04c84c into main Dec 2, 2025
20 checks passed
@findolor findolor deleted the local-db-apply-post-batch branch December 2, 2025 06:51
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Dec 2, 2025

@coderabbitai assess this PR size classification for the totality of the PR with the following criterias and report it in your comment:

S/M/L PR Classification Guidelines:

This guide helps classify merged pull requests by effort and complexity rather than just line count. The goal is to assess the difficulty and scope of changes after they have been completed.

Small (S)

Characteristics:

  • Simple bug fixes, typos, or minor refactoring
  • Single-purpose changes affecting 1-2 files
  • Documentation updates
  • Configuration tweaks
  • Changes that require minimal context to review

Review Effort: Would have taken 5-10 minutes

Examples:

  • Fix typo in variable name
  • Update README with new instructions
  • Adjust configuration values
  • Simple one-line bug fixes
  • Import statement cleanup

Medium (M)

Characteristics:

  • Feature additions or enhancements
  • Refactoring that touches multiple files but maintains existing behavior
  • Breaking changes with backward compatibility
  • Changes requiring some domain knowledge to review

Review Effort: Would have taken 15-30 minutes

Examples:

  • Add new feature or component
  • Refactor common utility functions
  • Update dependencies with minor breaking changes
  • Add new component with tests
  • Performance optimizations
  • More complex bug fixes

Large (L)

Characteristics:

  • Major feature implementations
  • Breaking changes or API redesigns
  • Complex refactoring across multiple modules
  • New architectural patterns or significant design changes
  • Changes requiring deep context and multiple review rounds

Review Effort: Would have taken 45+ minutes

Examples:

  • Complete new feature with frontend/backend changes
  • Protocol upgrades or breaking changes
  • Major architectural refactoring
  • Framework or technology upgrades

Additional Factors to Consider

When deciding between sizes, also consider:

  • Test coverage impact: More comprehensive test changes lean toward larger classification
  • Risk level: Changes to critical systems bump up a size category
  • Team familiarity: Novel patterns or technologies increase complexity

Notes:

  • the assessment must be for the totality of the PR, that means comparing the base branch to the last commit of the PR
  • the assessment output must be exactly one of: S, M or L (single-line comment) in format of: SIZE={S/M/L}
  • do not include any additional text, only the size classification
  • your assessment comment must not include tips or additional sections
  • do NOT tag me or anyone else on your comment

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Dec 2, 2025

Tip

For best results, initiate chat on the files or code changes.

SIZE=L


🧠 Learnings used
Learnt from: rouzwelt
Repo: rainlanguage/rain.orderbook PR: 0
File: :0-0
Timestamp: 2025-05-21T21:24:42.275Z
Learning: For PR #1884, after each commit review, I should provide a new comment with a PR size report in the format: `TOTAL=number ADDITIONS=number DELETIONS=number`, excluding irrelevant files such as lock files (package-lock.json, cargo.lock, etc.).

Learnt from: rouzwelt
Repo: rainlanguage/rain.orderbook PR: 0
File: :0-0
Timestamp: 2025-05-21T21:24:42.275Z
Learning: After each commit in PR #1884, I should provide a new comment with the PR size report in the format: `TOTAL=number ADDITIONS=number DELETIONS=number`. The report should exclude irrelevant files such as lock files (e.g., package-lock.json, cargo.lock).

Learnt from: rouzwelt
Repo: rainlanguage/rain.orderbook PR: 0
File: :0-0
Timestamp: 2025-05-21T21:25:47.873Z
Learning: After each new commit review for rainlanguage/rain.orderbook repository, generate a PR size report in a separate comment with the format: "TOTAL=number ADDITIONS=number DELETIONS=number". This report should exclude irrelevant files such as lock files (e.g., package-lock.json, cargo.lock).

Learnt from: rouzwelt
Repo: rainlanguage/rain.orderbook PR: 0
File: :0-0
Timestamp: 2025-05-21T21:25:47.873Z
Learning: After each new commit review for rainlanguage/rain.orderbook repository, generate a PR size report in a separate comment with the exact format: "TOTAL=number\nADDITIONS=number\nDELETIONS=number". This report should exclude irrelevant files such as lock files (package-lock.json, yarn.lock, pnpm-lock.yaml, cargo.lock).

Learnt from: rouzwelt
Repo: rainlanguage/rain.orderbook PR: 0
File: :0-0
Timestamp: 2025-05-21T22:14:22.646Z
Learning: For PR #1884 in rainlanguage/rain.orderbook, I must consistently report the PR size after EVERY new commit in the exact format "TOTAL=number\nADDITIONS=number\nDELETIONS=number" without any formatting blocks. The report must exclude lock files (package-lock.json, yarn.lock, pnpm-lock.yaml, cargo.lock) and can be included either as part of the review or as a separate comment.

Learnt from: rouzwelt
Repo: rainlanguage/rain.orderbook PR: 0
File: :0-0
Timestamp: 2025-05-21T22:14:22.646Z
Learning: For PR #1884 in rainlanguage/rain.orderbook, I must consistently report the PR size after EVERY new commit in the exact format "TOTAL=number\nADDITIONS=number\nDELETIONS=number" without any additional text or formatting blocks. The report must exclude lock files (package-lock.json, yarn.lock, pnpm-lock.yaml, cargo.lock) and can be included either as part of the review or as a separate comment.

Learnt from: rouzwelt
Repo: rainlanguage/rain.orderbook PR: 0
File: :0-0
Timestamp: 2025-05-21T22:46:08.530Z
Learning: For PR #1884 in rainlanguage/rain.orderbook, the PR size report should be the only content in the comment - no text before it, no text after it, no formatting blocks, just the raw report in the exact format: "TOTAL=number\nADDITIONS=number\nDELETIONS=number". The report must exclude lock files (package-lock.json, yarn.lock, pnpm-lock.yaml, cargo.lock).

Learnt from: rouzwelt
Repo: rainlanguage/rain.orderbook PR: 0
File: :0-0
Timestamp: 2025-05-21T21:24:53.708Z
Learning: For PR #1884 in rainlanguage/rain.orderbook, provide a separate comment after each review with PR size statistics in the format: `TOTAL=number ADDITIONS=number DELETIONS=number`, excluding lock files like package-lock.json and cargo.lock.

Learnt from: rouzwelt
Repo: rainlanguage/rain.orderbook PR: 0
File: :0-0
Timestamp: 2025-05-21T21:24:53.708Z
Learning: For PR #1884 in rainlanguage/rain.orderbook, provide a separate comment after each review with PR size statistics in the format: `TOTAL=number ADDITIONS=number DELETIONS=number`, excluding lock files like package-lock.json and cargo.lock.

Learnt from: rouzwelt
Repo: rainlanguage/rain.orderbook PR: 0
File: :0-0
Timestamp: 2025-05-21T21:24:53.708Z
Learning: For PR #1884 in rainlanguage/rain.orderbook, provide a separate comment after each review with PR size statistics in the format: `TOTAL=number ADDITIONS=number DELETIONS=number`, excluding lock files like package-lock.json and cargo.lock.

Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 1971
File: .github/workflows/vercel-docs-prod.yaml:32-34
Timestamp: 2025-07-11T12:30:09.245Z
Learning: findolor prefers not to pin Node versions explicitly in GitHub Actions workflows when using Nix with webapp-shell, considering the current setup sufficient for deterministic builds in the rainlanguage/rain.orderbook project.

Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 1971
File: .github/workflows/vercel-docs-prod.yaml:10-14
Timestamp: 2025-07-11T12:29:49.284Z
Learning: In GitHub Actions workflows for the rainlanguage/rain.orderbook project, findolor is comfortable with job names that may seem misleading (like "Deploy-Docs-Preview" in a production workflow) when there's only one job in the workflow, as the context makes it clear enough.

Learnt from: rouzwelt
Repo: rainlanguage/rain.orderbook PR: 0
File: :0-0
Timestamp: 2025-05-21T21:24:53.708Z
Learning: For PR #1884 in rainlanguage/rain.orderbook, provide a separate comment after each review with PR size statistics in the format: `TOTAL=number ADDITIONS=number DELETIONS=number`, excluding lock files like package-lock.json and cargo.lock.

Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 1994
File: crates/common/src/raindex_client/vaults.rs:282-292
Timestamp: 2025-07-15T08:01:38.534Z
Learning: In the rainlanguage/rain.orderbook codebase, findolor prefers to avoid concurrency optimizations like using `futures::future::try_join_all` for parallel processing of balance changes, considering such optimizations "not that critical at the moment" when the performance impact is minimal.

Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 2145
File: crates/common/src/raindex_client/local_db/query/create_tables/query.sql:71-72
Timestamp: 2025-10-06T11:44:07.888Z
Learning: The local DB feature in the rain.orderbook codebase is not live yet (as of PR #2145), so schema migrations for existing databases are not required when modifying table structures in `crates/common/src/raindex_client/local_db/query/create_tables/query.sql`.

Learnt from: rouzwelt
Repo: rainlanguage/rain.orderbook PR: 0
File: :0-0
Timestamp: 2025-05-21T21:26:31.566Z
Learning: For PR #1884 and future PRs in rainlanguage/rain.orderbook repository, provide PR size reports in a separate comment with ONLY the exact format "TOTAL=number\nADDITIONS=number\nDELETIONS=number", without any additional text or explanation. Reports should exclude irrelevant files such as lock files (package-lock.json, yarn.lock, pnpm-lock.yaml, cargo.lock).

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.

3 participants