MangoAccount: Fixes after audit
This commit is contained in:
parent
d63c5bfc76
commit
7d508e5df5
|
@ -1159,7 +1159,7 @@ mod tests {
|
|||
// Run a health test that includes all the side values (like referrer_rebates_accrued)
|
||||
#[test]
|
||||
fn test_health0() {
|
||||
let buffer = MangoAccount::default().try_to_vec().unwrap();
|
||||
let buffer = MangoAccount::default_for_tests().try_to_vec().unwrap();
|
||||
let mut account = MangoAccountValue::from_bytes(&buffer).unwrap();
|
||||
|
||||
let group = Pubkey::new_unique();
|
||||
|
@ -1338,7 +1338,7 @@ mod tests {
|
|||
expected_health: f64,
|
||||
}
|
||||
fn test_health1_runner(testcase: &TestHealth1Case) {
|
||||
let buffer = MangoAccount::default().try_to_vec().unwrap();
|
||||
let buffer = MangoAccount::default_for_tests().try_to_vec().unwrap();
|
||||
let mut account = MangoAccountValue::from_bytes(&buffer).unwrap();
|
||||
|
||||
let group = Pubkey::new_unique();
|
||||
|
|
|
@ -103,8 +103,8 @@ pub struct MangoAccount {
|
|||
pub perp_open_orders: Vec<PerpOpenOrder>,
|
||||
}
|
||||
|
||||
impl Default for MangoAccount {
|
||||
fn default() -> Self {
|
||||
impl MangoAccount {
|
||||
pub fn default_for_tests() -> Self {
|
||||
Self {
|
||||
name: Default::default(),
|
||||
group: Pubkey::default(),
|
||||
|
@ -131,9 +131,8 @@ impl Default for MangoAccount {
|
|||
perp_open_orders: vec![PerpOpenOrder::default(); 2],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl MangoAccount {
|
||||
/// Number of bytes needed for the MangoAccount, including the discriminator
|
||||
pub fn space(
|
||||
token_count: u8,
|
||||
serum3_count: u8,
|
||||
|
@ -185,7 +184,7 @@ impl MangoAccount {
|
|||
|
||||
#[test]
|
||||
fn test_serialization_match() {
|
||||
let mut account = MangoAccount::default();
|
||||
let mut account = MangoAccount::default_for_tests();
|
||||
account.group = Pubkey::new_unique();
|
||||
account.owner = Pubkey::new_unique();
|
||||
account.name = crate::util::fill_from_str("abcdef").unwrap();
|
||||
|
@ -502,13 +501,11 @@ impl<
|
|||
|
||||
// get iter over all active TokenPositions
|
||||
pub fn active_token_positions(&self) -> impl Iterator<Item = &TokenPosition> + '_ {
|
||||
(0..self.header().token_count())
|
||||
.map(|i| self.token_position_by_raw_index(i))
|
||||
.filter(|token| token.is_active())
|
||||
self.all_token_positions().filter(|token| token.is_active())
|
||||
}
|
||||
|
||||
pub fn serum3_orders(&self, market_index: Serum3MarketIndex) -> Option<&Serum3Orders> {
|
||||
self.active_serum3_orders()
|
||||
self.all_serum3_orders()
|
||||
.find(|p| p.is_active_for_market(market_index))
|
||||
}
|
||||
|
||||
|
@ -521,13 +518,12 @@ impl<
|
|||
}
|
||||
|
||||
pub fn active_serum3_orders(&self) -> impl Iterator<Item = &Serum3Orders> + '_ {
|
||||
(0..self.header().serum3_count())
|
||||
.map(|i| self.serum3_orders_by_raw_index(i))
|
||||
self.all_serum3_orders()
|
||||
.filter(|serum3_order| serum3_order.is_active())
|
||||
}
|
||||
|
||||
pub fn perp_position(&self, market_index: PerpMarketIndex) -> Option<&PerpPosition> {
|
||||
self.active_perp_positions()
|
||||
self.all_perp_positions()
|
||||
.find(|p| p.is_active_for_market(market_index))
|
||||
}
|
||||
|
||||
|
@ -540,17 +536,15 @@ impl<
|
|||
}
|
||||
|
||||
pub fn active_perp_positions(&self) -> impl Iterator<Item = &PerpPosition> {
|
||||
(0..self.header().perp_count())
|
||||
.map(|i| self.perp_position_by_raw_index(i))
|
||||
.filter(|p| p.is_active())
|
||||
self.all_perp_positions().filter(|p| p.is_active())
|
||||
}
|
||||
|
||||
pub fn perp_orders_by_raw_index(&self, raw_index: usize) -> &PerpOpenOrder {
|
||||
pub fn perp_order_by_raw_index(&self, raw_index: usize) -> &PerpOpenOrder {
|
||||
get_helper(self.dynamic(), self.header().perp_oo_offset(raw_index))
|
||||
}
|
||||
|
||||
pub fn all_perp_orders(&self) -> impl Iterator<Item = &PerpOpenOrder> {
|
||||
(0..self.header().perp_oo_count()).map(|i| self.perp_orders_by_raw_index(i))
|
||||
(0..self.header().perp_oo_count()).map(|i| self.perp_order_by_raw_index(i))
|
||||
}
|
||||
|
||||
pub fn perp_next_order_slot(&self) -> Option<usize> {
|
||||
|
@ -563,8 +557,7 @@ impl<
|
|||
market_index: PerpMarketIndex,
|
||||
client_order_id: u64,
|
||||
) -> Option<(i128, Side)> {
|
||||
for i in 0..self.header().perp_oo_count() {
|
||||
let oo = self.perp_orders_by_raw_index(i);
|
||||
for oo in self.all_perp_orders() {
|
||||
if oo.order_market == market_index && oo.client_order_id == client_order_id {
|
||||
return Some((oo.order_id, oo.order_side));
|
||||
}
|
||||
|
@ -577,8 +570,7 @@ impl<
|
|||
market_index: PerpMarketIndex,
|
||||
order_id: i128,
|
||||
) -> Option<Side> {
|
||||
for i in 0..self.header().perp_oo_count() {
|
||||
let oo = self.perp_orders_by_raw_index(i);
|
||||
for oo in self.all_perp_orders() {
|
||||
if oo.order_market == market_index && oo.order_id == order_id {
|
||||
return Some(oo.order_side);
|
||||
}
|
||||
|
@ -730,7 +722,7 @@ impl<
|
|||
market_index: Serum3MarketIndex,
|
||||
) -> Option<&mut Serum3Orders> {
|
||||
let raw_index_opt = self
|
||||
.active_serum3_orders()
|
||||
.all_serum3_orders()
|
||||
.position(|p| p.is_active_for_market(market_index));
|
||||
raw_index_opt.map(|raw_index| self.serum3_orders_mut_by_raw_index(raw_index))
|
||||
}
|
||||
|
@ -741,7 +733,7 @@ impl<
|
|||
get_helper_mut(self.dynamic_mut(), offset)
|
||||
}
|
||||
|
||||
pub fn perp_orders_mut_by_raw_index(&mut self, raw_index: usize) -> &mut PerpOpenOrder {
|
||||
pub fn perp_order_mut_by_raw_index(&mut self, raw_index: usize) -> &mut PerpOpenOrder {
|
||||
let offset = self.header().perp_oo_offset(raw_index);
|
||||
get_helper_mut(self.dynamic_mut(), offset)
|
||||
}
|
||||
|
@ -751,7 +743,7 @@ impl<
|
|||
perp_market_index: PerpMarketIndex,
|
||||
) -> Result<(&mut PerpPosition, usize)> {
|
||||
let mut raw_index_opt = self
|
||||
.active_perp_positions()
|
||||
.all_perp_positions()
|
||||
.position(|p| p.is_active_for_market(perp_market_index));
|
||||
if raw_index_opt.is_none() {
|
||||
raw_index_opt = self.all_perp_positions().position(|p| !p.is_active());
|
||||
|
@ -779,6 +771,7 @@ impl<
|
|||
side: Side,
|
||||
order: &LeafNode,
|
||||
) -> Result<()> {
|
||||
// TODO: pass in the PerpPosition, currently has a creation side-effect
|
||||
let mut perp_account = self.ensure_perp_position(perp_market_index).unwrap().0;
|
||||
match side {
|
||||
Side::Bid => {
|
||||
|
@ -790,7 +783,7 @@ impl<
|
|||
};
|
||||
let slot = order.owner_slot as usize;
|
||||
|
||||
let mut oo = self.perp_orders_mut_by_raw_index(slot);
|
||||
let mut oo = self.perp_order_mut_by_raw_index(slot);
|
||||
oo.order_market = perp_market_index;
|
||||
oo.order_side = side;
|
||||
oo.order_id = order.key;
|
||||
|
@ -799,8 +792,9 @@ impl<
|
|||
}
|
||||
|
||||
pub fn remove_perp_order(&mut self, slot: usize, quantity: i64) -> Result<()> {
|
||||
// TODO: pass in the PerpPosition, currently has a creation side-effect
|
||||
{
|
||||
let oo = self.perp_orders_mut_by_raw_index(slot);
|
||||
let oo = self.perp_order_mut_by_raw_index(slot);
|
||||
require_neq!(oo.order_market, FREE_ORDER_SLOT);
|
||||
let order_side = oo.order_side;
|
||||
let perp_market_index = oo.order_market;
|
||||
|
@ -818,7 +812,7 @@ impl<
|
|||
}
|
||||
|
||||
// release space
|
||||
let oo = self.perp_orders_mut_by_raw_index(slot);
|
||||
let oo = self.perp_order_mut_by_raw_index(slot);
|
||||
oo.order_market = FREE_ORDER_SLOT;
|
||||
oo.order_side = Side::Bid;
|
||||
oo.order_id = 0i128;
|
||||
|
@ -832,6 +826,7 @@ impl<
|
|||
perp_market: &mut PerpMarket,
|
||||
fill: &FillEvent,
|
||||
) -> Result<()> {
|
||||
// TODO: pass in the PerpPosition, currently has a creation side-effect
|
||||
let pa = self.ensure_perp_position(perp_market_index).unwrap().0;
|
||||
pa.settle_funding(perp_market);
|
||||
|
||||
|
@ -871,6 +866,7 @@ impl<
|
|||
perp_market: &mut PerpMarket,
|
||||
fill: &FillEvent,
|
||||
) -> Result<()> {
|
||||
// TODO: pass in the PerpPosition, currently has a creation side-effect
|
||||
let pa = self.ensure_perp_position(perp_market_index).unwrap().0;
|
||||
pa.settle_funding(perp_market);
|
||||
|
||||
|
|
|
@ -393,7 +393,7 @@ impl<'a> Book<'a> {
|
|||
side_to_cancel_option: Option<Side>,
|
||||
) -> Result<()> {
|
||||
for i in 0..mango_account.header.perp_oo_count() {
|
||||
let oo = mango_account.perp_orders_by_raw_index(i);
|
||||
let oo = mango_account.perp_order_by_raw_index(i);
|
||||
if oo.order_market == FREE_ORDER_SLOT
|
||||
|| oo.order_market != perp_market.perp_market_index
|
||||
{
|
||||
|
|
|
@ -101,7 +101,7 @@ mod tests {
|
|||
|
||||
let mut new_order =
|
||||
|book: &mut Book, event_queue: &mut EventQueue, side, price, now_ts| -> i128 {
|
||||
let buffer = MangoAccount::default().try_to_vec().unwrap();
|
||||
let buffer = MangoAccount::default_for_tests().try_to_vec().unwrap();
|
||||
let mut account = MangoAccountValue::from_bytes(&buffer).unwrap();
|
||||
|
||||
let quantity = 1;
|
||||
|
@ -124,7 +124,7 @@ mod tests {
|
|||
u8::MAX,
|
||||
)
|
||||
.unwrap();
|
||||
account.perp_orders_by_raw_index(0).order_id
|
||||
account.perp_order_by_raw_index(0).order_id
|
||||
};
|
||||
|
||||
// insert bids until book side is full
|
||||
|
@ -196,7 +196,7 @@ mod tests {
|
|||
market.maker_fee = I80F48::from_num(-0.001f64);
|
||||
market.taker_fee = I80F48::from_num(0.01f64);
|
||||
|
||||
let buffer = MangoAccount::default().try_to_vec().unwrap();
|
||||
let buffer = MangoAccount::default_for_tests().try_to_vec().unwrap();
|
||||
let mut maker = MangoAccountValue::from_bytes(&buffer).unwrap();
|
||||
let mut taker = MangoAccountValue::from_bytes(&buffer).unwrap();
|
||||
|
||||
|
@ -225,19 +225,19 @@ mod tests {
|
|||
)
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
maker.perp_orders_mut_by_raw_index(0).order_market,
|
||||
maker.perp_order_mut_by_raw_index(0).order_market,
|
||||
market.perp_market_index
|
||||
);
|
||||
assert_eq!(
|
||||
maker.perp_orders_mut_by_raw_index(1).order_market,
|
||||
maker.perp_order_mut_by_raw_index(1).order_market,
|
||||
FREE_ORDER_SLOT
|
||||
);
|
||||
assert_ne!(maker.perp_orders_mut_by_raw_index(0).order_id, 0);
|
||||
assert_eq!(maker.perp_orders_mut_by_raw_index(0).client_order_id, 42);
|
||||
assert_eq!(maker.perp_orders_mut_by_raw_index(0).order_side, Side::Bid);
|
||||
assert_ne!(maker.perp_order_mut_by_raw_index(0).order_id, 0);
|
||||
assert_eq!(maker.perp_order_mut_by_raw_index(0).client_order_id, 42);
|
||||
assert_eq!(maker.perp_order_mut_by_raw_index(0).order_side, Side::Bid);
|
||||
assert!(bookside_contains_key(
|
||||
&book.bids,
|
||||
maker.perp_orders_mut_by_raw_index(0).order_id
|
||||
maker.perp_order_mut_by_raw_index(0).order_id
|
||||
));
|
||||
assert!(bookside_contains_price(&book.bids, price));
|
||||
assert_eq!(
|
||||
|
@ -279,7 +279,7 @@ mod tests {
|
|||
// the remainder of the maker order is still on the book
|
||||
// (the maker account is unchanged: it was not even passed in)
|
||||
let order =
|
||||
bookside_leaf_by_key(&book.bids, maker.perp_orders_by_raw_index(0).order_id).unwrap();
|
||||
bookside_leaf_by_key(&book.bids, maker.perp_order_by_raw_index(0).order_id).unwrap();
|
||||
assert_eq!(order.price(), price);
|
||||
assert_eq!(order.quantity, bid_quantity - match_quantity);
|
||||
|
||||
|
@ -292,7 +292,7 @@ mod tests {
|
|||
|
||||
// the taker account is updated
|
||||
assert_eq!(
|
||||
taker.perp_orders_by_raw_index(0).order_market,
|
||||
taker.perp_order_by_raw_index(0).order_market,
|
||||
FREE_ORDER_SLOT
|
||||
);
|
||||
assert_eq!(taker.perp_position_by_raw_index(0).bids_base_lots, 0);
|
||||
|
@ -334,7 +334,7 @@ mod tests {
|
|||
.unwrap();
|
||||
assert_eq!(market.open_interest, 2 * match_quantity);
|
||||
|
||||
assert_eq!(maker.perp_orders_by_raw_index(0).order_market, 0);
|
||||
assert_eq!(maker.perp_order_by_raw_index(0).order_market, 0);
|
||||
assert_eq!(
|
||||
maker.perp_position_by_raw_index(0).bids_base_lots,
|
||||
bid_quantity - match_quantity
|
||||
|
|
Loading…
Reference in New Issue