Skip to content

Commit b461f9d

Browse files
authored
Merge pull request #185 from quicknode/claude/peaceful-tesla-k0gp10
Order book: test the costliest cancel on a full side
2 parents b0f8bf2 + 36a6d4e commit b461f9d

7 files changed

Lines changed: 96 additions & 2 deletions

File tree

‎CHANGELOG.md‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,16 @@ All notable changes to this repository are documented here.
44

55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
66

7+
## [2026-10-03] - Order book tests cover the costliest cancel
8+
9+
`cancel_order` finds an order's place in the tree by walking its side from the
10+
best price down, so its cost grows with the number of resting orders. Both
11+
Anchor copies gain `full_side_cancel_of_the_last_scanned_order_fits_the_default_budget`,
12+
which fills the bid side to its 512 orders, cancels the bid the walk reaches
13+
last, and checks it stays inside the default 200,000-unit instruction budget.
14+
It measures 50,078 compute units in the Anchor v2 copy and 57,383 in the v1
15+
copy. No program behavior changes.
16+
717
## [2026-10-02] - Token Swap (Quasar): reserves live at PDAs of the pool
818

919
### Changed

‎finance/order-book/anchor-v1/CHANGELOG.md‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
# Changelog
22

3+
## 2026-10-03
4+
5+
### Added
6+
7+
- `full_side_cancel_of_the_last_scanned_order_fits_the_default_budget`:
8+
`cancel_order` finds an order by walking its side from the best price, so
9+
on a full side of 512 bids the worst bid is the last one it reads. Canceling
10+
it stays inside the default 200,000-unit instruction budget.
11+
312
## 2026-09-23
413

514
### Added

‎finance/order-book/anchor-v1/README.md‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1473,15 +1473,20 @@ anchor test --skip-local-validator
14731473
Expected:
14741474

14751475
```
1476-
running 29 tests
1476+
running 35 tests
14771477
test authority_can_withdraw_fees_after_match ... ok
1478+
test better_order_evicts_the_worst_and_rests ... ok
14781479
test cancel_and_settle_bid_refunds_full_quote ... ok
14791480
test cancel_ask_credits_unsettled_base ... ok
14801481
test cancel_order_rejects_non_owner ... ok
14811482
test deepest_path_adds_little_compute_to_insert_fill_and_cancel ... ok
14821483
test doubling_prices_build_the_deepest_path_prices_allow ... ok
1484+
test evicted_maker_settles_their_refund ... ok
1485+
test eviction_rejects_missing_or_wrong_evicted_accounts ... ok
14831486
test fee_rounds_up_when_gross_is_not_a_bps_multiple ... ok
14841487
test fee_vault_receives_exactly_bps_of_taker_gross ... ok
1488+
test full_side_cancel_of_the_last_scanned_order_fits_the_default_budget ... ok
1489+
test full_side_refuses_an_order_no_better_than_its_worst ... ok
14851490
test initialize_market_rejects_oversized_fee ... ok
14861491
test initialize_market_rejects_zero_base_lot_size ... ok
14871492
test initialize_market_rejects_zero_quote_lot_size ... ok
@@ -1503,6 +1508,7 @@ test taker_bid_gets_price_improvement_from_resting_ask ... ok
15031508
test taker_crosses_multiple_resting_orders_best_price_first ... ok
15041509
test taker_partially_filled_remainder_rests_on_book ... ok
15051510
test taker_partially_fills_resting_order_rest_stays_on_book ... ok
1511+
test trader_can_evict_their_own_worst_order ... ok
15061512
```
15071513

15081514
### What each test exercises
@@ -1554,6 +1560,7 @@ test taker_partially_fills_resting_order_rest_stays_on_book ... ok
15541560
- `evicted_maker_settles_their_refund`: The evicted owner's `settle_funds` pays out the refund
15551561
- `eviction_rejects_missing_or_wrong_evicted_accounts`: No evicted order, a non-worst order, or the wrong owner's `MarketUser`
15561562
- `trader_can_evict_their_own_worst_order`: Only the `Order` account is passed, and the caller's own `MarketUser` is credited
1563+
- `full_side_cancel_of_the_last_scanned_order_fits_the_default_budget`: Canceling the bid found last among 512 stays inside the default 200,000-unit budget
15571564

15581565
### CI note
15591566

‎finance/order-book/anchor-v1/programs/order-book/tests/test_order_book.rs‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2775,3 +2775,29 @@ fn trader_can_evict_their_own_worst_order() {
27752775
ORDERS_PER_FILLER as u32
27762776
);
27772777
}
2778+
2779+
#[test]
2780+
fn full_side_cancel_of_the_last_scanned_order_fits_the_default_budget() {
2781+
// `cancel_order` finds the order's tree key by walking the side from the
2782+
// best price down, so on a full bid side the worst bid is the last of
2783+
// 512 leaves it reads. That is the most compute a cancel can cost.
2784+
let mut sc = full_setup();
2785+
initialize_market_and_users(&mut sc);
2786+
let fillers = fill_bid_side(&mut sc);
2787+
2788+
let instruction = build_cancel_order_ix(
2789+
&sc,
2790+
&fillers[0].keypair.pubkey(),
2791+
fillers[0].market_user,
2792+
WORST_BID_ORDER_ID,
2793+
);
2794+
let units = send_and_measure(&mut sc.svm, instruction, &fillers[0].keypair);
2795+
println!("cancel of the last of {ORDERS_PER_SIDE} bids scanned: {units} CU");
2796+
assert!(units < DEFAULT_INSTRUCTION_COMPUTE_UNITS, "{units} CU");
2797+
2798+
let (_, status) = read_order_fill_and_status(
2799+
&sc.svm,
2800+
&order_pda(&sc.program_id, &sc.market, WORST_BID_ORDER_ID),
2801+
);
2802+
assert_eq!(status, ORDER_STATUS_CANCELLED);
2803+
}

‎finance/order-book/anchor/CHANGELOG.md‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
# Changelog
22

3+
## 2026-10-03
4+
5+
### Added
6+
7+
- `full_side_cancel_of_the_last_scanned_order_fits_the_default_budget`:
8+
`cancel_order` finds an order by walking its side from the best price, so
9+
on a full side of 512 bids the worst bid is the last one it reads. Canceling
10+
it stays inside the default 200,000-unit instruction budget.
11+
312
## 2026-09-23
413

514
### Added

‎finance/order-book/anchor/README.md‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1481,15 +1481,20 @@ anchor test --skip-local-validator
14811481
Expected:
14821482

14831483
```
1484-
running 29 tests
1484+
running 35 tests
14851485
test authority_can_withdraw_fees_after_match ... ok
1486+
test better_order_evicts_the_worst_and_rests ... ok
14861487
test cancel_and_settle_bid_refunds_full_quote ... ok
14871488
test cancel_ask_credits_unsettled_base ... ok
14881489
test cancel_order_rejects_non_owner ... ok
14891490
test deepest_path_adds_little_compute_to_insert_fill_and_cancel ... ok
14901491
test doubling_prices_build_the_deepest_path_prices_allow ... ok
1492+
test evicted_maker_settles_their_refund ... ok
1493+
test eviction_rejects_missing_or_wrong_evicted_accounts ... ok
14911494
test fee_rounds_up_when_gross_is_not_a_bps_multiple ... ok
14921495
test fee_vault_receives_exactly_bps_of_taker_gross ... ok
1496+
test full_side_cancel_of_the_last_scanned_order_fits_the_default_budget ... ok
1497+
test full_side_refuses_an_order_no_better_than_its_worst ... ok
14931498
test initialize_market_rejects_oversized_fee ... ok
14941499
test initialize_market_rejects_zero_base_lot_size ... ok
14951500
test initialize_market_rejects_zero_quote_lot_size ... ok
@@ -1511,6 +1516,7 @@ test taker_bid_gets_price_improvement_from_resting_ask ... ok
15111516
test taker_crosses_multiple_resting_orders_best_price_first ... ok
15121517
test taker_partially_filled_remainder_rests_on_book ... ok
15131518
test taker_partially_fills_resting_order_rest_stays_on_book ... ok
1519+
test trader_can_evict_their_own_worst_order ... ok
15141520
```
15151521

15161522
### What each test exercises
@@ -1562,6 +1568,7 @@ test taker_partially_fills_resting_order_rest_stays_on_book ... ok
15621568
- `evicted_maker_settles_their_refund`: The evicted owner's `settle_funds` pays out the refund
15631569
- `eviction_rejects_missing_or_wrong_evicted_accounts`: No evicted order, a non-worst order, or the wrong owner's `MarketUser`
15641570
- `trader_can_evict_their_own_worst_order`: Only the `Order` account is passed, and the caller's own `MarketUser` is credited
1571+
- `full_side_cancel_of_the_last_scanned_order_fits_the_default_budget`: Canceling the bid found last among 512 stays inside the default 200,000-unit budget
15651572

15661573
### CI note
15671574

‎finance/order-book/anchor/programs/order-book/tests/test_order_book.rs‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2783,3 +2783,29 @@ fn trader_can_evict_their_own_worst_order() {
27832783
ORDERS_PER_FILLER as u32
27842784
);
27852785
}
2786+
2787+
#[test]
2788+
fn full_side_cancel_of_the_last_scanned_order_fits_the_default_budget() {
2789+
// `cancel_order` finds the order's tree key by walking the side from the
2790+
// best price down, so on a full bid side the worst bid is the last of
2791+
// 512 leaves it reads. That is the most compute a cancel can cost.
2792+
let mut sc = full_setup();
2793+
initialize_market_and_users(&mut sc);
2794+
let fillers = fill_bid_side(&mut sc);
2795+
2796+
let instruction = build_cancel_order_ix(
2797+
&sc,
2798+
&fillers[0].keypair.pubkey(),
2799+
fillers[0].market_user,
2800+
WORST_BID_ORDER_ID,
2801+
);
2802+
let units = send_and_measure(&mut sc.svm, instruction, &fillers[0].keypair);
2803+
println!("cancel of the last of {ORDERS_PER_SIDE} bids scanned: {units} CU");
2804+
assert!(units < DEFAULT_INSTRUCTION_COMPUTE_UNITS, "{units} CU");
2805+
2806+
let (_, status) = read_order_fill_and_status(
2807+
&sc.svm,
2808+
&order_pda(&sc.program_id, &sc.market, WORST_BID_ORDER_ID),
2809+
);
2810+
assert_eq!(status, ORDER_STATUS_CANCELLED);
2811+
}

0 commit comments

Comments
 (0)