Skip to content

Commit

Permalink
Traits and impls for adding context and exit codes to results. (filec…
Browse files Browse the repository at this point in the history
…oin-project#589)

Co-authored-by: dignifiedquire <[email protected]>
  • Loading branch information
2 people authored and shamb0 committed Jan 31, 2023
1 parent de646c5 commit 8164f11
Show file tree
Hide file tree
Showing 11 changed files with 236 additions and 261 deletions.
15 changes: 5 additions & 10 deletions actors/init/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,10 @@
use cid::Cid;
use fil_actors_runtime::runtime::builtins::Type;
use fil_actors_runtime::runtime::{ActorCode, Runtime};
use fil_actors_runtime::{actor_error, cbor, ActorDowncast, ActorError, SYSTEM_ACTOR_ADDR};
use fil_actors_runtime::{actor_error, cbor, ActorContext, ActorError, SYSTEM_ACTOR_ADDR};
use fvm_ipld_blockstore::Blockstore;
use fvm_ipld_encoding::RawBytes;
use fvm_shared::address::Address;
use fvm_shared::error::ExitCode;
use fvm_shared::{ActorID, MethodNum, METHOD_CONSTRUCTOR};
use num_derive::FromPrimitive;
use num_traits::FromPrimitive;
Expand Down Expand Up @@ -42,10 +41,7 @@ impl Actor {
{
let sys_ref: &Address = &SYSTEM_ACTOR_ADDR;
rt.validate_immediate_caller_is(std::iter::once(sys_ref))?;
let state = State::new(rt.store(), params.network_name).map_err(|e| {
e.downcast_default(ExitCode::USR_ILLEGAL_STATE, "failed to construct init actor state")
})?;

let state = State::new(rt.store(), params.network_name)?;
rt.create(&state)?;

Ok(())
Expand Down Expand Up @@ -86,9 +82,8 @@ impl Actor {
// Allocate an ID for this actor.
// Store mapping of pubkey or actor address to actor ID
let id_address: ActorID = rt.transaction(|s: &mut State, rt| {
s.map_address_to_new_id(rt.store(), &robust_address).map_err(|e| {
e.downcast_default(ExitCode::USR_ILLEGAL_STATE, "failed to allocate ID address")
})
s.map_address_to_new_id(rt.store(), &robust_address)
.context("failed to allocate ID address")
})?;

// Create an empty actor
Expand All @@ -101,7 +96,7 @@ impl Actor {
params.constructor_params,
rt.message().value_received(),
)
.map_err(|err| err.wrap("constructor failed"))?;
.context("constructor failed")?;

Ok(ExecReturn { id_address: Address::new_id(id_address), robust_address })
}
Expand Down
35 changes: 22 additions & 13 deletions actors/init/src/state.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
// Copyright 2019-2022 ChainSafe Systems
// SPDX-License-Identifier: Apache-2.0, MIT

use anyhow::anyhow;
use cid::Cid;
use fil_actors_runtime::{
actor_error, make_empty_map, make_map_with_root_and_bitwidth, FIRST_NON_SINGLETON_ADDR,
actor_error, make_empty_map, make_map_with_root_and_bitwidth, ActorError, AsActorError,
FIRST_NON_SINGLETON_ADDR,
};
use fvm_ipld_blockstore::Blockstore;
use fvm_ipld_encoding::tuple::*;
use fvm_ipld_encoding::Cbor;
use fvm_shared::address::{Address, Protocol};
use fvm_shared::error::ExitCode;
use fvm_shared::{ActorID, HAMT_BIT_WIDTH};

/// State is reponsible for creating
Expand All @@ -21,10 +22,10 @@ pub struct State {
}

impl State {
pub fn new<BS: Blockstore>(store: &BS, network_name: String) -> anyhow::Result<Self> {
pub fn new<BS: Blockstore>(store: &BS, network_name: String) -> Result<Self, ActorError> {
let empty_map = make_empty_map::<_, ()>(store, HAMT_BIT_WIDTH)
.flush()
.map_err(|e| anyhow!("failed to create empty map: {}", e))?;
.context_code(ExitCode::USR_ILLEGAL_STATE, "failed to create empty map")?;
Ok(Self { address_map: empty_map, next_id: FIRST_NON_SINGLETON_ADDR, network_name })
}

Expand All @@ -36,22 +37,26 @@ impl State {
&mut self,
store: &BS,
addr: &Address,
) -> anyhow::Result<ActorID> {
) -> Result<ActorID, ActorError> {
let id = self.next_id;
self.next_id += 1;

let mut map = make_map_with_root_and_bitwidth(&self.address_map, store, HAMT_BIT_WIDTH)?;
let is_new = map.set_if_absent(addr.to_bytes().into(), id)?;
let mut map = make_map_with_root_and_bitwidth(&self.address_map, store, HAMT_BIT_WIDTH)
.context_code(ExitCode::USR_ILLEGAL_STATE, "failed to load address map")?;
let is_new = map
.set_if_absent(addr.to_bytes().into(), id)
.context_code(ExitCode::USR_ILLEGAL_STATE, "failed to set map key")?;
if !is_new {
// this is impossible today as the robust address is a hash of unique inputs
// but in close future predictable address generation will make this possible
return Err(anyhow!(actor_error!(
return Err(actor_error!(
forbidden,
"robust address {} is already allocated in the address map",
addr
)));
));
}
self.address_map = map.flush()?;
self.address_map =
map.flush().context_code(ExitCode::USR_ILLEGAL_STATE, "failed to store address map")?;

Ok(id)
}
Expand All @@ -70,14 +75,18 @@ impl State {
&self,
store: &BS,
addr: &Address,
) -> anyhow::Result<Option<Address>> {
) -> Result<Option<Address>, ActorError> {
if addr.protocol() == Protocol::ID {
return Ok(Some(*addr));
}

let map = make_map_with_root_and_bitwidth(&self.address_map, store, HAMT_BIT_WIDTH)?;
let map = make_map_with_root_and_bitwidth(&self.address_map, store, HAMT_BIT_WIDTH)
.context_code(ExitCode::USR_ILLEGAL_STATE, "failed to load address map")?;

Ok(map.get(&addr.to_bytes())?.copied().map(Address::new_id))
let found = map
.get(&addr.to_bytes())
.context_code(ExitCode::USR_ILLEGAL_STATE, "failed to get address entry")?;
Ok(found.copied().map(Address::new_id))
}
}

Expand Down
Loading

0 comments on commit 8164f11

Please sign in to comment.