From 7f72218a151b6196be0ad83008ddb80d499f34e4 Mon Sep 17 00:00:00 2001 From: skrrb Date: Wed, 7 Feb 2024 11:44:55 +0100 Subject: [PATCH] impl ZeroCopyDeserialize for jup --- lib/client/src/jup.rs | 15 +++++++++------ lib/client/src/util.rs | 17 ++++++++++++++++- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/lib/client/src/jup.rs b/lib/client/src/jup.rs index 77d0b0ebf..83d67a60b 100644 --- a/lib/client/src/jup.rs +++ b/lib/client/src/jup.rs @@ -1,4 +1,3 @@ -use anchor_lang::AccountDeserialize; use anchor_lang::__private::bytemuck::Zeroable; use anchor_lang::prelude::*; use anchor_spl::token::Token; @@ -14,6 +13,7 @@ use openbook_v2::{ use crate::{ book::{amounts_from_book, Amounts}, remaining_accounts_to_crank, + util::ZeroCopyDeserialize, }; use jupiter_amm_interface::{ AccountMap, Amm, KeyedAccount, Quote, QuoteParams, Side as JupiterSide, Swap, @@ -59,7 +59,8 @@ impl Amm for OpenBookMarket { } fn from_keyed_account(keyed_account: &KeyedAccount) -> Result { - let market = Market::try_deserialize(&mut keyed_account.account.data.as_slice())?; + let market = + Market::try_deserialize_from_slice(&mut keyed_account.account.data.as_slice())?; let mut related_accounts = vec![ market.bids, market.asks, @@ -91,13 +92,14 @@ impl Amm for OpenBookMarket { fn update(&mut self, account_map: &AccountMap) -> Result<()> { let bids_data = account_map.get(&self.market.bids).unwrap(); - self.bids = BookSide::try_deserialize(&mut bids_data.data.as_slice()).unwrap(); + self.bids = BookSide::try_deserialize_from_slice(&mut bids_data.data.as_slice()).unwrap(); let asks_data = account_map.get(&self.market.asks).unwrap(); - self.asks = BookSide::try_deserialize(&mut asks_data.data.as_slice()).unwrap(); + self.asks = BookSide::try_deserialize_from_slice(&mut asks_data.data.as_slice()).unwrap(); let event_heap_data = account_map.get(&self.market.event_heap).unwrap(); - self.event_heap = EventHeap::try_deserialize(&mut event_heap_data.data.as_slice()).unwrap(); + self.event_heap = + EventHeap::try_deserialize_from_slice(&mut event_heap_data.data.as_slice()).unwrap(); let clock_data = account_map.get(&clock::ID).unwrap(); let clock: Clock = bincode::deserialize(clock_data.data.as_slice())?; @@ -401,7 +403,8 @@ mod test { let user_input_account = Pubkey::new_unique(); let user_output_account = Pubkey::new_unique(); - let market_data = Market::try_deserialize(&mut market_account.account.data.as_slice())?; + let market_data = + Market::try_deserialize_from_slice(&mut market_account.account.data.as_slice())?; add_token_account(user_input_account, user.pubkey(), input_mint); add_token_account(user_output_account, user.pubkey(), output_mint); diff --git a/lib/client/src/util.rs b/lib/client/src/util.rs index 02d0e9177..fd771debb 100644 --- a/lib/client/src/util.rs +++ b/lib/client/src/util.rs @@ -1,3 +1,4 @@ +use anchor_lang::{error::Error, AccountDeserialize, ZeroCopy}; use solana_client::{ client_error::Result as ClientResult, rpc_client::RpcClient, rpc_request::RpcError, }; @@ -6,9 +7,23 @@ use solana_sdk::{ clock::Slot, commitment_config::CommitmentConfig, signature::Signature, transaction::uses_durable_nonce, }; - use std::{thread, time}; +/// zero copy accounts could be larger than the underlying struct +/// https://github.com/coral-xyz/anchor/blob/08110e63fa5a7369830db972d4abdcfa1aaa7f2e/lang/src/accounts/account_loader.rs#L165 +/// https://github.com/coral-xyz/anchor/blob/08110e63fa5a7369830db972d4abdcfa1aaa7f2e/lang/attribute/account/src/lib.rs#L195 +pub trait ZeroCopyDeserialize { + fn try_deserialize_from_slice(buf: &mut &[u8]) -> Result + where + Self: Sized; +} + +impl ZeroCopyDeserialize for T { + fn try_deserialize_from_slice(buf: &mut &[u8]) -> Result { + Self::try_deserialize(&mut &buf[..std::mem::size_of::() + 8]) + } +} + /// Some Result<> types don't convert to anyhow::Result nicely. Force them through stringification. pub trait AnyhowWrap { type Value;