From 09fc5f716b0484d953d1e0683546ef66bed04269 Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Thu, 18 Aug 2022 13:45:31 +0200 Subject: [PATCH] Renames in MangoAccount - Accessors in MangoAccountValue - PerpPositions -> PerpPosition --- client/src/client.rs | 20 +- client/src/context.rs | 13 +- keeper/src/taker.rs | 4 +- liquidator/src/liquidate.rs | 10 +- liquidator/src/rebalance.rs | 6 +- liquidator/src/snapshot_source.rs | 2 +- .../src/instructions/account_close.rs | 6 +- .../mango-v4/src/instructions/flash_loan.rs | 6 +- .../src/instructions/liq_token_bankruptcy.rs | 12 +- .../src/instructions/liq_token_with_token.rs | 22 +- .../src/instructions/perp_cancel_order.rs | 2 +- .../perp_cancel_order_by_client_order_id.rs | 2 +- .../src/instructions/perp_consume_events.rs | 20 +- .../instructions/serum3_cancel_all_orders.rs | 2 +- .../src/instructions/serum3_cancel_order.rs | 4 +- .../instructions/serum3_close_open_orders.rs | 4 +- .../instructions/serum3_create_open_orders.rs | 6 +- .../serum3_liq_force_cancel_orders.rs | 2 +- .../src/instructions/serum3_place_order.rs | 12 +- .../src/instructions/serum3_settle_funds.rs | 10 +- .../src/instructions/token_deposit.rs | 4 +- .../src/instructions/token_withdraw.rs | 4 +- programs/mango-v4/src/logs.rs | 4 +- programs/mango-v4/src/state/equity.rs | 4 +- programs/mango-v4/src/state/health.rs | 34 +-- programs/mango-v4/src/state/mango_account.rs | 200 +++++++++--------- .../src/state/mango_account_components.rs | 20 +- programs/mango-v4/src/state/orderbook/book.rs | 10 +- programs/mango-v4/src/state/orderbook/mod.rs | 94 ++++---- .../tests/program_test/mango_client.rs | 38 ++-- programs/mango-v4/tests/test_liq_tokens.rs | 2 +- programs/mango-v4/tests/test_margin_trade.rs | 2 +- .../mango-v4/tests/test_position_lifetime.rs | 4 +- programs/mango-v4/tests/test_serum.rs | 2 +- ts/client/src/accounts/mangoAccount.ts | 12 +- ts/client/src/mango_v4.ts | 8 +- 36 files changed, 310 insertions(+), 297 deletions(-) diff --git a/client/src/client.rs b/client/src/client.rs index d1c9a6d65..c7815874a 100644 --- a/client/src/client.rs +++ b/client/src/client.rs @@ -321,8 +321,8 @@ impl MangoClient { let account = self.mango_account()?; let token_indexes = liqee - .token_iter_active() - .chain(account.token_iter_active()) + .active_token_positions() + .chain(account.active_token_positions()) .map(|ta| ta.token_index) .unique(); @@ -334,12 +334,12 @@ impl MangoClient { } let serum_oos = liqee - .serum3_iter_active() - .chain(account.serum3_iter_active()) + .active_serum3_orders() + .chain(account.active_serum3_orders()) .map(|&s| s.open_orders); let perp_markets = liqee - .perp_iter_active_accounts() - .chain(account.perp_iter_active_accounts()) + .active_perp_positions() + .chain(account.active_perp_positions()) .map(|&pa| self.context.perp_market_address(pa.market_index)); Ok(banks @@ -543,7 +543,7 @@ impl MangoClient { let s3 = self.serum3_data(name)?; let account = self.mango_account()?; - let open_orders = account.serum3_find(s3.market_index).unwrap().open_orders; + let open_orders = account.serum3_orders(s3.market_index).unwrap().open_orders; let health_check_metas = self.derive_health_check_remaining_account_metas(vec![], false)?; @@ -658,7 +658,7 @@ impl MangoClient { let s3 = self.serum3_data(name)?; let account = self.mango_account()?; - let open_orders = account.serum3_find(s3.market_index).unwrap().open_orders; + let open_orders = account.serum3_orders(s3.market_index).unwrap().open_orders; self.program() .request() @@ -700,7 +700,7 @@ impl MangoClient { .get(market_name) .unwrap(); let account = self.mango_account()?; - let open_orders = account.serum3_find(market_index).unwrap().open_orders; + let open_orders = account.serum3_orders(market_index).unwrap().open_orders; let open_orders_bytes = self.account_fetcher.fetch_raw_account(open_orders)?.data; let open_orders_data: &serum_dex::state::OpenOrders = bytemuck::from_bytes( @@ -732,7 +732,7 @@ impl MangoClient { let s3 = self.serum3_data(market_name)?; let account = self.mango_account()?; - let open_orders = account.serum3_find(s3.market_index).unwrap().open_orders; + let open_orders = account.serum3_orders(s3.market_index).unwrap().open_orders; self.program() .request() diff --git a/client/src/context.rs b/client/src/context.rs index 70cd1e657..73e35ec13 100644 --- a/client/src/context.rs +++ b/client/src/context.rs @@ -211,29 +211,32 @@ impl MangoGroupContext { // figure out all the banks/oracles that need to be passed for the health check let mut banks = vec![]; let mut oracles = vec![]; - for position in account.token_iter_active() { + for position in account.active_token_positions() { let mint_info = self.mint_info(position.token_index); banks.push(mint_info.first_bank()); oracles.push(mint_info.oracle); } for affected_token_index in affected_tokens { if account - .token_iter_active() + .active_token_positions() .find(|p| p.token_index == affected_token_index) .is_none() { // If there is not yet an active position for the token, we need to pass // the bank/oracle for health check anyway. - let new_position = account.token_iter().position(|p| !p.is_active()).unwrap(); + let new_position = account + .all_token_positions() + .position(|p| !p.is_active()) + .unwrap(); let mint_info = self.mint_info(affected_token_index); banks.insert(new_position, mint_info.first_bank()); oracles.insert(new_position, mint_info.oracle); } } - let serum_oos = account.serum3_iter_active().map(|&s| s.open_orders); + let serum_oos = account.active_serum3_orders().map(|&s| s.open_orders); let perp_markets = account - .perp_iter_active_accounts() + .active_perp_positions() .map(|&pa| self.perp_market_address(pa.market_index)); Ok(banks diff --git a/keeper/src/taker.rs b/keeper/src/taker.rs index d29bf8b87..8feaedf58 100644 --- a/keeper/src/taker.rs +++ b/keeper/src/taker.rs @@ -77,7 +77,7 @@ fn ensure_oo(mango_client: &Arc) -> Result<(), anyhow::Error> { let account = mango_client.mango_account()?; for (market_index, serum3_market) in mango_client.context.serum3_markets.iter() { - if account.serum3_find(*market_index).is_none() { + if account.serum3_orders(*market_index).is_none() { mango_client.serum3_create_open_orders(serum3_market.market.name())?; } } @@ -92,7 +92,7 @@ fn ensure_deposit(mango_client: &Arc) -> Result<(), anyhow::Error> let bank = mango_client.first_bank(token_index)?; let desired_balance = I80F48::from_num(10_000 * 10u64.pow(bank.mint_decimals as u32)); - let token_account_opt = mango_account.token_find(token_index); + let token_account_opt = mango_account.token_position(token_index).ok(); let deposit_native = match token_account_opt { Some(token_account) => { diff --git a/liquidator/src/liquidate.rs b/liquidator/src/liquidate.rs index eb3674d7b..fd6219558 100644 --- a/liquidator/src/liquidate.rs +++ b/liquidator/src/liquidate.rs @@ -20,8 +20,8 @@ pub fn new_health_cache_( account_fetcher: &chain_data::AccountFetcher, account: &MangoAccountValue, ) -> anyhow::Result { - let active_token_len = account.token_iter_active().count(); - let active_perp_len = account.perp_iter_active_accounts().count(); + let active_token_len = account.active_token_positions().count(); + let active_perp_len = account.active_perp_positions().count(); let metas = context.derive_health_check_remaining_account_metas(account, vec![], false)?; let accounts = metas @@ -138,7 +138,7 @@ pub fn maybe_liquidate_account( // find asset and liab tokens let mut tokens = account - .token_iter_active() + .active_token_positions() .map(|token_position| { let token = mango_client.context.token(token_position.token_index); let bank = account_fetcher.fetch::(&token.mint_info.first_bank())?; @@ -164,8 +164,8 @@ pub fn maybe_liquidate_account( // Ensure the tokens are activated, so they appear in the health cache and // max_swap_source() will work. - liqor.token_get_mut_or_create(source)?; - liqor.token_get_mut_or_create(target)?; + liqor.ensure_token_position(source)?; + liqor.ensure_token_position(target)?; let health_cache = new_health_cache_(&mango_client.context, account_fetcher, &liqor).expect("always ok"); diff --git a/liquidator/src/rebalance.rs b/liquidator/src/rebalance.rs index e10a26cbf..34e59c6df 100644 --- a/liquidator/src/rebalance.rs +++ b/liquidator/src/rebalance.rs @@ -68,7 +68,7 @@ pub fn zero_all_non_quote( let account = account_fetcher.fetch_mango_account(mango_account_address)?; let tokens = account - .token_iter_active() + .active_token_positions() .map(|token_position| { let token = mango_client.context.token(token_position.token_index); Ok(( @@ -140,7 +140,7 @@ pub fn zero_all_non_quote( let bank = TokenState::bank(token, account_fetcher)?; amount = mango_client .mango_account()? - .token_get(token_index) + .token_position_and_raw_index(token_index) .map(|(position, _)| position.native(&bank)) .unwrap_or(I80F48::ZERO); } else if token_state.native_position < 0 { @@ -167,7 +167,7 @@ pub fn zero_all_non_quote( let bank = TokenState::bank(token, account_fetcher)?; amount = mango_client .mango_account()? - .token_get(token_index) + .token_position_and_raw_index(token_index) .map(|(position, _)| position.native(&bank)) .unwrap_or(I80F48::ZERO); } diff --git a/liquidator/src/snapshot_source.rs b/liquidator/src/snapshot_source.rs index 71624d5f6..28df1b299 100644 --- a/liquidator/src/snapshot_source.rs +++ b/liquidator/src/snapshot_source.rs @@ -164,7 +164,7 @@ async fn feed_snapshots( }) .flat_map(|mango_account| { mango_account - .serum3_iter_active() + .active_serum3_orders() .map(|serum3account| serum3account.open_orders) .collect::>() }) diff --git a/programs/mango-v4/src/instructions/account_close.rs b/programs/mango-v4/src/instructions/account_close.rs index 9f0795f0d..7572aa149 100644 --- a/programs/mango-v4/src/instructions/account_close.rs +++ b/programs/mango-v4/src/instructions/account_close.rs @@ -32,13 +32,13 @@ pub fn account_close(ctx: Context) -> Result<()> { // don't perform checks if group is just testing if !group.is_testing() { require!(!account.fixed.being_liquidated(), MangoError::SomeError); - for ele in account.token_iter() { + for ele in account.all_token_positions() { require_eq!(ele.is_active(), false); } - for ele in account.serum3_iter() { + for ele in account.all_serum3_orders() { require_eq!(ele.is_active(), false); } - for ele in account.perp_iter() { + for ele in account.all_perp_positions() { require_eq!(ele.is_active(), false); } } diff --git a/programs/mango-v4/src/instructions/flash_loan.rs b/programs/mango-v4/src/instructions/flash_loan.rs index 7c9dc8c2d..2616ff5a0 100644 --- a/programs/mango-v4/src/instructions/flash_loan.rs +++ b/programs/mango-v4/src/instructions/flash_loan.rs @@ -265,7 +265,7 @@ pub fn flash_loan_end<'key, 'accounts, 'remaining, 'info>( require_neq!(bank.flash_loan_token_account_initial, u64::MAX); // Create the token position now, so we can compute the pre-health with fixed order health accounts - let (_, raw_token_index, _) = account.token_get_mut_or_create(bank.token_index)?; + let (_, raw_token_index, _) = account.ensure_token_position(bank.token_index)?; // Transfer any excess over the inital balance of the token account back // into the vault. Compute the total change in the vault balance. @@ -337,7 +337,7 @@ pub fn flash_loan_end<'key, 'accounts, 'remaining, 'info>( let mut token_loan_details = Vec::with_capacity(changes.len()); for (change, price) in changes.iter().zip(prices.iter()) { let mut bank = health_ais[change.bank_index].load_mut::()?; - let position = account.token_get_mut_raw(change.raw_token_index); + let position = account.token_position_mut_by_raw_index(change.raw_token_index); let native = position.native(&bank); let approved_amount = I80F48::from(bank.flash_loan_approved_amount); @@ -398,7 +398,7 @@ pub fn flash_loan_end<'key, 'accounts, 'remaining, 'info>( // Deactivate inactive token accounts after health check for raw_token_index in deactivated_token_positions { - account.token_deactivate(raw_token_index); + account.deactivate_token_position(raw_token_index); } Ok(()) diff --git a/programs/mango-v4/src/instructions/liq_token_bankruptcy.rs b/programs/mango-v4/src/instructions/liq_token_bankruptcy.rs index 7622ff7cc..b620268d2 100644 --- a/programs/mango-v4/src/instructions/liq_token_bankruptcy.rs +++ b/programs/mango-v4/src/instructions/liq_token_bankruptcy.rs @@ -99,7 +99,7 @@ pub fn liq_token_bankruptcy( let (liab_bank, liab_price, opt_quote_bank_and_price) = account_retriever.banks_mut_and_oracles(liab_token_index, QUOTE_TOKEN_INDEX)?; let liab_deposit_index = liab_bank.deposit_index; - let (liqee_liab, liqee_raw_token_index) = liqee.token_get_mut(liab_token_index)?; + let (liqee_liab, liqee_raw_token_index) = liqee.token_position_mut(liab_token_index)?; let initial_liab_native = liqee_liab.native(&liab_bank); let mut remaining_liab_loss = -initial_liab_native; require_gt!(remaining_liab_loss, I80F48::ZERO); @@ -158,12 +158,12 @@ pub fn liq_token_bankruptcy( // credit the liqor let (liqor_quote, liqor_quote_raw_token_index, _) = - liqor.token_get_mut_or_create(QUOTE_TOKEN_INDEX)?; + liqor.ensure_token_position(QUOTE_TOKEN_INDEX)?; let liqor_quote_active = quote_bank.deposit(liqor_quote, insurance_transfer_i80f48)?; // transfer liab from liqee to liqor let (liqor_liab, liqor_liab_raw_token_index, _) = - liqor.token_get_mut_or_create(liab_token_index)?; + liqor.ensure_token_position(liab_token_index)?; let liqor_liab_active = liab_bank.withdraw_with_fee(liqor_liab, liab_transfer)?; // Check liqor's health @@ -172,10 +172,10 @@ pub fn liq_token_bankruptcy( require!(liqor_health >= 0, MangoError::HealthMustBePositive); if !liqor_quote_active { - liqor.token_deactivate(liqor_quote_raw_token_index); + liqor.deactivate_token_position(liqor_quote_raw_token_index); } if !liqor_liab_active { - liqor.token_deactivate(liqor_liab_raw_token_index); + liqor.deactivate_token_position(liqor_liab_raw_token_index); } } else { // For liab_token_index == QUOTE_TOKEN_INDEX: the insurance fund deposits directly into liqee, @@ -240,7 +240,7 @@ pub fn liq_token_bankruptcy( .maybe_recover_from_being_liquidated(liqee_init_health); if !liqee_liab_active { - liqee.token_deactivate(liqee_raw_token_index); + liqee.deactivate_token_position(liqee_raw_token_index); } Ok(()) diff --git a/programs/mango-v4/src/instructions/liq_token_with_token.rs b/programs/mango-v4/src/instructions/liq_token_with_token.rs index a1486f039..f34f8403d 100644 --- a/programs/mango-v4/src/instructions/liq_token_with_token.rs +++ b/programs/mango-v4/src/instructions/liq_token_with_token.rs @@ -88,11 +88,13 @@ pub fn liq_token_with_token( // The main complication here is that we can't keep the liqee_asset_position and liqee_liab_position // borrows alive at the same time. Possibly adding get_mut_pair() would be helpful. - let (liqee_asset_position, liqee_asset_raw_index) = liqee.token_get(asset_token_index)?; + let (liqee_asset_position, liqee_asset_raw_index) = + liqee.token_position_and_raw_index(asset_token_index)?; let liqee_asset_native = liqee_asset_position.native(asset_bank); require!(liqee_asset_native.is_positive(), MangoError::SomeError); - let (liqee_liab_position, liqee_liab_raw_index) = liqee.token_get(liab_token_index)?; + let (liqee_liab_position, liqee_liab_raw_index) = + liqee.token_position_and_raw_index(liab_token_index)?; let liqee_liab_native = liqee_liab_position.native(liab_bank); require!(liqee_liab_native.is_negative(), MangoError::SomeError); @@ -135,23 +137,23 @@ pub fn liq_token_with_token( // is nominally in-use. // Apply the balance changes to the liqor and liqee accounts - let liqee_liab_position = liqee.token_get_mut_raw(liqee_liab_raw_index); + let liqee_liab_position = liqee.token_position_mut_by_raw_index(liqee_liab_raw_index); let liqee_liab_active = liab_bank.deposit_with_dusting(liqee_liab_position, liab_transfer)?; let liqee_liab_position_indexed = liqee_liab_position.indexed_position; let (liqor_liab_position, liqor_liab_raw_index, _) = - liqor.token_get_mut_or_create(liab_token_index)?; + liqor.ensure_token_position(liab_token_index)?; let liqor_liab_active = liab_bank.withdraw_with_fee(liqor_liab_position, liab_transfer)?; let liqor_liab_position_indexed = liqor_liab_position.indexed_position; let liqee_liab_native_after = liqee_liab_position.native(&liab_bank); let (liqor_asset_position, liqor_asset_raw_index, _) = - liqor.token_get_mut_or_create(asset_token_index)?; + liqor.ensure_token_position(asset_token_index)?; let liqor_asset_active = asset_bank.deposit(liqor_asset_position, asset_transfer)?; let liqor_asset_position_indexed = liqor_asset_position.indexed_position; - let liqee_asset_position = liqee.token_get_mut_raw(liqee_asset_raw_index); + let liqee_asset_position = liqee.token_position_mut_by_raw_index(liqee_asset_raw_index); let liqee_asset_active = asset_bank.withdraw_without_fee_with_dusting(liqee_asset_position, asset_transfer)?; let liqee_asset_position_indexed = liqee_asset_position.indexed_position; @@ -229,16 +231,16 @@ pub fn liq_token_with_token( // Since we use a scanning account retriever, it's safe to deactivate inactive token positions if !liqee_asset_active { - liqee.token_deactivate(liqee_asset_raw_index); + liqee.deactivate_token_position(liqee_asset_raw_index); } if !liqee_liab_active { - liqee.token_deactivate(liqee_liab_raw_index); + liqee.deactivate_token_position(liqee_liab_raw_index); } if !liqor_asset_active { - liqor.token_deactivate(liqor_asset_raw_index); + liqor.deactivate_token_position(liqor_asset_raw_index); } if !liqor_liab_active { - liqor.token_deactivate(liqor_liab_raw_index) + liqor.deactivate_token_position(liqor_liab_raw_index) } } diff --git a/programs/mango-v4/src/instructions/perp_cancel_order.rs b/programs/mango-v4/src/instructions/perp_cancel_order.rs index 7a1e99dec..f8e2a59d2 100644 --- a/programs/mango-v4/src/instructions/perp_cancel_order.rs +++ b/programs/mango-v4/src/instructions/perp_cancel_order.rs @@ -46,5 +46,5 @@ pub fn perp_cancel_order(ctx: Context, order_id: i128) -> Resul MangoError::SomeError // InvalidOwner ); - account.perp_remove_order(order.owner_slot as usize, order.quantity) + account.remove_perp_order(order.owner_slot as usize, order.quantity) } diff --git a/programs/mango-v4/src/instructions/perp_cancel_order_by_client_order_id.rs b/programs/mango-v4/src/instructions/perp_cancel_order_by_client_order_id.rs index cac74445e..45d446698 100644 --- a/programs/mango-v4/src/instructions/perp_cancel_order_by_client_order_id.rs +++ b/programs/mango-v4/src/instructions/perp_cancel_order_by_client_order_id.rs @@ -49,5 +49,5 @@ pub fn perp_cancel_order_by_client_order_id( MangoError::SomeError // InvalidOwner ); - account.perp_remove_order(order.owner_slot as usize, order.quantity) + account.remove_perp_order(order.owner_slot as usize, order.quantity) } diff --git a/programs/mango-v4/src/instructions/perp_consume_events.rs b/programs/mango-v4/src/instructions/perp_consume_events.rs index 365786920..27bca076e 100644 --- a/programs/mango-v4/src/instructions/perp_consume_events.rs +++ b/programs/mango-v4/src/instructions/perp_consume_events.rs @@ -50,12 +50,12 @@ pub fn perp_consume_events(ctx: Context, limit: usize) -> Res let mal: AccountLoaderDynamic = AccountLoaderDynamic::try_from(ai)?; let mut ma = mal.load_mut()?; - ma.perp_execute_maker( + ma.execute_perp_maker( perp_market.perp_market_index, &mut perp_market, fill, )?; - ma.perp_execute_taker( + ma.execute_perp_taker( perp_market.perp_market_index, &mut perp_market, fill, @@ -65,7 +65,7 @@ pub fn perp_consume_events(ctx: Context, limit: usize) -> Res fill.maker, perp_market.perp_market_index as u64, fill.price, - ma.perp_find_account(perp_market.perp_market_index).unwrap(), + ma.perp_position(perp_market.perp_market_index).unwrap(), &perp_market, ); } @@ -91,12 +91,12 @@ pub fn perp_consume_events(ctx: Context, limit: usize) -> Res AccountLoaderDynamic::try_from(ai)?; let mut taker = mal.load_mut()?; - maker.perp_execute_maker( + maker.execute_perp_maker( perp_market.perp_market_index, &mut perp_market, fill, )?; - taker.perp_execute_taker( + taker.execute_perp_taker( perp_market.perp_market_index, &mut perp_market, fill, @@ -106,9 +106,7 @@ pub fn perp_consume_events(ctx: Context, limit: usize) -> Res fill.maker, perp_market.perp_market_index as u64, fill.price, - maker - .perp_find_account(perp_market.perp_market_index) - .unwrap(), + maker.perp_position(perp_market.perp_market_index).unwrap(), &perp_market, ); emit_perp_balances( @@ -116,9 +114,7 @@ pub fn perp_consume_events(ctx: Context, limit: usize) -> Res fill.taker, perp_market.perp_market_index as u64, fill.price, - taker - .perp_find_account(perp_market.perp_market_index) - .unwrap(), + taker.perp_position(perp_market.perp_market_index).unwrap(), &perp_market, ); } @@ -161,7 +157,7 @@ pub fn perp_consume_events(ctx: Context, limit: usize) -> Res AccountLoaderDynamic::try_from(ai)?; let mut ma = mal.load_mut()?; - ma.perp_remove_order(out.owner_slot as usize, out.quantity)?; + ma.remove_perp_order(out.owner_slot as usize, out.quantity)?; } }; } diff --git a/programs/mango-v4/src/instructions/serum3_cancel_all_orders.rs b/programs/mango-v4/src/instructions/serum3_cancel_all_orders.rs index dfd558258..48ba91d2e 100644 --- a/programs/mango-v4/src/instructions/serum3_cancel_all_orders.rs +++ b/programs/mango-v4/src/instructions/serum3_cancel_all_orders.rs @@ -56,7 +56,7 @@ pub fn serum3_cancel_all_orders(ctx: Context, limit: u8) // Validate open_orders require!( account - .serum3_find(serum_market.market_index) + .serum3_orders(serum_market.market_index) .ok_or_else(|| error!(MangoError::SomeError))? .open_orders == ctx.accounts.open_orders.key(), diff --git a/programs/mango-v4/src/instructions/serum3_cancel_order.rs b/programs/mango-v4/src/instructions/serum3_cancel_order.rs index 1a9dad8c6..c55c8590d 100644 --- a/programs/mango-v4/src/instructions/serum3_cancel_order.rs +++ b/programs/mango-v4/src/instructions/serum3_cancel_order.rs @@ -67,7 +67,7 @@ pub fn serum3_cancel_order( // Validate open_orders require!( account - .serum3_find(serum_market.market_index) + .serum3_orders(serum_market.market_index) .ok_or_else(|| error!(MangoError::SomeError))? .open_orders == ctx.accounts.open_orders.key(), @@ -111,7 +111,7 @@ pub fn decrease_maybe_loan( before_oo: &OpenOrdersSlim, after_oo: &OpenOrdersSlim, ) { - let serum3_account = account.serum3_find_mut(market_index).unwrap(); + let serum3_account = account.serum3_orders_mut(market_index).unwrap(); if after_oo.native_coin_free > before_oo.native_coin_free { let native_coin_free_increase = after_oo.native_coin_free - before_oo.native_coin_free; diff --git a/programs/mango-v4/src/instructions/serum3_close_open_orders.rs b/programs/mango-v4/src/instructions/serum3_close_open_orders.rs index ad2f2d00c..a457b6661 100644 --- a/programs/mango-v4/src/instructions/serum3_close_open_orders.rs +++ b/programs/mango-v4/src/instructions/serum3_close_open_orders.rs @@ -46,7 +46,7 @@ pub fn serum3_close_open_orders(ctx: Context) -> Result<( // Validate open_orders require!( account - .serum3_find(serum_market.market_index) + .serum3_orders(serum_market.market_index) .ok_or_else(|| error!(MangoError::SomeError))? .open_orders == ctx.accounts.open_orders.key(), @@ -59,7 +59,7 @@ pub fn serum3_close_open_orders(ctx: Context) -> Result<( cpi_close_open_orders(ctx.accounts)?; // TODO: decrement in_use_count on the base token and quote token - account.serum3_deactivate(serum_market.market_index)?; + account.deactivate_serum3_orders(serum_market.market_index)?; Ok(()) } diff --git a/programs/mango-v4/src/instructions/serum3_create_open_orders.rs b/programs/mango-v4/src/instructions/serum3_create_open_orders.rs index 58473f26c..e2dfd3ab4 100644 --- a/programs/mango-v4/src/instructions/serum3_create_open_orders.rs +++ b/programs/mango-v4/src/instructions/serum3_create_open_orders.rs @@ -53,7 +53,7 @@ pub fn serum3_create_open_orders(ctx: Context) -> Result MangoError::SomeError ); - let serum_account = account.serum3_create(serum_market.market_index)?; + let serum_account = account.create_serum3_orders(serum_market.market_index)?; serum_account.open_orders = ctx.accounts.open_orders.key(); serum_account.base_token_index = serum_market.base_token_index; serum_account.quote_token_index = serum_market.quote_token_index; @@ -61,9 +61,9 @@ pub fn serum3_create_open_orders(ctx: Context) -> Result // Make it so that the token_account_map for the base and quote currency // stay permanently blocked. Otherwise users may end up in situations where // they can't settle a market because they don't have free token_account_map! - let (quote_position, _, _) = account.token_get_mut_or_create(serum_market.quote_token_index)?; + let (quote_position, _, _) = account.ensure_token_position(serum_market.quote_token_index)?; quote_position.in_use_count += 1; - let (base_position, _, _) = account.token_get_mut_or_create(serum_market.base_token_index)?; + let (base_position, _, _) = account.ensure_token_position(serum_market.base_token_index)?; base_position.in_use_count += 1; Ok(()) diff --git a/programs/mango-v4/src/instructions/serum3_liq_force_cancel_orders.rs b/programs/mango-v4/src/instructions/serum3_liq_force_cancel_orders.rs index ca067b976..9717d77e3 100644 --- a/programs/mango-v4/src/instructions/serum3_liq_force_cancel_orders.rs +++ b/programs/mango-v4/src/instructions/serum3_liq_force_cancel_orders.rs @@ -75,7 +75,7 @@ pub fn serum3_liq_force_cancel_orders( // Validate open_orders require!( account - .serum3_find(serum_market.market_index) + .serum3_orders(serum_market.market_index) .ok_or_else(|| error!(MangoError::SomeError))? .open_orders == ctx.accounts.open_orders.key(), diff --git a/programs/mango-v4/src/instructions/serum3_place_order.rs b/programs/mango-v4/src/instructions/serum3_place_order.rs index 242f223c7..2bff6d01c 100644 --- a/programs/mango-v4/src/instructions/serum3_place_order.rs +++ b/programs/mango-v4/src/instructions/serum3_place_order.rs @@ -172,7 +172,7 @@ pub fn serum3_place_order( // Validate open_orders require!( account - .serum3_find(serum_market.market_index) + .serum3_orders(serum_market.market_index) .ok_or_else(|| error!(MangoError::SomeError))? .open_orders == ctx.accounts.open_orders.key(), @@ -308,7 +308,7 @@ pub fn inc_maybe_loan( before_oo: &OpenOrdersSlim, after_oo: &OpenOrdersSlim, ) { - let serum3_account = account.serum3_find_mut(market_index).unwrap(); + let serum3_account = account.serum3_orders_mut(market_index).unwrap(); if after_oo.native_coin_reserved() > before_oo.native_coin_reserved() { let native_coin_reserved_increase = @@ -334,10 +334,10 @@ pub struct VaultDifferenceResult { impl VaultDifferenceResult { pub fn deactivate_inactive_token_accounts(&self, account: &mut MangoAccountRefMut) { if !self.base_active { - account.token_deactivate(self.base_raw_index); + account.deactivate_token_position(self.base_raw_index); } if !self.quote_active { - account.token_deactivate(self.quote_raw_index); + account.deactivate_token_position(self.quote_raw_index); } } } @@ -355,11 +355,11 @@ pub fn apply_vault_difference( // charged if an order executes and the loan materializes? Otherwise MMs that place // an order without having the funds will be charged for each place_order! - let (base_position, base_raw_index) = account.token_get_mut(base_bank.token_index)?; + let (base_position, base_raw_index) = account.token_position_mut(base_bank.token_index)?; let base_change = I80F48::from(after_base_vault) - I80F48::from(before_base_vault); let base_active = base_bank.change_with_fee(base_position, base_change)?; - let (quote_position, quote_raw_index) = account.token_get_mut(quote_bank.token_index)?; + let (quote_position, quote_raw_index) = account.token_position_mut(quote_bank.token_index)?; let quote_change = I80F48::from(after_quote_vault) - I80F48::from(before_quote_vault); let quote_active = quote_bank.change_with_fee(quote_position, quote_change)?; diff --git a/programs/mango-v4/src/instructions/serum3_settle_funds.rs b/programs/mango-v4/src/instructions/serum3_settle_funds.rs index cb905d08a..101727fc9 100644 --- a/programs/mango-v4/src/instructions/serum3_settle_funds.rs +++ b/programs/mango-v4/src/instructions/serum3_settle_funds.rs @@ -81,7 +81,7 @@ pub fn serum3_settle_funds(ctx: Context) -> Result<()> { // Validate open_orders require!( account - .serum3_find(serum_market.market_index) + .serum3_orders(serum_market.market_index) .ok_or_else(|| error!(MangoError::SomeError))? .open_orders == ctx.accounts.open_orders.key(), @@ -172,7 +172,7 @@ pub fn charge_maybe_fees( account: &mut MangoAccountRefMut, after_oo: &OpenOrdersSlim, ) -> Result<()> { - let serum3_account = account.serum3_find_mut(market_index).unwrap(); + let serum3_account = account.serum3_orders_mut(market_index).unwrap(); let maybe_actualized_coin_loan = I80F48::from_num::( serum3_account @@ -184,7 +184,7 @@ pub fn charge_maybe_fees( serum3_account.previous_native_coin_reserved = after_oo.native_coin_reserved(); // loan origination fees - let coin_token_account = account.token_get_mut(coin_bank.token_index)?.0; + let coin_token_account = account.token_position_mut(coin_bank.token_index)?.0; let coin_token_native = coin_token_account.native(coin_bank); if coin_token_native.is_negative() { @@ -198,7 +198,7 @@ pub fn charge_maybe_fees( } } - let serum3_account = account.serum3_find_mut(market_index).unwrap(); + let serum3_account = account.serum3_orders_mut(market_index).unwrap(); let maybe_actualized_pc_loan = I80F48::from_num::( serum3_account .previous_native_pc_reserved @@ -209,7 +209,7 @@ pub fn charge_maybe_fees( serum3_account.previous_native_pc_reserved = after_oo.native_pc_reserved(); // loan origination fees - let pc_token_account = account.token_get_mut(pc_bank.token_index)?.0; + let pc_token_account = account.token_position_mut(pc_bank.token_index)?.0; let pc_token_native = pc_token_account.native(pc_bank); if pc_token_native.is_negative() { diff --git a/programs/mango-v4/src/instructions/token_deposit.rs b/programs/mango-v4/src/instructions/token_deposit.rs index a48a163ae..1cae507f9 100644 --- a/programs/mango-v4/src/instructions/token_deposit.rs +++ b/programs/mango-v4/src/instructions/token_deposit.rs @@ -57,7 +57,7 @@ pub fn token_deposit(ctx: Context, amount: u64) -> Result<()> { let mut account = ctx.accounts.account.load_mut()?; let (position, raw_token_index, active_token_index) = - account.token_get_mut_or_create(token_index)?; + account.ensure_token_position(token_index)?; let amount_i80f48 = I80F48::from(amount); let position_is_active = { @@ -103,7 +103,7 @@ pub fn token_deposit(ctx: Context, amount: u64) -> Result<()> { // Deposits can deactivate a position if they cancel out a previous borrow. // if !position_is_active { - account.token_deactivate(raw_token_index); + account.deactivate_token_position(raw_token_index); } emit!(DepositLog { diff --git a/programs/mango-v4/src/instructions/token_withdraw.rs b/programs/mango-v4/src/instructions/token_withdraw.rs index e7b162427..d7477e8ec 100644 --- a/programs/mango-v4/src/instructions/token_withdraw.rs +++ b/programs/mango-v4/src/instructions/token_withdraw.rs @@ -58,7 +58,7 @@ pub fn token_withdraw(ctx: Context, amount: u64, allow_borrow: bo let mut account = ctx.accounts.account.load_mut()?; let (position, raw_token_index, active_token_index) = - account.token_get_mut_or_create(token_index)?; + account.ensure_token_position(token_index)?; // The bank will also be passed in remainingAccounts. Use an explicit scope // to drop the &mut before we borrow it immutably again later. @@ -144,7 +144,7 @@ pub fn token_withdraw(ctx: Context, amount: u64, allow_borrow: bo // deactivated. // if !position_is_active { - account.token_deactivate(raw_token_index); + account.deactivate_token_position(raw_token_index); } emit!(WithdrawLog { diff --git a/programs/mango-v4/src/logs.rs b/programs/mango-v4/src/logs.rs index a1902b372..97eeffe53 100644 --- a/programs/mango-v4/src/logs.rs +++ b/programs/mango-v4/src/logs.rs @@ -1,6 +1,6 @@ use crate::{ instructions::FlashLoanType, - state::{PerpMarket, PerpPositions}, + state::{PerpMarket, PerpPosition}, }; use anchor_lang::prelude::*; use borsh::BorshSerialize; @@ -11,7 +11,7 @@ pub fn emit_perp_balances( mango_account: Pubkey, market_index: u64, price: i64, - pp: &PerpPositions, + pp: &PerpPosition, pm: &PerpMarket, ) { emit!(PerpBalanceLog { diff --git a/programs/mango-v4/src/state/equity.rs b/programs/mango-v4/src/state/equity.rs index 85a8639ff..ff2120bd3 100644 --- a/programs/mango-v4/src/state/equity.rs +++ b/programs/mango-v4/src/state/equity.rs @@ -15,7 +15,7 @@ pub fn compute_equity( let mut token_equity_map = HashMap::new(); // token contributions - for (_i, position) in account.token_iter_active().enumerate() { + for (_i, position) in account.active_token_positions().enumerate() { let (bank, oracle_price) = retriever.scanned_bank_and_oracle(position.token_index)?; // converts the token value to the basis token value for health computations // TODO: health basis token == USDC? @@ -24,7 +24,7 @@ pub fn compute_equity( } // token contributions from Serum3 - for (_i, serum_account) in account.serum3_iter_active().enumerate() { + for (_i, serum_account) in account.active_serum3_orders().enumerate() { let oo = retriever.scanned_serum_oo(&serum_account.open_orders)?; // note base token value diff --git a/programs/mango-v4/src/state/health.rs b/programs/mango-v4/src/state/health.rs index ced0fea69..6dda44174 100644 --- a/programs/mango-v4/src/state/health.rs +++ b/programs/mango-v4/src/state/health.rs @@ -63,9 +63,9 @@ pub fn new_fixed_order_account_retriever<'a, 'info>( ais: &'a [AccountInfo<'info>], account: &MangoAccountRef, ) -> Result>> { - let active_token_len = account.token_iter_active().count(); - let active_serum3_len = account.serum3_iter_active().count(); - let active_perp_len = account.perp_iter_active_accounts().count(); + let active_token_len = account.active_token_positions().count(); + let active_serum3_len = account.active_serum3_orders().count(); + let active_perp_len = account.active_perp_positions().count(); let expected_ais = cm!(active_token_len * 2 // banks + oracles + active_perp_len // PerpMarkets + active_serum3_len); // open_orders @@ -787,7 +787,7 @@ pub fn new_health_cache( // token contribution from token accounts let mut token_infos = vec![]; - for (i, position) in account.token_iter_active().enumerate() { + for (i, position) in account.active_token_positions().enumerate() { let (bank, oracle_price) = retriever.bank_and_oracle(&account.fixed.group, i, position.token_index)?; @@ -810,7 +810,7 @@ pub fn new_health_cache( // Fill the TokenInfo balance with free funds in serum3 oo accounts, and fill // the serum3_max_reserved with their reserved funds. Also build Serum3Infos. let mut serum3_infos = vec![]; - for (i, serum_account) in account.serum3_iter_active().enumerate() { + for (i, serum_account) in account.active_serum3_orders().enumerate() { let oo = retriever.serum_oo(i, &serum_account.open_orders)?; // find the TokenInfos for the market's base and quote tokens @@ -847,8 +847,8 @@ pub fn new_health_cache( // TODO: also account for perp funding in health // health contribution from perp accounts - let mut perp_infos = Vec::with_capacity(account.perp_iter_active_accounts().count()); - for (i, perp_account) in account.perp_iter_active_accounts().enumerate() { + let mut perp_infos = Vec::with_capacity(account.active_perp_positions().count()); + for (i, perp_account) in account.active_perp_positions().enumerate() { let perp_market = retriever.perp_market(&account.fixed.group, i, perp_account.market_index)?; @@ -1074,20 +1074,20 @@ mod tests { bank1 .data() .deposit( - account.token_get_mut_or_create(1).unwrap().0, + account.ensure_token_position(1).unwrap().0, I80F48::from(100), ) .unwrap(); bank2 .data() .withdraw_without_fee( - account.token_get_mut_or_create(4).unwrap().0, + account.ensure_token_position(4).unwrap().0, I80F48::from(10), ) .unwrap(); let mut oo1 = TestAccount::::new_zeroed(); - let serum3account = account.serum3_create(2).unwrap(); + let serum3account = account.create_serum3_orders(2).unwrap(); serum3account.open_orders = oo1.pubkey; serum3account.base_token_index = 4; serum3account.quote_token_index = 1; @@ -1107,7 +1107,7 @@ mod tests { perp1.data().maint_liab_weight = I80F48::from_num(1.0 + 0.1f64); perp1.data().quote_lot_size = 100; perp1.data().base_lot_size = 10; - let perpaccount = account.perp_get_account_mut_or_create(9).unwrap().0; + let perpaccount = account.ensure_perp_position(9).unwrap().0; perpaccount.base_position_lots = 3; perpaccount.quote_position_native = -I80F48::from(310u16); perpaccount.bids_base_lots = 7; @@ -1254,27 +1254,27 @@ mod tests { bank1 .data() .change_without_fee( - account.token_get_mut_or_create(1).unwrap().0, + account.ensure_token_position(1).unwrap().0, I80F48::from(testcase.token1), ) .unwrap(); bank2 .data() .change_without_fee( - account.token_get_mut_or_create(4).unwrap().0, + account.ensure_token_position(4).unwrap().0, I80F48::from(testcase.token2), ) .unwrap(); bank3 .data() .change_without_fee( - account.token_get_mut_or_create(5).unwrap().0, + account.ensure_token_position(5).unwrap().0, I80F48::from(testcase.token3), ) .unwrap(); let mut oo1 = TestAccount::::new_zeroed(); - let serum3account1 = account.serum3_create(2).unwrap(); + let serum3account1 = account.create_serum3_orders(2).unwrap(); serum3account1.open_orders = oo1.pubkey; serum3account1.base_token_index = 4; serum3account1.quote_token_index = 1; @@ -1282,7 +1282,7 @@ mod tests { oo1.data().native_coin_total = testcase.oo_1_2.1; let mut oo2 = TestAccount::::new_zeroed(); - let serum3account2 = account.serum3_create(3).unwrap(); + let serum3account2 = account.create_serum3_orders(3).unwrap(); serum3account2.open_orders = oo2.pubkey; serum3account2.base_token_index = 5; serum3account2.quote_token_index = 1; @@ -1299,7 +1299,7 @@ mod tests { perp1.data().maint_liab_weight = I80F48::from_num(1.0 + 0.1f64); perp1.data().quote_lot_size = 100; perp1.data().base_lot_size = 10; - let perpaccount = account.perp_get_account_mut_or_create(9).unwrap().0; + let perpaccount = account.ensure_perp_position(9).unwrap().0; perpaccount.base_position_lots = testcase.perp1.0; perpaccount.quote_position_native = I80F48::from(testcase.perp1.1); perpaccount.bids_base_lots = testcase.perp1.2; diff --git a/programs/mango-v4/src/state/mango_account.rs b/programs/mango-v4/src/state/mango_account.rs index 098a2d8d3..df017df14 100644 --- a/programs/mango-v4/src/state/mango_account.rs +++ b/programs/mango-v4/src/state/mango_account.rs @@ -22,7 +22,7 @@ use super::Serum3MarketIndex; use super::Side; use super::TokenIndex; use super::FREE_ORDER_SLOT; -use super::{PerpPositions, Serum3Orders, TokenPosition}; +use super::{PerpPosition, Serum3Orders, TokenPosition}; use checked_math as cm; type BorshVecLength = u32; @@ -87,7 +87,7 @@ pub struct MangoAccount { // that is active on this MangoAccount. pub serum3: Vec, pub padding6: u32, - pub perps: Vec, + pub perps: Vec, pub padding7: u32, pub perp_open_orders: Vec, } @@ -114,7 +114,7 @@ impl Default for MangoAccount { padding5: Default::default(), serum3: vec![Serum3Orders::default(); 5], padding6: Default::default(), - perps: vec![PerpPositions::default(); 2], + perps: vec![PerpPosition::default(); 2], padding7: Default::default(), perp_open_orders: vec![PerpOpenOrders::default(); 2], } @@ -156,7 +156,7 @@ impl MangoAccount { pub fn dynamic_perp_oo_vec_offset(token_count: u8, serum3_count: u8, perp_count: u8) -> usize { Self::dynamic_perp_vec_offset(token_count, serum3_count) - + (BORSH_VEC_SIZE_BYTES + size_of::() * usize::from(perp_count)) + + (BORSH_VEC_SIZE_BYTES + size_of::() * usize::from(perp_count)) + BORSH_VEC_PADDING_BYTES } @@ -185,8 +185,7 @@ fn test_serialization_match() { account.tokens.resize(8, TokenPosition::default()); account.tokens[0].token_index = 5; account.serum3.resize(8, Serum3Orders::default()); - account.serum3[0].open_orders = Pubkey::new_unique(); - account.perps.resize(8, PerpPositions::default()); + account.perps.resize(8, PerpPosition::default()); account.perps[0].market_index = 6; account .perp_open_orders @@ -209,15 +208,15 @@ fn test_serialization_match() { assert_eq!(account.net_settled, account2.fixed.net_settled); assert_eq!( account.tokens[0].token_index, - account2.token_get_raw(0).token_index + account2.token_position_by_raw_index(0).token_index ); assert_eq!( account.serum3[0].open_orders, - account2.serum3_get_raw(0).open_orders + account2.serum3_orders_by_raw_index(0).open_orders ); assert_eq!( account.perps[0].market_index, - account2.perp_get_raw(0).market_index + account2.perp_position_by_raw_index(0).market_index ); } @@ -362,11 +361,11 @@ impl MangoAccountDynamicHeader { + raw_index * size_of::() } - // offset into dynamic data where 1st PerpPositions would be found + // offset into dynamic data where 1st PerpPosition would be found fn perp_offset(&self, raw_index: usize) -> usize { MangoAccount::dynamic_perp_vec_offset(self.token_count, self.serum3_count) + BORSH_VEC_SIZE_BYTES - + raw_index * size_of::() + + raw_index * size_of::() } fn perp_oo_offset(&self, raw_index: usize) -> usize { @@ -449,85 +448,85 @@ impl< /// Returns /// - the position /// - the raw index into the token positions list (for use with get_raw/deactivate) - pub fn token_get(&self, token_index: TokenIndex) -> Result<(&TokenPosition, usize)> { - self.token_iter() + pub fn token_position_and_raw_index( + &self, + token_index: TokenIndex, + ) -> Result<(&TokenPosition, usize)> { + self.all_token_positions() .enumerate() .find_map(|(raw_index, p)| p.is_active_for_token(token_index).then(|| (p, raw_index))) .ok_or_else(|| error_msg!("position for token index {} not found", token_index)) } - // get TokenPosition at raw_index - pub fn token_get_raw(&self, raw_index: usize) -> &TokenPosition { + pub fn token_position(&self, token_index: TokenIndex) -> Result<&TokenPosition> { + self.token_position_and_raw_index(token_index) + .map(|(p, _)| p) + } + + pub fn token_position_by_raw_index(&self, raw_index: usize) -> &TokenPosition { get_helper(self.dynamic(), self.header().token_offset(raw_index)) } // get iter over all TokenPositions (including inactive) - pub fn token_iter(&self) -> impl Iterator + '_ { - (0..self.header().token_count()).map(|i| self.token_get_raw(i)) + pub fn all_token_positions(&self) -> impl Iterator + '_ { + (0..self.header().token_count()).map(|i| self.token_position_by_raw_index(i)) } // get iter over all active TokenPositions - pub fn token_iter_active(&self) -> impl Iterator + '_ { + pub fn active_token_positions(&self) -> impl Iterator + '_ { (0..self.header().token_count()) - .map(|i| self.token_get_raw(i)) + .map(|i| self.token_position_by_raw_index(i)) .filter(|token| token.is_active()) } - pub fn token_find(&self, token_index: TokenIndex) -> Option<&TokenPosition> { - self.token_iter_active() - .find(|p| p.is_active_for_token(token_index)) + pub fn serum3_orders(&self, market_index: Serum3MarketIndex) -> Option<&Serum3Orders> { + self.active_serum3_orders() + .find(|p| p.is_active_for_market(market_index)) } - // get Serum3Orders at raw_index - pub fn serum3_get_raw(&self, raw_index: usize) -> &Serum3Orders { + pub fn serum3_orders_by_raw_index(&self, raw_index: usize) -> &Serum3Orders { get_helper(self.dynamic(), self.header().serum3_offset(raw_index)) } - pub fn serum3_iter(&self) -> impl Iterator + '_ { - (0..self.header().serum3_count()).map(|i| self.serum3_get_raw(i)) + pub fn all_serum3_orders(&self) -> impl Iterator + '_ { + (0..self.header().serum3_count()).map(|i| self.serum3_orders_by_raw_index(i)) } - pub fn serum3_iter_active(&self) -> impl Iterator + '_ { + pub fn active_serum3_orders(&self) -> impl Iterator + '_ { (0..self.header().serum3_count()) - .map(|i| self.serum3_get_raw(i)) + .map(|i| self.serum3_orders_by_raw_index(i)) .filter(|serum3_order| serum3_order.is_active()) } - pub fn serum3_find(&self, market_index: Serum3MarketIndex) -> Option<&Serum3Orders> { - self.serum3_iter_active() + pub fn perp_position(&self, market_index: PerpMarketIndex) -> Option<&PerpPosition> { + self.active_perp_positions() .find(|p| p.is_active_for_market(market_index)) } - // get PerpPosition at raw_index - pub fn perp_get_raw(&self, raw_index: usize) -> &PerpPositions { + pub fn perp_position_by_raw_index(&self, raw_index: usize) -> &PerpPosition { get_helper(self.dynamic(), self.header().perp_offset(raw_index)) } - pub fn perp_iter(&self) -> impl Iterator { - (0..self.header().perp_count()).map(|i| self.perp_get_raw(i)) + pub fn all_perp_positions(&self) -> impl Iterator { + (0..self.header().perp_count()).map(|i| self.perp_position_by_raw_index(i)) } - pub fn perp_iter_active_accounts(&self) -> impl Iterator { + pub fn active_perp_positions(&self) -> impl Iterator { (0..self.header().perp_count()) - .map(|i| self.perp_get_raw(i)) + .map(|i| self.perp_position_by_raw_index(i)) .filter(|p| p.is_active()) } - pub fn perp_find_account(&self, market_index: PerpMarketIndex) -> Option<&PerpPositions> { - self.perp_iter_active_accounts() - .find(|p| p.is_active_for_market(market_index)) - } - - pub fn perp_oo_get_raw(&self, raw_index: usize) -> &PerpOpenOrders { + pub fn perp_orders_by_raw_index(&self, raw_index: usize) -> &PerpOpenOrders { get_helper(self.dynamic(), self.header().perp_oo_offset(raw_index)) } - pub fn perp_oo_iter(&self) -> impl Iterator { - (0..self.header().perp_oo_count()).map(|i| self.perp_oo_get_raw(i)) + pub fn all_perp_orders(&self) -> impl Iterator { + (0..self.header().perp_oo_count()).map(|i| self.perp_orders_by_raw_index(i)) } pub fn perp_next_order_slot(&self) -> Option { - self.perp_oo_iter() + self.all_perp_orders() .position(|&oo| oo.order_market == FREE_ORDER_SLOT) } @@ -537,7 +536,7 @@ impl< client_order_id: u64, ) -> Option<(i128, Side)> { for i in 0..self.header().perp_oo_count() { - let oo = self.perp_oo_get_raw(i); + let oo = self.perp_orders_by_raw_index(i); if oo.order_market == market_index && oo.client_order_id == client_order_id { return Some((oo.order_id, oo.order_side)); } @@ -551,7 +550,7 @@ impl< order_id: i128, ) -> Option { for i in 0..self.header().perp_oo_count() { - let oo = self.perp_oo_get_raw(i); + let oo = self.perp_orders_by_raw_index(i); if oo.order_market == market_index && oo.order_id == order_id { return Some(oo.order_side); } @@ -596,20 +595,20 @@ impl< /// Returns /// - the position /// - the raw index into the token positions list (for use with get_raw/deactivate) - pub fn token_get_mut( + pub fn token_position_mut( &mut self, token_index: TokenIndex, ) -> Result<(&mut TokenPosition, usize)> { let raw_index = self - .token_iter() + .all_token_positions() .enumerate() .find_map(|(raw_index, p)| p.is_active_for_token(token_index).then(|| raw_index)) .ok_or_else(|| error_msg!("position for token index {} not found", token_index))?; - Ok((self.token_get_mut_raw(raw_index), raw_index)) + Ok((self.token_position_mut_by_raw_index(raw_index), raw_index)) } // get mut TokenPosition at raw_index - pub fn token_get_mut_raw(&mut self, raw_index: usize) -> &mut TokenPosition { + pub fn token_position_mut_by_raw_index(&mut self, raw_index: usize) -> &mut TokenPosition { let offset = self.header().token_offset(raw_index); get_helper_mut(self.dynamic_mut(), offset) } @@ -619,13 +618,13 @@ impl< /// - the position /// - the raw index into the token positions list (for use with get_raw) /// - the active index, for use with FixedOrderAccountRetriever - pub fn token_get_mut_or_create( + pub fn ensure_token_position( &mut self, token_index: TokenIndex, ) -> Result<(&mut TokenPosition, usize, usize)> { let mut active_index = 0; let mut match_or_free = None; - for (raw_index, position) in self.token_iter().enumerate() { + for (raw_index, position) in self.all_token_positions().enumerate() { if position.is_active_for_token(token_index) { // Can't return early because of lifetimes match_or_free = Some((raw_index, active_index)); @@ -638,7 +637,7 @@ impl< } } if let Some((raw_index, bank_index)) = match_or_free { - let v = self.token_get_mut_raw(raw_index); + let v = self.token_position_mut_by_raw_index(raw_index); if !v.is_active_for_token(token_index) { *v = TokenPosition { indexed_position: I80F48::ZERO, @@ -655,101 +654,101 @@ impl< } } - pub fn token_deactivate(&mut self, raw_index: usize) { - assert!(self.token_get_mut_raw(raw_index).in_use_count == 0); - self.token_get_mut_raw(raw_index).token_index = TokenIndex::MAX; + pub fn deactivate_token_position(&mut self, raw_index: usize) { + assert!(self.token_position_mut_by_raw_index(raw_index).in_use_count == 0); + self.token_position_mut_by_raw_index(raw_index).token_index = TokenIndex::MAX; } // get mut Serum3Orders at raw_index - pub fn serum3_get_mut_raw(&mut self, raw_index: usize) -> &mut Serum3Orders { + pub fn serum3_orders_mut_by_raw_index(&mut self, raw_index: usize) -> &mut Serum3Orders { let offset = self.header().serum3_offset(raw_index); get_helper_mut(self.dynamic_mut(), offset) } - pub fn serum3_create(&mut self, market_index: Serum3MarketIndex) -> Result<&mut Serum3Orders> { - if self.serum3_find(market_index).is_some() { + pub fn create_serum3_orders( + &mut self, + market_index: Serum3MarketIndex, + ) -> Result<&mut Serum3Orders> { + if self.serum3_orders(market_index).is_some() { return err!(MangoError::Serum3OpenOrdersExistAlready); } - let raw_index_opt = self.serum3_iter().position(|p| !p.is_active()); + let raw_index_opt = self.all_serum3_orders().position(|p| !p.is_active()); if let Some(raw_index) = raw_index_opt { - *(self.serum3_get_mut_raw(raw_index)) = Serum3Orders { + *(self.serum3_orders_mut_by_raw_index(raw_index)) = Serum3Orders { market_index: market_index as Serum3MarketIndex, ..Serum3Orders::default() }; - return Ok(self.serum3_get_mut_raw(raw_index)); + return Ok(self.serum3_orders_mut_by_raw_index(raw_index)); } else { return err!(MangoError::NoFreeSerum3OpenOrdersIndex); } } - pub fn serum3_deactivate(&mut self, market_index: Serum3MarketIndex) -> Result<()> { + pub fn deactivate_serum3_orders(&mut self, market_index: Serum3MarketIndex) -> Result<()> { let raw_index = self - .serum3_iter() + .all_serum3_orders() .position(|p| p.is_active_for_market(market_index)) .ok_or_else(|| error_msg!("serum3 open orders index {} not found", market_index))?; - self.serum3_get_mut_raw(raw_index).market_index = Serum3MarketIndex::MAX; + self.serum3_orders_mut_by_raw_index(raw_index).market_index = Serum3MarketIndex::MAX; Ok(()) } - pub fn serum3_find_mut( + pub fn serum3_orders_mut( &mut self, market_index: Serum3MarketIndex, ) -> Option<&mut Serum3Orders> { let raw_index_opt = self - .serum3_iter_active() + .active_serum3_orders() .position(|p| p.is_active_for_market(market_index)); - raw_index_opt.map(|raw_index| self.serum3_get_mut_raw(raw_index)) + raw_index_opt.map(|raw_index| self.serum3_orders_mut_by_raw_index(raw_index)) } // get mut PerpPosition at raw_index - pub fn perp_get_mut_raw(&mut self, raw_index: usize) -> &mut PerpPositions { + pub fn perp_position_mut_by_raw_index(&mut self, raw_index: usize) -> &mut PerpPosition { let offset = self.header().perp_offset(raw_index); get_helper_mut(self.dynamic_mut(), offset) } - pub fn perp_oo_get_mut_raw(&mut self, raw_index: usize) -> &mut PerpOpenOrders { + pub fn perp_orders_mut_by_raw_index(&mut self, raw_index: usize) -> &mut PerpOpenOrders { let offset = self.header().perp_oo_offset(raw_index); get_helper_mut(self.dynamic_mut(), offset) } - pub fn perp_get_account_mut_or_create( + pub fn ensure_perp_position( &mut self, perp_market_index: PerpMarketIndex, - ) -> Result<(&mut PerpPositions, usize)> { + ) -> Result<(&mut PerpPosition, usize)> { let mut raw_index_opt = self - .perp_iter_active_accounts() + .active_perp_positions() .position(|p| p.is_active_for_market(perp_market_index)); if raw_index_opt.is_none() { - raw_index_opt = self.perp_iter().position(|p| !p.is_active()); + raw_index_opt = self.all_perp_positions().position(|p| !p.is_active()); if let Some(raw_index) = raw_index_opt { - *(self.perp_get_mut_raw(raw_index)) = PerpPositions { + *(self.perp_position_mut_by_raw_index(raw_index)) = PerpPosition { market_index: perp_market_index, ..Default::default() }; } } if let Some(raw_index) = raw_index_opt { - Ok((self.perp_get_mut_raw(raw_index), raw_index)) + Ok((self.perp_position_mut_by_raw_index(raw_index), raw_index)) } else { err!(MangoError::NoFreePerpPositionIndex) } } - pub fn perp_deactivate_account(&mut self, raw_index: usize) { - self.perp_get_mut_raw(raw_index).market_index = PerpMarketIndex::MAX; + pub fn deactivate_perp_position(&mut self, raw_index: usize) { + self.perp_position_mut_by_raw_index(raw_index).market_index = PerpMarketIndex::MAX; } - pub fn perp_add_order( + pub fn add_perp_order( &mut self, perp_market_index: PerpMarketIndex, side: Side, order: &LeafNode, ) -> Result<()> { - let mut perp_account = self - .perp_get_account_mut_or_create(perp_market_index) - .unwrap() - .0; + let mut perp_account = self.ensure_perp_position(perp_market_index).unwrap().0; match side { Side::Bid => { perp_account.bids_base_lots = cm!(perp_account.bids_base_lots + order.quantity); @@ -760,7 +759,7 @@ impl< }; let slot = order.owner_slot as usize; - let mut oo = self.perp_oo_get_mut_raw(slot); + let mut oo = self.perp_orders_mut_by_raw_index(slot); oo.order_market = perp_market_index; oo.order_side = side; oo.order_id = order.key; @@ -768,16 +767,13 @@ impl< Ok(()) } - pub fn perp_remove_order(&mut self, slot: usize, quantity: i64) -> Result<()> { + pub fn remove_perp_order(&mut self, slot: usize, quantity: i64) -> Result<()> { { - let oo = self.perp_oo_get_mut_raw(slot); + let oo = self.perp_orders_mut_by_raw_index(slot); require_neq!(oo.order_market, FREE_ORDER_SLOT); let order_side = oo.order_side; let perp_market_index = oo.order_market; - let perp_account = self - .perp_get_account_mut_or_create(perp_market_index) - .unwrap() - .0; + let perp_account = self.ensure_perp_position(perp_market_index).unwrap().0; // accounting match order_side { @@ -791,7 +787,7 @@ impl< } // release space - let oo = self.perp_oo_get_mut_raw(slot); + let oo = self.perp_orders_mut_by_raw_index(slot); oo.order_market = FREE_ORDER_SLOT; oo.order_side = Side::Bid; oo.order_id = 0i128; @@ -799,16 +795,13 @@ impl< Ok(()) } - pub fn perp_execute_maker( + pub fn execute_perp_maker( &mut self, perp_market_index: PerpMarketIndex, perp_market: &mut PerpMarket, fill: &FillEvent, ) -> Result<()> { - let pa = self - .perp_get_account_mut_or_create(perp_market_index) - .unwrap() - .0; + let pa = self.ensure_perp_position(perp_market_index).unwrap().0; pa.settle_funding(perp_market); let side = fill.taker_side.invert_side(); @@ -827,7 +820,7 @@ impl< pa.quote_position_native = pa.quote_position_native.checked_add(quote - fees).unwrap(); if fill.maker_out { - self.perp_remove_order(fill.maker_slot as usize, base_change.abs()) + self.remove_perp_order(fill.maker_slot as usize, base_change.abs()) } else { match side { Side::Bid => { @@ -841,16 +834,13 @@ impl< } } - pub fn perp_execute_taker( + pub fn execute_perp_taker( &mut self, perp_market_index: PerpMarketIndex, perp_market: &mut PerpMarket, fill: &FillEvent, ) -> Result<()> { - let pa = self - .perp_get_account_mut_or_create(perp_market_index) - .unwrap() - .0; + let pa = self.ensure_perp_position(perp_market_index).unwrap().0; pa.settle_funding(perp_market); let (base_change, quote_change) = fill.base_quote_change(fill.taker_side); @@ -959,12 +949,12 @@ impl< sol_memmove( &mut dynamic[new_header.perp_offset(0)], &mut dynamic[old_header.perp_offset(0)], - size_of::() * old_header.perp_count(), + size_of::() * old_header.perp_count(), ); } for i in old_header.perp_count..new_perp_count { *get_helper_mut(dynamic, new_header.perp_offset(i.into())) = - PerpPositions::default(); + PerpPosition::default(); } } diff --git a/programs/mango-v4/src/state/mango_account_components.rs b/programs/mango-v4/src/state/mango_account_components.rs index 0aade0316..5a5cf1cbe 100644 --- a/programs/mango-v4/src/state/mango_account_components.rs +++ b/programs/mango-v4/src/state/mango_account_components.rs @@ -147,7 +147,7 @@ impl Default for Serum3Orders { #[zero_copy] #[derive(AnchorSerialize, AnchorDeserialize, Derivative)] #[derivative(Debug)] -pub struct PerpPositions { +pub struct PerpPosition { pub market_index: PerpMarketIndex, #[derivative(Debug = "ignore")] pub padding: [u8; 6], @@ -181,13 +181,13 @@ pub struct PerpPositions { #[derivative(Debug = "ignore")] pub reserved: [u8; 64], } -const_assert_eq!(size_of::(), 8 + 7 * 8 + 3 * 16 + 64); -const_assert_eq!(size_of::() % 8, 0); +const_assert_eq!(size_of::(), 8 + 7 * 8 + 3 * 16 + 64); +const_assert_eq!(size_of::() % 8, 0); -unsafe impl bytemuck::Pod for PerpPositions {} -unsafe impl bytemuck::Zeroable for PerpPositions {} +unsafe impl bytemuck::Pod for PerpPosition {} +unsafe impl bytemuck::Zeroable for PerpPosition {} -impl Default for PerpPositions { +impl Default for PerpPosition { fn default() -> Self { Self { market_index: PerpMarketIndex::MAX, @@ -207,7 +207,7 @@ impl Default for PerpPositions { } } -impl PerpPositions { +impl PerpPosition { /// Add taker trade after it has been matched but before it has been process on EventQueue pub fn add_taker_trade(&mut self, side: Side, base_lots: i64, quote_lots: i64) { match side { @@ -373,10 +373,10 @@ mod tests { use fixed::types::I80F48; use rand::Rng; - use super::PerpPositions; + use super::PerpPosition; - fn create_perp_position(base_pos: i64, quote_pos: i64, entry_pos: i64) -> PerpPositions { - let mut pos = PerpPositions::default(); + fn create_perp_position(base_pos: i64, quote_pos: i64, entry_pos: i64) -> PerpPosition { + let mut pos = PerpPosition::default(); pos.base_position_lots = base_pos; pos.quote_position_native = I80F48::from(quote_pos); pos.quote_entry_native = entry_pos; diff --git a/programs/mango-v4/src/state/orderbook/book.rs b/programs/mango-v4/src/state/orderbook/book.rs index 50ae44d6e..da78ec8a0 100644 --- a/programs/mango-v4/src/state/orderbook/book.rs +++ b/programs/mango-v4/src/state/orderbook/book.rs @@ -265,7 +265,7 @@ impl<'a> Book<'a> { // Record the taker trade in the account already, even though it will only be // realized when the fill event gets executed let perp_account = mango_account - .perp_get_account_mut_or_create(market.perp_market_index)? + .ensure_perp_position(market.perp_market_index)? .0; perp_account.add_taker_trade(side, match_base_lots, match_quote_lots); @@ -373,7 +373,7 @@ impl<'a> Book<'a> { price_lots ); - mango_account.perp_add_order(market.perp_market_index, side, &new_order)?; + mango_account.add_perp_order(market.perp_market_index, side, &new_order)?; } // if there were matched taker quote apply ref fees @@ -393,7 +393,7 @@ impl<'a> Book<'a> { side_to_cancel_option: Option, ) -> Result<()> { for i in 0..mango_account.header.perp_oo_count() { - let oo = mango_account.perp_oo_get_raw(i); + let oo = mango_account.perp_orders_by_raw_index(i); if oo.order_market == FREE_ORDER_SLOT || oo.order_market != perp_market.perp_market_index { @@ -411,7 +411,7 @@ impl<'a> Book<'a> { if let Ok(leaf_node) = self.cancel_order(order_id, order_side) { mango_account - .perp_remove_order(leaf_node.owner_slot as usize, leaf_node.quantity)? + .remove_perp_order(leaf_node.owner_slot as usize, leaf_node.quantity)? }; limit -= 1; @@ -459,7 +459,7 @@ fn apply_fees( let taker_fees = taker_quote_native * market.taker_fee; let perp_account = mango_account - .perp_get_account_mut_or_create(market.perp_market_index)? + .ensure_perp_position(market.perp_market_index)? .0; perp_account.quote_position_native -= taker_fees; market.fees_accrued += taker_fees + maker_fees; diff --git a/programs/mango-v4/src/state/orderbook/mod.rs b/programs/mango-v4/src/state/orderbook/mod.rs index a5df865b8..6d144f863 100644 --- a/programs/mango-v4/src/state/orderbook/mod.rs +++ b/programs/mango-v4/src/state/orderbook/mod.rs @@ -124,7 +124,7 @@ mod tests { u8::MAX, ) .unwrap(); - account.perp_oo_get_raw(0).order_id + account.perp_orders_by_raw_index(0).order_id }; // insert bids until book side is full @@ -225,25 +225,34 @@ mod tests { ) .unwrap(); assert_eq!( - maker.perp_oo_get_mut_raw(0).order_market, + maker.perp_orders_mut_by_raw_index(0).order_market, market.perp_market_index ); - assert_eq!(maker.perp_oo_get_mut_raw(1).order_market, FREE_ORDER_SLOT); - assert_ne!(maker.perp_oo_get_mut_raw(0).order_id, 0); - assert_eq!(maker.perp_oo_get_mut_raw(0).client_order_id, 42); - assert_eq!(maker.perp_oo_get_mut_raw(0).order_side, Side::Bid); + assert_eq!( + maker.perp_orders_mut_by_raw_index(1).order_market, + FREE_ORDER_SLOT + ); + assert_ne!(maker.perp_orders_mut_by_raw_index(0).order_id, 0); + assert_eq!(maker.perp_orders_mut_by_raw_index(0).client_order_id, 42); + assert_eq!(maker.perp_orders_mut_by_raw_index(0).order_side, Side::Bid); assert!(bookside_contains_key( &book.bids, - maker.perp_oo_get_mut_raw(0).order_id + maker.perp_orders_mut_by_raw_index(0).order_id )); assert!(bookside_contains_price(&book.bids, price)); - assert_eq!(maker.perp_get_raw(0).bids_base_lots, bid_quantity); - assert_eq!(maker.perp_get_raw(0).asks_base_lots, 0); - assert_eq!(maker.perp_get_raw(0).taker_base_lots, 0); - assert_eq!(maker.perp_get_raw(0).taker_quote_lots, 0); - assert_eq!(maker.perp_get_raw(0).base_position_lots, 0); assert_eq!( - maker.perp_get_raw(0).quote_position_native.to_num::(), + maker.perp_position_by_raw_index(0).bids_base_lots, + bid_quantity + ); + assert_eq!(maker.perp_position_by_raw_index(0).asks_base_lots, 0); + assert_eq!(maker.perp_position_by_raw_index(0).taker_base_lots, 0); + assert_eq!(maker.perp_position_by_raw_index(0).taker_quote_lots, 0); + assert_eq!(maker.perp_position_by_raw_index(0).base_position_lots, 0); + assert_eq!( + maker + .perp_position_by_raw_index(0) + .quote_position_native + .to_num::(), 0 ); assert_eq!(event_queue.len(), 0); @@ -269,7 +278,8 @@ mod tests { .unwrap(); // the remainder of the maker order is still on the book // (the maker account is unchanged: it was not even passed in) - let order = bookside_leaf_by_key(&book.bids, maker.perp_oo_get_raw(0).order_id).unwrap(); + let order = + bookside_leaf_by_key(&book.bids, maker.perp_orders_by_raw_index(0).order_id).unwrap(); assert_eq!(order.price(), price); assert_eq!(order.quantity, bid_quantity - match_quantity); @@ -281,17 +291,23 @@ mod tests { ); // the taker account is updated - assert_eq!(taker.perp_oo_get_raw(0).order_market, FREE_ORDER_SLOT); - assert_eq!(taker.perp_get_raw(0).bids_base_lots, 0); - assert_eq!(taker.perp_get_raw(0).asks_base_lots, 0); - assert_eq!(taker.perp_get_raw(0).taker_base_lots, -match_quantity); assert_eq!( - taker.perp_get_raw(0).taker_quote_lots, + taker.perp_orders_by_raw_index(0).order_market, + FREE_ORDER_SLOT + ); + assert_eq!(taker.perp_position_by_raw_index(0).bids_base_lots, 0); + assert_eq!(taker.perp_position_by_raw_index(0).asks_base_lots, 0); + assert_eq!( + taker.perp_position_by_raw_index(0).taker_base_lots, + -match_quantity + ); + assert_eq!( + taker.perp_position_by_raw_index(0).taker_quote_lots, match_quantity * price ); - assert_eq!(taker.perp_get_raw(0).base_position_lots, 0); + assert_eq!(taker.perp_position_by_raw_index(0).base_position_lots, 0); assert_eq!( - taker.perp_get_raw(0).quote_position_native, + taker.perp_position_by_raw_index(0).quote_position_native, -match_quote * market.taker_fee ); @@ -311,34 +327,40 @@ mod tests { // simulate event queue processing maker - .perp_execute_maker(market.perp_market_index, &mut market, &fill) + .execute_perp_maker(market.perp_market_index, &mut market, &fill) .unwrap(); taker - .perp_execute_taker(market.perp_market_index, &mut market, &fill) + .execute_perp_taker(market.perp_market_index, &mut market, &fill) .unwrap(); assert_eq!(market.open_interest, 2 * match_quantity); - assert_eq!(maker.perp_oo_get_raw(0).order_market, 0); + assert_eq!(maker.perp_orders_by_raw_index(0).order_market, 0); assert_eq!( - maker.perp_get_raw(0).bids_base_lots, + maker.perp_position_by_raw_index(0).bids_base_lots, bid_quantity - match_quantity ); - assert_eq!(maker.perp_get_raw(0).asks_base_lots, 0); - assert_eq!(maker.perp_get_raw(0).taker_base_lots, 0); - assert_eq!(maker.perp_get_raw(0).taker_quote_lots, 0); - assert_eq!(maker.perp_get_raw(0).base_position_lots, match_quantity); + assert_eq!(maker.perp_position_by_raw_index(0).asks_base_lots, 0); + assert_eq!(maker.perp_position_by_raw_index(0).taker_base_lots, 0); + assert_eq!(maker.perp_position_by_raw_index(0).taker_quote_lots, 0); assert_eq!( - maker.perp_get_raw(0).quote_position_native, + maker.perp_position_by_raw_index(0).base_position_lots, + match_quantity + ); + assert_eq!( + maker.perp_position_by_raw_index(0).quote_position_native, -match_quote - match_quote * market.maker_fee ); - assert_eq!(taker.perp_get_raw(0).bids_base_lots, 0); - assert_eq!(taker.perp_get_raw(0).asks_base_lots, 0); - assert_eq!(taker.perp_get_raw(0).taker_base_lots, 0); - assert_eq!(taker.perp_get_raw(0).taker_quote_lots, 0); - assert_eq!(taker.perp_get_raw(0).base_position_lots, -match_quantity); + assert_eq!(taker.perp_position_by_raw_index(0).bids_base_lots, 0); + assert_eq!(taker.perp_position_by_raw_index(0).asks_base_lots, 0); + assert_eq!(taker.perp_position_by_raw_index(0).taker_base_lots, 0); + assert_eq!(taker.perp_position_by_raw_index(0).taker_quote_lots, 0); assert_eq!( - taker.perp_get_raw(0).quote_position_native, + taker.perp_position_by_raw_index(0).base_position_lots, + -match_quantity + ); + assert_eq!( + taker.perp_position_by_raw_index(0).quote_position_native, match_quote - match_quote * market.taker_fee ); } diff --git a/programs/mango-v4/tests/program_test/mango_client.rs b/programs/mango-v4/tests/program_test/mango_client.rs index 0be7ec21a..1d12ecc6d 100644 --- a/programs/mango-v4/tests/program_test/mango_client.rs +++ b/programs/mango-v4/tests/program_test/mango_client.rs @@ -181,19 +181,19 @@ async fn derive_health_check_remaining_account_metas( if let Some(affected_bank) = affected_bank { let bank: Bank = account_loader.load(&affected_bank).await.unwrap(); adjusted_account - .token_get_mut_or_create(bank.token_index) + .ensure_token_position(bank.token_index) .unwrap(); } if let Some(affected_perp_market_index) = affected_perp_market_index { adjusted_account - .perp_get_account_mut_or_create(affected_perp_market_index) + .ensure_perp_position(affected_perp_market_index) .unwrap(); } // figure out all the banks/oracles that need to be passed for the health check let mut banks = vec![]; let mut oracles = vec![]; - for position in adjusted_account.token_iter_active() { + for position in adjusted_account.active_token_positions() { let mint_info = get_mint_info_by_token_index(account_loader, account, position.token_index).await; banks.push(mint_info.first_bank()); @@ -201,10 +201,10 @@ async fn derive_health_check_remaining_account_metas( } let perp_markets = adjusted_account - .perp_iter_active_accounts() + .active_perp_positions() .map(|perp| get_perp_market_address_by_index(account.fixed.group, perp.market_index)); - let serum_oos = account.serum3_iter_active().map(|&s| s.open_orders); + let serum_oos = account.active_serum3_orders().map(|&s| s.open_orders); let to_account_meta = |pubkey| AccountMeta { pubkey, @@ -237,8 +237,8 @@ async fn derive_liquidation_remaining_account_metas( let mut banks = vec![]; let mut oracles = vec![]; let token_indexes = liqee - .token_iter_active() - .chain(liqor.token_iter_active()) + .active_token_positions() + .chain(liqor.active_token_positions()) .map(|ta| ta.token_index) .unique(); for token_index in token_indexes { @@ -255,14 +255,14 @@ async fn derive_liquidation_remaining_account_metas( } let perp_markets = liqee - .perp_iter_active_accounts() - .chain(liqee.perp_iter_active_accounts()) + .active_perp_positions() + .chain(liqee.active_perp_positions()) .map(|perp| get_perp_market_address_by_index(liqee.fixed.group, perp.market_index)) .unique(); let serum_oos = liqee - .serum3_iter_active() - .chain(liqor.serum3_iter_active()) + .active_serum3_orders() + .chain(liqor.active_serum3_orders()) .map(|&s| s.open_orders); let to_account_meta = |pubkey| AccountMeta { @@ -297,7 +297,7 @@ pub async fn account_position(solana: &SolanaCookie, account: Pubkey, bank: Pubk let account_data = get_mango_account(solana, account).await; let bank_data: Bank = solana.get_account(bank).await; let native = account_data - .token_find(bank_data.token_index) + .token_position(bank_data.token_index) .unwrap() .native(&bank_data); native.round().to_num::() @@ -306,14 +306,14 @@ pub async fn account_position(solana: &SolanaCookie, account: Pubkey, bank: Pubk pub async fn account_position_closed(solana: &SolanaCookie, account: Pubkey, bank: Pubkey) -> bool { let account_data = get_mango_account(solana, account).await; let bank_data: Bank = solana.get_account(bank).await; - account_data.token_find(bank_data.token_index).is_none() + account_data.token_position(bank_data.token_index).is_err() } pub async fn account_position_f64(solana: &SolanaCookie, account: Pubkey, bank: Pubkey) -> f64 { let account_data = get_mango_account(solana, account).await; let bank_data: Bank = solana.get_account(bank).await; let native = account_data - .token_find(bank_data.token_index) + .token_position(bank_data.token_index) .unwrap() .native(&bank_data); native.to_num::() @@ -1527,7 +1527,7 @@ impl<'keypair> ClientInstruction for Serum3PlaceOrderInstruction<'keypair> { .unwrap(); let serum_market: Serum3Market = account_loader.load(&self.serum_market).await.unwrap(); let open_orders = account - .serum3_find(serum_market.market_index) + .serum3_orders(serum_market.market_index) .unwrap() .open_orders; let quote_info = @@ -1629,7 +1629,7 @@ impl<'keypair> ClientInstruction for Serum3CancelOrderInstruction<'keypair> { .unwrap(); let serum_market: Serum3Market = account_loader.load(&self.serum_market).await.unwrap(); let open_orders = account - .serum3_find(serum_market.market_index) + .serum3_orders(serum_market.market_index) .unwrap() .open_orders; @@ -1690,7 +1690,7 @@ impl<'keypair> ClientInstruction for Serum3CancelAllOrdersInstruction<'keypair> .unwrap(); let serum_market: Serum3Market = account_loader.load(&self.serum_market).await.unwrap(); let open_orders = account - .serum3_find(serum_market.market_index) + .serum3_orders(serum_market.market_index) .unwrap() .open_orders; @@ -1751,7 +1751,7 @@ impl<'keypair> ClientInstruction for Serum3SettleFundsInstruction<'keypair> { .unwrap(); let serum_market: Serum3Market = account_loader.load(&self.serum_market).await.unwrap(); let open_orders = account - .serum3_find(serum_market.market_index) + .serum3_orders(serum_market.market_index) .unwrap() .open_orders; let quote_info = @@ -1827,7 +1827,7 @@ impl ClientInstruction for Serum3LiqForceCancelOrdersInstruction { .unwrap(); let serum_market: Serum3Market = account_loader.load(&self.serum_market).await.unwrap(); let open_orders = account - .serum3_find(serum_market.market_index) + .serum3_orders(serum_market.market_index) .unwrap() .open_orders; let quote_info = diff --git a/programs/mango-v4/tests/test_liq_tokens.rs b/programs/mango-v4/tests/test_liq_tokens.rs index 5a7ad3dda..d89a2b59c 100644 --- a/programs/mango-v4/tests/test_liq_tokens.rs +++ b/programs/mango-v4/tests/test_liq_tokens.rs @@ -563,7 +563,7 @@ async fn test_liq_tokens_with_token() -> Result<(), TransportError> { // Liqee's remaining collateral got dusted, only borrows remain // but the borrow amount is so tiny, that being_liquidated is already switched off let liqee = get_mango_account(solana, account).await; - assert_eq!(liqee.token_iter_active().count(), 1); + assert_eq!(liqee.active_token_positions().count(), 1); assert!(account_position_f64(solana, account, borrow_token1.bank).await > -1.0); assert!(!liqee.being_liquidated()); diff --git a/programs/mango-v4/tests/test_margin_trade.rs b/programs/mango-v4/tests/test_margin_trade.rs index b08810635..be485ab1a 100644 --- a/programs/mango-v4/tests/test_margin_trade.rs +++ b/programs/mango-v4/tests/test_margin_trade.rs @@ -231,7 +231,7 @@ async fn test_margin_trade() -> Result<(), BanksClientError> { ); // Check that position is fully deactivated let account_data = get_mango_account(solana, account).await; - assert_eq!(account_data.token_iter_active().count(), 0); + assert_eq!(account_data.active_token_positions().count(), 0); // // TEST: Activating a token via margin trade diff --git a/programs/mango-v4/tests/test_position_lifetime.rs b/programs/mango-v4/tests/test_position_lifetime.rs index b5fdc49a7..ca79d613e 100644 --- a/programs/mango-v4/tests/test_position_lifetime.rs +++ b/programs/mango-v4/tests/test_position_lifetime.rs @@ -130,7 +130,7 @@ async fn test_position_lifetime() -> Result<()> { // Check that positions are fully deactivated let account = get_mango_account(solana, account).await; - assert_eq!(account.token_iter_active().count(), 0); + assert_eq!(account.active_token_positions().count(), 0); // No user tokens got lost for &payer_token in payer_mint_accounts { @@ -230,7 +230,7 @@ async fn test_position_lifetime() -> Result<()> { // Check that positions are fully deactivated let account = get_mango_account(solana, account).await; - assert_eq!(account.token_iter_active().count(), 0); + assert_eq!(account.active_token_positions().count(), 0); // No user tokens got lost // TODO: -1 is a workaround for rounding down in withdraw diff --git a/programs/mango-v4/tests/test_serum.rs b/programs/mango-v4/tests/test_serum.rs index bb41f3c00..b7d9b63f9 100644 --- a/programs/mango-v4/tests/test_serum.rs +++ b/programs/mango-v4/tests/test_serum.rs @@ -130,7 +130,7 @@ async fn test_serum() -> Result<(), TransportError> { let account_data = get_mango_account(solana, account).await; assert_eq!( account_data - .serum3_iter_active() + .active_serum3_orders() .map(|v| (v.open_orders, v.market_index)) .collect::>(), [(open_orders, 0)] diff --git a/ts/client/src/accounts/mangoAccount.ts b/ts/client/src/accounts/mangoAccount.ts index c5fbac82a..c155c90e6 100644 --- a/ts/client/src/accounts/mangoAccount.ts +++ b/ts/client/src/accounts/mangoAccount.ts @@ -16,7 +16,7 @@ import { export class MangoAccount { public tokens: TokenPosition[]; public serum3: Serum3Orders[]; - public perps: PerpPositions[]; + public perps: PerpPosition[]; public name: string; static from( @@ -79,7 +79,7 @@ export class MangoAccount { this.name = utf8.decode(new Uint8Array(name)).split('\x00')[0]; this.tokens = tokens.map((dto) => TokenPosition.from(dto)); this.serum3 = serum3.map((dto) => Serum3Orders.from(dto)); - this.perps = perps.map((dto) => PerpPositions.from(dto)); + this.perps = perps.map((dto) => PerpPosition.from(dto)); } async reload(client: MangoClient, group: Group) { @@ -360,7 +360,7 @@ export class MangoAccount { return this.serum3.filter((serum3) => serum3.isActive()); } - perpActive(): PerpPositions[] { + perpActive(): PerpPosition[] { return this.perps.filter((perp) => perp.isActive()); } @@ -532,10 +532,10 @@ export class Serum3PositionDto { ) {} } -export class PerpPositions { +export class PerpPosition { static PerpMarketIndexUnset = 65535; static from(dto: PerpPositionDto) { - return new PerpPositions( + return new PerpPosition( dto.marketIndex, dto.basePositionLots.toNumber(), dto.quotePositionNative.val.toNumber(), @@ -557,7 +557,7 @@ export class PerpPositions { ) {} isActive(): boolean { - return this.marketIndex != PerpPositions.PerpMarketIndexUnset; + return this.marketIndex != PerpPosition.PerpMarketIndexUnset; } } diff --git a/ts/client/src/mango_v4.ts b/ts/client/src/mango_v4.ts index 5a65ff681..33fdfa3b0 100644 --- a/ts/client/src/mango_v4.ts +++ b/ts/client/src/mango_v4.ts @@ -3083,7 +3083,7 @@ export type MangoV4 = { "name": "perps", "type": { "vec": { - "defined": "PerpPositions" + "defined": "PerpPosition" } } }, @@ -3978,7 +3978,7 @@ export type MangoV4 = { } }, { - "name": "PerpPositions", + "name": "PerpPosition", "type": { "kind": "struct", "fields": [ @@ -8146,7 +8146,7 @@ export const IDL: MangoV4 = { "name": "perps", "type": { "vec": { - "defined": "PerpPositions" + "defined": "PerpPosition" } } }, @@ -9041,7 +9041,7 @@ export const IDL: MangoV4 = { } }, { - "name": "PerpPositions", + "name": "PerpPosition", "type": { "kind": "struct", "fields": [