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"
|
||||
checksum = "8aebca1129a03dc6dc2b127edd729435bbc4a37e1d5f4d7513165089ceb02634"
|
||||
|
||||
[[package]]
|
||||
name = "crunchy"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
|
||||
|
||||
[[package]]
|
||||
name = "crypto-mac"
|
||||
version = "0.8.0"
|
||||
|
@ -206,6 +212,17 @@ dependencies = [
|
|||
"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]]
|
||||
name = "digest"
|
||||
version = "0.8.1"
|
||||
|
@ -260,6 +277,15 @@ version = "0.1.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
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]]
|
||||
name = "generic-array"
|
||||
version = "0.12.4"
|
||||
|
@ -392,6 +418,28 @@ dependencies = [
|
|||
"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]]
|
||||
name = "opaque-debug"
|
||||
version = "0.3.0"
|
||||
|
@ -404,6 +452,16 @@ version = "0.2.10"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
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]]
|
||||
name = "proc-macro-crate"
|
||||
version = "0.1.5"
|
||||
|
@ -687,6 +745,26 @@ dependencies = [
|
|||
"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]]
|
||||
name = "subtle"
|
||||
version = "2.4.0"
|
||||
|
@ -733,6 +811,20 @@ dependencies = [
|
|||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "token-bridge"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"borsh",
|
||||
"byteorder",
|
||||
"primitive-types",
|
||||
"rocksalt",
|
||||
"sha3",
|
||||
"solana-program",
|
||||
"solitaire",
|
||||
"spl-token",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.5.8"
|
||||
|
@ -748,6 +840,18 @@ version = "1.13.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
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]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.2"
|
||||
|
|
|
@ -32,11 +32,15 @@ pub use borsh::{BorshDeserialize, BorshSerialize};
|
|||
use solana_program::{
|
||||
account_info::next_account_info,
|
||||
instruction::AccountMeta,
|
||||
program::invoke_signed,
|
||||
program_error::ProgramError,
|
||||
program_pack::Pack,
|
||||
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.
|
||||
#[derive(Debug)]
|
||||
|
@ -55,25 +59,69 @@ pub enum SolitaireError {
|
|||
|
||||
/// An IO error was captured, wrap it up and forward it along.
|
||||
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 {
|
||||
fn into(self) -> ProgramError {
|
||||
//TODO
|
||||
if let SolitaireError::ProgramError(e) = self {
|
||||
return e;
|
||||
}
|
||||
// TODO
|
||||
ProgramError::Custom(0)
|
||||
}
|
||||
}
|
||||
|
||||
/// 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 trait Persist {
|
||||
fn persist(self);
|
||||
}
|
||||
|
||||
pub trait Seeded {
|
||||
fn seeds(self) -> Vec<Vec<Vec<u8>>>;
|
||||
#[repr(transparent)]
|
||||
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
|
||||
|
@ -383,8 +431,7 @@ impl<'a, 'b: 'a, 'c, T: BorshDeserialize, const IsInitialized: bool, const Lazy:
|
|||
ctx.deps.push(system_program::ID);
|
||||
}
|
||||
|
||||
let data = T::try_from_slice(&mut *ctx.info().data.borrow_mut())
|
||||
.map_err::<ProgramError, _>(|e| SolitaireError::IoError(e).into())?;
|
||||
let data = T::try_from_slice(&mut *ctx.info().data.borrow_mut())?;
|
||||
|
||||
Ok(Data(ctx.info().clone(), data))
|
||||
}
|
||||
|
@ -461,7 +508,7 @@ macro_rules! solitaire {
|
|||
mod instruction {
|
||||
use super::*;
|
||||
use borsh::{BorshDeserialize, BorshSerialize};
|
||||
use solitaire::{Persist, FromAccounts};
|
||||
use solitaire::{Persist, FromAccounts, Result};
|
||||
|
||||
/// Generated:
|
||||
/// 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
|
||||
/// and automatically dispatches to the correct method.
|
||||
pub fn dispatch<'a, 'b: 'a, 'c>(p: &Pubkey, a: &'c [AccountInfo<'b>], d: &[u8]) -> ProgramResult {
|
||||
match Instruction::try_from_slice(d)? {
|
||||
pub fn dispatch<'a, 'b: 'a, 'c>(p: &Pubkey, a: &'c [AccountInfo<'b>], d: &[u8]) -> Result<()> {
|
||||
match BorshDeserialize::try_from_slice(d).map_err(|_| SolitaireError::InstructionDeserializeFailed)? {
|
||||
$(
|
||||
Instruction::$row(ix_data) => {
|
||||
let (mut accounts, _deps): ($row, _) = FromAccounts::from(p, &mut a.iter(), &()).unwrap();
|
||||
|
|
Loading…
Reference in New Issue