Skip to content

Commit 2075285

Browse files
committed
cleaner error handling
1 parent 18759e2 commit 2075285

File tree

5 files changed

+85
-94
lines changed

5 files changed

+85
-94
lines changed

fil_token/src/runtime/mod.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,8 @@
1-
pub trait Runtime {}
1+
use anyhow::Result;
2+
use fvm_shared::address::Address;
3+
4+
pub trait Runtime {
5+
fn caller(&self) -> u64;
6+
7+
fn resolve_address(&self, addr: &Address) -> Result<u64>;
8+
}

fil_token/src/token/errors.rs

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,57 @@
1-
use super::state::StateError;
1+
use std::{error::Error, fmt::Display};
2+
23
use fvm_ipld_hamt::Error as HamtError;
34
use fvm_shared::address::Address;
45

6+
#[derive(Debug)]
7+
pub enum RuntimeError {
8+
AddrNotFound(Address),
9+
}
10+
11+
impl Display for RuntimeError {
12+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13+
match self {
14+
RuntimeError::AddrNotFound(_) => write!(f, "Address not found: {}", self),
15+
}
16+
}
17+
}
18+
19+
impl Error for RuntimeError {}
20+
21+
#[derive(Debug)]
22+
pub enum StateError {}
23+
24+
impl Display for StateError {
25+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
26+
write!(f, "State error")
27+
}
28+
}
29+
30+
impl Error for StateError {}
31+
32+
#[derive(Debug)]
533
pub enum ActorError {
634
AddrNotFound(Address),
35+
Arithmetic(String),
736
IpldState(StateError),
837
IpldHamt(HamtError),
9-
Arithmetic(String),
38+
RuntimeError(RuntimeError),
1039
}
1140

41+
impl Display for ActorError {
42+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
43+
match self {
44+
ActorError::AddrNotFound(e) => write!(f, "{}", e),
45+
ActorError::Arithmetic(e) => write!(f, "{}", e),
46+
ActorError::IpldState(e) => write!(f, "{}", e),
47+
ActorError::IpldHamt(e) => write!(f, "{}", e),
48+
ActorError::RuntimeError(e) => write!(f, "{}", e),
49+
}
50+
}
51+
}
52+
53+
impl Error for ActorError {}
54+
1255
impl From<StateError> for ActorError {
1356
fn from(e: StateError) -> Self {
1457
Self::IpldState(e)
@@ -20,3 +63,9 @@ impl From<HamtError> for ActorError {
2063
Self::IpldHamt(e)
2164
}
2265
}
66+
67+
impl From<RuntimeError> for ActorError {
68+
fn from(e: RuntimeError) -> Self {
69+
ActorError::RuntimeError(e)
70+
}
71+
}

fil_token/src/token/mod.rs

Lines changed: 23 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,20 @@ pub mod errors;
22
pub mod receiver;
33
pub mod state;
44
pub mod types;
5+
use self::errors::ActorError;
6+
use self::state::TokenState;
7+
use self::types::*;
8+
use crate::runtime::Runtime;
59

10+
use anyhow::bail;
11+
use anyhow::Result;
612
use fvm_ipld_blockstore::Blockstore as IpldStore;
713
use fvm_shared::address::Address;
814
use fvm_shared::bigint::bigint_ser::BigIntDe;
915
use fvm_shared::bigint::BigInt;
1016
use fvm_shared::bigint::Zero;
1117
use fvm_shared::econ::TokenAmount;
1218

13-
use self::errors::ActorError;
14-
use self::state::TokenState;
15-
use self::types::*;
16-
use crate::runtime::Runtime;
17-
1819
/// A macro to abort concisely.
1920
macro_rules! abort {
2021
($code:ident, $msg:literal $(, $ex:expr)*) => {
@@ -25,8 +26,6 @@ macro_rules! abort {
2526
};
2627
}
2728

28-
type Result<T> = std::result::Result<T, ActorError>;
29-
3029
/// A standard fungible token interface allowing for on-chain transactions
3130
pub trait Token {
3231
/// Constructs the token
@@ -82,7 +81,7 @@ where
8281
/// Injected blockstore
8382
bs: BS,
8483
/// Access to the runtime
85-
_fvm: FVM,
84+
fvm: FVM,
8685
}
8786

8887
impl<BS, FVM> StandardToken<BS, FVM>
@@ -132,10 +131,9 @@ where
132131
let mut state = self.load_state();
133132
let mut balances = state.get_balance_map(&self.bs);
134133

135-
// FIXME: replace fvm_sdk with abstraction
136-
let holder = match fvm_sdk::actor::resolve_address(&params.initial_holder) {
137-
Some(id) => id,
138-
None => {
134+
let holder = match self.fvm.resolve_address(&params.initial_holder) {
135+
Ok(id) => id,
136+
Err(_) => {
139137
return Ok(MintReturn {
140138
newly_minted: TokenAmount::zero(),
141139
successful: false,
@@ -176,10 +174,7 @@ where
176174
let balances = state.get_balance_map(&self.bs);
177175

178176
// Resolve the address
179-
let addr_id = match fvm_sdk::actor::resolve_address(&holder) {
180-
Some(id) => id,
181-
None => return Err(ActorError::AddrNotFound(holder)),
182-
};
177+
let addr_id = self.fvm.resolve_address(&holder)?;
183178

184179
match balances.get(&addr_id) {
185180
Ok(Some(bal)) => Ok(bal.clone().0),
@@ -196,23 +191,18 @@ where
196191
// Load the HAMT holding balances
197192
let state = self.load_state();
198193

199-
// FIXME: replace with runtime service call
200-
let caller_id = fvm_sdk::message::caller();
194+
let caller_id = self.fvm.caller();
201195
let mut caller_allowances_map = state.get_actor_allowance_map(&self.bs, caller_id);
202196

203-
let spender = match fvm_sdk::actor::resolve_address(&params.spender) {
204-
Some(id) => id,
205-
None => return Err(ActorError::AddrNotFound(params.spender)),
206-
};
207-
197+
let spender = self.fvm.resolve_address(&&params.spender)?;
208198
let new_amount = match caller_allowances_map.get(&spender)? {
209199
// Allowance exists - attempt to calculate new allowance
210200
Some(existing_allowance) => match existing_allowance.0.checked_add(&params.value) {
211201
Some(new_allowance) => {
212202
caller_allowances_map.set(spender, BigIntDe(new_allowance.clone()))?;
213203
new_allowance
214204
}
215-
None => return Err(ActorError::Arithmetic(String::from("Allowance overflowed"))),
205+
None => bail!(ActorError::Arithmetic(String::from("Allowance overflowed"))),
216206
},
217207
// No allowance recorded previously
218208
None => {
@@ -234,13 +224,10 @@ where
234224
// Load the HAMT holding balances
235225
let state = self.load_state();
236226

237-
// FIXME: replace with runtime service call
238-
let caller_id = fvm_sdk::message::caller();
227+
let caller_id = self.fvm.caller();
239228
let mut caller_allowances_map = state.get_actor_allowance_map(&self.bs, caller_id);
240-
let spender = match fvm_sdk::actor::resolve_address(&params.spender) {
241-
Some(id) => id,
242-
None => return Err(ActorError::AddrNotFound(params.spender)),
243-
};
229+
230+
let spender = self.fvm.resolve_address(&&params.spender)?;
244231

245232
let new_allowance = match caller_allowances_map.get(&spender)? {
246233
Some(existing_allowance) => {
@@ -275,16 +262,13 @@ where
275262
// Load the HAMT holding balances
276263
let state = self.load_state();
277264

278-
// FIXME: replace with runtime service call
279-
let caller_id = fvm_sdk::message::caller();
265+
let caller_id = self.fvm.caller();
280266
let mut caller_allowances_map = state.get_actor_allowance_map(&self.bs, caller_id);
281-
let spender = match fvm_sdk::actor::resolve_address(&params.spender) {
282-
Some(id) => id,
283-
None => return Err(ActorError::AddrNotFound(params.spender)),
284-
};
285267

268+
let spender = self.fvm.resolve_address(&&params.spender)?;
286269
let new_allowance = TokenAmount::zero();
287270
caller_allowances_map.set(spender, BigIntDe(new_allowance.clone()))?;
271+
288272
state.save(&self.bs);
289273

290274
Ok(AllowanceReturn {
@@ -298,17 +282,10 @@ where
298282
// Load the HAMT holding balances
299283
let state = self.load_state();
300284

301-
// FIXME: replace with runtime service call
302-
let owner = match fvm_sdk::actor::resolve_address(&params.owner) {
303-
Some(id) => id,
304-
None => return Err(ActorError::AddrNotFound(params.spender)),
305-
};
306-
285+
let owner = self.fvm.resolve_address(&params.owner)?;
307286
let owner_allowances_map = state.get_actor_allowance_map(&self.bs, owner);
308-
let spender = match fvm_sdk::actor::resolve_address(&params.spender) {
309-
Some(id) => id,
310-
None => return Err(ActorError::AddrNotFound(params.spender)),
311-
};
287+
288+
let spender = self.fvm.resolve_address(&&params.spender)?;
312289

313290
let allowance = match owner_allowances_map.get(&spender)? {
314291
Some(allowance) => allowance.0.clone(),

fil_token/src/token/receiver.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
1+
use anyhow::Result;
12
use fvm_shared::{address::Address, econ::TokenAmount};
23

3-
pub type Result<T> = std::result::Result<T, ReceiverError>;
4-
5-
pub enum ReceiverError {}
6-
74
/// Standard interface for a contract that wishes to receive tokens
85
pub trait TokenReceiver {
96
fn token_received(from: Address, amount: TokenAmount, data: &[u8]) -> Result<u32>;

fil_token/src/token/state.rs

Lines changed: 2 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use anyhow::anyhow;
2+
use anyhow::Result;
23
use cid::multihash::Code;
34
use cid::Cid;
45

@@ -10,7 +11,6 @@ use fvm_ipld_encoding::CborStore;
1011
use fvm_ipld_encoding::DAG_CBOR;
1112
use fvm_ipld_hamt::Hamt;
1213
use fvm_sdk::sself;
13-
use fvm_shared::address::Address;
1414
use fvm_shared::bigint::bigint_ser;
1515
use fvm_shared::bigint::bigint_ser::BigIntDe;
1616
use fvm_shared::econ::TokenAmount;
@@ -46,7 +46,7 @@ pub struct TokenState {
4646

4747
/// Functions to get and modify token state to and from the IPLD layer
4848
impl TokenState {
49-
pub fn new<BS: IpldStore>(store: &BS, name: &str, symbol: &str) -> StateResult<Self> {
49+
pub fn new<BS: IpldStore>(store: &BS, name: &str, symbol: &str) -> Result<Self> {
5050
let empty_balance_map = Hamt::<_, ()>::new_with_bit_width(store, HAMT_BIT_WIDTH)
5151
.flush()
5252
.map_err(|e| anyhow!("Failed to create empty balances map state {}", e))?;
@@ -245,42 +245,3 @@ impl TokenState {
245245
}
246246

247247
impl Cbor for TokenState {}
248-
249-
pub struct TokenAmountDiff {
250-
pub required: TokenAmount,
251-
pub actual: TokenAmount,
252-
}
253-
254-
pub enum TransferError {
255-
NoRecrHook,
256-
InsufficientAllowance(TokenAmountDiff),
257-
InsufficientBalance(TokenAmountDiff),
258-
}
259-
260-
pub enum StateError {
261-
AddrNotFound(Address),
262-
Arithmetic,
263-
Ipld(fvm_ipld_hamt::Error),
264-
Err(anyhow::Error),
265-
Transfer(TransferError),
266-
}
267-
268-
pub type StateResult<T> = std::result::Result<T, StateError>;
269-
270-
impl From<anyhow::Error> for StateError {
271-
fn from(e: anyhow::Error) -> Self {
272-
Self::Err(e)
273-
}
274-
}
275-
276-
impl From<fvm_ipld_hamt::Error> for StateError {
277-
fn from(e: fvm_ipld_hamt::Error) -> Self {
278-
Self::Ipld(e)
279-
}
280-
}
281-
282-
impl From<TransferError> for StateError {
283-
fn from(e: TransferError) -> Self {
284-
Self::Transfer(e)
285-
}
286-
}

0 commit comments

Comments
 (0)