diff --git a/Cargo.lock b/Cargo.lock index 6486d9df8..53a06919d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3156,6 +3156,7 @@ dependencies = [ "async-trait", "base64 0.13.0", "bincode", + "borsh", "bytemuck", "checked_math", "env_logger 0.9.0", diff --git a/programs/mango-v4/Cargo.toml b/programs/mango-v4/Cargo.toml index 0a58ebc99..a6cfe6349 100644 --- a/programs/mango-v4/Cargo.toml +++ b/programs/mango-v4/Cargo.toml @@ -25,6 +25,7 @@ anchor-lang = { path = "../../anchor/lang" } anchor-spl = { path = "../../anchor/spl" } arrayref = "0.3.6" bincode = "1.3.3" +borsh = { version = "0.9.3", features = ["const-generics"] } bytemuck = "^1.7.2" checked_math = { path = "../../lib/checked_math" } fixed = { version = "=1.11.0", features = ["serde", "borsh"] } # todo: higher versions don't work diff --git a/programs/mango-v4/src/error.rs b/programs/mango-v4/src/error.rs index 7ef6d279d..53b411399 100644 --- a/programs/mango-v4/src/error.rs +++ b/programs/mango-v4/src/error.rs @@ -7,6 +7,8 @@ use core::fmt::Display; pub enum MangoError { #[msg("")] SomeError, + #[msg("")] + NotImplementedError, #[msg("checked math error")] MathError, #[msg("")] diff --git a/programs/mango-v4/src/instructions/perp_create_market.rs b/programs/mango-v4/src/instructions/perp_create_market.rs index ea01edd4a..80d5c52c5 100644 --- a/programs/mango-v4/src/instructions/perp_create_market.rs +++ b/programs/mango-v4/src/instructions/perp_create_market.rs @@ -96,8 +96,9 @@ pub fn perp_create_market( base_token_decimals, perp_market_index, base_token_index: base_token_index_opt.ok_or(TokenIndex::MAX).unwrap(), - padding: Default::default(), - reserved: Default::default(), + padding1: Default::default(), + padding2: Default::default(), + reserved: [0; 128], }; let mut bids = ctx.accounts.bids.load_init()?; diff --git a/programs/mango-v4/src/instructions/serum3_register_market.rs b/programs/mango-v4/src/instructions/serum3_register_market.rs index a8db144ee..aa0fc0e75 100644 --- a/programs/mango-v4/src/instructions/serum3_register_market.rs +++ b/programs/mango-v4/src/instructions/serum3_register_market.rs @@ -75,8 +75,9 @@ pub fn serum3_register_market( base_token_index: base_bank.token_index, quote_token_index: quote_bank.token_index, bump: *ctx.bumps.get("serum_market").ok_or(MangoError::SomeError)?, - padding: Default::default(), - reserved: Default::default(), + padding1: Default::default(), + padding2: Default::default(), + reserved: [0; 128], }; Ok(()) diff --git a/programs/mango-v4/src/instructions/token_register.rs b/programs/mango-v4/src/instructions/token_register.rs index aa152efb7..51db22576 100644 --- a/programs/mango-v4/src/instructions/token_register.rs +++ b/programs/mango-v4/src/instructions/token_register.rs @@ -154,7 +154,8 @@ pub fn token_register( bump: *ctx.bumps.get("bank").ok_or(MangoError::SomeError)?, mint_decimals: ctx.accounts.mint.decimals, bank_num: 0, - reserved: Default::default(), + padding: Default::default(), + reserved: [0; 256], }; // TODO: ALTs are unavailable @@ -174,8 +175,9 @@ pub fn token_register( token_index, address_lookup_table_bank_index: alt_previous_size as u8, address_lookup_table_oracle_index: alt_previous_size as u8 + 1, - padding: Default::default(), - reserved: Default::default(), + padding1: Default::default(), + padding2: Default::default(), + reserved: [0; 256], }; mint_info.banks[0] = ctx.accounts.bank.key(); diff --git a/programs/mango-v4/src/state/bank.rs b/programs/mango-v4/src/state/bank.rs index 6033a7321..177df3bb4 100644 --- a/programs/mango-v4/src/state/bank.rs +++ b/programs/mango-v4/src/state/bank.rs @@ -91,15 +91,15 @@ pub struct Bank { pub mint_decimals: u8, - pub reserved: [u8; 4], + pub padding: [u8; 4], pub bank_num: u64, - // TODO: add space for an oracle which services interest rate for the bank's mint - // interest rate tied to oracle might help reduce spreads between deposits and borrows + + pub reserved: [u8; 256], } const_assert_eq!( size_of::(), - 16 + 32 * 4 + 8 * 2 + 16 * 23 + 2 * 8 + 2 + 1 + 1 + 4 + 8 + 16 + 32 * 4 + 8 * 2 + 16 * 23 + 2 * 8 + 2 + 1 + 1 + 4 + 8 + 256 ); const_assert_eq!(size_of::() % 8, 0); @@ -190,7 +190,8 @@ impl Bank { token_index: existing_bank.token_index, bump: existing_bank.bump, mint_decimals: existing_bank.mint_decimals, - reserved: Default::default(), + padding: Default::default(), + reserved: [0; 256], bank_num, } } @@ -591,7 +592,8 @@ mod tests { indexed_position: I80F48::ZERO, token_index: 0, in_use_count: if is_in_use { 1 } else { 0 }, - reserved: Default::default(), + padding: Default::default(), + reserved: [0; 40], }; account.indexed_position = indexed(I80F48::from_num(start), &bank); diff --git a/programs/mango-v4/src/state/group.rs b/programs/mango-v4/src/state/group.rs index e19d6b754..5fa039de9 100644 --- a/programs/mango-v4/src/state/group.rs +++ b/programs/mango-v4/src/state/group.rs @@ -32,9 +32,10 @@ pub struct Group { pub version: u8, pub padding2: [u8; 5], - pub reserved: [u8; 8], + + pub reserved: [u8; 256], } -const_assert_eq!(size_of::(), 32 * 5 + 4 + 4 + 1 * 2 + 6 + 8); +const_assert_eq!(size_of::(), 32 * 5 + 4 + 4 + 1 * 2 + 6 + 256); const_assert_eq!(size_of::() % 8, 0); impl Group { diff --git a/programs/mango-v4/src/state/mango_account.rs b/programs/mango-v4/src/state/mango_account.rs index 4cba2e328..a87ee54fe 100644 --- a/programs/mango-v4/src/state/mango_account.rs +++ b/programs/mango-v4/src/state/mango_account.rs @@ -31,6 +31,7 @@ use checked_math as cm; type BorshVecLength = u32; const BORSH_VEC_PADDING_BYTES: usize = 4; const BORSH_VEC_SIZE_BYTES: usize = 4; +const DEFAULT_MANGO_ACCOUNT_VERSION: u8 = 1; #[derive( Debug, @@ -96,8 +97,7 @@ pub struct MangoAccount { pub account_num: u8, pub bump: u8, - // pub info: [u8; INFO_LEN], // TODO: Info could be in a separate PDA? - pub reserved: [u8; 4], + pub padding: [u8; 4], // Cumulative (deposits - withdraws) // using USD prices at the time of the deposit/withdraw @@ -107,7 +107,11 @@ pub struct MangoAccount { // TODO: unimplemented pub net_settled: f32, + pub reserved: [u8; 256], + // dynamic + pub header_version: u8, + pub padding0: [u8; 7], // note: padding is required for TokenPosition, etc. to be aligned pub padding1: u32, // Maps token_index -> deposit/borrow account for each token @@ -134,9 +138,12 @@ impl Default for MangoAccount { is_bankrupt: 0, account_num: 0, bump: 0, - reserved: Default::default(), + padding: Default::default(), net_deposits: 0.0, net_settled: 0.0, + reserved: [0; 256], + header_version: DEFAULT_MANGO_ACCOUNT_VERSION, + padding0: Default::default(), padding1: Default::default(), tokens: vec![TokenPosition::default(); 3], padding2: Default::default(), @@ -158,7 +165,8 @@ impl MangoAccount { } pub fn dynamic_token_vec_offset() -> usize { - BORSH_VEC_PADDING_BYTES + 8 // header version + padding + + BORSH_VEC_PADDING_BYTES } pub fn dynamic_serum3_vec_offset(token_count: u8) -> usize { @@ -217,11 +225,12 @@ pub struct MangoAccountFixed { is_bankrupt: u8, pub account_num: u8, pub bump: u8, - pub reserved: [u8; 4], + pub padding: [u8; 4], pub net_deposits: f32, pub net_settled: f32, + pub reserved: [u8; 256], } -const_assert_eq!(size_of::(), 32 * 4 + 4 + 4 + 2 * 4); +const_assert_eq!(size_of::(), 32 * 4 + 4 + 4 + 2 * 4 + 256); const_assert_eq!(size_of::() % 8, 0); impl MangoAccountFixed { @@ -267,43 +276,52 @@ pub struct MangoAccountDynamicHeader { impl DynamicHeader for MangoAccountDynamicHeader { fn from_bytes(data: &[u8]) -> Result { - let token_count = u8::try_from(BorshVecLength::from_le_bytes(*array_ref![ - data, - MangoAccount::dynamic_token_vec_offset(), - BORSH_VEC_SIZE_BYTES - ])) - .unwrap(); + let header_version = u8::from_le_bytes(*array_ref![data, 0, size_of::()]); - let serum3_count = u8::try_from(BorshVecLength::from_le_bytes(*array_ref![ - data, - MangoAccount::dynamic_serum3_vec_offset(token_count), - BORSH_VEC_SIZE_BYTES - ])) - .unwrap(); + match header_version { + 1 => { + let token_count = u8::try_from(BorshVecLength::from_le_bytes(*array_ref![ + data, + MangoAccount::dynamic_token_vec_offset(), + BORSH_VEC_SIZE_BYTES + ])) + .unwrap(); - let perp_count = u8::try_from(BorshVecLength::from_le_bytes(*array_ref![ - data, - MangoAccount::dynamic_perp_vec_offset(token_count, serum3_count), - BORSH_VEC_SIZE_BYTES - ])) - .unwrap(); + let serum3_count = u8::try_from(BorshVecLength::from_le_bytes(*array_ref![ + data, + MangoAccount::dynamic_serum3_vec_offset(token_count), + BORSH_VEC_SIZE_BYTES + ])) + .unwrap(); - let perp_oo_count = u8::try_from(BorshVecLength::from_le_bytes(*array_ref![ - data, - MangoAccount::dynamic_perp_oo_vec_offset(token_count, serum3_count, perp_count), - BORSH_VEC_SIZE_BYTES - ])) - .unwrap(); + let perp_count = u8::try_from(BorshVecLength::from_le_bytes(*array_ref![ + data, + MangoAccount::dynamic_perp_vec_offset(token_count, serum3_count), + BORSH_VEC_SIZE_BYTES + ])) + .unwrap(); - Ok(Self { - token_count, - serum3_count, - perp_count, - perp_oo_count, - }) + let perp_oo_count = u8::try_from(BorshVecLength::from_le_bytes(*array_ref![ + data, + MangoAccount::dynamic_perp_oo_vec_offset(token_count, serum3_count, perp_count), + BORSH_VEC_SIZE_BYTES + ])) + .unwrap(); + + Ok(Self { + token_count, + serum3_count, + perp_count, + perp_oo_count, + }) + } + _ => err!(MangoError::NotImplementedError).context("unexpected header version number"), + } } - fn initialize(_data: &mut [u8]) -> Result<()> { + fn initialize(data: &mut [u8]) -> Result<()> { + let dst: &mut [u8] = &mut data[0..1]; + dst.copy_from_slice(&DEFAULT_MANGO_ACCOUNT_VERSION.to_le_bytes()); Ok(()) } } @@ -620,7 +638,8 @@ impl< indexed_position: I80F48::ZERO, token_index, in_use_count: 0, - reserved: Default::default(), + padding: Default::default(), + reserved: [0; 40], }; } Ok((v, raw_index, bank_index)) diff --git a/programs/mango-v4/src/state/mango_account_components.rs b/programs/mango-v4/src/state/mango_account_components.rs index aa06ee7e7..a53bc6251 100644 --- a/programs/mango-v4/src/state/mango_account_components.rs +++ b/programs/mango-v4/src/state/mango_account_components.rs @@ -26,13 +26,15 @@ pub struct TokenPosition { /// incremented when a market requires this position to stay alive pub in_use_count: u8, - pub reserved: [u8; 5], + pub padding: [u8; 5], + + pub reserved: [u8; 40], } unsafe impl bytemuck::Pod for TokenPosition {} unsafe impl bytemuck::Zeroable for TokenPosition {} -const_assert_eq!(size_of::(), 24); +const_assert_eq!(size_of::(), 24 + 40); const_assert_eq!(size_of::() % 8, 0); impl Default for TokenPosition { @@ -41,7 +43,8 @@ impl Default for TokenPosition { indexed_position: I80F48::ZERO, token_index: TokenIndex::MAX, in_use_count: 0, - reserved: Default::default(), + padding: Default::default(), + reserved: [0; 40], } } } @@ -98,9 +101,11 @@ pub struct Serum3Orders { pub base_token_index: TokenIndex, pub quote_token_index: TokenIndex, - pub reserved: [u8; 2], + pub padding: [u8; 2], + + pub reserved: [u8; 64], } -const_assert_eq!(size_of::(), 32 + 8 * 2 + 2 * 3 + 2); // 56 +const_assert_eq!(size_of::(), 32 + 8 * 2 + 2 * 3 + 2 + 64); const_assert_eq!(size_of::() % 8, 0); unsafe impl bytemuck::Pod for Serum3Orders {} @@ -123,7 +128,8 @@ impl Default for Serum3Orders { market_index: Serum3MarketIndex::MAX, base_token_index: TokenIndex::MAX, quote_token_index: TokenIndex::MAX, - reserved: Default::default(), + reserved: [0; 64], + padding: Default::default(), previous_native_coin_reserved: 0, previous_native_pc_reserved: 0, } @@ -134,7 +140,7 @@ impl Default for Serum3Orders { #[derive(AnchorSerialize, AnchorDeserialize)] pub struct PerpPositions { pub market_index: PerpMarketIndex, - pub reserved: [u8; 6], + pub padding: [u8; 6], /// Active position size, measured in base lots pub base_position_lots: i64, @@ -157,6 +163,8 @@ pub struct PerpPositions { /// Amount that's on EventQueue waiting to be processed pub taker_base_lots: i64, pub taker_quote_lots: i64, + + pub reserved: [u8; 64], } impl std::fmt::Debug for PerpPositions { @@ -172,7 +180,7 @@ impl std::fmt::Debug for PerpPositions { .finish() } } -const_assert_eq!(size_of::(), 8 + 8 * 5 + 3 * 16); // 96 +const_assert_eq!(size_of::(), 8 + 8 * 5 + 3 * 16 + 64); const_assert_eq!(size_of::() % 8, 0); unsafe impl bytemuck::Pod for PerpPositions {} @@ -188,9 +196,10 @@ impl Default for PerpPositions { asks_base_lots: 0, taker_base_lots: 0, taker_quote_lots: 0, - reserved: Default::default(), + reserved: [0; 64], long_settled_funding: I80F48::ZERO, short_settled_funding: I80F48::ZERO, + padding: Default::default(), } } } @@ -254,22 +263,24 @@ impl PerpPositions { #[derive(AnchorSerialize, AnchorDeserialize, Debug)] pub struct PerpOpenOrders { pub order_side: Side, // TODO: storing enums isn't POD - pub reserved1: [u8; 1], + pub padding1: [u8; 1], pub order_market: PerpMarketIndex, - pub reserved2: [u8; 4], + pub padding2: [u8; 4], pub client_order_id: u64, pub order_id: i128, + pub reserved: [u8; 64], } impl Default for PerpOpenOrders { fn default() -> Self { Self { order_side: Side::Bid, - reserved1: Default::default(), + padding1: Default::default(), order_market: FREE_ORDER_SLOT, - reserved2: Default::default(), + padding2: Default::default(), client_order_id: 0, order_id: 0, + reserved: [0; 64], } } } @@ -277,7 +288,7 @@ impl Default for PerpOpenOrders { unsafe impl bytemuck::Pod for PerpOpenOrders {} unsafe impl bytemuck::Zeroable for PerpOpenOrders {} -const_assert_eq!(size_of::(), 1 + 1 + 2 + 4 + 8 + 16); +const_assert_eq!(size_of::(), 1 + 1 + 2 + 4 + 8 + 16 + 64); const_assert_eq!(size_of::() % 8, 0); #[macro_export] diff --git a/programs/mango-v4/src/state/mint_info.rs b/programs/mango-v4/src/state/mint_info.rs index 47d7ef5e8..5c7144df7 100644 --- a/programs/mango-v4/src/state/mint_info.rs +++ b/programs/mango-v4/src/state/mint_info.rs @@ -21,7 +21,7 @@ pub struct MintInfo { // ABI: Clients rely on this being at offset 40 pub token_index: TokenIndex, - pub padding: [u8; 6], + pub padding1: [u8; 6], pub mint: Pubkey, pub banks: [Pubkey; MAX_BANKS], pub vaults: [Pubkey; MAX_BANKS], @@ -32,11 +32,13 @@ pub struct MintInfo { pub address_lookup_table_bank_index: u8, pub address_lookup_table_oracle_index: u8, - pub reserved: [u8; 6], + pub padding2: [u8; 6], + + pub reserved: [u8; 256], } const_assert_eq!( size_of::(), - MAX_BANKS * 2 * 32 + 4 * 32 + 2 + 6 + 2 + 6 + MAX_BANKS * 2 * 32 + 4 * 32 + 2 + 6 + 2 + 6 + 256 ); const_assert_eq!(size_of::() % 8, 0); diff --git a/programs/mango-v4/src/state/oracle.rs b/programs/mango-v4/src/state/oracle.rs index 94559f9a2..9fc09d290 100644 --- a/programs/mango-v4/src/state/oracle.rs +++ b/programs/mango-v4/src/state/oracle.rs @@ -78,9 +78,9 @@ pub struct StubOracle { pub mint: Pubkey, pub price: I80F48, pub last_updated: i64, - pub reserved: [u8; 8], + pub reserved: [u8; 128], } -const_assert_eq!(size_of::(), 32 + 32 + 16 + 8 + 8); +const_assert_eq!(size_of::(), 32 + 32 + 16 + 8 + 128); const_assert_eq!(size_of::() % 8, 0); pub fn determine_oracle_type(acc_info: &impl KeyedAccountReader) -> Result { diff --git a/programs/mango-v4/src/state/orderbook/bookside.rs b/programs/mango-v4/src/state/orderbook/bookside.rs index fc41d5a19..5bb941f38 100644 --- a/programs/mango-v4/src/state/orderbook/bookside.rs +++ b/programs/mango-v4/src/state/orderbook/bookside.rs @@ -45,10 +45,11 @@ pub struct BookSide { pub root_node: NodeHandle, pub leaf_count: u32, pub nodes: [AnyNode; MAX_BOOK_NODES], + pub reserved: [u8; 256], } const_assert_eq!( std::mem::size_of::(), - 1 + 3 + 4 * 2 + 4 + 4 + 4 + 88 * 1024 + 1 + 3 + 4 * 2 + 4 + 4 + 4 + 96 * 1024 + 256 // 98584 ); const_assert_eq!(std::mem::size_of::() % 8, 0); @@ -262,7 +263,7 @@ impl BookSide { NodeTag::FreeNode.into() }, next: self.free_list_head, - reserve: [0; 80], + reserved: [0; 88], }); self.free_list_len += 1; @@ -458,6 +459,7 @@ mod tests { root_node: 0, leaf_count: 0, nodes: [AnyNode::zeroed(); MAX_BOOK_NODES], + reserved: [0; 256], } } diff --git a/programs/mango-v4/src/state/orderbook/mod.rs b/programs/mango-v4/src/state/orderbook/mod.rs index f34c45a4c..a5df865b8 100644 --- a/programs/mango-v4/src/state/orderbook/mod.rs +++ b/programs/mango-v4/src/state/orderbook/mod.rs @@ -32,6 +32,7 @@ mod tests { root_node: 0, leaf_count: 0, nodes: [AnyNode::zeroed(); MAX_BOOK_NODES], + reserved: [0; 256], } } diff --git a/programs/mango-v4/src/state/orderbook/nodes.rs b/programs/mango-v4/src/state/orderbook/nodes.rs index 7ffc18b52..7d86c244c 100644 --- a/programs/mango-v4/src/state/orderbook/nodes.rs +++ b/programs/mango-v4/src/state/orderbook/nodes.rs @@ -9,7 +9,7 @@ use static_assertions::const_assert_eq; use super::order_type::OrderType; pub type NodeHandle = u32; -const NODE_SIZE: usize = 88; +const NODE_SIZE: usize = 96; #[derive(IntoPrimitive, TryFromPrimitive)] #[repr(u32)] @@ -46,7 +46,7 @@ pub struct InnerNode { /// iterate through the whole bookside. pub child_earliest_expiry: [u64; 2], - pub reserve: [u8; NODE_SIZE - 48], + pub reserved: [u8; NODE_SIZE - 48], } impl InnerNode { @@ -57,7 +57,7 @@ impl InnerNode { key, children: [0; 2], child_earliest_expiry: [u64::MAX; 2], - reserve: [0; NODE_SIZE - 48], + reserved: [0; NODE_SIZE - 48], } } @@ -98,7 +98,7 @@ pub struct LeafNode { // The time the order was placed pub timestamp: u64, - pub reserve: [u8; NODE_SIZE - 81], + pub reserved: [u8; NODE_SIZE - 81], } #[inline(always)] @@ -128,7 +128,7 @@ impl LeafNode { quantity, client_order_id, timestamp, - reserve: [0; NODE_SIZE - 81], + reserved: [0; NODE_SIZE - 81], } } @@ -158,14 +158,14 @@ impl LeafNode { pub struct FreeNode { pub(crate) tag: u32, pub(crate) next: NodeHandle, - pub(crate) reserve: [u8; NODE_SIZE - 8], + pub(crate) reserved: [u8; NODE_SIZE - 8], } #[zero_copy] #[derive(Pod)] pub struct AnyNode { pub tag: u32, - pub data: [u8; 84], // note: anchor can't parse the struct for IDL when it includes non numbers, NODE_SIZE == 88, 84 == 88 - 4 + pub data: [u8; 92], // note: anchor can't parse the struct for IDL when it includes non numbers, NODE_SIZE == 96, 92 == 96 - 4 } const_assert_eq!(size_of::(), NODE_SIZE); diff --git a/programs/mango-v4/src/state/orderbook/queue.rs b/programs/mango-v4/src/state/orderbook/queue.rs index 328283479..f25e34435 100644 --- a/programs/mango-v4/src/state/orderbook/queue.rs +++ b/programs/mango-v4/src/state/orderbook/queue.rs @@ -8,7 +8,7 @@ use std::mem::size_of; use super::Side; -pub const MAX_NUM_EVENTS: u32 = 512; +pub const MAX_NUM_EVENTS: u32 = 488; pub trait QueueHeader: bytemuck::Pod { type Item: bytemuck::Pod + Copy; @@ -153,15 +153,15 @@ impl QueueHeader for EventQueueHeader { } } -const_assert_eq!(std::mem::size_of::(), 4 * 2 + 8 + 512 * 200); +const_assert_eq!(std::mem::size_of::(), 4 * 2 + 8 + 488 * 208); const_assert_eq!(std::mem::size_of::() % 8, 0); -const EVENT_SIZE: usize = 200; +const EVENT_SIZE: usize = 208; #[zero_copy] #[derive(Debug, Pod)] pub struct AnyEvent { pub event_type: u8, - pub padding: [u8; 199], // note: anchor can't parse the struct for IDL when it includes non numbers, EVENT_SIZE == 200, 199 == 200 - 1 + pub padding: [u8; 207], // note: anchor can't parse the struct for IDL when it includes non numbers, EVENT_SIZE == 208, 207 == 208 - 1 } const_assert_eq!(size_of::(), EVENT_SIZE); @@ -201,7 +201,7 @@ pub struct FillEvent { pub price: i64, pub quantity: i64, // number of quote lots - pub reserved: [u8; 8], + pub reserved: [u8; 16], } const_assert_eq!(size_of::(), EVENT_SIZE); @@ -246,7 +246,7 @@ impl FillEvent { taker_fee, price, quantity, - reserved: Default::default(), + reserved: [0; 16], } } diff --git a/programs/mango-v4/src/state/perp_market.rs b/programs/mango-v4/src/state/perp_market.rs index ff293ec1f..dc20cd4a6 100644 --- a/programs/mango-v4/src/state/perp_market.rs +++ b/programs/mango-v4/src/state/perp_market.rs @@ -26,7 +26,7 @@ pub struct PerpMarket { /// Lookup indices pub perp_market_index: PerpMarketIndex, - pub padding: [u8; 4], + pub padding1: [u8; 4], pub name: [u8; 16], @@ -86,12 +86,14 @@ pub struct PerpMarket { pub base_token_decimals: u8, - pub reserved: [u8; 6], + pub padding2: [u8; 6], + + pub reserved: [u8; 128], } const_assert_eq!( size_of::(), - 32 + 2 + 2 + 4 + 16 + 32 + 16 + 32 * 3 + 8 * 2 + 16 * 11 + 8 * 2 + 8 * 2 + 16 + 2 + 6 + 32 + 2 + 2 + 4 + 16 + 32 + 16 + 32 * 3 + 8 * 2 + 16 * 11 + 8 * 2 + 8 * 2 + 16 + 2 + 6 + 128 ); const_assert_eq!(size_of::() % 8, 0); diff --git a/programs/mango-v4/src/state/serum3_market.rs b/programs/mango-v4/src/state/serum3_market.rs index dd861f01d..350bd1d1b 100644 --- a/programs/mango-v4/src/state/serum3_market.rs +++ b/programs/mango-v4/src/state/serum3_market.rs @@ -15,7 +15,7 @@ pub struct Serum3Market { pub base_token_index: TokenIndex, // ABI: Clients rely on this being at offset 42 pub quote_token_index: TokenIndex, - pub padding: [u8; 4], + pub padding1: [u8; 4], pub name: [u8; 16], pub serum_program: Pubkey, pub serum_market_external: Pubkey, @@ -23,11 +23,14 @@ pub struct Serum3Market { pub market_index: Serum3MarketIndex, pub bump: u8, - pub reserved: [u8; 5], + + pub padding2: [u8; 5], + + pub reserved: [u8; 128], } const_assert_eq!( size_of::(), - 32 + 2 + 2 + 4 + 16 + 2 * 32 + 2 + 1 + 5 + 32 + 2 + 2 + 4 + 16 + 2 * 32 + 2 + 1 + 5 + 128 ); const_assert_eq!(size_of::() % 8, 0);