Skip to content

Pack OrderIntent flags into a single byte - #116

Merged
kaze-cow merged 12 commits into
mainfrom
kaze/sc-288-on-chain-orders-should-be-reclaimable-when-order-is
Aug 26, 2026
Merged

Pack OrderIntent flags into a single byte#116
kaze-cow merged 12 commits into
mainfrom
kaze/sc-288-on-chain-orders-should-be-reclaimable-when-order-is

Conversation

@kaze-cow

@kaze-cow kaze-cow commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Description

Fold the encoded OrderIntent's kind and partially_fillable into a single
flags byte.

Split out of the reclaim work in #116's original scope, as suggested in
#116 (review).
The follow-up that introduces the created_on_chain flag and the early-reclaim
behaviour is stacked on top of this branch in #122 .

Motivation

kind and partially_fillable each took a whole byte of the wire format and
each needed its own range check on decode. Both carry a single bit of
information, so a flags byte replaces two validated bytes with one, and leaves
room for the flags we know are coming.

Implementation

partially_fillable takes the most significant defined bit, kind the next one
down (Sell = 0, Buy = 1). Every remaining bit is reserved and must be zero.

OrderIntent keeps the idiomatic representation — an OrderKind enum and a
bool — so callers are unaffected. Only the encoding and its validation change.

EncodedOrderIntent::SIZE goes 150 → 149 and EncodedOrderAccount::SIZE
201 → 200.

This is a BREAKING CHANGE for the OrderIntent encoding because it repurposes
existing bytes, and therefore it modifies the location of the order PDA and
changes the hash of all orders.

Testing Plan

The existing codec tests carry over to the new representation, plus:

  • every_flag_owns_a_distinct_bit pins that each flag occupies one bit, that no
    two flags share a bit, that they run from the most significant defined bit
    down, and that together they are exactly FLAGS_MASK.
  • decode_accepts_defined_flag_bits_only walks all 256 flag bytes and checks
    each one is either rejected or decodes to the expected kind and
    partially_fillable.
  • The proptest rejects_reserved_flag_bits is the property-based counterpart,
    and bytes_roundtrip pins that any accepted byte string re-encodes to itself.
  • uid_digest_regression and encoding_regression are updated for the new
    encoding.

@kaze-cow kaze-cow self-assigned this Aug 24, 2026
@linear-code

linear-code Bot commented Aug 24, 2026

Copy link
Copy Markdown

SC-288

@kaze-cow
kaze-cow marked this pull request as ready for review August 24, 2026 13:09
@kaze-cow
kaze-cow requested a review from a team as a code owner August 24, 2026 13:09

@fedgiac fedgiac left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This PR would have a very natural split: the introduction of the flag encoding and then introducing the new flag for on-chain orders. Not having this makes the reviewing process longer imho. I reviewed the file interface/src/data/intent.rs for now, which mostly involves the new flag approach (which makes sense to me overall). Will review the rest once the comments are addressed.

Also, something I don't see discussed and I didn't reach in the review: what happens if an order is reclaimesd in the middle of a settlement?

Comment thread interface/src/data/intent.rs Outdated
Comment thread interface/src/data/intent.rs Outdated
Comment thread interface/src/data/intent.rs Outdated
Comment thread interface/src/data/intent.rs Outdated
Comment thread interface/src/data/intent.rs Outdated
Comment thread interface/src/data/intent.rs Outdated
Comment thread interface/src/data/intent.rs Outdated
Comment thread interface/src/data/intent.rs Outdated
Comment thread interface/src/data/intent.rs Outdated
Comment thread interface/src/data/intent.rs
`kind` and `partially_fillable` each occupied a whole byte of the encoded
intent, and each needed its own range check on decode. Fold both into one
flags byte instead: `partially_fillable` takes the most significant defined
bit, `kind` the next one down, and every remaining bit is reserved and must
be zero.

`OrderIntent` keeps the idiomatic representation — an `OrderKind` enum and a
`bool` — so callers are unaffected. Only the wire format and the validation
change: a single mask check now rejects any byte carrying an undefined bit,
which keeps the encoding injective and so keeps order UIDs unique.

`EncodedOrderIntent::SIZE` goes 150 -> 149 and `EncodedOrderAccount::SIZE`
201 -> 200.

This is a BREAKING CHANGE to the `OrderIntent` encoding: it repurposes
existing bytes, so it moves every order PDA and changes every order UID.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@kaze-cow
kaze-cow force-pushed the kaze/sc-288-on-chain-orders-should-be-reclaimable-when-order-is branch from d00b0db to dd787a3 Compare August 26, 2026 08:08
@kaze-cow kaze-cow changed the title Allow ReclaimOrder of completed orders before expiry Pack OrderIntent flags into a single byte Aug 26, 2026
@kaze-cow
kaze-cow requested a review from fedgiac August 26, 2026 09:37

@fedgiac fedgiac left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Wonderful!

@kaze-cow
kaze-cow requested a review from fedgiac August 26, 2026 12:11

@fedgiac fedgiac left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Looks good after the merge!

EncodedOrderIntent::WIDTH_PARTIALLY_FILLABLE,
size_of_val(&intent.partially_fillable)
EncodedOrderIntent::WIDTH_FLAGS,
// in truth if there was a problem here it would actually cause a compilation error

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Good! 🙂

@kaze-cow
kaze-cow merged commit d5d8cf0 into main Aug 26, 2026
14 checks passed
@kaze-cow
kaze-cow deleted the kaze/sc-288-on-chain-orders-should-be-reclaimable-when-order-is branch August 26, 2026 12:29
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