From ba4300acccb8a1bbba73fb7a9a7c5e16ebc120bc Mon Sep 17 00:00:00 2001 From: microwavedcola1 Date: Thu, 24 Mar 2022 14:40:08 +0100 Subject: [PATCH] simplify Signed-off-by: microwavedcola1 --- .../src/instructions/create_perp_market.rs | 6 +- .../src/instructions/place_perp_order.rs | 12 +- programs/mango-v4/src/state/orderbook/book.rs | 3 +- .../mango-v4/src/state/orderbook/queue.rs | 106 +++--------------- programs/mango-v4/tests/test_perp.rs | 4 +- 5 files changed, 28 insertions(+), 103 deletions(-) diff --git a/programs/mango-v4/src/instructions/create_perp_market.rs b/programs/mango-v4/src/instructions/create_perp_market.rs index 58f267ae7..437c42014 100644 --- a/programs/mango-v4/src/instructions/create_perp_market.rs +++ b/programs/mango-v4/src/instructions/create_perp_market.rs @@ -29,8 +29,8 @@ pub struct CreatePerpMarket<'info> { pub bids: AccountLoader<'info, BookSide>, #[account(zero)] pub asks: AccountLoader<'info, BookSide>, - - pub event_queue: UncheckedAccount<'info>, + #[account(zero)] + pub event_queue: AccountLoader<'info, EventQueue>, #[account(mut)] pub payer: Signer<'info>, @@ -68,7 +68,5 @@ pub fn create_perp_market( let mut asks = ctx.accounts.asks.load_init()?; asks.book_side_type = BookSideType::Asks; - // TODO: discriminator on event queue - Ok(()) } diff --git a/programs/mango-v4/src/instructions/place_perp_order.rs b/programs/mango-v4/src/instructions/place_perp_order.rs index c3b0d7999..281befd6c 100644 --- a/programs/mango-v4/src/instructions/place_perp_order.rs +++ b/programs/mango-v4/src/instructions/place_perp_order.rs @@ -1,6 +1,8 @@ use anchor_lang::prelude::*; -use crate::state::{Book, BookSide, EventQueue, Group, MangoAccount, OrderType, PerpMarket}; +use crate::state::{ + Book, BookSide, EventQueueHeader, Group, MangoAccount, OrderType, PerpMarket, Queue, +}; #[derive(Accounts)] pub struct PlacePerpOrder<'info> { @@ -25,7 +27,9 @@ pub struct PlacePerpOrder<'info> { pub asks: AccountLoader<'info, BookSide>, #[account(mut)] pub bids: AccountLoader<'info, BookSide>, - pub event_queue: UncheckedAccount<'info>, + #[account(mut)] + pub event_queue: AccountLoader<'info, Queue>, + pub oracle: UncheckedAccount<'info>, pub owner: Signer<'info>, @@ -51,9 +55,7 @@ pub fn place_perp_order( let asks = &ctx.accounts.asks.to_account_info(); let mut book = Book::load_checked(bids, asks, &perp_market)?; - let event_queue_ai = &ctx.accounts.event_queue.to_account_info(); - let mut event_queue = - EventQueue::load_mut_checked(event_queue_ai, ctx.program_id, &perp_market)?; + let mut event_queue = ctx.accounts.event_queue.load_mut()?; // let oracle_price = oracle_price(&ctx.accounts.oracle.to_account_info())?; diff --git a/programs/mango-v4/src/state/orderbook/book.rs b/programs/mango-v4/src/state/orderbook/book.rs index af38d4296..015d549b3 100644 --- a/programs/mango-v4/src/state/orderbook/book.rs +++ b/programs/mango-v4/src/state/orderbook/book.rs @@ -8,7 +8,6 @@ use crate::{ }, }; use anchor_lang::prelude::*; -use bytemuck::cast; use fixed::types::I80F48; use fixed_macro::types::I80F48; @@ -341,7 +340,7 @@ impl<'a> Book<'a> { // mango_group: &MangoGroup, // mango_group_pk: &Pubkey, // mango_cache: &MangoCache, - event_queue: &mut EventQueue, + _event_queue: &mut EventQueue, market: &mut PerpMarket, // oracle_price: I80F48, // mango_account: &mut MangoAccount, diff --git a/programs/mango-v4/src/state/orderbook/queue.rs b/programs/mango-v4/src/state/orderbook/queue.rs index d4151ccfe..acbe59c09 100644 --- a/programs/mango-v4/src/state/orderbook/queue.rs +++ b/programs/mango-v4/src/state/orderbook/queue.rs @@ -1,36 +1,9 @@ -use std::cell::RefMut; -use std::mem::size_of; - use crate::error::MangoError; -use crate::state::PerpMarket; use anchor_lang::prelude::*; -use bytemuck::{cast_slice_mut, from_bytes_mut}; -use solana_program::account_info::AccountInfo; -use solana_program::pubkey::Pubkey; -use solana_program::sysvar::rent::Rent; - use mango_macro::Pod; -use super::metadata::MetaData; - pub const MAX_NUM_EVENTS: usize = 512; -#[inline] -pub fn remove_slop_mut(bytes: &mut [u8]) -> &mut [T] { - let slop = bytes.len() % size_of::(); - let new_len = bytes.len() - slop; - cast_slice_mut(&mut bytes[..new_len]) -} - -pub fn strip_header_mut<'a, H: bytemuck::Pod, D: bytemuck::Pod>( - account: &'a AccountInfo, -) -> std::result::Result<(RefMut<'a, H>, RefMut<'a, [D]>), Error> { - Ok(RefMut::map_split(account.try_borrow_mut_data()?, |data| { - let (header_bytes, inner_bytes) = data.split_at_mut(size_of::()); - (from_bytes_mut(header_bytes), remove_slop_mut(inner_bytes)) - })) -} - pub trait QueueHeader: bytemuck::Pod { type Item: bytemuck::Pod + Copy; @@ -43,25 +16,21 @@ pub trait QueueHeader: bytemuck::Pod { fn decr_event_id(&mut self, n: usize); } -pub struct Queue<'a, H: QueueHeader> { - pub header: RefMut<'a, H>, - pub buf: RefMut<'a, [H::Item]>, +#[account(zero_copy)] +pub struct Queue { + pub header: H, + pub buf: [H::Item; MAX_NUM_EVENTS], } -impl<'a, H: QueueHeader> Queue<'a, H> { - pub fn new(header: RefMut<'a, H>, buf: RefMut<'a, [H::Item]>) -> Self { - Self { header, buf } - } - - pub fn load_mut(account: &'a AccountInfo) -> Result { - let (header, buf) = strip_header_mut::(account)?; - Ok(Self { header, buf }) - } - +impl<'a, H: QueueHeader> Queue { pub fn len(&self) -> usize { self.header.count() } + pub fn is_empty(&self) -> bool { + self.len() == 0 + } + pub fn full(&self) -> bool { self.header.count() == self.buf.len() } @@ -98,10 +67,9 @@ impl<'a, H: QueueHeader> Queue<'a, H> { Some(&mut self.buf[self.header.head()]) } - pub fn pop_front(&mut self) -> std::result::Result { - if self.empty() { - return Err(()); - } + pub fn pop_front(&mut self) -> Result { + require!(!self.empty(), MangoError::SomeError); + let value = self.buf[self.header.head()]; let count = self.header.count(); @@ -129,13 +97,13 @@ impl<'a, H: QueueHeader> Queue<'a, H> { } } -struct QueueIterator<'a, 'b, H: QueueHeader> { - queue: &'b Queue<'a, H>, +struct QueueIterator<'a, H: QueueHeader> { + queue: &'a Queue, index: usize, } -impl<'a, 'b, H: QueueHeader> Iterator for QueueIterator<'a, 'b, H> { - type Item = &'b H::Item; +impl<'a, H: QueueHeader> Iterator for QueueIterator<'a, H> { + type Item = &'a H::Item; fn next(&mut self) -> Option { if self.index == self.queue.len() { None @@ -150,12 +118,10 @@ impl<'a, 'b, H: QueueHeader> Iterator for QueueIterator<'a, 'b, H> { #[account(zero_copy)] pub struct EventQueueHeader { - pub meta_data: MetaData, head: usize, count: usize, pub seq_num: usize, } -// unsafe impl TriviallyTransmutable for EventQueueHeader {} impl QueueHeader for EventQueueHeader { type Item = AnyEvent; @@ -180,45 +146,7 @@ impl QueueHeader for EventQueueHeader { } } -pub type EventQueue<'a> = Queue<'a, EventQueueHeader>; - -impl<'a> EventQueue<'a> { - pub fn load_mut_checked( - account: &'a AccountInfo, - program_id: &Pubkey, - perp_market: &PerpMarket, - ) -> Result { - require!(account.owner == program_id, MangoError::SomeError); - require!( - &perp_market.event_queue == account.key, - MangoError::SomeError - ); - Self::load_mut(account) - } - - pub fn load_and_init( - account: &'a AccountInfo, - program_id: &Pubkey, - rent: &Rent, - ) -> Result { - // NOTE: check this first so we can borrow account later - require!( - rent.is_exempt(account.lamports(), account.data_len()), - MangoError::SomeError - ); - - let state = Self::load_mut(account)?; - require!(account.owner == program_id, MangoError::SomeError); - - // require!( - // !state.header.meta_data.is_initialized, - // MangoError::SomeError - // ); - // state.header.meta_data = MetaData::new(DataType::EventQueue, 0, true); - - Ok(state) - } -} +pub type EventQueue = Queue; const EVENT_SIZE: usize = 200; #[derive(Copy, Clone, Debug, Pod)] diff --git a/programs/mango-v4/tests/test_perp.rs b/programs/mango-v4/tests/test_perp.rs index 88014d4a0..08a17f659 100644 --- a/programs/mango-v4/tests/test_perp.rs +++ b/programs/mango-v4/tests/test_perp.rs @@ -98,11 +98,9 @@ async fn test_perp() -> Result<(), TransportError> { .create_account_for_type::(&mango_v4::id()) .await, event_queue: { - let len = std::mem::size_of::() - + std::mem::size_of::() * MAX_NUM_EVENTS; context .solana - .create_account_from_len(&mango_v4::id(), len) + .create_account_for_type::(&mango_v4::id()) .await }, admin,