Skip to content

Commit 0151da0

Browse files
committed
deserialize properly
1 parent 5483284 commit 0151da0

File tree

8 files changed

+187
-67
lines changed

8 files changed

+187
-67
lines changed

test-integration/Cargo.lock

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test-integration/programs/schedulecommit/src/api.rs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ use solana_program::{
99
};
1010

1111
use crate::{
12-
DelegateCpiArgs, ScheduleCommitCpiArgs, ScheduleCommitInstruction,
12+
BookUpdate, DelegateCpiArgs, ScheduleCommitCpiArgs,
13+
ScheduleCommitInstruction,
1314
};
1415

1516
pub fn init_account_instruction(
@@ -161,6 +162,24 @@ pub fn schedule_commit_cpi_instruction(
161162
)
162163
}
163164

165+
pub fn update_order_book_instruction(
166+
payer: Pubkey,
167+
order_book: Pubkey,
168+
update: BookUpdate,
169+
) -> Instruction {
170+
let program_id = crate::id();
171+
let account_metas = vec![
172+
AccountMeta::new(payer, true),
173+
AccountMeta::new(order_book, false),
174+
];
175+
176+
Instruction::new_with_borsh(
177+
program_id,
178+
&ScheduleCommitInstruction::UpdateOrderBook(update),
179+
account_metas,
180+
)
181+
}
182+
164183
pub fn schedule_commit_diff_instruction_for_order_book(
165184
payer: Pubkey,
166185
order_book: Pubkey,

test-integration/programs/schedulecommit/src/lib.rs

Lines changed: 13 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ mod utils;
3636

3737
use order_book::*;
3838

39-
pub use order_book::{OrderBookOwned, OrderLevel};
39+
pub use order_book::{BookUpdate, OrderBookOwned, OrderLevel};
4040

4141
declare_id!("9hgprgZiRWmy8KkfvUuaVkDGrqo9GzeXMohwq6BazgUY");
4242

@@ -372,12 +372,6 @@ pub fn process_delegate_order_book(
372372
Ok(())
373373
}
374374

375-
#[derive(BorshSerialize, BorshDeserialize, Debug, Clone)]
376-
pub struct BookUpdate {
377-
bids: Vec<OrderLevel>,
378-
asks: Vec<OrderLevel>,
379-
}
380-
381375
// -----------------
382376
// UpdateOrderBook
383377
// -----------------
@@ -393,10 +387,8 @@ fn process_update_order_book<'a>(
393387
assert_is_signer(payer_info, "payer")?;
394388

395389
let mut book_raw = order_book_account.try_borrow_mut_data()?;
396-
let mut order_book = OrderBook::new(&mut book_raw);
397390

398-
order_book.add_bids(&updates.bids);
399-
order_book.add_asks(&updates.asks);
391+
OrderBook::new(&mut book_raw).update_from(updates);
400392

401393
Ok(())
402394
}
@@ -418,17 +410,17 @@ pub fn process_schedulecommit_for_orderbook(
418410
// - TransactionError(InstructionError(0, AccountBorrowFailed))
419411
// - Program 9hgprgZiRWmy8KkfvUuaVkDGrqo9GzeXMohwq6BazgUY failed: instruction tries to borrow reference for an account which is already borrowed
420412
{
421-
let mut book_raw = order_book_account.try_borrow_mut_data()?;
422-
let mut order_book = OrderBook::new(&mut book_raw);
423-
424-
order_book.add_bids(&[OrderLevel {
425-
price: 90000,
426-
size: 10,
427-
}]);
428-
order_book.add_asks(&[OrderLevel {
429-
price: 125000,
430-
size: 16,
431-
}]);
413+
// let mut book_raw = order_book_account.try_borrow_mut_data()?;
414+
// let mut order_book = OrderBook::new(&mut book_raw);
415+
416+
// order_book.add_bids(&[OrderLevel {
417+
// price: 90000,
418+
// size: 10,
419+
// }]);
420+
// order_book.add_asks(&[OrderLevel {
421+
// price: 125000,
422+
// size: 16,
423+
// }]);
432424
}
433425

434426
commit_diff_and_undelegate_accounts(

test-integration/programs/schedulecommit/src/order_book.rs

Lines changed: 67 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,19 @@ use borsh::{BorshDeserialize, BorshSerialize};
44

55
#[repr(C)]
66
#[derive(
7-
BorshSerialize, BorshDeserialize, Debug, Clone, Copy, PartialEq, Eq,
7+
BorshSerialize, BorshDeserialize, Debug, Clone, Copy, Default, PartialEq, Eq,
88
)]
99
pub struct OrderLevel {
10-
pub price: u64, // use f64
10+
pub price: u64, // ideally both fields could be some decimal value
1111
pub size: u64,
1212
}
1313

14+
#[derive(BorshSerialize, BorshDeserialize, Debug, Clone, Default)]
15+
pub struct BookUpdate {
16+
pub bids: Vec<OrderLevel>,
17+
pub asks: Vec<OrderLevel>,
18+
}
19+
1420
#[repr(C, align(4))]
1521
pub struct OrderBookHeader {
1622
pub bids_len: u32,
@@ -20,24 +26,37 @@ pub struct OrderBookHeader {
2026
const ORDER_LEVEL_SIZE: usize = std::mem::size_of::<OrderLevel>();
2127
const HEADER_SIZE: usize = std::mem::size_of::<OrderBookHeader>();
2228

23-
#[derive(Debug, Clone, PartialEq, Eq)]
29+
#[derive(Default, Debug, Clone, PartialEq, Eq)]
2430
pub struct OrderBookOwned {
2531
pub bids: Vec<OrderLevel>,
2632
pub asks: Vec<OrderLevel>,
2733
}
2834

35+
impl From<&OrderBook<'_>> for OrderBookOwned {
36+
fn from(book_ref: &OrderBook) -> Self {
37+
let mut book = Self::default();
38+
book.bids.extend_from_slice(book_ref.bids());
39+
book.asks.extend(book_ref.asks_reversed().iter().rev());
40+
book
41+
}
42+
}
43+
2944
impl borsh::de::BorshDeserialize for OrderBookOwned {
45+
fn deserialize(buf: &mut &[u8]) -> Result<Self, borsh::io::Error> {
46+
let (book_bytes, rest) = buf.split_at(buf.len());
47+
*buf = rest; // rest is actually empty
48+
49+
Ok(Self::from(&OrderBook::new(unsafe {
50+
slice::from_raw_parts_mut(
51+
book_bytes.as_ptr() as *mut u8,
52+
book_bytes.len(),
53+
)
54+
})))
55+
}
3056
fn deserialize_reader<R: borsh::io::Read>(
31-
reader: &mut R,
57+
_reader: &mut R,
3258
) -> ::core::result::Result<Self, borsh::io::Error> {
33-
println!("OrderBookOwned deserialization");
34-
reader.read_to_end(&mut vec![]);
35-
Ok(Self {
36-
bids: vec![],
37-
asks: vec![],
38-
})
39-
//let read
40-
//reader.read_exact(buf)
59+
unimplemented!("deserialize_reader() not implemented. Please use buffer version as it needs to know size of the buffer")
4160
}
4261
}
4362
pub struct OrderBook<'a> {
@@ -74,6 +93,11 @@ impl<'a> OrderBook<'a> {
7493
}
7594
}
7695

96+
pub fn update_from(&mut self, updates: BookUpdate) {
97+
self.add_bids(&updates.bids);
98+
self.add_asks(&updates.asks);
99+
}
100+
77101
pub fn add_bids(
78102
&mut self,
79103
bids: &[OrderLevel],
@@ -82,18 +106,15 @@ impl<'a> OrderBook<'a> {
82106
return None;
83107
}
84108
let new_bids_len = self.bids_len() + bids.len();
85-
let bids_space = unsafe { self.bids(new_bids_len) };
109+
let bids_space =
110+
unsafe { self.bids_with_uninitialized_slots(new_bids_len) };
86111

87112
bids_space[self.bids_len()..].copy_from_slice(bids);
88113
self.header.bids_len = new_bids_len as u32;
89114

90115
Some(bids_space)
91116
}
92117

93-
pub fn bids_len(&self) -> usize {
94-
self.header.bids_len as usize
95-
}
96-
97118
pub fn add_asks(
98119
&mut self,
99120
asks: &[OrderLevel],
@@ -102,7 +123,8 @@ impl<'a> OrderBook<'a> {
102123
return None;
103124
}
104125
let new_asks_len = self.asks_len() + asks.len();
105-
let asks_space = unsafe { self.asks(new_asks_len) };
126+
let asks_space =
127+
unsafe { self.asks_with_uninitialized_slots(new_asks_len) };
106128

107129
// copy in the reverse order
108130
for (dst, src) in
@@ -115,15 +137,40 @@ impl<'a> OrderBook<'a> {
115137
Some(asks_space)
116138
}
117139

140+
pub fn bids(&self) -> &'a [OrderLevel] {
141+
unsafe { slice::from_raw_parts(self.levels, self.bids_len()) }
142+
}
143+
144+
/// Note that the returned slice is in reverse order, means the first entry is the latest
145+
/// entry and the last entry is the oldest entry.
146+
pub fn asks_reversed(&self) -> &'a [OrderLevel] {
147+
unsafe {
148+
slice::from_raw_parts(
149+
self.levels.add(self.capacity - self.asks_len()),
150+
self.asks_len(),
151+
)
152+
}
153+
}
154+
155+
pub fn bids_len(&self) -> usize {
156+
self.header.bids_len as usize
157+
}
158+
118159
pub fn asks_len(&self) -> usize {
119160
self.header.asks_len as usize
120161
}
121162

122-
unsafe fn bids(&mut self, bids_len: usize) -> &'a mut [OrderLevel] {
163+
unsafe fn bids_with_uninitialized_slots(
164+
&mut self,
165+
bids_len: usize,
166+
) -> &'a mut [OrderLevel] {
123167
slice::from_raw_parts_mut(self.levels, bids_len)
124168
}
125169

126-
unsafe fn asks(&mut self, asks_len: usize) -> &'a mut [OrderLevel] {
170+
unsafe fn asks_with_uninitialized_slots(
171+
&mut self,
172+
asks_len: usize,
173+
) -> &'a mut [OrderLevel] {
127174
slice::from_raw_parts_mut(
128175
self.levels.add(self.capacity - asks_len),
129176
asks_len as usize,

test-integration/schedulecommit/client/src/schedule_commit_context.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
use std::{fmt, ops::Deref};
22

33
use anyhow::{Context, Result};
4-
use integration_test_tools::{scheduled_commits, IntegrationTestContext};
4+
use integration_test_tools::IntegrationTestContext;
55
use program_schedulecommit::api::{
6-
delegate_account_cpi_instruction, grow_order_book_instruction,
7-
init_account_instruction, init_order_book_instruction, init_payer_escrow,
8-
pda_and_bump,
6+
delegate_account_cpi_instruction, init_account_instruction,
7+
init_order_book_instruction, init_payer_escrow,
98
};
109
use solana_rpc_client::rpc_client::{RpcClient, SerializableTransaction};
1110
use solana_rpc_client_api::config::RpcSendTransactionConfig;
@@ -14,7 +13,6 @@ use solana_sdk::signer::SeedDerivable;
1413
use solana_sdk::{
1514
commitment_config::CommitmentConfig,
1615
compute_budget::ComputeBudgetInstruction,
17-
entrypoint::MAX_PERMITTED_DATA_INCREASE,
1816
hash::Hash,
1917
native_token::LAMPORTS_PER_SOL,
2018
pubkey::Pubkey,
@@ -134,7 +132,7 @@ impl ScheduleCommitTestContext {
134132
// [grow_order_book_instruction(
135133
// payer.pubkey(),
136134
// *committee,
137-
// MAX_PERMITTED_DATA_INCREASE as u64,
135+
// 10 * 1024
138136
// )]
139137
// },
140138
// ));

test-integration/schedulecommit/test-scenarios/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,5 @@ solana-rpc-client = { workspace = true }
1616
solana-rpc-client-api = { workspace = true }
1717
solana-sdk = { workspace = true }
1818
test-tools-core = { workspace = true }
19+
rand = { workspace = true }
20+
borsh = { workspace = true }

0 commit comments

Comments
 (0)