Skip to content

Encode account and instruction integers as little-endian#63

Open
kaze-cow wants to merge 1 commit into
mainfrom
le-encoding-fixes
Open

Encode account and instruction integers as little-endian#63
kaze-cow wants to merge 1 commit into
mainfrom
le-encoding-fixes

Conversation

@kaze-cow

@kaze-cow kaze-cow commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Switches every hand-rolled multi-byte integer field in the settlement program's account/instruction wire formats from big-endian to little-endian: OrderIntent's sell_amount/buy_amount/valid_to, OrderAccount's amount_withdrawn/amount_received, and the BeginSettle/FinalizeSettle counterpart-index fields (finalize_ix_index/begin_ix_index).
  • Little-endian is the Borsh/Anchor convention; this is groundwork toward Anchor-compatible on-chain data so external tooling (indexers, block explorers) can decode it without bespoke logic, and is a prerequisite for a follow-up PR that adds Anchor-style account discriminators.
  • Breaking: changes the order UID hash (SHA-256 preimage) and the wire format of CreateOrder, BeginSettle, and FinalizeSettle. Not compatible with any existing on-chain state or off-chain signers built against the old big-endian format. We are not concerned about this breakage at this stage.

Test plan

  • just build-verified to rebuild the on-chain .so
  • cargo test --workspace — all tests pass, including updated regression tests pinning the new little-endian byte layouts and UID hash

🤖 Generated with Claude Code

Switches every hand-rolled u16/u32/u64 field currently stored/sent
big-endian to little-endian: OrderIntent's sell_amount/buy_amount/valid_to,
OrderAccount's amount_withdrawn/amount_received, and the BeginSettle/
FinalizeSettle counterpart-index fields (finalize_ix_index/begin_ix_index).

Little-endian is the Borsh/Anchor convention; this is a first step toward
Anchor-compatible on-chain data so external tooling (indexers, explorers)
can read it without bespoke decoding. This changes the order UID hash and
the wire format of CreateOrder/BeginSettle/FinalizeSettle - not backwards
compatible with any existing on-chain state or off-chain signers.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@squadgazzz

Copy link
Copy Markdown

This gets external tooling the right byte values, but on its own it won't let the off-chain indexer decode without bespoke logic. The crate's instruction parsers are AccountView-coupled (parse_body takes &mut [AccountView]), so an off-chain indexer can't call them. The data-only decoders cover most of it (recover_discriminator, recover_counterpart, both decode_and_hash), but the BeginSettle pull layout ([n][bump x n][count x n][amount x T]) is parsed only inside BeginSettleInput::parse_body. So our indexer hand-copies that layout, and it will silently drift the moment this PR flips the amounts to little-endian (and again when #49 moves the bumps).

Could we expose the pull parse as a data-only pub fn parse_begin_settle_pulls(body) -> (finalize_ix_index, pulls) with no AccountView, have parse_body call it, and let the indexer call the same fn? One place for the layout and the endianness, and we drop the hand-parse.

@kaze-cow

Copy link
Copy Markdown
Contributor Author

the BeginSettle pull layout ([n][bump x n][count x n][amount x T]) is parsed only inside BeginSettleInput::parse_body. So our indexer hand-copies that layout, and it will silently drift the moment this PR flips the amounts to little-endian (and again when #49 moves the bumps).

Yep, sorry about that. The purpose of this PR is not designed to provide all in one fix to our indexing/data decoding issues, only to start taking steps to try and improve this. Regarding the BeginSettle, yes, unless we fundamentally change the way data is stored and provided, this is not expected to improve in the near future.

BTW on #49 I don't know if we have made a final decision on this yet, but my guess is we will end up moving there because its easier to maintain and simplifies a lot of functions.

Could we expose the pull parse as a data-only pub fn parse_begin_settle_pulls(body) -> (finalize_ix_index, pulls) with no AccountView, have parse_body call it, and let the indexer call the same fn? One place for the layout and the endianness, and we drop the hand-parse.

A data-only on-chain call? We should have a call to confirm what the use case is, but perhaps its possible to clal the affected order pda's data sturctures instead (which is now 100% IDL compliant with this and #64 change)

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