Signed-off-by: microwavedcola1 <microwavedcola@gmail.com>
This commit is contained in:
microwavedcola1 2022-03-24 14:40:08 +01:00
parent 4a3d61a0b0
commit ba4300accc
5 changed files with 28 additions and 103 deletions

View File

@ -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(())
}

View File

@ -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<EventQueueHeader>>,
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())?;

View File

@ -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,

View File

@ -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<T: bytemuck::Pod>(bytes: &mut [u8]) -> &mut [T] {
let slop = bytes.len() % size_of::<T>();
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::<H>());
(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]>,
}
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<Self> {
let (header, buf) = strip_header_mut::<H, H::Item>(account)?;
Ok(Self { header, buf })
#[account(zero_copy)]
pub struct Queue<H: QueueHeader> {
pub header: H,
pub buf: [H::Item; MAX_NUM_EVENTS],
}
impl<'a, H: QueueHeader> Queue<H> {
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<H::Item, ()> {
if self.empty() {
return Err(());
}
pub fn pop_front(&mut self) -> Result<H::Item> {
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<H>,
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<Self::Item> {
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<Self> {
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<Self> {
// 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<EventQueueHeader>;
const EVENT_SIZE: usize = 200;
#[derive(Copy, Clone, Debug, Pod)]

View File

@ -98,11 +98,9 @@ async fn test_perp() -> Result<(), TransportError> {
.create_account_for_type::<BookSide>(&mango_v4::id())
.await,
event_queue: {
let len = std::mem::size_of::<queue::EventQueue>()
+ std::mem::size_of::<AnyEvent>() * MAX_NUM_EVENTS;
context
.solana
.create_account_from_len(&mango_v4::id(), len)
.create_account_for_type::<EventQueue>(&mango_v4::id())
.await
},
admin,