Skip to content

Commit

Permalink
refactor: Runtime: Move create and state into default impl
Browse files Browse the repository at this point in the history
  • Loading branch information
arajasek committed Jan 30, 2023
1 parent b47f5f7 commit 50a6a84
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 57 deletions.
21 changes: 0 additions & 21 deletions runtime/src/runtime/fvm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,27 +235,6 @@ where
})
}

fn create<T: Serialize>(&mut self, obj: &T) -> Result<(), ActorError> {
let root = fvm::sself::root()?;
if root != EMPTY_ARR_CID {
return Err(
actor_error!(illegal_state; "failed to create state; expected empty array CID, got: {}", root),
);
}
let new_root = ActorBlockstore.put_cbor(obj, Code::Blake2b256)
.map_err(|e| actor_error!(illegal_argument; "failed to write actor state during creation: {}", e.to_string()))?;
fvm::sself::set_root(&new_root)?;
Ok(())
}

fn state<T: DeserializeOwned>(&self) -> Result<T, ActorError> {
let root = fvm::sself::root()?;
Ok(ActorBlockstore
.get_cbor(&root)
.map_err(|_| actor_error!(illegal_argument; "failed to get actor for Readonly state"))?
.expect("State does not exist for actor state root"))
}

fn get_state_root(&self) -> Result<Cid, ActorError> {
Ok(fvm::sself::root()?)
}
Expand Down
25 changes: 22 additions & 3 deletions runtime/src/runtime/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

use cid::Cid;
use fvm_ipld_blockstore::Blockstore;
use fvm_ipld_encoding::CborStore;
use fvm_shared::address::Address;
use fvm_shared::clock::ChainEpoch;
use fvm_shared::consensus::ConsensusFault;
Expand All @@ -23,7 +24,7 @@ pub use self::actor_code::*;
pub use self::policy::*;
pub use self::randomness::DomainSeparationTag;
use crate::runtime::builtins::Type;
use crate::ActorError;
use crate::{actor_error, ActorError};

mod actor_code;
pub mod builtins;
Expand All @@ -43,6 +44,7 @@ pub use empty::EMPTY_ARR_CID;
use fvm_ipld_encoding::ipld_block::IpldBlock;
use fvm_shared::error::ErrorNumber;
use fvm_shared::sys::SendFlags;
use multihash::Code;

/// Runtime is the VM's internal runtime object.
/// this is everything that is accessible to actors, beyond parameters.
Expand Down Expand Up @@ -106,10 +108,27 @@ pub trait Runtime: Primitives + Verifier + RuntimePolicy {
/// Initializes the state object.
/// This is only valid when the state has not yet been initialized.
/// NOTE: we should also limit this to being invoked during the constructor method
fn create<T: Serialize>(&mut self, obj: &T) -> Result<(), ActorError>;
fn create<T: Serialize>(&mut self, obj: &T) -> Result<(), ActorError> {
let root = self.get_state_root()?;
if root != EMPTY_ARR_CID {
return Err(
actor_error!(illegal_state; "failed to create state; expected empty array CID, got: {}", root),
);
}
let new_root = self.store().put_cbor(obj, Code::Blake2b256)
.map_err(|e| actor_error!(illegal_argument; "failed to write actor state during creation: {}", e.to_string()))?;
self.set_state_root(&new_root)?;
Ok(())
}

/// Loads a readonly copy of the state of the receiver into the argument.
fn state<T: DeserializeOwned>(&self) -> Result<T, ActorError>;
fn state<T: DeserializeOwned>(&self) -> Result<T, ActorError> {
Ok(self
.store()
.get_cbor(&self.get_state_root()?)
.map_err(|_| actor_error!(illegal_argument; "failed to get actor for Readonly state"))?
.expect("State does not exist for actor state root"))
}

/// Gets the state-root.
fn get_state_root(&self) -> Result<Cid, ActorError>;
Expand Down
33 changes: 0 additions & 33 deletions test_vm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -941,35 +941,6 @@ impl<'invocation, 'bs> Runtime for InvocationCtx<'invocation, 'bs> {
Ok(TEST_VM_RAND_ARRAY)
}

fn create<T: Serialize>(&mut self, obj: &T) -> Result<(), ActorError> {
if self.read_only {
return Err(ActorError::unchecked(
ExitCode::USR_READ_ONLY,
"cannot create state in read-only".to_string(),
));
}

let maybe_act = self.v.get_actor(self.to());
match maybe_act {
None => Err(ActorError::unchecked(
ExitCode::SYS_ASSERTION_FAILED,
"failed to create state".to_string(),
)),
Some(mut act) => {
if act.head != EMPTY_ARR_CID {
Err(ActorError::unchecked(
ExitCode::SYS_ASSERTION_FAILED,
"failed to construct state: already initialized".to_string(),
))
} else {
act.head = self.v.store.put_cbor(obj, Code::Blake2b256).unwrap();
self.v.set_actor(self.to(), act);
Ok(())
}
}
}
}

fn get_state_root(&self) -> Result<Cid, ActorError> {
Ok(self.v.get_actor(self.to()).unwrap().head)
}
Expand All @@ -993,10 +964,6 @@ impl<'invocation, 'bs> Runtime for InvocationCtx<'invocation, 'bs> {
}
}

fn state<T: DeserializeOwned>(&self) -> Result<T, ActorError> {
Ok(self.v.get_state::<T>(self.to()).unwrap())
}

fn transaction<S, RT, F>(&mut self, f: F) -> Result<RT, ActorError>
where
S: Serialize + DeserializeOwned,
Expand Down

0 comments on commit 50a6a84

Please sign in to comment.