1use anyhow::{bail, Result};
2use percli_core::RiskEngine;
3
4const MARKET_DISCRIMINATOR: &[u8; 8] = b"percmrkt";
6
7const HEADER_SIZE: usize = 136;
9
10const ENGINE_OFFSET: usize = 8 + HEADER_SIZE;
12
13pub fn min_account_size() -> usize {
15 ENGINE_OFFSET + std::mem::size_of::<RiskEngine>()
16}
17
18pub fn read_authority(data: &[u8]) -> Result<[u8; 32]> {
20 if data.len() < ENGINE_OFFSET {
21 bail!("Account data too small for market header");
22 }
23 if &data[..8] != MARKET_DISCRIMINATOR {
25 bail!(
26 "Invalid market discriminator: expected {:?}, got {:?}",
27 MARKET_DISCRIMINATOR,
28 &data[..8]
29 );
30 }
31 let mut authority = [0u8; 32];
32 authority.copy_from_slice(&data[8..40]);
33 Ok(authority)
34}
35
36pub fn engine_from_data(data: &[u8]) -> Result<&RiskEngine> {
43 if data.len() < min_account_size() {
44 bail!(
45 "Account data too small: {} < {}",
46 data.len(),
47 min_account_size()
48 );
49 }
50 if &data[..8] != MARKET_DISCRIMINATOR {
51 bail!("Invalid market discriminator");
52 }
53 let engine_bytes = &data[ENGINE_OFFSET..ENGINE_OFFSET + std::mem::size_of::<RiskEngine>()];
54 Ok(unsafe { &*(engine_bytes.as_ptr() as *const RiskEngine) })
57}