mc/review reserved on accounts (#130)

* review and extend reserved on accounts

Signed-off-by: microwavedcola1 <microwavedcola@gmail.com>

* revert changes to node size, stack gets smashed in rust unit tests

Signed-off-by: microwavedcola1 <microwavedcola@gmail.com>

* max possible

Signed-off-by: microwavedcola1 <microwavedcola@gmail.com>

* max

Signed-off-by: microwavedcola1 <microwavedcola@gmail.com>

* Fixes from review

Signed-off-by: microwavedcola1 <microwavedcola@gmail.com>

* header version

Signed-off-by: microwavedcola1 <microwavedcola@gmail.com>

* Fix from review

Signed-off-by: microwavedcola1 <microwavedcola@gmail.com>

* fix

Signed-off-by: microwavedcola1 <microwavedcola@gmail.com>

* fixes from review

Signed-off-by: microwavedcola1 <microwavedcola@gmail.com>

* fix from review

Signed-off-by: microwavedcola1 <microwavedcola@gmail.com>
This commit is contained in:
microwavedcola1 2022-08-01 16:53:30 +02:00 committed by GitHub
parent e8e774a1a4
commit c516e45d08
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 144 additions and 93 deletions

1
Cargo.lock generated
View File

@ -3156,6 +3156,7 @@ dependencies = [
"async-trait", "async-trait",
"base64 0.13.0", "base64 0.13.0",
"bincode", "bincode",
"borsh",
"bytemuck", "bytemuck",
"checked_math", "checked_math",
"env_logger 0.9.0", "env_logger 0.9.0",

View File

@ -25,6 +25,7 @@ anchor-lang = { path = "../../anchor/lang" }
anchor-spl = { path = "../../anchor/spl" } anchor-spl = { path = "../../anchor/spl" }
arrayref = "0.3.6" arrayref = "0.3.6"
bincode = "1.3.3" bincode = "1.3.3"
borsh = { version = "0.9.3", features = ["const-generics"] }
bytemuck = "^1.7.2" bytemuck = "^1.7.2"
checked_math = { path = "../../lib/checked_math" } checked_math = { path = "../../lib/checked_math" }
fixed = { version = "=1.11.0", features = ["serde", "borsh"] } # todo: higher versions don't work fixed = { version = "=1.11.0", features = ["serde", "borsh"] } # todo: higher versions don't work

View File

@ -7,6 +7,8 @@ use core::fmt::Display;
pub enum MangoError { pub enum MangoError {
#[msg("")] #[msg("")]
SomeError, SomeError,
#[msg("")]
NotImplementedError,
#[msg("checked math error")] #[msg("checked math error")]
MathError, MathError,
#[msg("")] #[msg("")]

View File

@ -96,8 +96,9 @@ pub fn perp_create_market(
base_token_decimals, base_token_decimals,
perp_market_index, perp_market_index,
base_token_index: base_token_index_opt.ok_or(TokenIndex::MAX).unwrap(), base_token_index: base_token_index_opt.ok_or(TokenIndex::MAX).unwrap(),
padding: Default::default(), padding1: Default::default(),
reserved: Default::default(), padding2: Default::default(),
reserved: [0; 128],
}; };
let mut bids = ctx.accounts.bids.load_init()?; let mut bids = ctx.accounts.bids.load_init()?;

View File

@ -75,8 +75,9 @@ pub fn serum3_register_market(
base_token_index: base_bank.token_index, base_token_index: base_bank.token_index,
quote_token_index: quote_bank.token_index, quote_token_index: quote_bank.token_index,
bump: *ctx.bumps.get("serum_market").ok_or(MangoError::SomeError)?, bump: *ctx.bumps.get("serum_market").ok_or(MangoError::SomeError)?,
padding: Default::default(), padding1: Default::default(),
reserved: Default::default(), padding2: Default::default(),
reserved: [0; 128],
}; };
Ok(()) Ok(())

View File

@ -154,7 +154,8 @@ pub fn token_register(
bump: *ctx.bumps.get("bank").ok_or(MangoError::SomeError)?, bump: *ctx.bumps.get("bank").ok_or(MangoError::SomeError)?,
mint_decimals: ctx.accounts.mint.decimals, mint_decimals: ctx.accounts.mint.decimals,
bank_num: 0, bank_num: 0,
reserved: Default::default(), padding: Default::default(),
reserved: [0; 256],
}; };
// TODO: ALTs are unavailable // TODO: ALTs are unavailable
@ -174,8 +175,9 @@ pub fn token_register(
token_index, token_index,
address_lookup_table_bank_index: alt_previous_size as u8, address_lookup_table_bank_index: alt_previous_size as u8,
address_lookup_table_oracle_index: alt_previous_size as u8 + 1, address_lookup_table_oracle_index: alt_previous_size as u8 + 1,
padding: Default::default(), padding1: Default::default(),
reserved: Default::default(), padding2: Default::default(),
reserved: [0; 256],
}; };
mint_info.banks[0] = ctx.accounts.bank.key(); mint_info.banks[0] = ctx.accounts.bank.key();

View File

@ -91,15 +91,15 @@ pub struct Bank {
pub mint_decimals: u8, pub mint_decimals: u8,
pub reserved: [u8; 4], pub padding: [u8; 4],
pub bank_num: u64, 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!( const_assert_eq!(
size_of::<Bank>(), size_of::<Bank>(),
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::<Bank>() % 8, 0); const_assert_eq!(size_of::<Bank>() % 8, 0);
@ -190,7 +190,8 @@ impl Bank {
token_index: existing_bank.token_index, token_index: existing_bank.token_index,
bump: existing_bank.bump, bump: existing_bank.bump,
mint_decimals: existing_bank.mint_decimals, mint_decimals: existing_bank.mint_decimals,
reserved: Default::default(), padding: Default::default(),
reserved: [0; 256],
bank_num, bank_num,
} }
} }
@ -591,7 +592,8 @@ mod tests {
indexed_position: I80F48::ZERO, indexed_position: I80F48::ZERO,
token_index: 0, token_index: 0,
in_use_count: if is_in_use { 1 } else { 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); account.indexed_position = indexed(I80F48::from_num(start), &bank);

View File

@ -32,9 +32,10 @@ pub struct Group {
pub version: u8, pub version: u8,
pub padding2: [u8; 5], pub padding2: [u8; 5],
pub reserved: [u8; 8],
pub reserved: [u8; 256],
} }
const_assert_eq!(size_of::<Group>(), 32 * 5 + 4 + 4 + 1 * 2 + 6 + 8); const_assert_eq!(size_of::<Group>(), 32 * 5 + 4 + 4 + 1 * 2 + 6 + 256);
const_assert_eq!(size_of::<Group>() % 8, 0); const_assert_eq!(size_of::<Group>() % 8, 0);
impl Group { impl Group {

View File

@ -31,6 +31,7 @@ use checked_math as cm;
type BorshVecLength = u32; type BorshVecLength = u32;
const BORSH_VEC_PADDING_BYTES: usize = 4; const BORSH_VEC_PADDING_BYTES: usize = 4;
const BORSH_VEC_SIZE_BYTES: usize = 4; const BORSH_VEC_SIZE_BYTES: usize = 4;
const DEFAULT_MANGO_ACCOUNT_VERSION: u8 = 1;
#[derive( #[derive(
Debug, Debug,
@ -96,8 +97,7 @@ pub struct MangoAccount {
pub account_num: u8, pub account_num: u8,
pub bump: u8, pub bump: u8,
// pub info: [u8; INFO_LEN], // TODO: Info could be in a separate PDA? pub padding: [u8; 4],
pub reserved: [u8; 4],
// Cumulative (deposits - withdraws) // Cumulative (deposits - withdraws)
// using USD prices at the time of the deposit/withdraw // using USD prices at the time of the deposit/withdraw
@ -107,7 +107,11 @@ pub struct MangoAccount {
// TODO: unimplemented // TODO: unimplemented
pub net_settled: f32, pub net_settled: f32,
pub reserved: [u8; 256],
// dynamic // dynamic
pub header_version: u8,
pub padding0: [u8; 7],
// note: padding is required for TokenPosition, etc. to be aligned // note: padding is required for TokenPosition, etc. to be aligned
pub padding1: u32, pub padding1: u32,
// Maps token_index -> deposit/borrow account for each token // Maps token_index -> deposit/borrow account for each token
@ -134,9 +138,12 @@ impl Default for MangoAccount {
is_bankrupt: 0, is_bankrupt: 0,
account_num: 0, account_num: 0,
bump: 0, bump: 0,
reserved: Default::default(), padding: Default::default(),
net_deposits: 0.0, net_deposits: 0.0,
net_settled: 0.0, net_settled: 0.0,
reserved: [0; 256],
header_version: DEFAULT_MANGO_ACCOUNT_VERSION,
padding0: Default::default(),
padding1: Default::default(), padding1: Default::default(),
tokens: vec![TokenPosition::default(); 3], tokens: vec![TokenPosition::default(); 3],
padding2: Default::default(), padding2: Default::default(),
@ -158,7 +165,8 @@ impl MangoAccount {
} }
pub fn dynamic_token_vec_offset() -> usize { 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 { pub fn dynamic_serum3_vec_offset(token_count: u8) -> usize {
@ -217,11 +225,12 @@ pub struct MangoAccountFixed {
is_bankrupt: u8, is_bankrupt: u8,
pub account_num: u8, pub account_num: u8,
pub bump: u8, pub bump: u8,
pub reserved: [u8; 4], pub padding: [u8; 4],
pub net_deposits: f32, pub net_deposits: f32,
pub net_settled: f32, pub net_settled: f32,
pub reserved: [u8; 256],
} }
const_assert_eq!(size_of::<MangoAccountFixed>(), 32 * 4 + 4 + 4 + 2 * 4); const_assert_eq!(size_of::<MangoAccountFixed>(), 32 * 4 + 4 + 4 + 2 * 4 + 256);
const_assert_eq!(size_of::<MangoAccountFixed>() % 8, 0); const_assert_eq!(size_of::<MangoAccountFixed>() % 8, 0);
impl MangoAccountFixed { impl MangoAccountFixed {
@ -267,43 +276,52 @@ pub struct MangoAccountDynamicHeader {
impl DynamicHeader for MangoAccountDynamicHeader { impl DynamicHeader for MangoAccountDynamicHeader {
fn from_bytes(data: &[u8]) -> Result<Self> { fn from_bytes(data: &[u8]) -> Result<Self> {
let token_count = u8::try_from(BorshVecLength::from_le_bytes(*array_ref![ let header_version = u8::from_le_bytes(*array_ref![data, 0, size_of::<u8>()]);
data,
MangoAccount::dynamic_token_vec_offset(),
BORSH_VEC_SIZE_BYTES
]))
.unwrap();
let serum3_count = u8::try_from(BorshVecLength::from_le_bytes(*array_ref![ match header_version {
data, 1 => {
MangoAccount::dynamic_serum3_vec_offset(token_count), let token_count = u8::try_from(BorshVecLength::from_le_bytes(*array_ref![
BORSH_VEC_SIZE_BYTES data,
])) MangoAccount::dynamic_token_vec_offset(),
.unwrap(); BORSH_VEC_SIZE_BYTES
]))
.unwrap();
let perp_count = u8::try_from(BorshVecLength::from_le_bytes(*array_ref![ let serum3_count = u8::try_from(BorshVecLength::from_le_bytes(*array_ref![
data, data,
MangoAccount::dynamic_perp_vec_offset(token_count, serum3_count), MangoAccount::dynamic_serum3_vec_offset(token_count),
BORSH_VEC_SIZE_BYTES BORSH_VEC_SIZE_BYTES
])) ]))
.unwrap(); .unwrap();
let perp_oo_count = u8::try_from(BorshVecLength::from_le_bytes(*array_ref![ let perp_count = u8::try_from(BorshVecLength::from_le_bytes(*array_ref![
data, data,
MangoAccount::dynamic_perp_oo_vec_offset(token_count, serum3_count, perp_count), MangoAccount::dynamic_perp_vec_offset(token_count, serum3_count),
BORSH_VEC_SIZE_BYTES BORSH_VEC_SIZE_BYTES
])) ]))
.unwrap(); .unwrap();
Ok(Self { let perp_oo_count = u8::try_from(BorshVecLength::from_le_bytes(*array_ref![
token_count, data,
serum3_count, MangoAccount::dynamic_perp_oo_vec_offset(token_count, serum3_count, perp_count),
perp_count, BORSH_VEC_SIZE_BYTES
perp_oo_count, ]))
}) .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(()) Ok(())
} }
} }
@ -620,7 +638,8 @@ impl<
indexed_position: I80F48::ZERO, indexed_position: I80F48::ZERO,
token_index, token_index,
in_use_count: 0, in_use_count: 0,
reserved: Default::default(), padding: Default::default(),
reserved: [0; 40],
}; };
} }
Ok((v, raw_index, bank_index)) Ok((v, raw_index, bank_index))

View File

@ -26,13 +26,15 @@ pub struct TokenPosition {
/// incremented when a market requires this position to stay alive /// incremented when a market requires this position to stay alive
pub in_use_count: u8, 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::Pod for TokenPosition {}
unsafe impl bytemuck::Zeroable for TokenPosition {} unsafe impl bytemuck::Zeroable for TokenPosition {}
const_assert_eq!(size_of::<TokenPosition>(), 24); const_assert_eq!(size_of::<TokenPosition>(), 24 + 40);
const_assert_eq!(size_of::<TokenPosition>() % 8, 0); const_assert_eq!(size_of::<TokenPosition>() % 8, 0);
impl Default for TokenPosition { impl Default for TokenPosition {
@ -41,7 +43,8 @@ impl Default for TokenPosition {
indexed_position: I80F48::ZERO, indexed_position: I80F48::ZERO,
token_index: TokenIndex::MAX, token_index: TokenIndex::MAX,
in_use_count: 0, 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 base_token_index: TokenIndex,
pub quote_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::<Serum3Orders>(), 32 + 8 * 2 + 2 * 3 + 2); // 56 const_assert_eq!(size_of::<Serum3Orders>(), 32 + 8 * 2 + 2 * 3 + 2 + 64);
const_assert_eq!(size_of::<Serum3Orders>() % 8, 0); const_assert_eq!(size_of::<Serum3Orders>() % 8, 0);
unsafe impl bytemuck::Pod for Serum3Orders {} unsafe impl bytemuck::Pod for Serum3Orders {}
@ -123,7 +128,8 @@ impl Default for Serum3Orders {
market_index: Serum3MarketIndex::MAX, market_index: Serum3MarketIndex::MAX,
base_token_index: TokenIndex::MAX, base_token_index: TokenIndex::MAX,
quote_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_coin_reserved: 0,
previous_native_pc_reserved: 0, previous_native_pc_reserved: 0,
} }
@ -134,7 +140,7 @@ impl Default for Serum3Orders {
#[derive(AnchorSerialize, AnchorDeserialize)] #[derive(AnchorSerialize, AnchorDeserialize)]
pub struct PerpPositions { pub struct PerpPositions {
pub market_index: PerpMarketIndex, pub market_index: PerpMarketIndex,
pub reserved: [u8; 6], pub padding: [u8; 6],
/// Active position size, measured in base lots /// Active position size, measured in base lots
pub base_position_lots: i64, pub base_position_lots: i64,
@ -157,6 +163,8 @@ pub struct PerpPositions {
/// Amount that's on EventQueue waiting to be processed /// Amount that's on EventQueue waiting to be processed
pub taker_base_lots: i64, pub taker_base_lots: i64,
pub taker_quote_lots: i64, pub taker_quote_lots: i64,
pub reserved: [u8; 64],
} }
impl std::fmt::Debug for PerpPositions { impl std::fmt::Debug for PerpPositions {
@ -172,7 +180,7 @@ impl std::fmt::Debug for PerpPositions {
.finish() .finish()
} }
} }
const_assert_eq!(size_of::<PerpPositions>(), 8 + 8 * 5 + 3 * 16); // 96 const_assert_eq!(size_of::<PerpPositions>(), 8 + 8 * 5 + 3 * 16 + 64);
const_assert_eq!(size_of::<PerpPositions>() % 8, 0); const_assert_eq!(size_of::<PerpPositions>() % 8, 0);
unsafe impl bytemuck::Pod for PerpPositions {} unsafe impl bytemuck::Pod for PerpPositions {}
@ -188,9 +196,10 @@ impl Default for PerpPositions {
asks_base_lots: 0, asks_base_lots: 0,
taker_base_lots: 0, taker_base_lots: 0,
taker_quote_lots: 0, taker_quote_lots: 0,
reserved: Default::default(), reserved: [0; 64],
long_settled_funding: I80F48::ZERO, long_settled_funding: I80F48::ZERO,
short_settled_funding: I80F48::ZERO, short_settled_funding: I80F48::ZERO,
padding: Default::default(),
} }
} }
} }
@ -254,22 +263,24 @@ impl PerpPositions {
#[derive(AnchorSerialize, AnchorDeserialize, Debug)] #[derive(AnchorSerialize, AnchorDeserialize, Debug)]
pub struct PerpOpenOrders { pub struct PerpOpenOrders {
pub order_side: Side, // TODO: storing enums isn't POD pub order_side: Side, // TODO: storing enums isn't POD
pub reserved1: [u8; 1], pub padding1: [u8; 1],
pub order_market: PerpMarketIndex, pub order_market: PerpMarketIndex,
pub reserved2: [u8; 4], pub padding2: [u8; 4],
pub client_order_id: u64, pub client_order_id: u64,
pub order_id: i128, pub order_id: i128,
pub reserved: [u8; 64],
} }
impl Default for PerpOpenOrders { impl Default for PerpOpenOrders {
fn default() -> Self { fn default() -> Self {
Self { Self {
order_side: Side::Bid, order_side: Side::Bid,
reserved1: Default::default(), padding1: Default::default(),
order_market: FREE_ORDER_SLOT, order_market: FREE_ORDER_SLOT,
reserved2: Default::default(), padding2: Default::default(),
client_order_id: 0, client_order_id: 0,
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::Pod for PerpOpenOrders {}
unsafe impl bytemuck::Zeroable for PerpOpenOrders {} unsafe impl bytemuck::Zeroable for PerpOpenOrders {}
const_assert_eq!(size_of::<PerpOpenOrders>(), 1 + 1 + 2 + 4 + 8 + 16); const_assert_eq!(size_of::<PerpOpenOrders>(), 1 + 1 + 2 + 4 + 8 + 16 + 64);
const_assert_eq!(size_of::<PerpOpenOrders>() % 8, 0); const_assert_eq!(size_of::<PerpOpenOrders>() % 8, 0);
#[macro_export] #[macro_export]

View File

@ -21,7 +21,7 @@ pub struct MintInfo {
// ABI: Clients rely on this being at offset 40 // ABI: Clients rely on this being at offset 40
pub token_index: TokenIndex, pub token_index: TokenIndex,
pub padding: [u8; 6], pub padding1: [u8; 6],
pub mint: Pubkey, pub mint: Pubkey,
pub banks: [Pubkey; MAX_BANKS], pub banks: [Pubkey; MAX_BANKS],
pub vaults: [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_bank_index: u8,
pub address_lookup_table_oracle_index: u8, pub address_lookup_table_oracle_index: u8,
pub reserved: [u8; 6], pub padding2: [u8; 6],
pub reserved: [u8; 256],
} }
const_assert_eq!( const_assert_eq!(
size_of::<MintInfo>(), size_of::<MintInfo>(),
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::<MintInfo>() % 8, 0); const_assert_eq!(size_of::<MintInfo>() % 8, 0);

View File

@ -78,9 +78,9 @@ pub struct StubOracle {
pub mint: Pubkey, pub mint: Pubkey,
pub price: I80F48, pub price: I80F48,
pub last_updated: i64, pub last_updated: i64,
pub reserved: [u8; 8], pub reserved: [u8; 128],
} }
const_assert_eq!(size_of::<StubOracle>(), 32 + 32 + 16 + 8 + 8); const_assert_eq!(size_of::<StubOracle>(), 32 + 32 + 16 + 8 + 128);
const_assert_eq!(size_of::<StubOracle>() % 8, 0); const_assert_eq!(size_of::<StubOracle>() % 8, 0);
pub fn determine_oracle_type(acc_info: &impl KeyedAccountReader) -> Result<OracleType> { pub fn determine_oracle_type(acc_info: &impl KeyedAccountReader) -> Result<OracleType> {

View File

@ -45,10 +45,11 @@ pub struct BookSide {
pub root_node: NodeHandle, pub root_node: NodeHandle,
pub leaf_count: u32, pub leaf_count: u32,
pub nodes: [AnyNode; MAX_BOOK_NODES], pub nodes: [AnyNode; MAX_BOOK_NODES],
pub reserved: [u8; 256],
} }
const_assert_eq!( const_assert_eq!(
std::mem::size_of::<BookSide>(), std::mem::size_of::<BookSide>(),
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::<BookSide>() % 8, 0); const_assert_eq!(std::mem::size_of::<BookSide>() % 8, 0);
@ -262,7 +263,7 @@ impl BookSide {
NodeTag::FreeNode.into() NodeTag::FreeNode.into()
}, },
next: self.free_list_head, next: self.free_list_head,
reserve: [0; 80], reserved: [0; 88],
}); });
self.free_list_len += 1; self.free_list_len += 1;
@ -458,6 +459,7 @@ mod tests {
root_node: 0, root_node: 0,
leaf_count: 0, leaf_count: 0,
nodes: [AnyNode::zeroed(); MAX_BOOK_NODES], nodes: [AnyNode::zeroed(); MAX_BOOK_NODES],
reserved: [0; 256],
} }
} }

View File

@ -32,6 +32,7 @@ mod tests {
root_node: 0, root_node: 0,
leaf_count: 0, leaf_count: 0,
nodes: [AnyNode::zeroed(); MAX_BOOK_NODES], nodes: [AnyNode::zeroed(); MAX_BOOK_NODES],
reserved: [0; 256],
} }
} }

View File

@ -9,7 +9,7 @@ use static_assertions::const_assert_eq;
use super::order_type::OrderType; use super::order_type::OrderType;
pub type NodeHandle = u32; pub type NodeHandle = u32;
const NODE_SIZE: usize = 88; const NODE_SIZE: usize = 96;
#[derive(IntoPrimitive, TryFromPrimitive)] #[derive(IntoPrimitive, TryFromPrimitive)]
#[repr(u32)] #[repr(u32)]
@ -46,7 +46,7 @@ pub struct InnerNode {
/// iterate through the whole bookside. /// iterate through the whole bookside.
pub child_earliest_expiry: [u64; 2], pub child_earliest_expiry: [u64; 2],
pub reserve: [u8; NODE_SIZE - 48], pub reserved: [u8; NODE_SIZE - 48],
} }
impl InnerNode { impl InnerNode {
@ -57,7 +57,7 @@ impl InnerNode {
key, key,
children: [0; 2], children: [0; 2],
child_earliest_expiry: [u64::MAX; 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 // The time the order was placed
pub timestamp: u64, pub timestamp: u64,
pub reserve: [u8; NODE_SIZE - 81], pub reserved: [u8; NODE_SIZE - 81],
} }
#[inline(always)] #[inline(always)]
@ -128,7 +128,7 @@ impl LeafNode {
quantity, quantity,
client_order_id, client_order_id,
timestamp, timestamp,
reserve: [0; NODE_SIZE - 81], reserved: [0; NODE_SIZE - 81],
} }
} }
@ -158,14 +158,14 @@ impl LeafNode {
pub struct FreeNode { pub struct FreeNode {
pub(crate) tag: u32, pub(crate) tag: u32,
pub(crate) next: NodeHandle, pub(crate) next: NodeHandle,
pub(crate) reserve: [u8; NODE_SIZE - 8], pub(crate) reserved: [u8; NODE_SIZE - 8],
} }
#[zero_copy] #[zero_copy]
#[derive(Pod)] #[derive(Pod)]
pub struct AnyNode { pub struct AnyNode {
pub tag: u32, 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::<AnyNode>(), NODE_SIZE); const_assert_eq!(size_of::<AnyNode>(), NODE_SIZE);

View File

@ -8,7 +8,7 @@ use std::mem::size_of;
use super::Side; use super::Side;
pub const MAX_NUM_EVENTS: u32 = 512; pub const MAX_NUM_EVENTS: u32 = 488;
pub trait QueueHeader: bytemuck::Pod { pub trait QueueHeader: bytemuck::Pod {
type Item: bytemuck::Pod + Copy; type Item: bytemuck::Pod + Copy;
@ -153,15 +153,15 @@ impl QueueHeader for EventQueueHeader {
} }
} }
const_assert_eq!(std::mem::size_of::<EventQueue>(), 4 * 2 + 8 + 512 * 200); const_assert_eq!(std::mem::size_of::<EventQueue>(), 4 * 2 + 8 + 488 * 208);
const_assert_eq!(std::mem::size_of::<EventQueue>() % 8, 0); const_assert_eq!(std::mem::size_of::<EventQueue>() % 8, 0);
const EVENT_SIZE: usize = 200; const EVENT_SIZE: usize = 208;
#[zero_copy] #[zero_copy]
#[derive(Debug, Pod)] #[derive(Debug, Pod)]
pub struct AnyEvent { pub struct AnyEvent {
pub event_type: u8, 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::<AnyEvent>(), EVENT_SIZE); const_assert_eq!(size_of::<AnyEvent>(), EVENT_SIZE);
@ -201,7 +201,7 @@ pub struct FillEvent {
pub price: i64, pub price: i64,
pub quantity: i64, // number of quote lots pub quantity: i64, // number of quote lots
pub reserved: [u8; 8], pub reserved: [u8; 16],
} }
const_assert_eq!(size_of::<FillEvent>(), EVENT_SIZE); const_assert_eq!(size_of::<FillEvent>(), EVENT_SIZE);
@ -246,7 +246,7 @@ impl FillEvent {
taker_fee, taker_fee,
price, price,
quantity, quantity,
reserved: Default::default(), reserved: [0; 16],
} }
} }

View File

@ -26,7 +26,7 @@ pub struct PerpMarket {
/// Lookup indices /// Lookup indices
pub perp_market_index: PerpMarketIndex, pub perp_market_index: PerpMarketIndex,
pub padding: [u8; 4], pub padding1: [u8; 4],
pub name: [u8; 16], pub name: [u8; 16],
@ -86,12 +86,14 @@ pub struct PerpMarket {
pub base_token_decimals: u8, pub base_token_decimals: u8,
pub reserved: [u8; 6], pub padding2: [u8; 6],
pub reserved: [u8; 128],
} }
const_assert_eq!( const_assert_eq!(
size_of::<PerpMarket>(), size_of::<PerpMarket>(),
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::<PerpMarket>() % 8, 0); const_assert_eq!(size_of::<PerpMarket>() % 8, 0);

View File

@ -15,7 +15,7 @@ pub struct Serum3Market {
pub base_token_index: TokenIndex, pub base_token_index: TokenIndex,
// ABI: Clients rely on this being at offset 42 // ABI: Clients rely on this being at offset 42
pub quote_token_index: TokenIndex, pub quote_token_index: TokenIndex,
pub padding: [u8; 4], pub padding1: [u8; 4],
pub name: [u8; 16], pub name: [u8; 16],
pub serum_program: Pubkey, pub serum_program: Pubkey,
pub serum_market_external: Pubkey, pub serum_market_external: Pubkey,
@ -23,11 +23,14 @@ pub struct Serum3Market {
pub market_index: Serum3MarketIndex, pub market_index: Serum3MarketIndex,
pub bump: u8, pub bump: u8,
pub reserved: [u8; 5],
pub padding2: [u8; 5],
pub reserved: [u8; 128],
} }
const_assert_eq!( const_assert_eq!(
size_of::<Serum3Market>(), size_of::<Serum3Market>(),
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::<Serum3Market>() % 8, 0); const_assert_eq!(size_of::<Serum3Market>() % 8, 0);