Implement account persistence
Accounts with data will now be persisted at the end of the program execution Change-Id: I1dd29f521f5c659ced5758203acf532b645f3b44
This commit is contained in:
parent
c3829b9266
commit
b3b083b08a
|
@ -68,10 +68,10 @@ fn main() -> Result<(), ErrBox> {
|
|||
payer: Signer(payer),
|
||||
};
|
||||
|
||||
let init_args = types::BridgeConfig {
|
||||
let init_args = bridge::instruction::Instruction::Initialize(types::BridgeConfig {
|
||||
guardian_set_expiration_time: DEFAULT_GUARDIAN_SET_EXPIRATION_TIME,
|
||||
fee: DEFAULT_MESSAGE_FEE,
|
||||
};
|
||||
});
|
||||
|
||||
let ix_data = init_args.try_to_vec()?;
|
||||
|
||||
|
|
|
@ -96,6 +96,10 @@ impl<'a, 'b: 'a, 'c, T: DeserializePayload> Peel<'a, 'b, 'c> for PayloadMessage<
|
|||
fn deps() -> Vec<Pubkey> {
|
||||
Data::<'b, PostedMessage, { AccountState::Initialized }>::deps()
|
||||
}
|
||||
|
||||
fn persist(&self, program_id: &Pubkey) -> Result<()> {
|
||||
Data::persist(&self.0, program_id)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'b, T: DeserializePayload> Deref for PayloadMessage<'b, T> {
|
||||
|
|
|
@ -80,7 +80,8 @@ pub use crate::{
|
|||
};
|
||||
|
||||
/// Library name and version to print in entrypoint. Must be evaluated in this crate in order to do the right thing
|
||||
pub const PKG_NAME_VERSION: &'static str = concat!(env!("CARGO_PKG_NAME"), " ", env!("CARGO_PKG_VERSION"));
|
||||
pub const PKG_NAME_VERSION: &'static str =
|
||||
concat!(env!("CARGO_PKG_NAME"), " ", env!("CARGO_PKG_VERSION"));
|
||||
|
||||
pub struct ExecutionContext<'a, 'b: 'a> {
|
||||
/// A reference to the program_id of the current program.
|
||||
|
|
|
@ -41,7 +41,7 @@ macro_rules! solitaire {
|
|||
Instruction::$row(ix_data) => {
|
||||
let (mut accounts): ($row) = FromAccounts::from(p, &mut a.iter(), &()).unwrap();
|
||||
$fn(&ExecutionContext{program_id: p, accounts: a}, &mut accounts, ix_data)?;
|
||||
accounts.persist();
|
||||
Persist::persist(&accounts, p)?;
|
||||
Ok(())
|
||||
}
|
||||
)*
|
||||
|
@ -128,6 +128,10 @@ macro_rules! data_wrapper {
|
|||
fn deps() -> Vec<Pubkey> {
|
||||
Data::<'_, $embed, { $state }>::deps()
|
||||
}
|
||||
|
||||
fn persist(&self, program_id: &Pubkey) -> solitaire::Result<()> {
|
||||
Data::<'_, $embed, { $state }>::persist(self, program_id)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'b> solitaire::processors::seeded::Owned for $name<'b> {
|
||||
|
|
|
@ -26,6 +26,7 @@ use crate::{
|
|||
Result,
|
||||
SolitaireError,
|
||||
};
|
||||
use borsh::BorshSerialize;
|
||||
|
||||
/// Generic Peel trait. This provides a way to describe what each "peeled"
|
||||
/// layer of our constraints should check.
|
||||
|
@ -35,6 +36,8 @@ pub trait Peel<'a, 'b: 'a, 'c> {
|
|||
Self: Sized;
|
||||
|
||||
fn deps() -> Vec<Pubkey>;
|
||||
|
||||
fn persist(&self, program_id: &Pubkey) -> Result<()>;
|
||||
}
|
||||
|
||||
/// Peel a Derived Key
|
||||
|
@ -49,9 +52,14 @@ impl<'a, 'b: 'a, 'c, T: Peel<'a, 'b, 'c>, const Seed: &'static str> Peel<'a, 'b,
|
|||
_ => Err(SolitaireError::InvalidDerive(*ctx.info().key).into()),
|
||||
}
|
||||
}
|
||||
|
||||
fn deps() -> Vec<Pubkey> {
|
||||
T::deps()
|
||||
}
|
||||
|
||||
fn persist(&self, program_id: &Pubkey) -> Result<()> {
|
||||
T::persist(self, program_id)
|
||||
}
|
||||
}
|
||||
|
||||
/// Peel a Signer.
|
||||
|
@ -62,9 +70,14 @@ impl<'a, 'b: 'a, 'c, T: Peel<'a, 'b, 'c>> Peel<'a, 'b, 'c> for Signer<T> {
|
|||
_ => Err(SolitaireError::InvalidSigner(*ctx.info().key).into()),
|
||||
}
|
||||
}
|
||||
|
||||
fn deps() -> Vec<Pubkey> {
|
||||
T::deps()
|
||||
}
|
||||
|
||||
fn persist(&self, program_id: &Pubkey) -> Result<()> {
|
||||
T::persist(self, program_id)
|
||||
}
|
||||
}
|
||||
|
||||
/// Expicitly depend upon the System account.
|
||||
|
@ -75,9 +88,14 @@ impl<'a, 'b: 'a, 'c, T: Peel<'a, 'b, 'c>> Peel<'a, 'b, 'c> for System<T> {
|
|||
_ => panic!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn deps() -> Vec<Pubkey> {
|
||||
T::deps()
|
||||
}
|
||||
|
||||
fn persist(&self, program_id: &Pubkey) -> Result<()> {
|
||||
T::persist(self, program_id)
|
||||
}
|
||||
}
|
||||
|
||||
/// Peel a Sysvar
|
||||
|
@ -94,9 +112,14 @@ where
|
|||
_ => Err(SolitaireError::InvalidSysvar(*ctx.info().key).into()),
|
||||
}
|
||||
}
|
||||
|
||||
fn deps() -> Vec<Pubkey> {
|
||||
vec![]
|
||||
}
|
||||
|
||||
fn persist(&self, _program_id: &Pubkey) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// This is our structural recursion base case, the trait system will stop generating new nested
|
||||
|
@ -108,12 +131,20 @@ impl<'a, 'b: 'a, 'c> Peel<'a, 'b, 'c> for Info<'b> {
|
|||
fn deps() -> Vec<Pubkey> {
|
||||
vec![]
|
||||
}
|
||||
fn persist(&self, _program_id: &Pubkey) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// This is our structural recursion base case, the trait system will stop generating new nested
|
||||
/// calls here.
|
||||
impl<'a, 'b: 'a, 'c, T: BorshDeserialize + Owned + Default, const IsInitialized: AccountState>
|
||||
Peel<'a, 'b, 'c> for Data<'b, T, IsInitialized>
|
||||
impl<
|
||||
'a,
|
||||
'b: 'a,
|
||||
'c,
|
||||
T: BorshDeserialize + BorshSerialize + Owned + Default,
|
||||
const IsInitialized: AccountState,
|
||||
> Peel<'a, 'b, 'c> for Data<'b, T, IsInitialized>
|
||||
{
|
||||
fn peel<I>(ctx: &'c mut Context<'a, 'b, 'c, I>) -> Result<Self> {
|
||||
let mut initialized = false;
|
||||
|
@ -165,4 +196,19 @@ impl<'a, 'b: 'a, 'c, T: BorshDeserialize + Owned + Default, const IsInitialized:
|
|||
|
||||
vec![sysvar::rent::ID, system_program::ID]
|
||||
}
|
||||
|
||||
fn persist(&self, program_id: &Pubkey) -> Result<()> {
|
||||
// Only write to accounts owned by us
|
||||
if self.0.owner != program_id {
|
||||
return Ok(());
|
||||
}
|
||||
if !self.0.is_writable {
|
||||
// TODO this needs to be checked properly
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
self.1.serialize(&mut *self.0.data.borrow_mut())?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
use solana_program::pubkey::Pubkey;
|
||||
|
||||
pub trait Persist {
|
||||
fn persist(self);
|
||||
fn persist(&self, program_id: &Pubkey) -> crate::Result<()>;
|
||||
}
|
||||
|
|
|
@ -129,15 +129,16 @@ pub fn derive_from_accounts(input: TokenStream) -> TokenStream {
|
|||
fn deps() -> Vec<solana_program::pubkey::Pubkey> {
|
||||
#deps_method
|
||||
}
|
||||
|
||||
fn persist(&self, program_id: &solana_program::pubkey::Pubkey) -> solitaire::Result<()> {
|
||||
solitaire::Persist::persist(self, program_id)
|
||||
}
|
||||
}
|
||||
|
||||
/// Macro generated implementation of Persist by Solitaire.
|
||||
impl #type_impl_g solitaire::Persist for #name #type_g {
|
||||
fn persist(self) {
|
||||
use borsh::BorshSerialize;
|
||||
//self.guardian_set.serialize(
|
||||
// &mut *self.guardian_set.0.data.borrow_mut()
|
||||
//);
|
||||
fn persist(&self, program_id: &solana_program::pubkey::Pubkey) -> solitaire::Result<()> {
|
||||
#persist_method
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -256,24 +257,14 @@ fn generate_persist(name: &syn::Ident, data: &Data) -> TokenStream2 {
|
|||
let ty = &f.ty;
|
||||
|
||||
quote! {
|
||||
let #name: #ty = Peel::peel(&mut solitaire::Context::new(
|
||||
pid,
|
||||
iter,
|
||||
data,
|
||||
))?;
|
||||
Peel::persist(&self.#name, program_id)?;
|
||||
}
|
||||
});
|
||||
|
||||
let names = fields.named.iter().map(|f| {
|
||||
let name = &f.ident;
|
||||
quote!(#name)
|
||||
});
|
||||
|
||||
// Write out our iterator and return the filled structure.
|
||||
quote! {
|
||||
use solana_program::account_info::next_account_info;
|
||||
#(#recurse;)*
|
||||
Ok(#name { #(#names,)* })
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue