Add STATE_VERSION to all settlement PDA seeds - #89
Conversation
Every account the settlement program stores lived at a PDA whose first seed was the bare string `settlement`. A program upgrade that changed the layout or meaning of stored state would therefore land on exactly the same addresses as the previous version, so old order and state accounts would be silently reinterpreted under the new layout. Fold a `STATE_VERSION` constant into the prefix seed that all three PDA families share, so bumping it relocates the program's whole address space at once and accounts written by an older version become unreachable rather than misread. The version is formatted as decimal ASCII and concatenated onto the prefix, giving `settlement1`, so the seed stays legible wherever seeds surface. It remains a single seed rather than an extra seed slot, which leaves the seed arity of all three schemes untouched and the compute cost of every derivation unchanged. The seed is built in a `const` item rather than a `const fn` because the workspace denies `clippy::arithmetic_side_effects` and that lint skips `const` item bodies but not `const fn` bodies. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… of github.com:cowprotocol/solana-programs into kaze/sc-287-add-state-version-as-a-seed-to-all-storage
fedgiac
left a comment
There was a problem hiding this comment.
Something missing from the description that I think deserves a mention: this affects all PDAs, not just the state PDA. This is intended behavior, but a distracted reviewer would miss that.
Also, there are some references to fixed lengths, but I don't see it in the code:
At 15 bytes it has ample headroom under the 32-byte MAX_SEED_LEN
15? Maybe under the assumption that the minor/major are 1 byte each?
The four extra seed bytes are free too: sol_create_program_address and sol_try_find_program_address
4? With the same assumption from before, maybe 5 including the extra space?
But anyway, the assumption is wrong, this isn't a fixed bytes and this in principle is a security concern (see comment).
Also, we should clearly write in the readme that we must increase the minor version on each new deployment, this would be very easy to miss.
The fix for that is that the deployment script tries to see if the state PDA exists and, if it already exists, it aborts the deployment suggesting to bump the version.
Do we want to enforce that its bumped on every version? or its OK to do a deployment without bumping (or only bumping patch) if the storage format hasn't changed?
We don't currently do anything in the deployment script to call |
will probably need to do something more sophisticated later
… of github.com:cowprotocol/solana-programs into kaze/sc-287-add-state-version-as-a-seed-to-all-storage
fedgiac
left a comment
There was a problem hiding this comment.
Do we want to enforce that its bumped on every version? or its OK to do a deployment without bumping (or only bumping patch) if the storage format hasn't changed?
I'd say the default should be enforcing the version bump but that it can be somehow overwritten. I don't have a concrete idea for how though.
We don't currently do anything in the deployment script to call Initialize actually, as there was no initialization when the deploy script was first created. It seems we might want to add something to the test-cli before we do the next big release.
Yep!
[making it permanent]
Mmh, I'm reconsidering the size, maybe 5 bytes (two minor, two major or one major, three minor) are more than enough for now. Maybe even (1, 2).
But yeah, why not making it permanent? I'll review the DESIGN file with this in mind.
Co-authored-by: Federico Giacon <58218759+fedgiac@users.noreply.github.com>
Co-authored-by: Federico Giacon <58218759+fedgiac@users.noreply.github.com>
Co-authored-by: Federico Giacon <58218759+fedgiac@users.noreply.github.com>
Ok for now my thought is, when we get the |
Description
Updates the settlement root PDA seed to correspond to the Major and minor cargo package versions. This causes all PDAs to be relocated on every minor or major package version bump.
Contents
Generally speaking the root state PDA is now:
The whole seed is printable ASCII, so it shows up readably in explorers, logs and
solana account.No CU cost. Everything resolves in
rustc—stringson the built.soshowssettlement .. v0.1baked into rodata — so nothing happens on-chain.Other considerations
How to test
Check new strategy
🤖 Generated with Claude Code