From e06736660a306cf31802654f8bace3ac4fe548cc Mon Sep 17 00:00:00 2001 From: microwavedcola1 <89031858+microwavedcola1@users.noreply.github.com> Date: Sun, 7 Aug 2022 14:16:06 +0200 Subject: [PATCH] remove account size, make mango account feature position counts explicit (#148) * remove account size from program, make position counts explicit Signed-off-by: microwavedcola1 * cargo-fix Signed-off-by: microwavedcola1 --- client/src/client.rs | 7 +- .../src/instructions/account_create.rs | 11 +- .../src/instructions/account_expand.rs | 19 +- programs/mango-v4/src/lib.rs | 31 +++- programs/mango-v4/src/state/mango_account.rs | 172 ++++++++---------- .../tests/program_test/mango_client.rs | 21 ++- .../mango-v4/tests/test_bankrupt_tokens.rs | 20 +- programs/mango-v4/tests/test_basic.rs | 9 +- programs/mango-v4/tests/test_delegate.rs | 5 +- .../mango-v4/tests/test_health_compute.rs | 15 +- programs/mango-v4/tests/test_liq_tokens.rs | 20 +- programs/mango-v4/tests/test_margin_trade.rs | 10 +- programs/mango-v4/tests/test_perp.rs | 10 +- .../mango-v4/tests/test_position_lifetime.rs | 10 +- programs/mango-v4/tests/test_serum.rs | 5 +- .../tests/test_token_update_index_and_rate.rs | 10 +- ts/client/src/accounts/mangoAccount.ts | 5 - ts/client/src/client.ts | 41 ++--- ts/client/src/mango_v4.ts | 132 ++++++++++---- .../scripts/example1-user-close-account.ts | 3 +- ts/client/src/scripts/example1-user.ts | 8 + 21 files changed, 349 insertions(+), 215 deletions(-) diff --git a/client/src/client.rs b/client/src/client.rs index 15fcbeb24..8d069d2c8 100644 --- a/client/src/client.rs +++ b/client/src/client.rs @@ -15,7 +15,7 @@ use bincode::Options; use fixed::types::I80F48; use itertools::Itertools; use mango_v4::instructions::{Serum3OrderType, Serum3SelfTradeBehavior, Serum3Side}; -use mango_v4::state::{AccountSize, Bank, Group, MangoAccountValue, Serum3MarketIndex, TokenIndex}; +use mango_v4::state::{Bank, Group, MangoAccountValue, Serum3MarketIndex, TokenIndex}; use solana_client::nonblocking::rpc_client::RpcClient as RpcClientAsync; use solana_client::rpc_client::RpcClient; @@ -206,7 +206,10 @@ impl MangoClient { data: anchor_lang::InstructionData::data(&mango_v4::instruction::AccountCreate { account_num, name: mango_account_name.to_owned(), - account_size: AccountSize::Small, + token_count: 8, + serum3_count: 8, + perp_count: 8, + perp_oo_count: 8, }), }) .signer(owner) diff --git a/programs/mango-v4/src/instructions/account_create.rs b/programs/mango-v4/src/instructions/account_create.rs index 7f22ae05f..2bc122213 100644 --- a/programs/mango-v4/src/instructions/account_create.rs +++ b/programs/mango-v4/src/instructions/account_create.rs @@ -5,7 +5,7 @@ use crate::state::*; use crate::util::fill32_from_str; #[derive(Accounts)] -#[instruction(account_num: u32, account_size: AccountSize)] +#[instruction(account_num: u32, token_count: u8, serum3_count: u8, perp_count: u8, perp_oo_count: u8)] pub struct AccountCreate<'info> { pub group: AccountLoader<'info, Group>, @@ -14,7 +14,7 @@ pub struct AccountCreate<'info> { seeds = [group.key().as_ref(), b"MangoAccount".as_ref(), owner.key().as_ref(), &account_num.to_le_bytes()], bump, payer = payer, - space = MangoAccount::space(account_size), + space = MangoAccount::space(token_count, serum3_count, perp_count, perp_oo_count)?, )] pub account: AccountLoaderDynamic<'info, MangoAccount>, pub owner: Signer<'info>, @@ -28,7 +28,10 @@ pub struct AccountCreate<'info> { pub fn account_create( ctx: Context, account_num: u32, - account_size: AccountSize, + token_count: u8, + serum3_count: u8, + perp_count: u8, + perp_oo_count: u8, name: String, ) -> Result<()> { let mut account = ctx.accounts.account.load_init()?; @@ -47,7 +50,7 @@ pub fn account_create( account.fixed.set_being_liquidated(false); account.fixed.set_bankrupt(false); - account.expand_dynamic_content(account_size)?; + account.expand_dynamic_content(token_count, serum3_count, perp_count, perp_oo_count)?; Ok(()) } diff --git a/programs/mango-v4/src/instructions/account_expand.rs b/programs/mango-v4/src/instructions/account_expand.rs index 950f01835..244ddca05 100644 --- a/programs/mango-v4/src/instructions/account_expand.rs +++ b/programs/mango-v4/src/instructions/account_expand.rs @@ -20,15 +20,14 @@ pub struct AccountExpand<'info> { pub system_program: Program<'info, System>, } -pub fn account_expand(ctx: Context) -> Result<()> { - let account_size = { - let account = ctx.accounts.account.load()?; - account.size() - }; - - require_eq!(account_size, AccountSize::Small); - - let new_space = MangoAccount::space(AccountSize::Large); +pub fn account_expand( + ctx: Context, + token_count: u8, + serum3_count: u8, + perp_count: u8, + perp_oo_count: u8, +) -> Result<()> { + let new_space = MangoAccount::space(token_count, serum3_count, perp_count, perp_oo_count)?; let new_rent_minimum = Rent::get()?.minimum_balance(new_space); let realloc_account = ctx.accounts.account.as_ref(); @@ -55,7 +54,7 @@ pub fn account_expand(ctx: Context) -> Result<()> { // expand dynamic content, e.g. to grow token positions, we need to slide serum3orders further later, and so on.... let mut account = ctx.accounts.account.load_mut()?; - account.expand_dynamic_content(AccountSize::Large)?; + account.expand_dynamic_content(token_count, serum3_count, perp_count, perp_oo_count)?; Ok(()) } diff --git a/programs/mango-v4/src/lib.rs b/programs/mango-v4/src/lib.rs index c0f211db5..d92f5ff5c 100644 --- a/programs/mango-v4/src/lib.rs +++ b/programs/mango-v4/src/lib.rs @@ -19,16 +19,14 @@ pub mod serum3_cpi; pub mod state; pub mod types; -use state::{ - AccountSize, OracleConfig, OrderType, PerpMarketIndex, Serum3MarketIndex, Side, TokenIndex, -}; +use state::{OracleConfig, OrderType, PerpMarketIndex, Serum3MarketIndex, Side, TokenIndex}; declare_id!("m43thNJ58XCjL798ZSq6JGAG1BnWskhdq5or6kcnfsD"); #[program] pub mod mango_v4 { - use crate::state::{AccountSize, OracleConfig}; + use crate::state::OracleConfig; use super::*; @@ -146,14 +144,31 @@ pub mod mango_v4 { pub fn account_create( ctx: Context, account_num: u32, - account_size: AccountSize, + token_count: u8, + serum3_count: u8, + perp_count: u8, + perp_oo_count: u8, name: String, ) -> Result<()> { - instructions::account_create(ctx, account_num, account_size, name) + instructions::account_create( + ctx, + account_num, + token_count, + serum3_count, + perp_count, + perp_oo_count, + name, + ) } - pub fn account_expand(ctx: Context) -> Result<()> { - instructions::account_expand(ctx) + pub fn account_expand( + ctx: Context, + token_count: u8, + serum3_count: u8, + perp_count: u8, + perp_oo_count: u8, + ) -> Result<()> { + instructions::account_expand(ctx, token_count, serum3_count, perp_count, perp_oo_count) } pub fn account_edit( diff --git a/programs/mango-v4/src/state/mango_account.rs b/programs/mango-v4/src/state/mango_account.rs index 18b4e7d6a..669f02b15 100644 --- a/programs/mango-v4/src/state/mango_account.rs +++ b/programs/mango-v4/src/state/mango_account.rs @@ -1,13 +1,10 @@ -use std::fmt; - use std::mem::size_of; use anchor_lang::prelude::*; use arrayref::array_ref; use fixed::types::I80F48; -use num_enum::IntoPrimitive; -use num_enum::TryFromPrimitive; + use solana_program::program_memory::sol_memmove; use static_assertions::const_assert_eq; @@ -33,42 +30,6 @@ const BORSH_VEC_PADDING_BYTES: usize = 4; const BORSH_VEC_SIZE_BYTES: usize = 4; const DEFAULT_MANGO_ACCOUNT_VERSION: u8 = 1; -#[derive( - Debug, - Eq, - PartialEq, - Clone, - Copy, - TryFromPrimitive, - IntoPrimitive, - AnchorSerialize, - AnchorDeserialize, -)] -#[repr(u8)] - -pub enum AccountSize { - Small = 0, - Large = 1, -} - -impl fmt::Display for AccountSize { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - AccountSize::Small => write!(f, "Small"), - AccountSize::Large => write!(f, "Large"), - } - } -} - -impl AccountSize { - pub fn space(&self) -> (u8, u8, u8, u8) { - match self { - AccountSize::Small => (8, 2, 2, 2), - AccountSize::Large => (16, 8, 8, 8), - } - } -} - // Mango Account // This struct definition is only for clients e.g. typescript, so that they can easily use out of the box // deserialization and not have to do custom deserialization @@ -157,11 +118,19 @@ impl Default for MangoAccount { } impl MangoAccount { - pub fn space(account_size: AccountSize) -> usize { - let (token_count, serum3_count, perp_count, perp_oo_count) = account_size.space(); + pub fn space( + token_count: u8, + serum3_count: u8, + perp_count: u8, + perp_oo_count: u8, + ) -> Result { + require_gte!(16, token_count); + require_gte!(8, serum3_count); + require_gte!(8, perp_count); + require_gte!(64, perp_oo_count); - 8 + size_of::() - + Self::dynamic_size(token_count, serum3_count, perp_count, perp_oo_count) + Ok(8 + size_of::() + + Self::dynamic_size(token_count, serum3_count, perp_count, perp_oo_count)) } pub fn dynamic_token_vec_offset() -> usize { @@ -201,7 +170,7 @@ impl MangoAccount { #[test] fn test_dynamic_offsets() { let mut account = MangoAccount::default(); - account.tokens.resize(16, TokenPosition::default()); + account.tokens.resize(8, TokenPosition::default()); account.serum3.resize(8, Serum3Orders::default()); account.perps.resize(8, PerpPositions::default()); account @@ -209,7 +178,7 @@ fn test_dynamic_offsets() { .resize(8, PerpOpenOrders::default()); assert_eq!( 8 + AnchorSerialize::try_to_vec(&account).unwrap().len(), - MangoAccount::space(AccountSize::Large) + MangoAccount::space(8, 8, 8, 8).unwrap() ); } @@ -563,13 +532,6 @@ impl< dynamic: self.dynamic(), } } - - pub fn size(&self) -> AccountSize { - if self.header().perp_count() > 4 { - return AccountSize::Large; - } - AccountSize::Small - } } impl< @@ -914,14 +876,17 @@ impl< dst.copy_from_slice(&BorshVecLength::from(count).to_le_bytes()); } - pub fn expand_dynamic_content(&mut self, account_size: AccountSize) -> Result<()> { - let (new_token_count, new_serum3_count, new_perp_count, new_perp_oo_count) = - account_size.space(); - - require_gt!(new_token_count, self.header().token_count); - require_gt!(new_serum3_count, self.header().serum3_count); - require_gt!(new_perp_count, self.header().perp_count); - require_gt!(new_perp_oo_count, self.header().perp_oo_count); + pub fn expand_dynamic_content( + &mut self, + new_token_count: u8, + new_serum3_count: u8, + new_perp_count: u8, + new_perp_oo_count: u8, + ) -> Result<()> { + require_gte!(new_token_count, self.header().token_count); + require_gte!(new_serum3_count, self.header().serum3_count); + require_gte!(new_perp_count, self.header().perp_count); + require_gte!(new_perp_oo_count, self.header().perp_oo_count); // create a temp copy to compute new starting offsets let new_header = MangoAccountDynamicHeader { @@ -936,52 +901,63 @@ impl< // expand dynamic components by first moving existing positions, and then setting new ones to defaults // perp oo - unsafe { - sol_memmove( - &mut dynamic[new_header.perp_oo_offset(0)], - &mut dynamic[old_header.perp_oo_offset(0)], - size_of::() * old_header.perp_oo_count(), - ); - } - for i in old_header.perp_oo_count..new_perp_oo_count { - *get_helper_mut(dynamic, new_header.perp_oo_offset(i.into())) = - PerpOpenOrders::default(); + if new_header.perp_oo_count() > old_header.perp_oo_count() { + unsafe { + sol_memmove( + &mut dynamic[new_header.perp_oo_offset(0)], + &mut dynamic[old_header.perp_oo_offset(0)], + size_of::() * old_header.perp_oo_count(), + ); + } + for i in old_header.perp_oo_count..new_perp_oo_count { + *get_helper_mut(dynamic, new_header.perp_oo_offset(i.into())) = + PerpOpenOrders::default(); + } } // perp positions - unsafe { - sol_memmove( - &mut dynamic[new_header.perp_offset(0)], - &mut dynamic[old_header.perp_offset(0)], - 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(); + if new_header.perp_count() > old_header.perp_count() { + unsafe { + sol_memmove( + &mut dynamic[new_header.perp_offset(0)], + &mut dynamic[old_header.perp_offset(0)], + 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(); + } } // serum3 positions - unsafe { - sol_memmove( - &mut dynamic[new_header.serum3_offset(0)], - &mut dynamic[old_header.serum3_offset(0)], - size_of::() * old_header.serum3_count(), - ); - } - for i in old_header.serum3_count..new_serum3_count { - *get_helper_mut(dynamic, new_header.serum3_offset(i.into())) = Serum3Orders::default(); + if new_header.serum3_count() > old_header.serum3_count() { + unsafe { + sol_memmove( + &mut dynamic[new_header.serum3_offset(0)], + &mut dynamic[old_header.serum3_offset(0)], + size_of::() * old_header.serum3_count(), + ); + } + for i in old_header.serum3_count..new_serum3_count { + *get_helper_mut(dynamic, new_header.serum3_offset(i.into())) = + Serum3Orders::default(); + } } // token positions - unsafe { - sol_memmove( - &mut dynamic[new_header.token_offset(0)], - &mut dynamic[old_header.token_offset(0)], - size_of::() * old_header.token_count(), - ); - } - for i in old_header.token_count..new_token_count { - *get_helper_mut(dynamic, new_header.token_offset(i.into())) = TokenPosition::default(); + if new_header.token_count() > old_header.token_count() { + unsafe { + sol_memmove( + &mut dynamic[new_header.token_offset(0)], + &mut dynamic[old_header.token_offset(0)], + size_of::() * old_header.token_count(), + ); + } + for i in old_header.token_count..new_token_count { + *get_helper_mut(dynamic, new_header.token_offset(i.into())) = + TokenPosition::default(); + } } // update header diff --git a/programs/mango-v4/tests/program_test/mango_client.rs b/programs/mango-v4/tests/program_test/mango_client.rs index 54761b7f6..367d470b1 100644 --- a/programs/mango-v4/tests/program_test/mango_client.rs +++ b/programs/mango-v4/tests/program_test/mango_client.rs @@ -1083,7 +1083,10 @@ impl<'keypair> ClientInstruction for GroupCloseInstruction<'keypair> { pub struct AccountCreateInstruction<'keypair> { pub account_num: u32, - pub account_size: AccountSize, + pub token_count: u8, + pub serum3_count: u8, + pub perp_count: u8, + pub perp_oo_count: u8, pub group: Pubkey, pub owner: &'keypair Keypair, pub payer: &'keypair Keypair, @@ -1099,7 +1102,10 @@ impl<'keypair> ClientInstruction for AccountCreateInstruction<'keypair> { let program_id = mango_v4::id(); let instruction = mango_v4::instruction::AccountCreate { account_num: self.account_num, - account_size: self.account_size, + token_count: self.token_count, + serum3_count: self.serum3_count, + perp_count: self.perp_count, + perp_oo_count: self.perp_oo_count, name: "my_mango_account".to_string(), }; @@ -1136,6 +1142,10 @@ pub struct AccountExpandInstruction<'keypair> { pub group: Pubkey, pub owner: &'keypair Keypair, pub payer: &'keypair Keypair, + pub token_count: u8, + pub serum3_count: u8, + pub perp_count: u8, + pub perp_oo_count: u8, } #[async_trait::async_trait(?Send)] impl<'keypair> ClientInstruction for AccountExpandInstruction<'keypair> { @@ -1146,7 +1156,12 @@ impl<'keypair> ClientInstruction for AccountExpandInstruction<'keypair> { _account_loader: impl ClientAccountLoader + 'async_trait, ) -> (Self::Accounts, instruction::Instruction) { let program_id = mango_v4::id(); - let instruction = mango_v4::instruction::AccountExpand {}; + let instruction = mango_v4::instruction::AccountExpand { + token_count: self.token_count, + serum3_count: self.serum3_count, + perp_count: self.perp_count, + perp_oo_count: self.perp_oo_count, + }; let account = Pubkey::find_program_address( &[ diff --git a/programs/mango-v4/tests/test_bankrupt_tokens.rs b/programs/mango-v4/tests/test_bankrupt_tokens.rs index e347629cb..6250eaaca 100644 --- a/programs/mango-v4/tests/test_bankrupt_tokens.rs +++ b/programs/mango-v4/tests/test_bankrupt_tokens.rs @@ -44,7 +44,10 @@ async fn test_bankrupt_tokens_socialize_loss() -> Result<(), TransportError> { solana, AccountCreateInstruction { account_num: 2, - account_size: AccountSize::Large, + token_count: 16, + serum3_count: 8, + perp_count: 8, + perp_oo_count: 8, group, owner, payer, @@ -90,7 +93,10 @@ async fn test_bankrupt_tokens_socialize_loss() -> Result<(), TransportError> { solana, AccountCreateInstruction { account_num: 0, - account_size: AccountSize::Large, + token_count: 16, + serum3_count: 8, + perp_count: 8, + perp_oo_count: 8, group, owner, payer, @@ -353,7 +359,10 @@ async fn test_bankrupt_tokens_insurance_fund() -> Result<(), TransportError> { solana, AccountCreateInstruction { account_num: 2, - account_size: AccountSize::Large, + token_count: 16, + serum3_count: 8, + perp_count: 8, + perp_oo_count: 8, group, owner, payer, @@ -399,7 +408,10 @@ async fn test_bankrupt_tokens_insurance_fund() -> Result<(), TransportError> { solana, AccountCreateInstruction { account_num: 0, - account_size: AccountSize::Large, + token_count: 16, + serum3_count: 8, + perp_count: 8, + perp_oo_count: 8, group, owner, payer, diff --git a/programs/mango-v4/tests/test_basic.rs b/programs/mango-v4/tests/test_basic.rs index c6b024888..e6cb9c1de 100644 --- a/programs/mango-v4/tests/test_basic.rs +++ b/programs/mango-v4/tests/test_basic.rs @@ -41,7 +41,10 @@ async fn test_basic() -> Result<(), TransportError> { solana, AccountCreateInstruction { account_num: 0, - account_size: AccountSize::Small, + token_count: 8, + serum3_count: 0, + perp_count: 0, + perp_oo_count: 0, group, owner, payer, @@ -55,6 +58,10 @@ async fn test_basic() -> Result<(), TransportError> { solana, AccountExpandInstruction { account_num: 0, + token_count: 16, + serum3_count: 8, + perp_count: 8, + perp_oo_count: 8, group, owner, payer, diff --git a/programs/mango-v4/tests/test_delegate.rs b/programs/mango-v4/tests/test_delegate.rs index 115bcc260..18e669b83 100644 --- a/programs/mango-v4/tests/test_delegate.rs +++ b/programs/mango-v4/tests/test_delegate.rs @@ -37,7 +37,10 @@ async fn test_delegate() -> Result<(), TransportError> { solana, AccountCreateInstruction { account_num: 0, - account_size: AccountSize::Large, + token_count: 16, + serum3_count: 8, + perp_count: 8, + perp_oo_count: 8, group, owner, payer, diff --git a/programs/mango-v4/tests/test_health_compute.rs b/programs/mango-v4/tests/test_health_compute.rs index bd22f6131..cf338cabc 100644 --- a/programs/mango-v4/tests/test_health_compute.rs +++ b/programs/mango-v4/tests/test_health_compute.rs @@ -37,7 +37,10 @@ async fn test_health_compute_tokens() -> Result<(), TransportError> { solana, AccountCreateInstruction { account_num: 0, - account_size: AccountSize::Large, + token_count: 16, + serum3_count: 8, + perp_count: 8, + perp_oo_count: 8, group, owner, payer, @@ -102,7 +105,10 @@ async fn test_health_compute_serum() -> Result<(), TransportError> { solana, AccountCreateInstruction { account_num: 0, - account_size: AccountSize::Large, + token_count: 16, + serum3_count: 8, + perp_count: 8, + perp_oo_count: 8, group, owner, payer, @@ -214,7 +220,10 @@ async fn test_health_compute_perp() -> Result<(), TransportError> { solana, AccountCreateInstruction { account_num: 0, - account_size: AccountSize::Large, + token_count: 16, + serum3_count: 8, + perp_count: 8, + perp_oo_count: 8, group, owner, payer, diff --git a/programs/mango-v4/tests/test_liq_tokens.rs b/programs/mango-v4/tests/test_liq_tokens.rs index 69a6d1da5..0c2d845a7 100644 --- a/programs/mango-v4/tests/test_liq_tokens.rs +++ b/programs/mango-v4/tests/test_liq_tokens.rs @@ -42,7 +42,10 @@ async fn test_liq_tokens_force_cancel() -> Result<(), TransportError> { solana, AccountCreateInstruction { account_num: 2, - account_size: AccountSize::Large, + token_count: 16, + serum3_count: 8, + perp_count: 8, + perp_oo_count: 8, group, owner, payer, @@ -98,7 +101,10 @@ async fn test_liq_tokens_force_cancel() -> Result<(), TransportError> { solana, AccountCreateInstruction { account_num: 0, - account_size: AccountSize::Large, + token_count: 16, + serum3_count: 8, + perp_count: 8, + perp_oo_count: 8, group, owner, payer, @@ -253,7 +259,10 @@ async fn test_liq_tokens_with_token() -> Result<(), TransportError> { solana, AccountCreateInstruction { account_num: 2, - account_size: AccountSize::Large, + token_count: 16, + serum3_count: 8, + perp_count: 8, + perp_oo_count: 8, group, owner, payer, @@ -284,7 +293,10 @@ async fn test_liq_tokens_with_token() -> Result<(), TransportError> { solana, AccountCreateInstruction { account_num: 0, - account_size: AccountSize::Large, + token_count: 16, + serum3_count: 8, + perp_count: 8, + perp_oo_count: 8, group, owner, payer, diff --git a/programs/mango-v4/tests/test_margin_trade.rs b/programs/mango-v4/tests/test_margin_trade.rs index 57254b720..a6e3c1c85 100644 --- a/programs/mango-v4/tests/test_margin_trade.rs +++ b/programs/mango-v4/tests/test_margin_trade.rs @@ -51,7 +51,10 @@ async fn test_margin_trade() -> Result<(), BanksClientError> { solana, AccountCreateInstruction { account_num: 1, - account_size: AccountSize::Large, + token_count: 16, + serum3_count: 8, + perp_count: 8, + perp_oo_count: 8, group, owner, payer, @@ -94,7 +97,10 @@ async fn test_margin_trade() -> Result<(), BanksClientError> { solana, AccountCreateInstruction { account_num: 0, - account_size: AccountSize::Large, + token_count: 16, + serum3_count: 8, + perp_count: 8, + perp_oo_count: 8, group, owner, payer, diff --git a/programs/mango-v4/tests/test_perp.rs b/programs/mango-v4/tests/test_perp.rs index d96d58440..64a8c5aef 100644 --- a/programs/mango-v4/tests/test_perp.rs +++ b/programs/mango-v4/tests/test_perp.rs @@ -36,7 +36,10 @@ async fn test_perp() -> Result<(), TransportError> { solana, AccountCreateInstruction { account_num: 0, - account_size: AccountSize::Large, + token_count: 16, + serum3_count: 8, + perp_count: 8, + perp_oo_count: 8, group, owner, payer, @@ -50,7 +53,10 @@ async fn test_perp() -> Result<(), TransportError> { solana, AccountCreateInstruction { account_num: 1, - account_size: AccountSize::Large, + token_count: 16, + serum3_count: 8, + perp_count: 8, + perp_oo_count: 8, group, owner, payer, diff --git a/programs/mango-v4/tests/test_position_lifetime.rs b/programs/mango-v4/tests/test_position_lifetime.rs index 4b341ec49..a8a47bcf6 100644 --- a/programs/mango-v4/tests/test_position_lifetime.rs +++ b/programs/mango-v4/tests/test_position_lifetime.rs @@ -38,7 +38,10 @@ async fn test_position_lifetime() -> Result<()> { solana, AccountCreateInstruction { account_num: 0, - account_size: AccountSize::Large, + token_count: 16, + serum3_count: 8, + perp_count: 8, + perp_oo_count: 8, group, owner, payer, @@ -52,7 +55,10 @@ async fn test_position_lifetime() -> Result<()> { solana, AccountCreateInstruction { account_num: 1, - account_size: AccountSize::Large, + token_count: 16, + serum3_count: 8, + perp_count: 8, + perp_oo_count: 8, group, owner, payer, diff --git a/programs/mango-v4/tests/test_serum.rs b/programs/mango-v4/tests/test_serum.rs index 0d8f914e4..c460b5807 100644 --- a/programs/mango-v4/tests/test_serum.rs +++ b/programs/mango-v4/tests/test_serum.rs @@ -40,7 +40,10 @@ async fn test_serum() -> Result<(), TransportError> { solana, AccountCreateInstruction { account_num: 0, - account_size: AccountSize::Large, + token_count: 16, + serum3_count: 8, + perp_count: 8, + perp_oo_count: 8, group, owner, payer, diff --git a/programs/mango-v4/tests/test_token_update_index_and_rate.rs b/programs/mango-v4/tests/test_token_update_index_and_rate.rs index f77dc4d48..dda8c7464 100644 --- a/programs/mango-v4/tests/test_token_update_index_and_rate.rs +++ b/programs/mango-v4/tests/test_token_update_index_and_rate.rs @@ -36,7 +36,10 @@ async fn test_token_update_index_and_rate() -> Result<(), TransportError> { solana, AccountCreateInstruction { account_num: 0, - account_size: AccountSize::Large, + token_count: 16, + serum3_count: 8, + perp_count: 8, + perp_oo_count: 8, group, owner, payer, @@ -64,7 +67,10 @@ async fn test_token_update_index_and_rate() -> Result<(), TransportError> { solana, AccountCreateInstruction { account_num: 1, - account_size: AccountSize::Large, + token_count: 16, + serum3_count: 8, + perp_count: 8, + perp_oo_count: 8, group, owner, payer, diff --git a/ts/client/src/accounts/mangoAccount.ts b/ts/client/src/accounts/mangoAccount.ts index 7fc0461e4..987666c3d 100644 --- a/ts/client/src/accounts/mangoAccount.ts +++ b/ts/client/src/accounts/mangoAccount.ts @@ -594,8 +594,3 @@ export class EquityDto { tokens: { tokenIndex: number; value: I80F48Dto }[]; perps: { perpMarketIndex: number; value: I80F48Dto }[]; } - -export class AccountSize { - static small = { small: {} }; - static large = { large: {} }; -} diff --git a/ts/client/src/client.ts b/ts/client/src/client.ts index d8fe89551..3afaf1000 100644 --- a/ts/client/src/client.ts +++ b/ts/client/src/client.ts @@ -30,11 +30,7 @@ import bs58 from 'bs58'; import { Bank, MintInfo } from './accounts/bank'; import { Group } from './accounts/group'; import { I80F48 } from './accounts/I80F48'; -import { - AccountSize, - MangoAccount, - MangoAccountData, -} from './accounts/mangoAccount'; +import { MangoAccount, MangoAccountData } from './accounts/mangoAccount'; import { StubOracle } from './accounts/oracle'; import { OrderType, PerpMarket, Side } from './accounts/perp'; import { @@ -467,12 +463,11 @@ export class MangoClient { group: Group, ownerPk: PublicKey, accountNumber?: number, - accountSize?: AccountSize, name?: string, ): Promise { let mangoAccounts = await this.getMangoAccountsForOwner(group, ownerPk); if (mangoAccounts.length === 0) { - await this.createMangoAccount(group, accountNumber, accountSize, name); + await this.createMangoAccount(group, accountNumber, name); mangoAccounts = await this.getMangoAccountsForOwner(group, ownerPk); } return mangoAccounts[0]; @@ -481,15 +476,10 @@ export class MangoClient { public async createMangoAccount( group: Group, accountNumber?: number, - accountSize?: AccountSize, name?: string, ): Promise { return await this.program.methods - .accountCreate( - accountNumber ?? 0, - accountSize ?? AccountSize.small, - name ?? '', - ) + .accountCreate(accountNumber ?? 0, 8, 0, 0, 0, name ?? '') .accounts({ group: group.publicKey, owner: (this.program.provider as AnchorProvider).wallet.publicKey, @@ -501,9 +491,13 @@ export class MangoClient { public async expandMangoAccount( group: Group, account: MangoAccount, + tokenCount: number, + serum3Count: number, + perpCount: number, + perpOoCount: number, ): Promise { return await this.program.methods - .accountExpand() + .accountExpand(tokenCount, serum3Count, perpCount, perpOoCount) .accounts({ group: group.publicKey, account: account.publicKey, @@ -1560,15 +1554,17 @@ export class MangoClient { } async updateIndexAndRate(group: Group, tokenName: string) { - let bank = group.banksMap.get(tokenName)!; let mintInfo = group.mintInfosMap.get(bank.tokenIndex)!; - - await this.program.methods.tokenUpdateIndexAndRate().accounts({ - 'group': group.publicKey, - 'mintInfo': mintInfo.publicKey, - 'oracle': mintInfo.oracle, - 'instructions': SYSVAR_INSTRUCTIONS_PUBKEY}) + + await this.program.methods + .tokenUpdateIndexAndRate() + .accounts({ + group: group.publicKey, + mintInfo: mintInfo.publicKey, + oracle: mintInfo.oracle, + instructions: SYSVAR_INSTRUCTIONS_PUBKEY, + }) .remainingAccounts([ { pubkey: bank.publicKey, @@ -1576,9 +1572,8 @@ export class MangoClient { isSigner: false, } as AccountMeta, ]) - .rpc() + .rpc(); } - /// liquidations diff --git a/ts/client/src/mango_v4.ts b/ts/client/src/mango_v4.ts index 4ac969640..1e41ac8d2 100644 --- a/ts/client/src/mango_v4.ts +++ b/ts/client/src/mango_v4.ts @@ -820,10 +820,20 @@ export type MangoV4 = { "type": "u32" }, { - "name": "accountSize", - "type": { - "defined": "AccountSize" - } + "name": "tokenCount", + "type": "u8" + }, + { + "name": "serum3Count", + "type": "u8" + }, + { + "name": "perpCount", + "type": "u8" + }, + { + "name": "perpOoCount", + "type": "u8" }, { "name": "name", @@ -860,7 +870,24 @@ export type MangoV4 = { "isSigner": false } ], - "args": [] + "args": [ + { + "name": "tokenCount", + "type": "u8" + }, + { + "name": "serum3Count", + "type": "u8" + }, + { + "name": "perpCount", + "type": "u8" + }, + { + "name": "perpOoCount", + "type": "u8" + } + ] }, { "name": "accountEdit", @@ -3980,6 +4007,21 @@ export type MangoV4 = { "defined": "I80F48" } }, + { + "name": "baseEntryLots", + "docs": [ + "Tracks what the position is to calculate average entry & break even price" + ], + "type": "i64" + }, + { + "name": "quoteEntryNative", + "type": "i64" + }, + { + "name": "quoteExitNative", + "type": "i64" + }, { "name": "longSettledFunding", "docs": [ @@ -4287,20 +4329,6 @@ export type MangoV4 = { ] } }, - { - "name": "AccountSize", - "type": { - "kind": "enum", - "variants": [ - { - "name": "Small" - }, - { - "name": "Large" - } - ] - } - }, { "name": "OracleType", "type": { @@ -5833,10 +5861,20 @@ export const IDL: MangoV4 = { "type": "u32" }, { - "name": "accountSize", - "type": { - "defined": "AccountSize" - } + "name": "tokenCount", + "type": "u8" + }, + { + "name": "serum3Count", + "type": "u8" + }, + { + "name": "perpCount", + "type": "u8" + }, + { + "name": "perpOoCount", + "type": "u8" }, { "name": "name", @@ -5873,7 +5911,24 @@ export const IDL: MangoV4 = { "isSigner": false } ], - "args": [] + "args": [ + { + "name": "tokenCount", + "type": "u8" + }, + { + "name": "serum3Count", + "type": "u8" + }, + { + "name": "perpCount", + "type": "u8" + }, + { + "name": "perpOoCount", + "type": "u8" + } + ] }, { "name": "accountEdit", @@ -8993,6 +9048,21 @@ export const IDL: MangoV4 = { "defined": "I80F48" } }, + { + "name": "baseEntryLots", + "docs": [ + "Tracks what the position is to calculate average entry & break even price" + ], + "type": "i64" + }, + { + "name": "quoteEntryNative", + "type": "i64" + }, + { + "name": "quoteExitNative", + "type": "i64" + }, { "name": "longSettledFunding", "docs": [ @@ -9300,20 +9370,6 @@ export const IDL: MangoV4 = { ] } }, - { - "name": "AccountSize", - "type": { - "kind": "enum", - "variants": [ - { - "name": "Small" - }, - { - "name": "Large" - } - ] - } - }, { "name": "OracleType", "type": { diff --git a/ts/client/src/scripts/example1-user-close-account.ts b/ts/client/src/scripts/example1-user-close-account.ts index 6486cdc44..ea875c271 100644 --- a/ts/client/src/scripts/example1-user-close-account.ts +++ b/ts/client/src/scripts/example1-user-close-account.ts @@ -107,9 +107,8 @@ async function main() { group, mangoAccount, group.findBank(token.tokenIndex)!.name, - nativeFlooredNumber, + nativeFlooredNumber - 1 /* see comment in token_withdraw in program */, false, - user, ); } diff --git a/ts/client/src/scripts/example1-user.ts b/ts/client/src/scripts/example1-user.ts index 887093f40..1cfdfd759 100644 --- a/ts/client/src/scripts/example1-user.ts +++ b/ts/client/src/scripts/example1-user.ts @@ -92,6 +92,14 @@ async function main() { console.log(mangoAccount.toString()); } + if (true) { + console.log( + `...expanding mango account to have serum3 and perp position slots`, + ); + await client.expandMangoAccount(group, mangoAccount, 16, 8, 8, 8); + await mangoAccount.reload(client, group); + } + if (true) { // deposit and withdraw