Skip to content

Commit 8dd3906

Browse files
committed
Add error context and conversion methods to replace downcasting
1 parent 10a30e2 commit 8dd3906

File tree

8 files changed

+126
-259
lines changed

8 files changed

+126
-259
lines changed

actors/init/src/lib.rs

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,10 @@
44
use cid::Cid;
55
use fil_actors_runtime::runtime::builtins::Type;
66
use fil_actors_runtime::runtime::{ActorCode, Runtime};
7-
use fil_actors_runtime::{actor_error, cbor, ActorDowncast, ActorError, SYSTEM_ACTOR_ADDR};
7+
use fil_actors_runtime::{actor_error, cbor, ActorContext, ActorError, SYSTEM_ACTOR_ADDR};
88
use fvm_ipld_blockstore::Blockstore;
99
use fvm_ipld_encoding::RawBytes;
1010
use fvm_shared::address::Address;
11-
use fvm_shared::error::ExitCode;
1211
use fvm_shared::{ActorID, MethodNum, METHOD_CONSTRUCTOR};
1312
use num_derive::FromPrimitive;
1413
use num_traits::FromPrimitive;
@@ -42,10 +41,7 @@ impl Actor {
4241
{
4342
let sys_ref: &Address = &SYSTEM_ACTOR_ADDR;
4443
rt.validate_immediate_caller_is(std::iter::once(sys_ref))?;
45-
let state = State::new(rt.store(), params.network_name).map_err(|e| {
46-
e.downcast_default(ExitCode::USR_ILLEGAL_STATE, "failed to construct init actor state")
47-
})?;
48-
44+
let state = State::new(rt.store(), params.network_name)?;
4945
rt.create(&state)?;
5046

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

9489
// Create an empty actor
@@ -101,7 +96,7 @@ impl Actor {
10196
params.constructor_params,
10297
rt.message().value_received(),
10398
)
104-
.map_err(|err| err.wrap("constructor failed"))?;
99+
.context("constructor failed")?;
105100

106101
Ok(ExecReturn { id_address: Address::new_id(id_address), robust_address })
107102
}

actors/init/src/state.rs

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
use cid::Cid;
55
use fil_actors_runtime::{
6-
actor_error, make_empty_map, make_map_with_root_and_bitwidth, AsActorError,
6+
actor_error, make_empty_map, make_map_with_root_and_bitwidth, ActorError, AsActorError,
77
FIRST_NON_SINGLETON_ADDR,
88
};
99
use fvm_ipld_blockstore::Blockstore;
@@ -22,7 +22,7 @@ pub struct State {
2222
}
2323

2424
impl State {
25-
pub fn new<BS: Blockstore>(store: &BS, network_name: String) -> anyhow::Result<Self> {
25+
pub fn new<BS: Blockstore>(store: &BS, network_name: String) -> Result<Self, ActorError> {
2626
let empty_map = make_empty_map::<_, ()>(store, HAMT_BIT_WIDTH)
2727
.flush()
2828
.context_code(ExitCode::USR_ILLEGAL_STATE, "failed to create empty map")?;
@@ -37,22 +37,26 @@ impl State {
3737
&mut self,
3838
store: &BS,
3939
addr: &Address,
40-
) -> anyhow::Result<ActorID> {
40+
) -> Result<ActorID, ActorError> {
4141
let id = self.next_id;
4242
self.next_id += 1;
4343

44-
let mut map = make_map_with_root_and_bitwidth(&self.address_map, store, HAMT_BIT_WIDTH)?;
45-
let is_new = map.set_if_absent(addr.to_bytes().into(), id)?;
44+
let mut map = make_map_with_root_and_bitwidth(&self.address_map, store, HAMT_BIT_WIDTH)
45+
.context_code(ExitCode::USR_ILLEGAL_STATE, "failed to load address map")?;
46+
let is_new = map
47+
.set_if_absent(addr.to_bytes().into(), id)
48+
.context_code(ExitCode::USR_ILLEGAL_STATE, "failed to set map key")?;
4649
if !is_new {
4750
// this is impossible today as the robust address is a hash of unique inputs
4851
// but in close future predictable address generation will make this possible
49-
return Err(anyhow!(actor_error!(
52+
return Err(actor_error!(
5053
forbidden,
5154
"robust address {} is already allocated in the address map",
5255
addr
53-
)));
56+
));
5457
}
55-
self.address_map = map.flush()?;
58+
self.address_map =
59+
map.flush().context_code(ExitCode::USR_ILLEGAL_STATE, "failed to store address map")?;
5660

5761
Ok(id)
5862
}
@@ -71,14 +75,18 @@ impl State {
7175
&self,
7276
store: &BS,
7377
addr: &Address,
74-
) -> anyhow::Result<Option<Address>> {
78+
) -> Result<Option<Address>, ActorError> {
7579
if addr.protocol() == Protocol::ID {
7680
return Ok(Some(*addr));
7781
}
7882

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

81-
Ok(map.get(&addr.to_bytes())?.copied().map(Address::new_id))
86+
let found = map
87+
.get(&addr.to_bytes())
88+
.context_code(ExitCode::USR_ILLEGAL_STATE, "failed to get address entry")?;
89+
Ok(found.copied().map(Address::new_id))
8290
}
8391
}
8492

0 commit comments

Comments
 (0)