update
This commit is contained in:
parent
b0a364523a
commit
3b680a6cf9
|
@ -1,6 +1,7 @@
|
|||
//! `anchor_client` provides an RPC client to send transactions and fetch
|
||||
//! deserialized accounts from Solana programs written in `anchor_lang`.
|
||||
|
||||
use anchor_lang::accounts::header;
|
||||
use anchor_lang::solana_program::instruction::{AccountMeta, Instruction};
|
||||
use anchor_lang::solana_program::program_error::ProgramError;
|
||||
use anchor_lang::solana_program::pubkey::Pubkey;
|
||||
|
@ -292,23 +293,11 @@ fn handle_program_log<T: anchor_lang::Event + anchor_lang::AnchorDeserialize>(
|
|||
|
||||
let mut slice: &[u8] = &borsh_bytes[..];
|
||||
|
||||
#[cfg(feature = "deprecated-layout")]
|
||||
let disc: [u8; 8] = {
|
||||
let mut disc = [0; 8];
|
||||
disc.copy_from_slice(&borsh_bytes[..8]);
|
||||
slice = &slice[8..];
|
||||
disc
|
||||
};
|
||||
#[cfg(not(feature = "deprecated-layout"))]
|
||||
let disc: [u8; 4] = {
|
||||
let mut disc = [0; 4];
|
||||
disc.copy_from_slice(&borsh_bytes[2..6]);
|
||||
slice = &slice[8..];
|
||||
disc
|
||||
};
|
||||
let disc = header::read_discriminator(slice);
|
||||
slice = &slice[8..];
|
||||
|
||||
let mut event = None;
|
||||
if disc == T::discriminator() {
|
||||
if disc == &T::discriminator() {
|
||||
let e: T = anchor_lang::AnchorDeserialize::deserialize(&mut slice)
|
||||
.map_err(|e| ClientError::LogParseError(e.to_string()))?;
|
||||
event = Some(e);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
//! Account container that checks ownership on deserialization.
|
||||
|
||||
use crate::accounts::header;
|
||||
use crate::error::ErrorCode;
|
||||
use crate::*;
|
||||
use solana_program::account_info::AccountInfo;
|
||||
|
@ -334,10 +335,7 @@ impl<'info, T: AccountSerialize + AccountDeserialize + Owner + Clone> AccountsEx
|
|||
if &T::owner() == program_id {
|
||||
let info = self.to_account_info();
|
||||
let mut data = info.try_borrow_mut_data()?;
|
||||
|
||||
// Chop off the header.
|
||||
let dst: &mut [u8] = &mut data[8..];
|
||||
|
||||
let dst = header::read_data_mut(&mut data);
|
||||
let mut cursor = std::io::Cursor::new(dst);
|
||||
self.account.try_serialize(&mut cursor)?;
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
//! Type facilitating on demand zero copy deserialization.
|
||||
|
||||
use crate::accounts::header;
|
||||
use crate::error::ErrorCode;
|
||||
use crate::*;
|
||||
use arrayref::array_ref;
|
||||
use solana_program::account_info::AccountInfo;
|
||||
use solana_program::entrypoint::ProgramResult;
|
||||
use solana_program::instruction::AccountMeta;
|
||||
|
@ -120,12 +120,7 @@ impl<'info, T: ZeroCopy + Owner> AccountLoader<'info, T> {
|
|||
return Err(ErrorCode::AccountOwnedByWrongProgram.into());
|
||||
}
|
||||
let data: &[u8] = &acc_info.try_borrow_data()?;
|
||||
// Discriminator must match.
|
||||
#[cfg(feature = "deprecated-layout")]
|
||||
let disc_bytes = array_ref![data, 0, 8];
|
||||
#[cfg(not(feature = "deprecated-layout"))]
|
||||
let disc_bytes = array_ref![data, 2, 4];
|
||||
|
||||
let disc_bytes = header::read_discriminator(data);
|
||||
if disc_bytes != &T::discriminator() {
|
||||
return Err(ErrorCode::AccountDiscriminatorMismatch.into());
|
||||
}
|
||||
|
@ -147,12 +142,7 @@ impl<'info, T: ZeroCopy + Owner> AccountLoader<'info, T> {
|
|||
/// Returns a Ref to the account data structure for reading.
|
||||
pub fn load(&self) -> Result<Ref<T>, ProgramError> {
|
||||
let data = self.acc_info.try_borrow_data()?;
|
||||
|
||||
#[cfg(feature = "deprecated-layout")]
|
||||
let disc_bytes = array_ref![data, 0, 8];
|
||||
#[cfg(not(feature = "deprecated-layout"))]
|
||||
let disc_bytes = array_ref![data, 2, 4];
|
||||
|
||||
let disc_bytes = header::read_discriminator(&data);
|
||||
if disc_bytes != &T::discriminator() {
|
||||
return Err(ErrorCode::AccountDiscriminatorMismatch.into());
|
||||
}
|
||||
|
@ -170,12 +160,7 @@ impl<'info, T: ZeroCopy + Owner> AccountLoader<'info, T> {
|
|||
}
|
||||
|
||||
let data = self.acc_info.try_borrow_mut_data()?;
|
||||
|
||||
#[cfg(feature = "deprecated-layout")]
|
||||
let disc_bytes = array_ref![data, 0, 8];
|
||||
#[cfg(not(feature = "deprecated-layout"))]
|
||||
let disc_bytes = array_ref![data, 2, 4];
|
||||
|
||||
let disc_bytes = header::read_discriminator(&data);
|
||||
if disc_bytes != &T::discriminator() {
|
||||
return Err(ErrorCode::AccountDiscriminatorMismatch.into());
|
||||
}
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
use arrayref::array_ref;
|
||||
|
||||
#[cfg(feature = "deprecated-layout")]
|
||||
pub fn read_discriminator(data: &[u8]) -> &[u8; 8] {
|
||||
array_ref![data, 0, 8]
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "deprecated-layout"))]
|
||||
pub fn read_discriminator<'a>(data: &[u8]) -> &[u8; 4] {
|
||||
array_ref![data, 2, 4]
|
||||
}
|
||||
|
||||
#[cfg(feature = "deprecated-layout")]
|
||||
pub fn create_discriminator(account_name: &str, namespace: Option<&str>) -> [u8; 8] {
|
||||
let discriminator_preimage = format!("{}:{}", namespace.unwrap_or("account"), account_name);
|
||||
let mut discriminator = [0u8; 8];
|
||||
discriminator.copy_from_slice(
|
||||
&crate::solana_program::hash::hash(discriminator_preimage.as_bytes()).to_bytes()[..8],
|
||||
);
|
||||
discriminator
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "deprecated-layout"))]
|
||||
pub fn create_discriminator(account_name: &str, namespace: Option<&str>) -> [u8; 4] {
|
||||
let discriminator_preimage = format!("{}:{}", namespace.unwrap_or("account"), account_name);
|
||||
let mut discriminator = [0u8; 4];
|
||||
discriminator.copy_from_slice(
|
||||
&crate::solana_program::hash::hash(discriminator_preimage.as_bytes()).to_bytes()[..4],
|
||||
);
|
||||
discriminator
|
||||
}
|
||||
|
||||
// Header is 8 bytes regardless of layout.
|
||||
pub fn read_data(account_data: &[u8]) -> &[u8] {
|
||||
&account_data[8..]
|
||||
}
|
||||
|
||||
pub fn read_data_mut(account_data: &mut [u8]) -> &mut [u8] {
|
||||
&mut account_data[8..]
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
use crate::accounts::header;
|
||||
use crate::error::ErrorCode;
|
||||
use crate::*;
|
||||
use arrayref::array_ref;
|
||||
|
@ -59,13 +60,7 @@ impl<'info, T: ZeroCopy> Loader<'info, T> {
|
|||
return Err(ErrorCode::AccountOwnedByWrongProgram.into());
|
||||
}
|
||||
let data: &[u8] = &acc_info.try_borrow_data()?;
|
||||
|
||||
// Discriminator must match.
|
||||
#[cfg(feature = "deprecated-layout")]
|
||||
let disc_bytes = array_ref![data, 0, 8];
|
||||
#[cfg(not(feature = "deprecated-layout"))]
|
||||
let disc_bytes = array_ref![data, 2, 4];
|
||||
|
||||
let disc_bytes = header::read_discriminator(data);
|
||||
if disc_bytes != &T::discriminator() {
|
||||
return Err(ErrorCode::AccountDiscriminatorMismatch.into());
|
||||
}
|
||||
|
@ -90,12 +85,7 @@ impl<'info, T: ZeroCopy> Loader<'info, T> {
|
|||
#[allow(deprecated)]
|
||||
pub fn load(&self) -> Result<Ref<T>, ProgramError> {
|
||||
let data = self.acc_info.try_borrow_data()?;
|
||||
|
||||
#[cfg(feature = "deprecated-layout")]
|
||||
let disc_bytes = array_ref![data, 0, 8];
|
||||
#[cfg(not(feature = "deprecated-layout"))]
|
||||
let disc_bytes = array_ref![data, 2, 4];
|
||||
|
||||
let disc_bytes = header::read_discriminator(&data);
|
||||
if disc_bytes != &T::discriminator() {
|
||||
return Err(ErrorCode::AccountDiscriminatorMismatch.into());
|
||||
}
|
||||
|
@ -113,12 +103,7 @@ impl<'info, T: ZeroCopy> Loader<'info, T> {
|
|||
}
|
||||
|
||||
let data = self.acc_info.try_borrow_mut_data()?;
|
||||
|
||||
#[cfg(feature = "deprecated-layout")]
|
||||
let disc_bytes = array_ref![data, 0, 8];
|
||||
#[cfg(not(feature = "deprecated-layout"))]
|
||||
let disc_bytes = array_ref![data, 2, 4];
|
||||
|
||||
let disc_bytes = header::read_discriminator(&data);
|
||||
if disc_bytes != &T::discriminator() {
|
||||
return Err(ErrorCode::AccountDiscriminatorMismatch.into());
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ pub mod cpi_account;
|
|||
#[doc(hidden)]
|
||||
#[allow(deprecated)]
|
||||
pub mod cpi_state;
|
||||
pub mod header;
|
||||
#[doc(hidden)]
|
||||
#[allow(deprecated)]
|
||||
pub mod loader;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#[allow(deprecated)]
|
||||
use crate::accounts::cpi_account::CpiAccount;
|
||||
use crate::accounts::header;
|
||||
use crate::error::ErrorCode;
|
||||
use crate::*;
|
||||
use solana_program::account_info::AccountInfo;
|
||||
|
@ -99,10 +100,7 @@ impl<'info, T: AccountSerialize + AccountDeserialize + Clone> AccountsExit<'info
|
|||
fn exit(&self, _program_id: &Pubkey) -> ProgramResult {
|
||||
let info = self.to_account_info();
|
||||
let mut data = info.try_borrow_mut_data()?;
|
||||
|
||||
// Chop off the header.
|
||||
let dst: &mut [u8] = &mut data[8..];
|
||||
|
||||
let dst = header::read_data_mut(&mut data);
|
||||
let mut cursor = std::io::Cursor::new(dst);
|
||||
self.inner.account.try_serialize(&mut cursor)?;
|
||||
Ok(())
|
||||
|
|
|
@ -19,7 +19,7 @@ const ACCOUNT_HEADER_SIZE = 8;
|
|||
* Number of bytes of the account discriminator.
|
||||
*/
|
||||
const ACCOUNT_DISCRIMINATOR_SIZE = 4;
|
||||
const DEPRECATED_ACCOUNT_DISCRIMINATOR_SIZE = 4;
|
||||
const DEPRECATED_ACCOUNT_DISCRIMINATOR_SIZE = 8;
|
||||
|
||||
/**
|
||||
* Encodes and decodes account objects.
|
||||
|
|
|
@ -24,7 +24,7 @@ import InstructionNamespaceFactory from "./instruction.js";
|
|||
import RpcNamespaceFactory from "./rpc.js";
|
||||
import TransactionNamespaceFactory from "./transaction.js";
|
||||
import { IdlTypes, TypeDef } from "./types.js";
|
||||
import * as features from "../../utils/features.js";
|
||||
import { BorshAccountHeader } from "../../coder/borsh/accounts.js";
|
||||
|
||||
export default class StateFactory {
|
||||
public static build<IDL extends Idl>(
|
||||
|
@ -175,15 +175,11 @@ export class StateClient<IDL extends Idl> {
|
|||
}
|
||||
|
||||
const expectedDiscriminator = await stateDiscriminator(state.struct.name);
|
||||
|
||||
if (features.isSet("deprecated-layout")) {
|
||||
if (expectedDiscriminator.compare(accountInfo.data.slice(0, 8))) {
|
||||
throw new Error("Invalid state discriminator");
|
||||
}
|
||||
} else {
|
||||
if (expectedDiscriminator.compare(accountInfo.data.slice(2, 6))) {
|
||||
throw new Error("Invalid state discriminator");
|
||||
}
|
||||
const discriminator = BorshAccountHeader.parseDiscriminator(
|
||||
accountInfo.data
|
||||
);
|
||||
if (discriminator.compare(expectedDiscriminator)) {
|
||||
throw new Error("Invalid state discriminator");
|
||||
}
|
||||
|
||||
return this.coder.state.decode(accountInfo.data);
|
||||
|
|
Loading…
Reference in New Issue