Skip to content

feat(solana-indexer) PR 13: index on-chain-created orders - #4740

Open
squadgazzz wants to merge 115 commits into
mainfrom
solana-indexer/PR13-onchain-orders
Open

feat(solana-indexer) PR 13: index on-chain-created orders#4740
squadgazzz wants to merge 115 commits into
mainfrom
solana-indexer/PR13-onchain-orders

Conversation

@squadgazzz

@squadgazzz squadgazzz commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Description

Orders placed directly on chain (the demo flow has no orderbook) now get their solana.orders row, which is what makes them visible to the autopilot's open-orders cut. The missing piece was the token mints. The intent only names token accounts, so at flush time the decoder resolves the batch's token accounts through getMultipleAccounts and reads each account's mint out of the SPL layout.

The lookup only trusts accounts owned by a token program with the token-account size, so an intent naming a garbage account cannot smuggle a fake mint into the orders table. When a mint cannot be resolved (not a token account, closed), the order keeps its order_pda row, the intent row is skipped, and the transaction is dead-lettered with reason unresolved_mints, so the replay machinery re-delivers it later. An RPC failure is handled differently: the slot's database write never starts and the last indexed slot does not advance, so a restart re-delivers the whole slot and transient outages lose nothing.

Changes

  • The decoder resolves each batch's token accounts to mints before persisting, fn token_account_mint reads the SPL account layout and rejects non-token accounts
  • CreatedOrder carries its transaction signature, the dead-letter key for unresolved orders
  • apply_order_created writes the solana.orders row (zero fee_amount, the on-chain intent has no fee, and creation_timestamp is indexing time, the stream carries no block time)
  • Rpc::new_mock for tests over a canned transport

How to test

New and updated DB tests: the pipeline test now runs through a mocked getMultipleAccounts and asserts the orders row, plus an unresolved-mints case. cargo nextest run -p solana-indexer solana_db --run-ignored ignored-only --test-threads 1, and they run in CI.

Related issues

Resolves BE-207.

squadgazzz and others added 30 commits July 24, 2026 08:07
The parsing-generic branch is merged and its ref deleted, so the branch
pin would break the next cargo update. Main's interface types the push
amount as u64, dropping the byte-array decode on our side.
Drops the pending-adapter and later-PR breadcrumbs, the spec anchor,
and the leftover cast comment resolved by the i64 pass-through.
… solana-indexer/PR9-pipeline-test

# Conflicts:
#	crates/solana-indexer/src/persistence.rs
…runcating

The order/push zip silently truncated to the shorter side and the pull
sum saturated. Both are layout violations, so the pair is skipped with
a warning. Also merges the no-event instruction arms, drops the
intermediate push collect, and inlines the test instruction helper.
The CreateOrder and BeginSettle/FinalizeSettle fixtures go through the
client crate's builders as a dev-dependency, so the tests round-trip
the real encoder into our parser instead of hand-rolling bytes. The
invalid-instruction fixtures stay hand-rolled: they craft data no
builder would produce, and they double as the wire-layout pin.
…arser' into solana-indexer/PR8-persist

# Conflicts:
#	crates/solana-indexer/src/indexer/decoder/tests.rs
…eline-test

# Conflicts:
#	crates/solana-indexer/src/persistence.rs
…xer/PR8-persist

# Conflicts:
#	crates/solana-indexer/src/indexer/decoder/tests.rs
@linear-code

linear-code Bot commented Aug 13, 2026

Copy link
Copy Markdown

BE-207

Base automatically changed from solana-indexer/PR12-rpc-client to main August 14, 2026 09:06
@squadgazzz
squadgazzz marked this pull request as ready for review August 14, 2026 09:38
@squadgazzz
squadgazzz requested a review from a team as a code owner August 14, 2026 09:38
@squadgazzz
squadgazzz requested a review from tilacog August 14, 2026 09:38
@claude

claude Bot commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Claude finished @squadgazzz's task in 2m 35s —— View job


PR Review: index on-chain-created orders

Reviewed the diff against origin/main. Overall this is clean, well-documented work — the batched mint resolution, the RPC-failure-vs-unresolved-mint distinction, the idempotent ON CONFLICT DO NOTHING inserts, and the mocked-RPC test coverage are all solid. SQL column/value/bind counts line up correctly, and the serde_json dependency is correctly dev-only.

Two points posted as inline comments (both worth a look, neither blocking):

  • decoder.rs token_account_mint — reads the first 32 bytes of any account without confirming it's actually an SPL token account (owner + exact 165-byte length). A non-token account could silently write a garbage mint into solana.orders.
  • persistence.rs unresolved-mint skip — the "until a replay fills it in" claim: since the slot still advances here, a restart won't re-deliver the event. Worth confirming a replay path exists or holding the slot back for this case, as is done for the RPC-error path.

Nice touches: distinct mints in the tests so a swapped binding fails, and the unresolved-mints test asserting order_pda is kept while orders is skipped.

  • Read the diff against origin/main
  • Review decoder changes (mint resolution)
  • Review persistence changes (apply_order_created)
  • Review rpc / error handling
  • Review tests
  • Post inline comments + summary

Comment thread crates/solana-indexer/src/indexer/decoder.rs
Comment thread crates/solana-indexer/src/persistence.rs Outdated
Comment thread crates/solana-indexer/src/indexer/decoder.rs
Comment thread crates/solana-indexer/src/persistence.rs Outdated
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.

1 participant