diff --git a/.github/workflows/ci-code-review-rust.yml b/.github/workflows/ci-code-review-rust.yml index 0c35840c..5d62c1b2 100644 --- a/.github/workflows/ci-code-review-rust.yml +++ b/.github/workflows/ci-code-review-rust.yml @@ -77,7 +77,7 @@ jobs: - name: Install Solana uses: metadaoproject/setup-solana@v1.0 with: - solana-cli-version: $SOLANA_VERSION + solana-cli-version: ${{ env.SOLANA_VERSION }} - name: Build OpenBook V2 run: cargo build-sbf --features enable-gpl @@ -103,7 +103,7 @@ jobs: - name: Install Solana uses: metadaoproject/setup-solana@v1.0 with: - solana-cli-version: $SOLANA_VERSION + solana-cli-version: ${{ env.SOLANA_VERSION }} - name: Create keypair run: solana-keygen new --no-bip39-passphrase diff --git a/Cargo.lock b/Cargo.lock index 644d45a0..694b6984 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -496,7 +496,7 @@ dependencies = [ "num-traits", "rusticata-macros", "thiserror", - "time 0.3.30", + "time 0.3.36", ] [[package]] @@ -2178,7 +2178,7 @@ dependencies = [ "serde_json", "simpl", "smpl_jwt", - "time 0.3.30", + "time 0.3.36", "tokio", ] @@ -3342,6 +3342,12 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + [[package]] name = "num-derive" version = "0.3.3" @@ -4424,7 +4430,7 @@ checksum = "ffbe84efe2f38dea12e9bfc1f65377fdf03e53a18cb3b995faedf7934c7e785b" dependencies = [ "pem", "ring 0.16.20", - "time 0.3.30", + "time 0.3.36", "yasna", ] @@ -5192,7 +5198,7 @@ dependencies = [ "serde_derive", "serde_json", "simpl", - "time 0.3.30", + "time 0.3.36", ] [[package]] @@ -7444,12 +7450,13 @@ dependencies = [ [[package]] name = "time" -version = "0.3.30" +version = "0.3.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4a34ab300f2dee6e562c10a046fc05e358b29f9bf92277f30c3c8d82275f6f5" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" dependencies = [ "deranged", "itoa", + "num-conv", "powerfmt", "serde", "time-core", @@ -7464,10 +7471,11 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.15" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ad70d68dba9e1f8aceda7aa6711965dfec1cac869f311a51bd08b3a2ccbce20" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" dependencies = [ + "num-conv", "time-core", ] @@ -8631,7 +8639,7 @@ dependencies = [ "oid-registry", "rusticata-macros", "thiserror", - "time 0.3.30", + "time 0.3.36", ] [[package]] @@ -8649,7 +8657,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e17bb3549cc1321ae1296b9cdc2698e2b6cb1992adfa19a8c72e5b7a738f44cd" dependencies = [ - "time 0.3.30", + "time 0.3.36", ] [[package]] diff --git a/lib/client/src/client.rs b/lib/client/src/client.rs index 0e7c45a8..ee95831e 100644 --- a/lib/client/src/client.rs +++ b/lib/client/src/client.rs @@ -566,8 +566,8 @@ impl OpenBookClient { open_orders_account: self.open_orders_account, signer: self.owner(), open_orders_admin: market.open_orders_admin.into(), - user_quote_account: user_quote_account, - user_base_account: user_base_account, + user_quote_account, + user_base_account, market: market_address, bids: market.bids, asks: market.asks, diff --git a/programs/openbook-v2/src/instructions/cancel_order.rs b/programs/openbook-v2/src/instructions/cancel_order.rs index 9d92924b..25d7e32c 100644 --- a/programs/openbook-v2/src/instructions/cancel_order.rs +++ b/programs/openbook-v2/src/instructions/cancel_order.rs @@ -14,7 +14,7 @@ pub fn cancel_order(ctx: Context, order_id: u128) -> Result<()> { error_msg_typed!(OpenBookError::OpenOrdersOrderNotFound, "id = {order_id}") })?; - let order_id = oo.id; + let order_id = oo.id.to_u128(); let order_side_and_tree = oo.side_and_tree(); let market = ctx.accounts.market.load()?; diff --git a/programs/openbook-v2/src/instructions/create_market.rs b/programs/openbook-v2/src/instructions/create_market.rs index b58ff07f..6b0c4396 100644 --- a/programs/openbook-v2/src/instructions/create_market.rs +++ b/programs/openbook-v2/src/instructions/create_market.rs @@ -86,10 +86,10 @@ pub fn create_market( registration_time, maker_fee, taker_fee, - fees_accrued: 0, - fees_to_referrers: 0, - maker_volume: 0, - taker_volume_wo_oo: 0, + fees_accrued: U128Bytes::from_u128(0), + fees_to_referrers: U128Bytes::from_u128(0), + maker_volume: U128Bytes::from_u128(0), + taker_volume_wo_oo: U128Bytes::from_u128(0), base_mint: ctx.accounts.base_mint.key(), quote_mint: ctx.accounts.quote_mint.key(), market_base_vault: ctx.accounts.market_base_vault.key(), diff --git a/programs/openbook-v2/src/instructions/settle_funds.rs b/programs/openbook-v2/src/instructions/settle_funds.rs index cc298473..3225544b 100644 --- a/programs/openbook-v2/src/instructions/settle_funds.rs +++ b/programs/openbook-v2/src/instructions/settle_funds.rs @@ -21,7 +21,9 @@ pub fn settle_funds<'info>(ctx: Context<'_, '_, '_, 'info, SettleFunds<'info>>) let referrer_rebate = pa.referrer_rebates_available + roundoff_maker_fees; if ctx.accounts.referrer_account.is_some() { - market.fees_to_referrers += referrer_rebate as u128; + market + .fees_to_referrers + .wrapping_add_assign(referrer_rebate as u128); market.quote_deposit_total -= referrer_rebate; } else { market.fees_available += referrer_rebate; diff --git a/programs/openbook-v2/src/state/market.rs b/programs/openbook-v2/src/state/market.rs index 03b6bc3b..ecb61423 100644 --- a/programs/openbook-v2/src/state/market.rs +++ b/programs/openbook-v2/src/state/market.rs @@ -9,6 +9,7 @@ use crate::pubkey_option::NonZeroPubkeyOption; use crate::state::oracle; use crate::{accounts_zerocopy::KeyedAccountReader, state::orderbook::Side}; +use super::orderbook::nodes::U128Bytes; use super::{orderbook, OracleConfig}; // For a 1bps taker fee, set taker_fee to 100, so taker_fee/FEES_SCALE_FACTOR = 10e-4 @@ -91,9 +92,9 @@ pub struct Market { pub taker_fee: i64, /// Total fees accrued in native quote - pub fees_accrued: u128, + pub fees_accrued: U128Bytes, /// Total fees settled in native quote - pub fees_to_referrers: u128, + pub fees_to_referrers: U128Bytes, /// Referrer rebates to be distributed pub referrer_rebates_accrued: u64, @@ -102,10 +103,10 @@ pub struct Market { pub fees_available: u64, /// Cumulative maker volume (same as taker volume) in quote native units - pub maker_volume: u128, + pub maker_volume: U128Bytes, /// Cumulative taker volume in quote native units due to place take orders - pub taker_volume_wo_oo: u128, + pub taker_volume_wo_oo: U128Bytes, pub base_mint: Pubkey, pub quote_mint: Pubkey, diff --git a/programs/openbook-v2/src/state/open_orders_account.rs b/programs/openbook-v2/src/state/open_orders_account.rs index 81ad493f..4f6fefbf 100644 --- a/programs/openbook-v2/src/state/open_orders_account.rs +++ b/programs/openbook-v2/src/state/open_orders_account.rs @@ -7,6 +7,7 @@ use crate::logs::{emit_stack, FillLog}; use crate::pubkey_option::NonZeroPubkeyOption; use crate::{error::*, logs::OpenOrdersPositionLog}; +use super::orderbook::nodes::U128Bytes; use super::{BookSideOrderTree, FillEvent, LeafNode, Market, Side, SideAndOrderTree}; pub const MAX_OPEN_ORDERS: usize = 24; @@ -120,7 +121,8 @@ impl OpenOrdersAccount { } pub fn find_order_with_order_id(&self, order_id: u128) -> Option<&OpenOrder> { - self.all_orders_in_use().find(|&oo| oo.id == order_id) + self.all_orders_in_use() + .find(|&oo| oo.id.to_u128() == order_id) } pub fn open_order_by_raw_index(&self, raw_index: usize) -> &OpenOrder { @@ -179,11 +181,13 @@ impl OpenOrdersAccount { } }; - pa.maker_volume += quote_native as u128; + pa.maker_volume.wrapping_add_assign(quote_native as u128); pa.referrer_rebates_available += maker_fees; market.referrer_rebates_accrued += maker_fees; - market.maker_volume += quote_native as u128; - market.fees_accrued += maker_fees as u128; + market + .maker_volume + .wrapping_add_assign(quote_native as u128); + market.fees_accrued.wrapping_add_assign(maker_fees as u128); if fill.maker_out() { self.remove_order(fill.maker_slot as usize, fill.quantity, locked_price); @@ -235,8 +239,8 @@ impl OpenOrdersAccount { quote_free_native: pa.quote_free_native, locked_maker_fees: pa.locked_maker_fees, referrer_rebates_available: pa.referrer_rebates_available, - maker_volume: pa.maker_volume, - taker_volume: pa.taker_volume, + maker_volume: pa.maker_volume.to_u128(), + taker_volume: pa.taker_volume.to_u128(), }) } @@ -256,7 +260,7 @@ impl OpenOrdersAccount { Side::Ask => pa.quote_free_native += quote_native - taker_fees, }; - pa.taker_volume += quote_native as u128; + pa.taker_volume.wrapping_add_assign(quote_native as u128); pa.referrer_rebates_available += referrer_amount; market.referrer_rebates_accrued += referrer_amount; @@ -271,8 +275,8 @@ impl OpenOrdersAccount { quote_free_native: pa.quote_free_native, locked_maker_fees: pa.locked_maker_fees, referrer_rebates_available: pa.referrer_rebates_available, - maker_volume: pa.maker_volume, - taker_volume: pa.taker_volume, + maker_volume: pa.maker_volume.to_u128(), + taker_volume: pa.taker_volume.to_u128(), }) } @@ -363,9 +367,9 @@ pub struct Position { pub penalty_heap_count: u64, /// Cumulative maker volume in quote native units (display only) - pub maker_volume: u128, + pub maker_volume: U128Bytes, /// Cumulative taker volume in quote native units (display only) - pub taker_volume: u128, + pub taker_volume: U128Bytes, /// Quote lots in open bids pub bids_quote_lots: i64, @@ -391,8 +395,8 @@ impl Default for Position { locked_maker_fees: 0, referrer_rebates_available: 0, penalty_heap_count: 0, - maker_volume: 0, - taker_volume: 0, + maker_volume: U128Bytes::from_u128(0), + taker_volume: U128Bytes::from_u128(0), bids_quote_lots: 0, reserved: [0; 64], } @@ -424,7 +428,7 @@ impl Position { #[zero_copy] #[derive(Debug)] pub struct OpenOrder { - pub id: u128, + pub id: U128Bytes, pub client_id: u64, /// Price at which user's assets were locked pub locked_price: i64, @@ -444,7 +448,7 @@ impl Default for OpenOrder { side_and_tree: SideAndOrderTree::BidFixed.into(), client_id: 0, locked_price: 0, - id: 0, + id: U128Bytes::from_u128(0), padding: [0; 6], } } diff --git a/programs/openbook-v2/src/state/orderbook/book.rs b/programs/openbook-v2/src/state/orderbook/book.rs index 1c65b2fc..cbce67dd 100644 --- a/programs/openbook-v2/src/state/orderbook/book.rs +++ b/programs/openbook-v2/src/state/orderbook/book.rs @@ -149,7 +149,7 @@ impl<'a> Orderbook<'a> { remaining_accs, )?; matched_order_deletes - .push((best_opposing.handle.order_tree, best_opposing.node.key)); + .push((best_opposing.handle.order_tree, best_opposing.node.key())); } continue; } @@ -197,7 +197,7 @@ impl<'a> Orderbook<'a> { *market, ); matched_order_deletes - .push((best_opposing.handle.order_tree, best_opposing.node.key)); + .push((best_opposing.handle.order_tree, best_opposing.node.key())); // skip actual matching continue; @@ -220,7 +220,7 @@ impl<'a> Orderbook<'a> { let maker_out = new_best_opposing_quantity == 0; if maker_out { matched_order_deletes - .push((best_opposing.handle.order_tree, best_opposing.node.key)); + .push((best_opposing.handle.order_tree, best_opposing.node.key())); } else { matched_order_changes.push((best_opposing.handle, new_best_opposing_quantity)); } @@ -277,7 +277,9 @@ impl<'a> Orderbook<'a> { // Only account taker fees now. Maker fees accounted once processing the event referrer_amount = taker_fees_native - maker_rebates_acc; - market.fees_accrued += referrer_amount as u128; + market + .fees_accrued + .wrapping_add_assign(referrer_amount as u128); }; if let Some(open_orders_account) = &mut open_orders_account { @@ -290,7 +292,9 @@ impl<'a> Orderbook<'a> { referrer_amount, ); } else { - market.taker_volume_wo_oo += total_quote_taken_native as u128; + market + .taker_volume_wo_oo + .wrapping_add_assign(total_quote_taken_native as u128); } let (total_quantity_paid, total_quantity_received) = match side { @@ -526,7 +530,7 @@ impl<'a> Orderbook<'a> { break; } - let order_id = oo.id; + let order_id = oo.id.to_u128(); let cancel_result = self.cancel_order( open_orders_account, diff --git a/programs/openbook-v2/src/state/orderbook/bookside.rs b/programs/openbook-v2/src/state/orderbook/bookside.rs index 41fca4f0..21cc6878 100644 --- a/programs/openbook-v2/src/state/orderbook/bookside.rs +++ b/programs/openbook-v2/src/state/orderbook/bookside.rs @@ -116,7 +116,7 @@ impl BookSide { oracle_price_lots, )?; let price = worse.price_lots; - let key = worse.node.key; + let key = worse.node.key(); let order_tree = worse.handle.order_tree; let n = self.remove_by_key(order_tree, key)?; Some((n, price)) @@ -271,7 +271,7 @@ mod tests { let mut last_price = if ascending { 0 } else { i64::MAX }; for order in bookside.iter_all_including_invalid(0, Some(oracle_price_lots)) { let price = order.price_lots; - println!("{} {:?} {price}", order.node.key, order.handle.order_tree); + println!("{} {:?} {price}", order.node.key(), order.handle.order_tree); if ascending { assert!(price >= last_price); } else { diff --git a/programs/openbook-v2/src/state/orderbook/bookside_iterator.rs b/programs/openbook-v2/src/state/orderbook/bookside_iterator.rs index 587b60c2..67f7c949 100644 --- a/programs/openbook-v2/src/state/orderbook/bookside_iterator.rs +++ b/programs/openbook-v2/src/state/orderbook/bookside_iterator.rs @@ -152,7 +152,7 @@ pub fn rank_orders<'a>( |a, b| a < b }; - if is_better(f.1.key, key_for_fixed_price(o.1.key, o.2)) ^ return_worse { + if is_better(f.1.key(), key_for_fixed_price(o.1.key(), o.2)) ^ return_worse { Some(fixed_to_result(f, now_ts)) } else { Some(oracle_pegged_to_result(o, now_ts)) diff --git a/programs/openbook-v2/src/state/orderbook/mod.rs b/programs/openbook-v2/src/state/orderbook/mod.rs index db1a5e6b..dd5d11bc 100644 --- a/programs/openbook-v2/src/state/orderbook/mod.rs +++ b/programs/openbook-v2/src/state/orderbook/mod.rs @@ -12,7 +12,7 @@ mod book; mod bookside; mod bookside_iterator; mod heap; -mod nodes; +pub mod nodes; mod order; mod order_type; mod ordertree; @@ -30,7 +30,7 @@ mod tests { fn order_tree_leaf_by_key(bookside: &BookSide, key: u128) -> Option<&LeafNode> { for component in [BookSideOrderTree::Fixed, BookSideOrderTree::OraclePegged] { for (_, leaf) in bookside.nodes.iter(bookside.root(component)) { - if leaf.key == key { + if leaf.key() == key { return Some(leaf); } } @@ -132,7 +132,7 @@ mod tests { &[], ) .unwrap(); - account.open_order_by_raw_index(0).id + account.open_order_by_raw_index(0).id.to_u128() }; // insert bids until book side is full @@ -276,11 +276,12 @@ mod tests { ) .unwrap(); let order = - order_tree_leaf_by_key(&book.bids, maker.open_order_by_raw_index(0).id).unwrap(); + order_tree_leaf_by_key(&book.bids, maker.open_order_by_raw_index(0).id.to_u128()) + .unwrap(); assert_eq!(order.client_order_id, 42); assert_eq!(order.quantity, bid_quantity); assert!(maker.open_order_by_raw_index(1).is_free()); - assert_ne!(maker.open_order_by_raw_index(0).id, 0); + assert_ne!(maker.open_order_by_raw_index(0).id.to_u128(), 0); assert_eq!(maker.open_order_by_raw_index(0).client_id, 42); assert_eq!( maker.open_order_by_raw_index(0).side_and_tree(), @@ -288,7 +289,7 @@ mod tests { ); assert!(order_tree_contains_key( &book.bids, - maker.open_order_by_raw_index(0).id + maker.open_order_by_raw_index(0).id.to_u128() )); assert!(order_tree_contains_price(&book.bids, price_lots as u64)); assert_eq!(maker.position.bids_base_lots, bid_quantity); @@ -325,14 +326,15 @@ mod tests { // the remainder of the maker order is still on the book // (the maker account is unchanged: it was not even passed in) let order = - order_tree_leaf_by_key(&book.bids, maker.open_order_by_raw_index(0).id).unwrap(); + order_tree_leaf_by_key(&book.bids, maker.open_order_by_raw_index(0).id.to_u128()) + .unwrap(); assert_eq!(fixed_price_lots(order.price_data()), price_lots); assert_eq!(order.quantity, bid_quantity - match_quantity); // fees were immediately accrued let match_quote = match_quantity * price_lots * market.quote_lot_size; assert_eq!( - market.fees_accrued as i64, + market.fees_accrued.to_u128() as i64, match_quote * (taker_fee) / (FEES_SCALE_FACTOR as i64) ); @@ -364,7 +366,7 @@ mod tests { assert_eq!(taker.position.asks_base_lots, 0); // Maker fee is accrued now assert_eq!( - market.fees_accrued as i64, + market.fees_accrued.to_u128() as i64, match_quote * (maker_fee + taker_fee) / (FEES_SCALE_FACTOR as i64) ); } @@ -411,7 +413,7 @@ mod tests { &[], ) .unwrap(); - account.open_order_by_raw_index(0).id + account.open_order_by_raw_index(0).id.to_u128() }; // Setup diff --git a/programs/openbook-v2/src/state/orderbook/nodes.rs b/programs/openbook-v2/src/state/orderbook/nodes.rs index ec8862ad..926ddfa8 100644 --- a/programs/openbook-v2/src/state/orderbook/nodes.rs +++ b/programs/openbook-v2/src/state/orderbook/nodes.rs @@ -10,6 +10,68 @@ use super::order_type::Side; pub type NodeHandle = u32; const NODE_SIZE: usize = 88; +/// Layout-stable 128-bit key representation. +/// +/// Replaces raw `u128` in persisted node structs to guarantee 8-byte alignment +/// and 16-byte size on all targets and Rust versions. Native `u128` alignment +/// varies by platform (8 on old x86, 16 on aarch64 and modern x86), which +/// would inflate node size beyond the required 88 bytes. +#[derive( + Copy, + Clone, + Debug, + Default, + PartialEq, + Eq, + bytemuck::Pod, + bytemuck::Zeroable, + AnchorSerialize, + AnchorDeserialize, +)] +#[repr(C)] +pub struct U128Bytes { + data: [u8; 16], +} +const_assert_eq!(size_of::(), 16); +const_assert_eq!(align_of::(), 1); + +impl U128Bytes { + #[inline(always)] + pub fn from_u128(v: u128) -> Self { + Self { + data: v.to_le_bytes(), + } + } + + #[inline(always)] + pub fn to_u128(self) -> u128 { + u128::from_le_bytes(self.data) + } + + #[inline(always)] + pub fn wrapping_add_assign(&mut self, rhs: u128) { + *self = Self::from_u128(self.to_u128().wrapping_add(rhs)); + } +} + +impl From for U128Bytes { + fn from(v: u128) -> Self { + Self::from_u128(v) + } +} + +impl PartialEq for U128Bytes { + fn eq(&self, other: &u128) -> bool { + self.to_u128() == *other + } +} + +impl std::fmt::Display for U128Bytes { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.to_u128()) + } +} + #[derive(IntoPrimitive, TryFromPrimitive)] #[repr(u8)] pub enum NodeTag { @@ -85,7 +147,7 @@ pub struct InnerNode { pub prefix_len: u32, /// only the top `prefix_len` bits of `key` are relevant - pub key: u128, + pub key: U128Bytes, /// indexes into `BookSide::nodes` pub children: [NodeHandle; 2], @@ -108,13 +170,19 @@ impl InnerNode { tag: NodeTag::InnerNode.into(), padding: Default::default(), prefix_len, - key, + key: U128Bytes::from_u128(key), children: [0; 2], child_earliest_expiry: [u64::MAX; 2], reserved: [0; NODE_SIZE - 48], } } + /// Returns the logical u128 key + #[inline(always)] + pub fn key(&self) -> u128 { + self.key.to_u128() + } + /// Returns the handle of the child that may contain the search key /// and 0 or 1 depending on which child it was. pub(crate) fn walk_down(&self, search_key: u128) -> (NodeHandle, bool) { @@ -157,7 +225,7 @@ pub struct LeafNode { pub padding: [u8; 4], /// The binary tree key, see new_node_key() - pub key: u128, + pub key: U128Bytes, /// Address of the owning OpenOrdersAccount pub owner: Pubkey, @@ -201,7 +269,7 @@ impl LeafNode { owner_slot, time_in_force, padding: Default::default(), - key, + key: U128Bytes::from_u128(key), owner, quantity, timestamp, @@ -210,12 +278,18 @@ impl LeafNode { } } + /// Returns the logical u128 key + #[inline(always)] + pub fn key(&self) -> u128 { + self.key.to_u128() + } + /// The order's price_data as stored in the key /// /// Needs to be unpacked differently for fixed and oracle pegged orders. #[inline(always)] pub fn price_data(&self) -> u64 { - (self.key >> 64) as u64 + (self.key() >> 64) as u64 } /// Time at which this order will expire, u64::MAX if never @@ -278,8 +352,8 @@ pub(crate) enum NodeRefMut<'a> { impl AnyNode { pub fn key(&self) -> Option { match self.case()? { - NodeRef::Inner(inner) => Some(inner.key), - NodeRef::Leaf(leaf) => Some(leaf.key), + NodeRef::Inner(inner) => Some(inner.key()), + NodeRef::Leaf(leaf) => Some(leaf.key()), } } diff --git a/programs/openbook-v2/src/state/orderbook/ordertree.rs b/programs/openbook-v2/src/state/orderbook/ordertree.rs index c2df482e..c4d7a6ef 100644 --- a/programs/openbook-v2/src/state/orderbook/ordertree.rs +++ b/programs/openbook-v2/src/state/orderbook/ordertree.rs @@ -104,7 +104,7 @@ impl OrderTreeNodes { } pub fn remove_worst(&mut self, root: &mut OrderTreeRoot) -> Option { - self.remove_by_key(root, self.find_worst(root)?.1.key) + self.remove_by_key(root, self.find_worst(root)?.1.key()) } pub fn find_worst(&self, root: &OrderTreeRoot) -> Option<(NodeHandle, &LeafNode)> { @@ -202,7 +202,7 @@ impl OrderTreeNodes { // special case potentially removing the root let mut parent_h = root.node()?; let (mut child_h, mut crit_bit) = match self.node(parent_h).unwrap().case().unwrap() { - NodeRef::Leaf(&leaf) if leaf.key == search_key => { + NodeRef::Leaf(&leaf) if leaf.key() == search_key => { assert_eq!(root.leaf_count, 1); root.maybe_node = 0; root.leaf_count = 0; @@ -225,7 +225,7 @@ impl OrderTreeNodes { stack.push((parent_h, crit_bit)); } NodeRef::Leaf(leaf) => { - if leaf.key != search_key { + if leaf.key() != search_key { return None; } break; @@ -330,7 +330,7 @@ impl OrderTreeNodes { // require if the new node will be a child of the root let parent_contents = *self.node(parent_handle).unwrap(); let parent_key = parent_contents.key().unwrap(); - if parent_key == new_leaf.key { + if parent_key == new_leaf.key() { // This should never happen because key should never match if let Some(NodeRef::Leaf(&old_parent_as_leaf)) = parent_contents.case() { // clobber the existing leaf @@ -344,13 +344,13 @@ impl OrderTreeNodes { } // InnerNodes have a random child's key, so matching can happen and is fine } - let shared_prefix_len: u32 = (parent_key ^ new_leaf.key).leading_zeros(); + let shared_prefix_len: u32 = (parent_key ^ new_leaf.key()).leading_zeros(); match parent_contents.case() { None => unreachable!(), Some(NodeRef::Inner(inner)) => { let keep_old_parent = shared_prefix_len >= inner.prefix_len; if keep_old_parent { - let (child, crit_bit) = inner.walk_down(new_leaf.key); + let (child, crit_bit) = inner.walk_down(new_leaf.key()); stack.push((parent_handle, crit_bit)); parent_handle = child; continue; @@ -363,7 +363,7 @@ impl OrderTreeNodes { // change the parent in place to represent the LCA of [new_leaf] and [parent] let crit_bit_mask: u128 = 1u128 << (127 - shared_prefix_len); - let new_leaf_crit_bit = (crit_bit_mask & new_leaf.key) != 0; + let new_leaf_crit_bit = (crit_bit_mask & new_leaf.key()) != 0; let old_parent_crit_bit = !new_leaf_crit_bit; let new_leaf_handle = self.insert(new_leaf.as_ref())?; @@ -376,7 +376,7 @@ impl OrderTreeNodes { }; let new_parent: &mut InnerNode = cast_mut(self.node_mut(parent_handle).unwrap()); - *new_parent = InnerNode::new(shared_prefix_len, new_leaf.key); + *new_parent = InnerNode::new(shared_prefix_len, new_leaf.key()); new_parent.children[new_leaf_crit_bit as usize] = new_leaf_handle; new_parent.children[old_parent_crit_bit as usize] = moved_parent_handle; @@ -473,8 +473,8 @@ mod tests { let right = order_tree.node(inner.children[1]).unwrap().key().unwrap(); // the left and right keys share the InnerNode's prefix - assert!((inner.key ^ left).leading_zeros() >= inner.prefix_len); - assert!((inner.key ^ right).leading_zeros() >= inner.prefix_len); + assert!((inner.key() ^ left).leading_zeros() >= inner.prefix_len); + assert!((inner.key() ^ right).leading_zeros() >= inner.prefix_len); // the left and right node key have the critbit unset and set respectively let crit_bit_mask: u128 = 1u128 << (127 - inner.prefix_len); @@ -497,7 +497,7 @@ mod tests { let ascending = order_tree.order_tree_type() == OrderTreeType::Asks; let mut last_key = if ascending { 0 } else { u128::MAX }; for (_, node) in order_tree.iter(root) { - let key = node.key; + let key = node.key(); if ascending { assert!(key >= last_key); } else { diff --git a/programs/openbook-v2/tests/cases/test.rs b/programs/openbook-v2/tests/cases/test.rs index afb4c685..bb8943c3 100644 --- a/programs/openbook-v2/tests/cases/test.rs +++ b/programs/openbook-v2/tests/cases/test.rs @@ -572,7 +572,7 @@ async fn test_cancel_orders() -> Result<(), TransportError> { signer: owner, market, open_orders_account: account_1, - order_id: order_id_to_cancel, + order_id: order_id_to_cancel.to_u128(), }, ) .await @@ -632,7 +632,7 @@ async fn test_cancel_orders() -> Result<(), TransportError> { signer: owner, market, open_orders_account: account_1, - order_id: order_id_to_cancel, + order_id: order_id_to_cancel.to_u128(), }, ) .await diff --git a/programs/openbook-v2/tests/cases/test_oracle_peg.rs b/programs/openbook-v2/tests/cases/test_oracle_peg.rs index 18e034ed..ecc05c63 100644 --- a/programs/openbook-v2/tests/cases/test_oracle_peg.rs +++ b/programs/openbook-v2/tests/cases/test_oracle_peg.rs @@ -157,7 +157,7 @@ async fn test_oracle_peg() -> Result<(), TransportError> { signer: owner, market, open_orders_account: account_1, - order_id: order.id, + order_id: order.id.to_u128(), }, ) .await