Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
cab3e70
Refactor state PDA accessors
fedgiac Aug 25, 2026
e4ec645
Add instruction to add a solver
fedgiac Aug 26, 2026
8e5d0dc
Merge branch 'main' into refactor-state-account-decoder
fedgiac Aug 26, 2026
7813e83
state_header -> state_account_bytes
fedgiac Aug 26, 2026
515547f
Simplify tests for `Role::ALL`
fedgiac Aug 26, 2026
3e79073
Implement StateAccount::from_account
fedgiac Aug 26, 2026
85c2fd5
StateAccount::new -> StateAccount::attach
fedgiac Aug 26, 2026
1379c01
Merge branch 'refactor-state-account-decoder' into federico/sc-299-ad…
fedgiac Aug 26, 2026
3e2393f
Add comment about saturating_sub
fedgiac Aug 26, 2026
5d0ea61
Move rejects_adding_solver_if_manager_is_not_signer next to rejects_a…
fedgiac Aug 26, 2026
a18f331
Clarify strict invariant check
fedgiac Aug 26, 2026
9dcc7b6
Add proptest verifying duplicate rejection
fedgiac Aug 26, 2026
7d19c0d
Move most resizing operations to interface
fedgiac Aug 26, 2026
8b489e4
cargo fmt & ambiguous import
fedgiac Aug 26, 2026
c6844b4
Simplify binary search
fedgiac Aug 26, 2026
5286c3a
`Header` -> `StateInitArgs`
fedgiac Aug 27, 2026
d189143
Merge branch 'main' into refactor-state-account-decoder
fedgiac Aug 27, 2026
5df9ad7
Add solver authentication to `BeginSettle`
fedgiac Aug 27, 2026
01c2b79
Merge branch 'refactor-state-account-decoder' into federico/sc-299-ad…
fedgiac Aug 27, 2026
c2311fe
Merge branch 'main' into federico/sc-299-add-functions-to-add-solver
fedgiac Aug 27, 2026
c468453
Fix merge issue
fedgiac Aug 27, 2026
641c07a
Reduce number of solvers created in test
fedgiac Aug 27, 2026
f4964e7
Move binary search into solver insertion
fedgiac Aug 27, 2026
75e4520
Merge branch 'main' into federico/sc-299-add-functions-to-add-solver
fedgiac Aug 28, 2026
4d5996b
Merge branch 'federico/sc-299-add-functions-to-add-solver' into feder…
fedgiac Aug 28, 2026
ce0d9e6
Leaner test
fedgiac Aug 28, 2026
81a346f
Update comment
fedgiac Aug 28, 2026
8765450
Simplify signer check
fedgiac Aug 28, 2026
7490c12
Clearer comments for with_state_pda_signer*
fedgiac Aug 28, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 25 additions & 25 deletions bench-report.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,23 +33,23 @@
"create_buffers/max_buffers_in_one_instruction": 177040,
"create_order/happy_path_creates_order_pda_with_expected_body": 4978,
"initialize/happy_path_initializes_state_pda_with_expected_data": 4529,
"reclaim_buffer/funded_buffer_is_skipped": 6333,
"reclaim_buffer/happy_path_reclaims_empty_buffer_to_the_authority_itself": 7481,
"reclaim_buffer/max_buffers_in_one_instruction": 136650,
"reclaim_buffer/reclaims_multiple_buffers_skipping_funded": 18080,
"reclaim_buffer/funded_buffer_is_skipped": 6335,
"reclaim_buffer/happy_path_reclaims_empty_buffer_to_the_authority_itself": 7483,
"reclaim_buffer/max_buffers_in_one_instruction": 136652,
"reclaim_buffer/reclaims_multiple_buffers_skipping_funded": 18082,
"reclaim_order/happy_path_returns_lamports_and_closes_pda": 2183,
"settle/finalizes_with_no_pushes": 7070,
"settle/pulls_from_multiple_orders": 19949,
"settle/pulls_funds_to_destination": 13542,
"settle/pulls_to_multiple_destinations": 14694,
"settle/pushes_a_single_order": 12380,
"settle/pushes_several_orders_from_different_buffers": 17632,
"settle/pushes_several_orders_from_one_buffer": 17631,
"settle/settles_a_single_order": 12398,
"settle/settles_multiple_orders": 22926,
"transfer_authority/manager_can_transfer_manager": 3175,
"transfer_authority/manager_can_transfer_reclaim_authority": 3177,
"transfer_authority/reclaim_authority_can_transfer_itself": 3181
"settle/finalizes_with_no_pushes": 7152,
"settle/pulls_from_multiple_orders": 20041,
"settle/pulls_funds_to_destination": 13630,
"settle/pulls_to_multiple_destinations": 14771,
"settle/pushes_a_single_order": 12485,
"settle/pushes_several_orders_from_different_buffers": 17749,
"settle/pushes_several_orders_from_one_buffer": 17748,
"settle/settles_a_single_order": 12503,
"settle/settles_multiple_orders": 23060,
"transfer_authority/manager_can_transfer_manager": 3174,
"transfer_authority/manager_can_transfer_reclaim_authority": 3176,
"transfer_authority/reclaim_authority_can_transfer_itself": 3180
},
"transaction_bytes": {
"add_solver/add_with_many_existing_solvers": 366,
Expand All @@ -64,15 +64,15 @@
"reclaim_buffer/max_buffers_in_one_instruction": 332,
"reclaim_buffer/reclaims_multiple_buffers_skipping_funded": 466,
"reclaim_order/happy_path_returns_lamports_and_closes_pda": 236,
"settle/finalizes_with_no_pushes": 289,
"settle/pulls_from_multiple_orders": 655,
"settle/pulls_funds_to_destination": 472,
"settle/pulls_to_multiple_destinations": 513,
"settle/pushes_a_single_order": 431,
"settle/pushes_several_orders_from_different_buffers": 573,
"settle/pushes_several_orders_from_one_buffer": 541,
"settle/settles_a_single_order": 431,
"settle/settles_multiple_orders": 715,
"settle/finalizes_with_no_pushes": 290,
"settle/pulls_from_multiple_orders": 656,
"settle/pulls_funds_to_destination": 473,
"settle/pulls_to_multiple_destinations": 514,
"settle/pushes_a_single_order": 432,
"settle/pushes_several_orders_from_different_buffers": 574,
"settle/pushes_several_orders_from_one_buffer": 542,
"settle/settles_a_single_order": 432,
"settle/settles_multiple_orders": 716,
"transfer_authority/manager_can_transfer_manager": 333,
"transfer_authority/manager_can_transfer_reclaim_authority": 333,
"transfer_authority/reclaim_authority_can_transfer_itself": 333
Expand Down
8 changes: 6 additions & 2 deletions client/src/instructions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ pub struct InitializedIntent<'a> {
/// Builder for a `BeginSettle` instruction settling the given orders.
pub struct BeginSettle<'a> {
pub program_id: Pubkey,
pub solver: Pubkey,
pub finalize_ix_index: u16,
/// The off-chain auction this settlement executes, carried so it can be tied
/// back to its auction off-chain.
Expand All @@ -48,6 +49,7 @@ impl From<BeginSettle<'_>> for Instruction {
cow_settlement_interface::instruction::settle::BeginSettle {
program_id: builder.program_id,
state_pda,
solver: builder.solver,
finalize_ix_index: builder.finalize_ix_index,
auction_id: builder.auction_id,
order_pdas: &order_pdas,
Expand Down Expand Up @@ -275,6 +277,7 @@ mod tests {
use ::proptest::{prelude::*, test_runner::TestCaseError};
use cow_settlement_interface::{
data::intent::fixtures::arb_order_intent,
fixtures::pubkey_from_seed,
instruction::{
fixtures::fake_account_from_array,
settle::{
Expand All @@ -294,7 +297,7 @@ mod tests {
finalize_ix_index in any::<u16>(),
intents in prop::collection::vec(arb_order_intent(), 1..=5),
) {
let program_id = Pubkey::new_unique();
let program_id = pubkey_from_seed("program id");
// No pulls here: this test only checks that orders are derived and
// laid out correctly.
let orders: Vec<InitializedIntent> = intents
Expand All @@ -303,6 +306,7 @@ mod tests {
.collect();
let ix = Instruction::from(BeginSettle {
program_id,
solver: pubkey_from_seed("solver"),
finalize_ix_index,
auction_id: 0,
orders: &orders,
Expand Down Expand Up @@ -358,7 +362,7 @@ mod tests {
1..=5,
),
) {
let program_id = Pubkey::new_unique();
let program_id = pubkey_from_seed("program id");
let orders: Vec<FinalizedIntent> = cases
.iter()
.map(|(intent, amount)| FinalizedIntent {
Expand Down
1 change: 1 addition & 0 deletions client/src/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ mod tests {
.into(),
SettlementInstruction::BeginSettle => BeginSettle {
program_id,
solver: payer,
finalize_ix_index: 1,
auction_id: 42,
orders: &[InitializedIntent {
Expand Down
28 changes: 28 additions & 0 deletions interface/src/data/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,11 @@ impl<T: Deref<Target = [u8]>> StateAccount<T> {
self.solver_region().binary_search(&seek)
}

/// Whether `solver` is in the solver list.
pub fn is_solver(&self, solver: &Pubkey) -> bool {
self.solver_search(solver).is_ok()
}

/// The stored solvers, in order (sorted ascending by address).
pub fn solvers(&self) -> impl Iterator<Item = Pubkey> + '_ {
self.solver_region()
Expand Down Expand Up @@ -481,6 +486,29 @@ mod tests {
use super::*;

proptest! {
/// `is_solver` is true for every stored solver and false for one that
/// isn't stored.
#[test]
fn is_solver_reflects_membership(
header in fixtures::arb_init_params(),
// Unique and already sorted, being a `BTreeSet`.
raw_solvers in prop::collection::btree_set(any::<[u8; 32]>(), 0..50),
raw_absent in any::<[u8; 32]>(),
) {
prop_assume!(!raw_solvers.contains(&raw_absent));
let stored: Vec<Pubkey> =
raw_solvers.into_iter().map(Pubkey::new_from_array).collect();
let absent = Pubkey::new_from_array(raw_absent);

let bytes = fixtures::state_account_bytes(&header, &stored);
let state = StateAccount::attach(&bytes[..]).expect("valid header");

for solver in &stored {
prop_assert!(state.is_solver(solver));
}
prop_assert!(!state.is_solver(&absent));
}

/// The encode roundtrip: any two role holders written with
/// `initialize` read back unchanged.
#[test]
Expand Down
Loading