Return errors in Data peeling
Change-Id: I3e0ae581e83ebbcf0d343b758dff033ddc9b362e
This commit is contained in:
parent
e6317449d5
commit
21c7399d55
|
@ -57,6 +57,8 @@ enum Error {
|
||||||
VAAAlreadyExecuted,
|
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 {
|
impl From<Error> for SolitaireError {
|
||||||
fn from(e: Error) -> SolitaireError {
|
fn from(e: Error) -> SolitaireError {
|
||||||
msg!("ProgramError: {:?}", e);
|
msg!("ProgramError: {:?}", e);
|
||||||
|
|
|
@ -24,6 +24,9 @@ pub enum SolitaireError {
|
||||||
/// The AccountInfo has an invalid owner.
|
/// The AccountInfo has an invalid owner.
|
||||||
InvalidOwner(Pubkey),
|
InvalidOwner(Pubkey),
|
||||||
|
|
||||||
|
/// The AccountInfo is non-writeable where a writeable key was expected.
|
||||||
|
NonWriteableAccount(Pubkey),
|
||||||
|
|
||||||
/// The instruction payload itself could not be deserialized.
|
/// The instruction payload itself could not be deserialized.
|
||||||
InstructionDeserializeFailed(std::io::Error),
|
InstructionDeserializeFailed(std::io::Error),
|
||||||
|
|
||||||
|
@ -56,10 +59,9 @@ impl From<std::io::Error> for SolitaireError {
|
||||||
|
|
||||||
impl Into<ProgramError> for SolitaireError {
|
impl Into<ProgramError> for SolitaireError {
|
||||||
fn into(self) -> ProgramError {
|
fn into(self) -> ProgramError {
|
||||||
if let SolitaireError::ProgramError(e) = self {
|
match self {
|
||||||
return e;
|
SolitaireError::ProgramError(e) => return e,
|
||||||
}
|
_ => ProgramError::Custom(0),
|
||||||
// TODO
|
}
|
||||||
ProgramError::Custom(0)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -147,25 +147,22 @@ impl<
|
||||||
> Peel<'a, 'b, 'c> for Data<'b, T, IsInitialized>
|
> Peel<'a, 'b, 'c> for Data<'b, T, IsInitialized>
|
||||||
{
|
{
|
||||||
fn peel<I>(ctx: &'c mut Context<'a, 'b, 'c, I>) -> Result<Self> {
|
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.
|
// 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 => {
|
AccountState::Uninitialized => {
|
||||||
if **ctx.info().lamports.borrow() != 0 {
|
if **ctx.info().lamports.borrow() != 0 {
|
||||||
return Err(SolitaireError::AlreadyInitialized(*ctx.info().key));
|
return Err(SolitaireError::AlreadyInitialized(*ctx.info().key));
|
||||||
}
|
}
|
||||||
T::default()
|
(false, T::default())
|
||||||
}
|
}
|
||||||
AccountState::Initialized => {
|
AccountState::Initialized => {
|
||||||
initialized = true;
|
(true, T::try_from_slice(&mut *ctx.info().data.borrow_mut())?)
|
||||||
T::try_from_slice(&mut *ctx.info().data.borrow_mut()).expect("Blew up in Initialized")
|
|
||||||
}
|
}
|
||||||
AccountState::MaybeInitialized => {
|
AccountState::MaybeInitialized => {
|
||||||
if **ctx.info().lamports.borrow() == 0 {
|
if **ctx.info().lamports.borrow() == 0 {
|
||||||
T::default()
|
(false, T::default())
|
||||||
} else {
|
} else {
|
||||||
initialized = true;
|
(true, T::try_from_slice(&mut *ctx.info().data.borrow_mut())?)
|
||||||
T::try_from_slice(&mut *ctx.info().data.borrow_mut())?
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -198,13 +195,14 @@ impl<
|
||||||
}
|
}
|
||||||
|
|
||||||
fn persist(&self, program_id: &Pubkey) -> Result<()> {
|
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 {
|
if self.0.owner != program_id {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// It is also a malformed program to attempt to write to a non-writeable account.
|
||||||
if !self.0.is_writable {
|
if !self.0.is_writable {
|
||||||
// TODO this needs to be checked properly
|
return Err(SolitaireError::NonWriteableAccount(*self.0.key));
|
||||||
return Ok(());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.1.serialize(&mut *self.0.data.borrow_mut())?;
|
self.1.serialize(&mut *self.0.data.borrow_mut())?;
|
||||||
|
|
Loading…
Reference in New Issue