Skip to content

Commit 8164f11

Browse files
anorthdignifiedquire
authored andcommitted
Traits and impls for adding context and exit codes to results. (filecoin-project#589)
Co-authored-by: dignifiedquire <[email protected]>
1 parent de646c5 commit 8164f11

File tree

11 files changed

+236
-261
lines changed

11 files changed

+236
-261
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: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
// Copyright 2019-2022 ChainSafe Systems
22
// SPDX-License-Identifier: Apache-2.0, MIT
33

4-
use anyhow::anyhow;
54
use cid::Cid;
65
use fil_actors_runtime::{
7-
actor_error, make_empty_map, make_map_with_root_and_bitwidth, FIRST_NON_SINGLETON_ADDR,
6+
actor_error, make_empty_map, make_map_with_root_and_bitwidth, ActorError, AsActorError,
7+
FIRST_NON_SINGLETON_ADDR,
88
};
99
use fvm_ipld_blockstore::Blockstore;
1010
use fvm_ipld_encoding::tuple::*;
1111
use fvm_ipld_encoding::Cbor;
1212
use fvm_shared::address::{Address, Protocol};
13+
use fvm_shared::error::ExitCode;
1314
use fvm_shared::{ActorID, HAMT_BIT_WIDTH};
1415

1516
/// State is reponsible for creating
@@ -21,10 +22,10 @@ pub struct State {
2122
}
2223

2324
impl State {
24-
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> {
2526
let empty_map = make_empty_map::<_, ()>(store, HAMT_BIT_WIDTH)
2627
.flush()
27-
.map_err(|e| anyhow!("failed to create empty map: {}", e))?;
28+
.context_code(ExitCode::USR_ILLEGAL_STATE, "failed to create empty map")?;
2829
Ok(Self { address_map: empty_map, next_id: FIRST_NON_SINGLETON_ADDR, network_name })
2930
}
3031

@@ -36,22 +37,26 @@ impl State {
3637
&mut self,
3738
store: &BS,
3839
addr: &Address,
39-
) -> anyhow::Result<ActorID> {
40+
) -> Result<ActorID, ActorError> {
4041
let id = self.next_id;
4142
self.next_id += 1;
4243

43-
let mut map = make_map_with_root_and_bitwidth(&self.address_map, store, HAMT_BIT_WIDTH)?;
44-
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")?;
4549
if !is_new {
4650
// this is impossible today as the robust address is a hash of unique inputs
4751
// but in close future predictable address generation will make this possible
48-
return Err(anyhow!(actor_error!(
52+
return Err(actor_error!(
4953
forbidden,
5054
"robust address {} is already allocated in the address map",
5155
addr
52-
)));
56+
));
5357
}
54-
self.address_map = map.flush()?;
58+
self.address_map =
59+
map.flush().context_code(ExitCode::USR_ILLEGAL_STATE, "failed to store address map")?;
5560

5661
Ok(id)
5762
}
@@ -70,14 +75,18 @@ impl State {
7075
&self,
7176
store: &BS,
7277
addr: &Address,
73-
) -> anyhow::Result<Option<Address>> {
78+
) -> Result<Option<Address>, ActorError> {
7479
if addr.protocol() == Protocol::ID {
7580
return Ok(Some(*addr));
7681
}
7782

78-
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")?;
7985

80-
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))
8190
}
8291
}
8392

0 commit comments

Comments
 (0)