Skip to content

Commit

Permalink
prototype abort error
Browse files Browse the repository at this point in the history
  • Loading branch information
dignifiedquire committed Apr 7, 2022
1 parent 5a92754 commit 09c204e
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 17 deletions.
12 changes: 6 additions & 6 deletions actors/account/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ use num_derive::FromPrimitive;
use num_traits::FromPrimitive;

use fil_actors_runtime::builtin::singletons::SYSTEM_ACTOR_ADDR;
use fil_actors_runtime::cbor;
use fil_actors_runtime::runtime::{ActorCode, Runtime};
use fil_actors_runtime::{actor_error, ensure_args, ActorError};
use fil_actors_runtime::{actor_error, ensure_args};
use fil_actors_runtime::{cbor, Abort};

pub use self::state::State;

Expand All @@ -34,7 +34,7 @@ pub enum Method {
pub struct Actor;
impl Actor {
/// Constructor for Account actor
pub fn constructor<BS, RT>(rt: &mut RT, address: Address) -> Result<(), ActorError>
pub fn constructor<BS, RT>(rt: &mut RT, address: Address) -> Result<(), Abort>
where
BS: Blockstore,
RT: Runtime<BS>,
Expand All @@ -50,7 +50,7 @@ impl Actor {
}

// Fetches the pubkey-type address from this actor.
pub fn pubkey_address<BS, RT>(rt: &mut RT) -> Result<Address, ActorError>
pub fn pubkey_address<BS, RT>(rt: &mut RT) -> Result<Address, Abort>
where
BS: Blockstore,
RT: Runtime<BS>,
Expand All @@ -66,7 +66,7 @@ impl ActorCode for Actor {
rt: &mut RT,
method: MethodNum,
params: &RawBytes,
) -> Result<RawBytes, ActorError>
) -> Result<RawBytes, Abort>
where
BS: Blockstore,
RT: Runtime<BS>,
Expand All @@ -80,7 +80,7 @@ impl ActorCode for Actor {
let addr = Self::pubkey_address(rt)?;
Ok(RawBytes::serialize(addr)?)
}
None => Err(actor_error!(SysErrInvalidMethod; "Invalid method")),
None => Err(actor_error!(SysErrInvalidMethod; "Invalid method").into()),
}
}
}
44 changes: 41 additions & 3 deletions actors/runtime/src/actor_error.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,44 @@
use fvm_shared::error::ExitCode;
use thiserror::Error;

mod abort {
use crate::ActorError;
use fvm_shared::error::ExitCode;

#[derive(thiserror::Error, Debug)]
#[error("abort error")]
pub struct Abort {
/// This ensures that this error can not be crated outside.
_private: (),
}

#[cfg(feature = "fil-actor")]
fn maybe_abort(exit_code: ExitCode, msg: Option<&str>) -> ! {
fvm_sdk::vm::abort(exit_code as u32, msg);
}
#[cfg(not(feature = "fil-actor"))]
fn maybe_abort(exit_code: ExitCode, msg: Option<&str>) -> ! {
// TODO: maybe not panic, needs discussion what we want here
panic!("Abort: {}: {:?}", exit_code, msg);
}

impl From<ActorError> for Abort {
fn from(err: ActorError) -> Self {
let ActorError { exit_code, msg } = err;
maybe_abort(exit_code, Some(&msg));
}
}

/// Converts a raw encoding error into an ErrSerialization.
impl From<fvm_ipld_encoding::Error> for Abort {
fn from(e: fvm_ipld_encoding::Error) -> Self {
maybe_abort(ExitCode::ErrSerialization, Some(&e.to_string()));
}
}
}

pub use abort::Abort;

/// TODO fix error system; actor errors should be transparent to the VM.
/// The error type that gets returned by actor method calls.
#[derive(Error, Debug, Clone, PartialEq)]
Expand Down Expand Up @@ -114,17 +152,17 @@ macro_rules! actor_error {
macro_rules! ensure {
($cond:expr, $code:ident, $msg:literal $(,)?) => {
if !$cond {
return Err($crate::actor_error!($code, $msg));
return Err($crate::actor_error!($code, $msg).into());
}
};
($cond:expr, $code:ident, $err:expr $(,)?) => {
if !$cond {
return Err($crate::actor_error!($code, $err));
return Err($crate::actor_error!($code, $err).into());
}
};
($cond:expr, $code:ident, $fmt:expr, $($arg:tt)*) => {
if !$cond {
return Err($crate::actor_error!($code, $fmt, $($arg)*));
return Err($crate::actor_error!($code, $fmt, $($arg)*).into());
}
};
}
Expand Down
4 changes: 2 additions & 2 deletions actors/runtime/src/runtime/actor_code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use fvm_ipld_blockstore::Blockstore;
use fvm_ipld_encoding::RawBytes;
use fvm_shared::MethodNum;

use crate::{ActorError, Runtime};
use crate::{Abort, Runtime};

/// Interface for invoking methods on an Actor
pub trait ActorCode {
Expand All @@ -15,7 +15,7 @@ pub trait ActorCode {
rt: &mut RT,
method: MethodNum,
params: &RawBytes,
) -> Result<RawBytes, ActorError>
) -> Result<RawBytes, Abort>
where
// TODO: remove the clone requirement on the blockstore when we fix "replica update" to not
// hold onto state between transactions.
Expand Down
5 changes: 3 additions & 2 deletions actors/runtime/src/runtime/fvm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -430,8 +430,9 @@ pub fn trampoline<C: ActorCode>(params: u32) -> u32 {
// Construct a new runtime.
let mut rt = FvmRuntime::default();
// Invoke the method, aborting if the actor returns an errored exit code.
let ret = C::invoke_method(&mut rt, method, &params)
.unwrap_or_else(|err| fvm::vm::abort(err.exit_code() as u32, Some(err.msg())));

// can unwrap because `Abort` will already have called rt::abort on an error.
let ret = C::invoke_method(&mut rt, method, &params).unwrap();

// Abort with "illegal actor" if the actor failed to validate the caller somewhere.
// We do this after handling the error, because the actor may have encountered an error before
Expand Down
3 changes: 2 additions & 1 deletion actors/runtime/src/test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,8 @@ impl MockRuntime {
self.state = prev_state;
}
self.in_call = false;
res
// res
todo!()
}

pub fn verify(&mut self) {
Expand Down
6 changes: 3 additions & 3 deletions actors/runtime/src/util/chaos/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ pub use state::*;
pub use types::*;

use crate::runtime::{ActorCode, Runtime};
use crate::{actor_error, cbor, ActorError};
use crate::{actor_error, cbor, Abort, ActorError};

mod state;
mod types;
Expand Down Expand Up @@ -197,7 +197,7 @@ impl ActorCode for Actor {
rt: &mut RT,
method: MethodNum,
params: &RawBytes,
) -> Result<RawBytes, ActorError>
) -> Result<RawBytes, Abort>
where
BS: Blockstore,
RT: Runtime<BS>,
Expand Down Expand Up @@ -246,7 +246,7 @@ impl ActorCode for Actor {
Ok(RawBytes::serialize(inspect)?)
}

None => Err(actor_error!(SysErrInvalidMethod; "Invalid method")),
None => Err(actor_error!(SysErrInvalidMethod; "Invalid method").into()),
}
}
}

0 comments on commit 09c204e

Please sign in to comment.