diff --git a/programs/openbook-v2/src/instructions/cancel_all_and_place_orders.rs b/programs/openbook-v2/src/instructions/cancel_all_and_place_orders.rs index 0a5de9ee5..e49c966bc 100644 --- a/programs/openbook-v2/src/instructions/cancel_all_and_place_orders.rs +++ b/programs/openbook-v2/src/instructions/cancel_all_and_place_orders.rs @@ -88,6 +88,7 @@ pub fn cancel_all_and_place_orders<'c: 'info, 'info>( } = book.new_order( order, &mut market, + &ctx.accounts.market.key(), &mut event_heap, oracle_price_lots, Some(&mut open_orders_account), diff --git a/programs/openbook-v2/src/instructions/deposit.rs b/programs/openbook-v2/src/instructions/deposit.rs index b25a320ce..5329c39c1 100644 --- a/programs/openbook-v2/src/instructions/deposit.rs +++ b/programs/openbook-v2/src/instructions/deposit.rs @@ -1,6 +1,6 @@ use crate::accounts_ix::Deposit; use crate::error::*; -use crate::logs::DepositLog; +use crate::logs::{emit_stack, DepositLog}; use crate::token_utils::*; use anchor_lang::prelude::*; @@ -33,7 +33,7 @@ pub fn deposit(ctx: Context, base_amount: u64, quote_amount: u64) -> Re market.quote_deposit_total += quote_amount; if base_amount > 0 || quote_amount > 0 { - emit!(DepositLog { + emit_stack(DepositLog { open_orders_account: ctx.accounts.open_orders_account.key(), signer: ctx.accounts.owner.key(), base_amount, diff --git a/programs/openbook-v2/src/instructions/place_order.rs b/programs/openbook-v2/src/instructions/place_order.rs index a7bdc9bb6..07b228d11 100644 --- a/programs/openbook-v2/src/instructions/place_order.rs +++ b/programs/openbook-v2/src/instructions/place_order.rs @@ -63,6 +63,7 @@ pub fn place_order<'c: 'info, 'info>( } = book.new_order( &order, &mut market, + &ctx.accounts.market.key(), &mut event_heap, oracle_price_lots, Some(&mut open_orders_account), diff --git a/programs/openbook-v2/src/instructions/place_take_order.rs b/programs/openbook-v2/src/instructions/place_take_order.rs index b25c9d097..53bada776 100644 --- a/programs/openbook-v2/src/instructions/place_take_order.rs +++ b/programs/openbook-v2/src/instructions/place_take_order.rs @@ -54,6 +54,7 @@ pub fn place_take_order<'c: 'info, 'info>( } = book.new_order( &order, &mut market, + &ctx.accounts.market.key(), &mut event_heap, oracle_price_lots, None, diff --git a/programs/openbook-v2/src/instructions/set_delegate.rs b/programs/openbook-v2/src/instructions/set_delegate.rs index a2f25422d..0bd5ab80c 100644 --- a/programs/openbook-v2/src/instructions/set_delegate.rs +++ b/programs/openbook-v2/src/instructions/set_delegate.rs @@ -1,7 +1,7 @@ use anchor_lang::prelude::*; use crate::accounts_ix::*; -use crate::logs::SetDelegateLog; +use crate::logs::{emit_stack, SetDelegateLog}; use crate::pubkey_option::NonZeroPubkeyOption; pub fn set_delegate(ctx: Context) -> Result<()> { @@ -16,9 +16,9 @@ pub fn set_delegate(ctx: Context) -> Result<()> { account.delegate = delegate_account; - emit!(SetDelegateLog { + emit_stack(SetDelegateLog { open_orders_account: ctx.accounts.open_orders_account.key(), - delegate: delegate_account.into() + delegate: delegate_account.into(), }); Ok(()) diff --git a/programs/openbook-v2/src/instructions/settle_funds.rs b/programs/openbook-v2/src/instructions/settle_funds.rs index 7f19b87e8..cc298473a 100644 --- a/programs/openbook-v2/src/instructions/settle_funds.rs +++ b/programs/openbook-v2/src/instructions/settle_funds.rs @@ -1,6 +1,7 @@ use anchor_lang::prelude::*; use crate::accounts_ix::*; +use crate::logs::emit_stack; use crate::logs::SettleFundsLog; use crate::state::*; use crate::token_utils::*; @@ -73,12 +74,12 @@ pub fn settle_funds<'info>(ctx: Context<'_, '_, '_, 'info, SettleFunds<'info>>) seeds, )?; - emit!(SettleFundsLog { + emit_stack(SettleFundsLog { open_orders_account: ctx.accounts.open_orders_account.key(), base_native: pa.base_free_native, quote_native: pa.quote_free_native, referrer_rebate, - referrer: ctx.accounts.referrer_account.as_ref().map(|acc| acc.key()) + referrer: ctx.accounts.referrer_account.as_ref().map(|acc| acc.key()), }); pa.base_free_native = 0; diff --git a/programs/openbook-v2/src/instructions/sweep_fees.rs b/programs/openbook-v2/src/instructions/sweep_fees.rs index 037130cb5..cefdd6008 100644 --- a/programs/openbook-v2/src/instructions/sweep_fees.rs +++ b/programs/openbook-v2/src/instructions/sweep_fees.rs @@ -2,7 +2,7 @@ use crate::state::market_seeds; use anchor_lang::prelude::*; use crate::accounts_ix::*; -use crate::logs::SweepFeesLog; +use crate::logs::{emit_stack, SweepFeesLog}; use crate::token_utils::*; pub fn sweep_fees(ctx: Context) -> Result<()> { @@ -24,7 +24,7 @@ pub fn sweep_fees(ctx: Context) -> Result<()> { seeds, )?; - emit!(SweepFeesLog { + emit_stack(SweepFeesLog { market: ctx.accounts.market.key(), amount, receiver: ctx.accounts.token_receiver_account.key(), diff --git a/programs/openbook-v2/src/logs.rs b/programs/openbook-v2/src/logs.rs index 98b3868ce..5de505883 100644 --- a/programs/openbook-v2/src/logs.rs +++ b/programs/openbook-v2/src/logs.rs @@ -1,6 +1,22 @@ use anchor_lang::prelude::*; use borsh::BorshSerialize; +#[inline(never)] // ensure fresh stack frame +pub fn emit_stack(e: T) { + use std::io::{Cursor, Write}; + + // stack buffer, stack frames are 4kb + let mut buffer = [0u8; 3000]; + + let mut cursor = Cursor::new(&mut buffer[..]); + cursor.write_all(&T::DISCRIMINATOR).unwrap(); + e.serialize(&mut cursor) + .expect("event must fit into stack buffer"); + + let pos = cursor.position() as usize; + anchor_lang::solana_program::log::sol_log_data(&[&buffer[..pos]]); +} + #[event] pub struct DepositLog { pub open_orders_account: Pubkey, @@ -33,6 +49,12 @@ pub struct FillLog { pub quantity: i64, // number of base lots } +#[event] +pub struct TakerSignatureLog { + pub market: Pubkey, + pub seq_num: u64, +} + #[event] pub struct MarketMetaDataLog { pub market: Pubkey, diff --git a/programs/openbook-v2/src/state/open_orders_account.rs b/programs/openbook-v2/src/state/open_orders_account.rs index e462c143a..81ad493f8 100644 --- a/programs/openbook-v2/src/state/open_orders_account.rs +++ b/programs/openbook-v2/src/state/open_orders_account.rs @@ -3,7 +3,7 @@ use derivative::Derivative; use static_assertions::const_assert_eq; use std::mem::size_of; -use crate::logs::FillLog; +use crate::logs::{emit_stack, FillLog}; use crate::pubkey_option::NonZeroPubkeyOption; use crate::{error::*, logs::OpenOrdersPositionLog}; @@ -205,13 +205,13 @@ impl OpenOrdersAccount { 0 }; - emit!(FillLog { + emit_stack(FillLog { market: self.market, taker_side: fill.taker_side, maker_slot: fill.maker_slot, maker_out: fill.maker_out(), timestamp: fill.timestamp, - seq_num: fill.seq_num, + seq_num: fill.market_seq_num, maker: fill.maker, maker_client_order_id: fill.maker_client_order_id, maker_fee: maker_fees, @@ -224,7 +224,7 @@ impl OpenOrdersAccount { }); let pa = &self.position; - emit!(OpenOrdersPositionLog { + emit_stack(OpenOrdersPositionLog { owner: self.owner, open_orders_account_num: self.account_num, market: self.market, @@ -236,7 +236,7 @@ impl OpenOrdersAccount { locked_maker_fees: pa.locked_maker_fees, referrer_rebates_available: pa.referrer_rebates_available, maker_volume: pa.maker_volume, - taker_volume: pa.taker_volume + taker_volume: pa.taker_volume, }) } @@ -260,7 +260,7 @@ impl OpenOrdersAccount { pa.referrer_rebates_available += referrer_amount; market.referrer_rebates_accrued += referrer_amount; - emit!(OpenOrdersPositionLog { + emit_stack(OpenOrdersPositionLog { owner: self.owner, open_orders_account_num: self.account_num, market: self.market, @@ -272,7 +272,7 @@ impl OpenOrdersAccount { locked_maker_fees: pa.locked_maker_fees, referrer_rebates_available: pa.referrer_rebates_available, maker_volume: pa.maker_volume, - taker_volume: pa.taker_volume + taker_volume: pa.taker_volume, }) } diff --git a/programs/openbook-v2/src/state/orderbook/book.rs b/programs/openbook-v2/src/state/orderbook/book.rs index 725fcf85f..9d771e05c 100644 --- a/programs/openbook-v2/src/state/orderbook/book.rs +++ b/programs/openbook-v2/src/state/orderbook/book.rs @@ -1,4 +1,4 @@ -use crate::logs::TotalOrderFillEvent; +use crate::logs::*; use crate::state::MAX_OPEN_ORDERS; use crate::{ error::*, @@ -62,6 +62,7 @@ impl<'a> Orderbook<'a> { &mut self, order: &Order, open_book_market: &mut Market, + market_pk: &Pubkey, event_heap: &mut EventHeap, oracle_price_lots: Option, mut open_orders_account: Option<&mut OpenOrdersAccount>, @@ -229,7 +230,7 @@ impl<'a> Orderbook<'a> { maker_out, best_opposing.node.owner_slot, now_ts, - event_heap.header.seq_num, + market.seq_num, best_opposing.node.owner, best_opposing.node.client_order_id, best_opposing.node.timestamp, @@ -240,6 +241,11 @@ impl<'a> Orderbook<'a> { match_base_lots, ); + emit_stack(TakerSignatureLog { + market: *market_pk, + seq_num: market.seq_num, + }); + process_fill_event( fill, market, @@ -298,7 +304,7 @@ impl<'a> Orderbook<'a> { ), }; - emit!(TotalOrderFillEvent { + emit_stack(TotalOrderFillEvent { side: side.into(), taker: *owner, total_quantity_paid, diff --git a/programs/openbook-v2/src/state/orderbook/heap.rs b/programs/openbook-v2/src/state/orderbook/heap.rs index 1d705bb23..d2ef2452e 100644 --- a/programs/openbook-v2/src/state/orderbook/heap.rs +++ b/programs/openbook-v2/src/state/orderbook/heap.rs @@ -243,7 +243,7 @@ pub struct FillEvent { pub maker_slot: u8, pub padding: [u8; 4], pub timestamp: u64, - pub seq_num: u64, + pub market_seq_num: u64, pub maker: Pubkey, @@ -269,7 +269,7 @@ impl FillEvent { maker_out: bool, maker_slot: u8, timestamp: u64, - seq_num: u64, + market_seq_num: u64, maker: Pubkey, maker_client_order_id: u64, maker_timestamp: u64, @@ -285,7 +285,7 @@ impl FillEvent { maker_out: maker_out.into(), maker_slot, timestamp, - seq_num, + market_seq_num, maker, maker_client_order_id, maker_timestamp, diff --git a/programs/openbook-v2/src/state/orderbook/mod.rs b/programs/openbook-v2/src/state/orderbook/mod.rs index 107f95347..db1a5e6b5 100644 --- a/programs/openbook-v2/src/state/orderbook/mod.rs +++ b/programs/openbook-v2/src/state/orderbook/mod.rs @@ -99,6 +99,7 @@ mod tests { let (mut openbook_market, oracle_price_lots, mut event_heap, book_accs) = test_setup(5000.0); let mut book = book_accs.orderbook(); + let market_pk = Pubkey::new_unique(); let mut new_order = |book: &mut Orderbook, event_heap: &mut EventHeap, side, price_lots, now_ts| -> u128 { @@ -121,6 +122,7 @@ mod tests { self_trade_behavior: SelfTradeBehavior::DecrementTake, }, &mut openbook_market, + &market_pk, event_heap, oracle_price_lots, Some(&mut account), @@ -229,6 +231,7 @@ mod tests { fn book_new_order() { let (mut market, oracle_price_lots, mut event_heap, book_accs) = test_setup(1000.0); let mut book = book_accs.orderbook(); + let market_pk = Pubkey::new_unique(); // Add lots and fees to make sure to exercise unit conversion market.base_lot_size = 10; @@ -262,6 +265,7 @@ mod tests { self_trade_behavior: SelfTradeBehavior::DecrementTake, }, &mut market, + &market_pk, &mut event_heap, oracle_price_lots, Some(&mut maker), @@ -308,6 +312,7 @@ mod tests { self_trade_behavior: SelfTradeBehavior::DecrementTake, }, &mut market, + &market_pk, &mut event_heap, oracle_price_lots, Some(&mut taker), @@ -371,6 +376,7 @@ mod tests { let (mut market, oracle_price_lots, mut event_heap, book_accs) = test_setup(5000.0); let quote_lot_size = market.quote_lot_size; let mut book = book_accs.orderbook(); + let market_pk = Pubkey::new_unique(); let mut new_order = |book: &mut Orderbook, event_heap: &mut EventHeap, @@ -395,6 +401,7 @@ mod tests { self_trade_behavior: SelfTradeBehavior::DecrementTake, }, &mut market, + &market_pk, event_heap, oracle_price_lots, Some(&mut account),