1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
use borsh::{BorshDeserialize, BorshSerialize};
use solana_program::{
account_info::{next_account_info, AccountInfo},
entrypoint::ProgramResult,
program_error::ProgramError,
pubkey::Pubkey,
};
use crate::{
error::AoError,
orderbook::{OrderBookState, OrderSummary},
state::{
get_side_from_order_id, EventQueue, EventQueueHeader, MarketState, EVENT_QUEUE_HEADER_LEN,
},
utils::{check_account_key, check_account_owner, check_signer, fp32_mul},
};
#[derive(BorshDeserialize, BorshSerialize, Clone)]
pub struct Params {
pub order_id: u128,
}
struct Accounts<'a, 'b: 'a> {
market: &'a AccountInfo<'b>,
event_queue: &'a AccountInfo<'b>,
bids: &'a AccountInfo<'b>,
asks: &'a AccountInfo<'b>,
authority: &'a AccountInfo<'b>,
}
impl<'a, 'b: 'a> Accounts<'a, 'b> {
pub fn parse(
program_id: &Pubkey,
accounts: &'a [AccountInfo<'b>],
) -> Result<Self, ProgramError> {
let accounts_iter = &mut accounts.iter();
let a = Self {
market: next_account_info(accounts_iter)?,
event_queue: next_account_info(accounts_iter)?,
bids: next_account_info(accounts_iter)?,
asks: next_account_info(accounts_iter)?,
authority: next_account_info(accounts_iter)?,
};
check_account_owner(a.market, program_id)?;
check_account_owner(a.event_queue, program_id)?;
check_account_owner(a.bids, program_id)?;
check_account_owner(a.asks, program_id)?;
check_signer(a.authority)?;
Ok(a)
}
}
pub(crate) fn process(
program_id: &Pubkey,
accounts: &[AccountInfo],
params: Params,
) -> ProgramResult {
let accounts = Accounts::parse(program_id, accounts)?;
let mut market_data: &[u8] = &accounts.market.data.borrow();
let market_state = MarketState::deserialize(&mut market_data)
.unwrap()
.check()?;
check_account_key(accounts.event_queue, &market_state.event_queue)
.map_err(|_| AoError::WrongEventQueueAccount)?;
check_account_key(accounts.bids, &market_state.bids).map_err(|_| AoError::WrongBidsAccount)?;
check_account_key(accounts.asks, &market_state.asks).map_err(|_| AoError::WrongAsksAccount)?;
check_account_key(accounts.authority, &market_state.caller_authority)
.map_err(|_| AoError::WrongCallerAuthority)?;
let callback_info_len = market_state.callback_info_len as usize;
let mut order_book = OrderBookState::new_safe(
accounts.bids,
accounts.asks,
market_state.callback_info_len as usize,
market_state.callback_id_len as usize,
)?;
let header = {
let mut event_queue_data: &[u8] =
&accounts.event_queue.data.borrow()[0..EVENT_QUEUE_HEADER_LEN];
EventQueueHeader::deserialize(&mut event_queue_data).unwrap()
};
let event_queue = EventQueue::new_safe(header, &accounts.event_queue, callback_info_len)?;
let slab = order_book.get_tree(get_side_from_order_id(params.order_id));
let node = slab
.remove_by_key(params.order_id)
.ok_or(AoError::OrderNotFound)?;
let leaf_node = node.as_leaf().unwrap();
let total_base_qty = leaf_node.base_quantity;
let total_quote_qty = fp32_mul(leaf_node.base_quantity, leaf_node.price());
let order_summary = OrderSummary {
posted_order_id: None,
total_base_qty,
total_quote_qty,
total_base_qty_posted: 0,
};
event_queue.write_to_register(order_summary);
let mut event_queue_header_data: &mut [u8] = &mut accounts.event_queue.data.borrow_mut();
event_queue
.header
.serialize(&mut event_queue_header_data)
.unwrap();
order_book.commit_changes();
Ok(())
}