Support deserialization on Pack types
Change-Id: I1eeee002b4a396f94661a938fb0dad1bf958719f
This commit is contained in:
parent
02ecdb691a
commit
e2195c9b17
|
@ -183,6 +183,12 @@ version = "0.1.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8aebca1129a03dc6dc2b127edd729435bbc4a37e1d5f4d7513165089ceb02634"
|
checksum = "8aebca1129a03dc6dc2b127edd729435bbc4a37e1d5f4d7513165089ceb02634"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crunchy"
|
||||||
|
version = "0.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crypto-mac"
|
name = "crypto-mac"
|
||||||
version = "0.8.0"
|
version = "0.8.0"
|
||||||
|
@ -206,6 +212,17 @@ dependencies = [
|
||||||
"zeroize",
|
"zeroize",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "derivative"
|
||||||
|
version = "2.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "digest"
|
name = "digest"
|
||||||
version = "0.8.1"
|
version = "0.8.1"
|
||||||
|
@ -260,6 +277,15 @@ version = "0.1.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "835a3dc7d1ec9e75e2b5fb4ba75396837112d2060b03f7d43bc1897c7f7211da"
|
checksum = "835a3dc7d1ec9e75e2b5fb4ba75396837112d2060b03f7d43bc1897c7f7211da"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fixed-hash"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cfcf0ed7fe52a17a03854ec54a9f76d6d84508d1c0e66bc1793301c73fc8493c"
|
||||||
|
dependencies = [
|
||||||
|
"static_assertions",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "generic-array"
|
name = "generic-array"
|
||||||
version = "0.12.4"
|
version = "0.12.4"
|
||||||
|
@ -392,6 +418,28 @@ dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num_enum"
|
||||||
|
version = "0.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "226b45a5c2ac4dd696ed30fa6b94b057ad909c7b7fc2e0d0808192bced894066"
|
||||||
|
dependencies = [
|
||||||
|
"derivative",
|
||||||
|
"num_enum_derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num_enum_derive"
|
||||||
|
version = "0.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1c0fd9eba1d5db0994a239e09c1be402d35622277e35468ba891aa5e3188ce7e"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro-crate",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "opaque-debug"
|
name = "opaque-debug"
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
|
@ -404,6 +452,16 @@ version = "0.2.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
|
checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "primitive-types"
|
||||||
|
version = "0.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2415937401cb030a2a0a4d922483f945fa068f52a7dbb22ce0fe5f2b6f6adace"
|
||||||
|
dependencies = [
|
||||||
|
"fixed-hash",
|
||||||
|
"uint",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro-crate"
|
name = "proc-macro-crate"
|
||||||
version = "0.1.5"
|
version = "0.1.5"
|
||||||
|
@ -687,6 +745,26 @@ dependencies = [
|
||||||
"solana-program",
|
"solana-program",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "spl-token"
|
||||||
|
version = "3.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fbfa8fd791aeb4d7ad5fedb7872478de9f4e8b4fcb02dfd9e7f2f9ae3f3ddd73"
|
||||||
|
dependencies = [
|
||||||
|
"arrayref",
|
||||||
|
"num-derive",
|
||||||
|
"num-traits",
|
||||||
|
"num_enum",
|
||||||
|
"solana-program",
|
||||||
|
"thiserror",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "static_assertions"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "subtle"
|
name = "subtle"
|
||||||
version = "2.4.0"
|
version = "2.4.0"
|
||||||
|
@ -733,6 +811,20 @@ dependencies = [
|
||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "token-bridge"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"borsh",
|
||||||
|
"byteorder",
|
||||||
|
"primitive-types",
|
||||||
|
"rocksalt",
|
||||||
|
"sha3",
|
||||||
|
"solana-program",
|
||||||
|
"solitaire",
|
||||||
|
"spl-token",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "toml"
|
name = "toml"
|
||||||
version = "0.5.8"
|
version = "0.5.8"
|
||||||
|
@ -748,6 +840,18 @@ version = "1.13.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06"
|
checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "uint"
|
||||||
|
version = "0.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e11fe9a9348741cf134085ad57c249508345fe16411b3d7fb4ff2da2f1d6382e"
|
||||||
|
dependencies = [
|
||||||
|
"byteorder",
|
||||||
|
"crunchy",
|
||||||
|
"hex",
|
||||||
|
"static_assertions",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-xid"
|
name = "unicode-xid"
|
||||||
version = "0.2.2"
|
version = "0.2.2"
|
||||||
|
|
|
@ -32,11 +32,15 @@ pub use borsh::{BorshDeserialize, BorshSerialize};
|
||||||
use solana_program::{
|
use solana_program::{
|
||||||
account_info::next_account_info,
|
account_info::next_account_info,
|
||||||
instruction::AccountMeta,
|
instruction::AccountMeta,
|
||||||
program::invoke_signed,
|
|
||||||
program_error::ProgramError,
|
program_error::ProgramError,
|
||||||
|
program_pack::Pack,
|
||||||
rent::Rent,
|
rent::Rent,
|
||||||
};
|
};
|
||||||
use std::slice::Iter;
|
use std::{
|
||||||
|
io::{ErrorKind, Write},
|
||||||
|
slice::Iter,
|
||||||
|
string::FromUtf8Error,
|
||||||
|
};
|
||||||
|
|
||||||
/// There are several places in Solitaire that might fail, we want descriptive errors.
|
/// There are several places in Solitaire that might fail, we want descriptive errors.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -55,25 +59,69 @@ pub enum SolitaireError {
|
||||||
|
|
||||||
/// An IO error was captured, wrap it up and forward it along.
|
/// An IO error was captured, wrap it up and forward it along.
|
||||||
IoError(std::io::Error),
|
IoError(std::io::Error),
|
||||||
|
|
||||||
|
/// An solana program error
|
||||||
|
ProgramError(ProgramError),
|
||||||
|
|
||||||
|
Custom(u64),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<ProgramError> for SolitaireError {
|
||||||
|
fn from(e: ProgramError) -> Self {
|
||||||
|
SolitaireError::ProgramError(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<std::io::Error> for SolitaireError {
|
||||||
|
fn from(e: std::io::Error) -> Self {
|
||||||
|
SolitaireError::IoError(e)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Into<ProgramError> for SolitaireError {
|
impl Into<ProgramError> for SolitaireError {
|
||||||
fn into(self) -> ProgramError {
|
fn into(self) -> ProgramError {
|
||||||
|
if let SolitaireError::ProgramError(e) = self {
|
||||||
|
return e;
|
||||||
|
}
|
||||||
// TODO
|
// TODO
|
||||||
ProgramError::Custom(0)
|
ProgramError::Custom(0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Quality of life Result type for the Solitaire stack.
|
/// Quality of life Result type for the Solitaire stack.
|
||||||
pub type Result<T> = std::result::Result<T, ProgramError>;
|
pub type Result<T> = std::result::Result<T, SolitaireError>;
|
||||||
pub type ErrBox = Box<dyn std::error::Error>;
|
pub type ErrBox = Box<dyn std::error::Error>;
|
||||||
|
|
||||||
pub trait Persist {
|
pub trait Persist {
|
||||||
fn persist(self);
|
fn persist(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Seeded {
|
#[repr(transparent)]
|
||||||
fn seeds(self) -> Vec<Vec<Vec<u8>>>;
|
pub struct Packed<T: Pack + solana_program::program_pack::IsInitialized>(T);
|
||||||
|
|
||||||
|
impl<T: Pack + solana_program::program_pack::IsInitialized> BorshDeserialize for Packed<T> {
|
||||||
|
fn deserialize(buf: &mut &[u8]) -> std::io::Result<Self> {
|
||||||
|
Ok(Packed(
|
||||||
|
T::unpack(buf).map_err(|e| std::io::Error::new(ErrorKind::Other, e))?,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Pack + solana_program::program_pack::IsInitialized> BorshSerialize for Packed<T> {
|
||||||
|
fn serialize<W: Write>(&self, writer: &mut W) -> std::io::Result<()> {
|
||||||
|
let mut data: [u8; 2000] = [0u8; 2000];
|
||||||
|
T::pack_into_slice(self, &mut data);
|
||||||
|
writer.write(&data);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Pack + solana_program::program_pack::IsInitialized> Deref for Packed<T> {
|
||||||
|
type Target = T;
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
unsafe { std::mem::transmute(&self.0) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The following set of recursive types form the basis of this library, each one represents a
|
// The following set of recursive types form the basis of this library, each one represents a
|
||||||
|
@ -383,8 +431,7 @@ impl<'a, 'b: 'a, 'c, T: BorshDeserialize, const IsInitialized: bool, const Lazy:
|
||||||
ctx.deps.push(system_program::ID);
|
ctx.deps.push(system_program::ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
let data = T::try_from_slice(&mut *ctx.info().data.borrow_mut())
|
let data = T::try_from_slice(&mut *ctx.info().data.borrow_mut())?;
|
||||||
.map_err::<ProgramError, _>(|e| SolitaireError::IoError(e).into())?;
|
|
||||||
|
|
||||||
Ok(Data(ctx.info().clone(), data))
|
Ok(Data(ctx.info().clone(), data))
|
||||||
}
|
}
|
||||||
|
@ -461,7 +508,7 @@ macro_rules! solitaire {
|
||||||
mod instruction {
|
mod instruction {
|
||||||
use super::*;
|
use super::*;
|
||||||
use borsh::{BorshDeserialize, BorshSerialize};
|
use borsh::{BorshDeserialize, BorshSerialize};
|
||||||
use solitaire::{Persist, FromAccounts};
|
use solitaire::{Persist, FromAccounts, Result};
|
||||||
|
|
||||||
/// Generated:
|
/// Generated:
|
||||||
/// This Instruction contains a 1-1 mapping for each enum variant to function call. The
|
/// This Instruction contains a 1-1 mapping for each enum variant to function call. The
|
||||||
|
@ -474,8 +521,8 @@ macro_rules! solitaire {
|
||||||
|
|
||||||
/// This entrypoint is generated from the enum above, it deserializes incoming bytes
|
/// This entrypoint is generated from the enum above, it deserializes incoming bytes
|
||||||
/// and automatically dispatches to the correct method.
|
/// and automatically dispatches to the correct method.
|
||||||
pub fn dispatch<'a, 'b: 'a, 'c>(p: &Pubkey, a: &'c [AccountInfo<'b>], d: &[u8]) -> ProgramResult {
|
pub fn dispatch<'a, 'b: 'a, 'c>(p: &Pubkey, a: &'c [AccountInfo<'b>], d: &[u8]) -> Result<()> {
|
||||||
match Instruction::try_from_slice(d)? {
|
match BorshDeserialize::try_from_slice(d).map_err(|_| SolitaireError::InstructionDeserializeFailed)? {
|
||||||
$(
|
$(
|
||||||
Instruction::$row(ix_data) => {
|
Instruction::$row(ix_data) => {
|
||||||
let (mut accounts, _deps): ($row, _) = FromAccounts::from(p, &mut a.iter(), &()).unwrap();
|
let (mut accounts, _deps): ($row, _) = FromAccounts::from(p, &mut a.iter(), &()).unwrap();
|
||||||
|
|
Loading…
Reference in New Issue