3
3
4
4
use cid:: Cid ;
5
5
use fvm_ipld_blockstore:: Blockstore ;
6
- use fvm_ipld_hamt:: Error as HamtError ;
7
6
use fvm_shared:: address:: Address ;
8
7
use fvm_shared:: econ:: TokenAmount ;
9
8
use num_traits:: Zero ;
10
9
11
- use fil_actors_runtime:: { make_empty_map , make_map_with_root_and_bitwidth , Map } ;
12
-
13
- pub const BALANCE_TABLE_BITWIDTH : u32 = 6 ;
10
+ use fil_actors_runtime:: {
11
+ actor_error , ActorContext , ActorError , Config , Map2 , DEFAULT_HAMT_CONFIG ,
12
+ } ;
14
13
15
14
/// Balance table which handles getting and updating token balances specifically
16
- pub struct BalanceTable < ' a , BS > ( pub Map < ' a , BS , TokenAmount > ) ;
15
+ pub struct BalanceTable < BS : Blockstore > ( pub Map2 < BS , Address , TokenAmount > ) ;
16
+
17
+ const CONF : Config = Config { bit_width : 6 , ..DEFAULT_HAMT_CONFIG } ;
17
18
18
- impl < ' a , BS > BalanceTable < ' a , BS >
19
+ impl < BS > BalanceTable < BS >
19
20
where
20
21
BS : Blockstore ,
21
22
{
22
23
/// Initializes a new empty balance table
23
- pub fn new ( bs : & ' a BS ) -> Self {
24
- Self ( make_empty_map ( bs, BALANCE_TABLE_BITWIDTH ) )
24
+ pub fn new ( bs : BS , name : & ' static str ) -> Self {
25
+ Self ( Map2 :: empty ( bs, CONF , name ) )
25
26
}
26
27
27
28
/// Initializes a balance table from a root Cid
28
- pub fn from_root ( bs : & ' a BS , cid : & Cid ) -> Result < Self , HamtError > {
29
- Ok ( Self ( make_map_with_root_and_bitwidth ( cid, bs , BALANCE_TABLE_BITWIDTH ) ?) )
29
+ pub fn from_root ( bs : BS , cid : & Cid , name : & ' static str ) -> Result < Self , ActorError > {
30
+ Ok ( Self ( Map2 :: load ( bs , cid, CONF , name ) ?) )
30
31
}
31
32
32
33
/// Retrieve root from balance table
33
- pub fn root ( & mut self ) -> Result < Cid , HamtError > {
34
+ pub fn root ( & mut self ) -> Result < Cid , ActorError > {
34
35
self . 0 . flush ( )
35
36
}
36
37
37
38
/// Gets token amount for given address in balance table
38
- pub fn get ( & self , key : & Address ) -> Result < TokenAmount , HamtError > {
39
- if let Some ( v) = self . 0 . get ( & key. to_bytes ( ) ) ? {
39
+ pub fn get ( & self , key : & Address ) -> Result < TokenAmount , ActorError > {
40
+ if let Some ( v) = self . 0 . get ( key) ? {
40
41
Ok ( v. clone ( ) )
41
42
} else {
42
43
Ok ( TokenAmount :: zero ( ) )
43
44
}
44
45
}
45
46
46
47
/// Adds token amount to previously initialized account.
47
- pub fn add ( & mut self , key : & Address , value : & TokenAmount ) -> Result < ( ) , HamtError > {
48
+ pub fn add ( & mut self , key : & Address , value : & TokenAmount ) -> Result < ( ) , ActorError > {
48
49
let prev = self . get ( key) ?;
49
50
let sum = & prev + value;
50
51
if sum. is_negative ( ) {
51
- Err ( format ! ( "New balance in table cannot be negative: {}" , sum) . into ( ) )
52
+ Err ( actor_error ! (
53
+ illegal_argument,
54
+ "negative balance for {} adding {} to {}" ,
55
+ key,
56
+ value,
57
+ prev
58
+ ) )
52
59
} else if sum. is_zero ( ) && !prev. is_zero ( ) {
53
- self . 0 . delete ( & key. to_bytes ( ) ) ?;
60
+ self . 0 . delete ( key) . context ( "adding balance" ) ?;
54
61
Ok ( ( ) )
55
62
} else {
56
- self . 0 . set ( key. to_bytes ( ) . into ( ) , sum ) ?;
63
+ self . 0 . set ( key, sum ) . context ( "adding balance" ) ?;
57
64
Ok ( ( ) )
58
65
}
59
66
}
@@ -66,34 +73,39 @@ where
66
73
key : & Address ,
67
74
req : & TokenAmount ,
68
75
floor : & TokenAmount ,
69
- ) -> Result < TokenAmount , HamtError > {
76
+ ) -> Result < TokenAmount , ActorError > {
70
77
let prev = self . get ( key) ?;
71
78
let available = std:: cmp:: max ( TokenAmount :: zero ( ) , prev - floor) ;
72
79
let sub: TokenAmount = std:: cmp:: min ( & available, req) . clone ( ) ;
73
80
74
81
if sub. is_positive ( ) {
75
- self . add ( key, & -sub. clone ( ) ) ?;
82
+ self . add ( key, & -sub. clone ( ) ) . context ( "subtracting balance" ) ?;
76
83
}
77
84
78
85
Ok ( sub)
79
86
}
80
87
81
88
/// Subtracts value from a balance, and errors if full amount was not substracted.
82
- pub fn must_subtract ( & mut self , key : & Address , req : & TokenAmount ) -> Result < ( ) , HamtError > {
89
+ pub fn must_subtract ( & mut self , key : & Address , req : & TokenAmount ) -> Result < ( ) , ActorError > {
83
90
let prev = self . get ( key) ?;
84
91
85
92
if req > & prev {
86
- Err ( "couldn't subtract the requested amount" . into ( ) )
93
+ Err ( actor_error ! (
94
+ illegal_argument,
95
+ "negative balance for {} subtracting {} from {}" ,
96
+ key,
97
+ req,
98
+ prev
99
+ ) )
87
100
} else {
88
101
self . add ( key, & -req)
89
102
}
90
103
}
91
104
92
105
/// Returns total balance held by this balance table
93
106
#[ allow( dead_code) ]
94
- pub fn total ( & self ) -> Result < TokenAmount , HamtError > {
107
+ pub fn total ( & self ) -> Result < TokenAmount , ActorError > {
95
108
let mut total = TokenAmount :: zero ( ) ;
96
-
97
109
self . 0 . for_each ( |_, v : & TokenAmount | {
98
110
total += v;
99
111
Ok ( ( ) )
@@ -116,7 +128,7 @@ mod tests {
116
128
let addr1 = Address :: new_id ( 100 ) ;
117
129
let addr2 = Address :: new_id ( 101 ) ;
118
130
let store = MemoryBlockstore :: default ( ) ;
119
- let mut bt = BalanceTable :: new ( & store) ;
131
+ let mut bt = BalanceTable :: new ( & store, "test" ) ;
120
132
121
133
assert ! ( bt. total( ) . unwrap( ) . is_zero( ) ) ;
122
134
@@ -143,7 +155,7 @@ mod tests {
143
155
fn balance_subtracts ( ) {
144
156
let addr = Address :: new_id ( 100 ) ;
145
157
let store = MemoryBlockstore :: default ( ) ;
146
- let mut bt = BalanceTable :: new ( & store) ;
158
+ let mut bt = BalanceTable :: new ( & store, "test" ) ;
147
159
148
160
bt. add ( & addr, & TokenAmount :: from_atto ( 80u8 ) ) . unwrap ( ) ;
149
161
assert_eq ! ( bt. get( & addr) . unwrap( ) , TokenAmount :: from_atto( 80u8 ) ) ;
0 commit comments