Return errors in Data peeling

Change-Id: I3e0ae581e83ebbcf0d343b758dff033ddc9b362e
This commit is contained in:
Reisen 2021-06-29 12:59:52 +00:00
parent e6317449d5
commit 21c7399d55
3 changed files with 17 additions and 15 deletions

View File

@ -57,6 +57,8 @@ enum Error {
VAAAlreadyExecuted,
}
/// Translate from program specific errors to Solitaire framework errors. Log the error on the way
/// out of the program for debugging.
impl From<Error> for SolitaireError {
fn from(e: Error) -> SolitaireError {
msg!("ProgramError: {:?}", e);

View File

@ -24,6 +24,9 @@ pub enum SolitaireError {
/// The AccountInfo has an invalid owner.
InvalidOwner(Pubkey),
/// The AccountInfo is non-writeable where a writeable key was expected.
NonWriteableAccount(Pubkey),
/// The instruction payload itself could not be deserialized.
InstructionDeserializeFailed(std::io::Error),
@ -56,10 +59,9 @@ impl From<std::io::Error> for SolitaireError {
impl Into<ProgramError> for SolitaireError {
fn into(self) -> ProgramError {
if let SolitaireError::ProgramError(e) = self {
return e;
match self {
SolitaireError::ProgramError(e) => return e,
_ => ProgramError::Custom(0),
}
// TODO
ProgramError::Custom(0)
}
}

View File

@ -147,25 +147,22 @@ impl<
> 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;
// If we're initializing the type, we should emit system/rent as deps.
let data: T = match IsInitialized {
let (initialized, data): (bool, T) = match IsInitialized {
AccountState::Uninitialized => {
if **ctx.info().lamports.borrow() != 0 {
return Err(SolitaireError::AlreadyInitialized(*ctx.info().key));
}
T::default()
(false, T::default())
}
AccountState::Initialized => {
initialized = true;
T::try_from_slice(&mut *ctx.info().data.borrow_mut()).expect("Blew up in Initialized")
(true, T::try_from_slice(&mut *ctx.info().data.borrow_mut())?)
}
AccountState::MaybeInitialized => {
if **ctx.info().lamports.borrow() == 0 {
T::default()
(false, T::default())
} else {
initialized = true;
T::try_from_slice(&mut *ctx.info().data.borrow_mut())?
(true, T::try_from_slice(&mut *ctx.info().data.borrow_mut())?)
}
}
};
@ -198,13 +195,14 @@ impl<
}
fn persist(&self, program_id: &Pubkey) -> Result<()> {
// Only write to accounts owned by us
// TODO: Introduce Mut<> to solve the check we really want to make here.
if self.0.owner != program_id {
return Ok(());
}
// It is also a malformed program to attempt to write to a non-writeable account.
if !self.0.is_writable {
// TODO this needs to be checked properly
return Ok(());
return Err(SolitaireError::NonWriteableAccount(*self.0.key));
}
self.1.serialize(&mut *self.0.data.borrow_mut())?;