Skip to content

chore: extract transaction syncer API#2

Open
thlorenz wants to merge 16 commits intomasterfrom
thlorenz/transaction-syncer-single-stream
Open

chore: extract transaction syncer API#2
thlorenz wants to merge 16 commits intomasterfrom
thlorenz/transaction-syncer-single-stream

Conversation

@thlorenz
Copy link

@thlorenz thlorenz commented Jan 20, 2026

Summary

Refactored the codebase to improve code organization and maintainability and allow transaction
specific logic to be used directly from chainlink:

  • Extracted all magic constants into a dedicated consts module for easier configuration and maintenance
  • Created a new transaction_syncer module containing stateless helpers for processing undelegation transactions
  • Simplified the main syncer module by delegating transaction processing logic to transaction_syncer
  • expose transaction_syncer API

Added tests and CI workflow as well.

Details

Code Organization Improvements

The refactoring improves code structure without changing functionality:

  • consts module: Centralizes all hardcoded values (public key sizes, program addresses, account indices, limits) in one place, making the codebase easier to configure and maintain
  • transaction_syncer module: Encapsulates transaction processing logic with pure functions (create_filter() and process_update()), improving testability and separation of concerns
  • syncer module: Simplified by removing constants and delegating transaction filtering/processing to the new modules, making the main logic clearer and easier to follow

The changes are purely structural—no behavioral changes or new features added.

Summary by CodeRabbit

  • Refactor
    • Moved transaction parsing and sync constants into dedicated modules and delegated undelegation processing to a shared component.
  • Bug Fixes / Reliability
    • Improved detection and handling of undelegation events and reconnection behavior during syncing.
  • New Features
    • Added helpers to build subscription filters and extract undelegation records from streamed transactions.
  • Tests
    • Added unit tests covering undelegation parsing and edge cases.
  • Chores
    • Added CI workflow and development dependencies for testing and formatting.

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

@coderabbitai
Copy link

coderabbitai bot commented Jan 20, 2026

Walkthrough

Adds a crate-scoped consts module, a new public transaction_syncer module with helpers to build transaction filters and extract undelegation record pubkeys, refactors syncer.rs to use the new module, includes unit tests for transaction parsing, adds a GitHub Actions CI workflow, and updates Cargo.toml with new dependencies.

Changes

Cohort / File(s) Summary
Constants Module
src/consts.rs
New file declaring crate-scoped constants: PUBKEY_LEN, DELEGATION_PROGRAM, DELEGATION_PROGRAM_PUBKEY (derived via bs58), DELEGATION_RECORD_SIZE, UNDELEGATE_DISCRIMINATOR, DISCRIMINATOR_LEN, DELEGATION_RECORD_ACCOUNT_INDEX, MAX_PENDING_REQUESTS, MAX_PENDING_UPDATES, MAX_RECONNECT_ATTEMPTS.
Transaction Syncer Module
src/transaction_syncer.rs
New file exporting pub fn create_filter() -> HashMap<String, SubscribeRequestFilterTransactions> and pub fn process_update(txn: &SubscribeUpdateTransaction) -> impl Iterator<Item = Pubkey>; parses transaction instructions to identify undelegate discriminators, resolves record account pubkeys, and includes unit tests covering multiple edge cases.
Syncer integration & lib entry
src/syncer.rs, src/lib.rs
src/lib.rs adds mod consts and pub mod transaction_syncer (and a small doc example annotation change). src/syncer.rs replaces inline undelegation parsing with calls to transaction_syncer::create_filter() and transaction_syncer::process_update(), and imports constants from crate::consts.
CI workflow
.github/workflows/ci.yml
New GitHub Actions workflow on pull_request: checks out code, installs stable and nightly Rust toolchains, caches Cargo, runs cargo test, cargo +nightly fmt --check, and cargo clippy.
Cargo manifest
Cargo.toml
Adds new dependencies: bs58 = "0.5.1" and either = "1.15.0".

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'chore: extract transaction syncer API' accurately describes the main refactoring work: extracting transaction syncer functionality into a separate module with a public API.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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 thlorenz/transaction-syncer-single-stream

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link

@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 `@src/consts.rs`:
- Around line 8-15: Add a unit test that decodes DELEGATION_PROGRAM (base58) and
asserts it equals DELEGATION_PROGRAM_PUBKEY to prevent future drift between
representations; create a #[cfg(test)] mod tests with a test function (e.g.,
delegation_program_pubkey_matches_string) that decodes DELEGATION_PROGRAM via
bs58::decode (or Solana's Pubkey::from_str) and compares the resulting
bytes/slice to DELEGATION_PROGRAM_PUBKEY using assert_eq!.

@thlorenz thlorenz requested a review from bmuddha January 20, 2026 16:39
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In @.github/workflows/ci.yml:
- Around line 17-29: Replace the deprecated actions-rs/toolchain steps with
dtolnay/rust-toolchain: update the two job steps currently named "Setup Rust"
and "Setup Rust nightly for formatting" to use uses: dtolnay/rust-toolchain@v1
(or latest), adjust the inputs to the new action's API (e.g., specify toolchain:
stable and components: rustfmt, clippy for the first step; toolchain: nightly
and components: rustfmt for the second) and ensure override/override behavior is
mapped to the new action's equivalent options; keep step names and intent the
same but change the action reference and input keys to match
dtolnay/rust-toolchain.
- Around line 31-47: Replace the three GitHub Actions cache steps currently
referencing actions/cache@v3 with actions/cache@v4: update the "uses" value in
the steps named "Cache cargo registry", "Cache cargo index", and "Cache cargo
build" to actions/cache@v4 while keeping their existing "path" and "key" fields
unchanged.
♻️ Duplicate comments (1)
src/consts.rs (1)

38-52: LGTM! Test ensures consistency between pubkey representations.

This test prevents drift between the base58 string and byte array representations of the delegation program pubkey.

Copy link
Collaborator

@bmuddha bmuddha left a comment

Choose a reason for hiding this comment

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

Almost LGTM, a few code style related issues to fix, and ready for merge.

thlorenz and others added 3 commits January 21, 2026 08:14
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: Babur Makhmudov <[email protected]>
Copy link

@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 @.github/workflows/ci.yml:
- Around line 1-12: The job-level `if` uses github.event.pull_request.draft
which is undefined on push events so CI never runs on pushes; update the `if` on
the `ci` job (job name "ci") to allow pushes as well, for example replace the
current condition with an expression that permits push events and only blocks
draft PRs — e.g. use: if: github.event_name == 'pull_request' &&
github.event.pull_request.draft == false || github.event_name == 'push' — to
ensure pushes to master/dev still trigger the job while preserving the draft-PR
guard.
♻️ Duplicate comments (1)
.github/workflows/ci.yml (1)

17-29: Replace deprecated actions-rs/toolchain.

actions-rs/toolchain@v1 is unmaintained and actionlint flags it as too old. Switch to dtolnay/rust-toolchain.

🔧 Proposed fix
-      - name: Setup Rust
-        uses: actions-rs/toolchain@v1
-        with:
-          toolchain: stable
-          components: rustfmt, clippy
-          override: true
+      - name: Setup Rust
+        uses: dtolnay/rust-toolchain@stable
+        with:
+          components: rustfmt, clippy

-      - name: Setup Rust nightly for formatting
-        uses: actions-rs/toolchain@v1
-        with:
-          toolchain: nightly
-          components: rustfmt
-          override: false
+      - name: Setup Rust nightly for formatting
+        uses: dtolnay/rust-toolchain@nightly
+        with:
+          components: rustfmt

Copy link

@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 `@src/transaction_syncer.rs`:
- Around line 30-33: The docstring for process_update is incorrect: it claims
the function "Returns a Vec of record_pubkeys" but the signature returns an
iterator (impl Iterator<Item = Pubkey> + '_). Update the doc comment above pub
fn process_update(txn: &SubscribeUpdateTransaction) to state that it returns an
iterator over Pubkey values (e.g., "Returns an iterator over record pubkeys for
each undelegation found") and remove any mention of Vec so the docs match the
function signature and behavior.

Comment on lines +30 to +33
/// Processes a transaction update and extracts undelegated pubkeys.
///
/// Returns a Vec of record_pubkeys for each undelegation found.
pub fn process_update(txn: &SubscribeUpdateTransaction) -> impl Iterator<Item = Pubkey> + '_ {
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Fix docstring: returns an iterator, not a Vec.

✏️ Proposed doc fix
-/// Returns a Vec of record_pubkeys for each undelegation found.
+/// Returns an iterator of record pubkeys for each undelegation found.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
/// Processes a transaction update and extracts undelegated pubkeys.
///
/// Returns a Vec of record_pubkeys for each undelegation found.
pub fn process_update(txn: &SubscribeUpdateTransaction) -> impl Iterator<Item = Pubkey> + '_ {
/// Processes a transaction update and extracts undelegated pubkeys.
///
/// Returns an iterator of record pubkeys for each undelegation found.
pub fn process_update(txn: &SubscribeUpdateTransaction) -> impl Iterator<Item = Pubkey> + '_ {
🤖 Prompt for AI Agents
In `@src/transaction_syncer.rs` around lines 30 - 33, The docstring for
process_update is incorrect: it claims the function "Returns a Vec of
record_pubkeys" but the signature returns an iterator (impl Iterator<Item =
Pubkey> + '_). Update the doc comment above pub fn process_update(txn:
&SubscribeUpdateTransaction) to state that it returns an iterator over Pubkey
values (e.g., "Returns an iterator over record pubkeys for each undelegation
found") and remove any mention of Vec so the docs match the function signature
and behavior.

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