1
1
// Copyright 2019-2022 ChainSafe Systems
2
2
// SPDX-License-Identifier: Apache-2.0, MIT
3
3
4
- use anyhow:: anyhow;
5
4
#[ cfg( feature = "m2-native" ) ]
6
5
use cid:: multihash:: Code ;
7
6
use cid:: Cid ;
8
- use fil_actors_runtime:: actor_error;
9
7
use fil_actors_runtime:: {
10
- make_empty_map, make_map_with_root_and_bitwidth, FIRST_NON_SINGLETON_ADDR ,
8
+ actor_error, make_empty_map, make_map_with_root_and_bitwidth, ActorError , AsActorError ,
9
+ FIRST_NON_SINGLETON_ADDR ,
11
10
} ;
12
11
use fvm_ipld_blockstore:: Blockstore ;
13
12
use fvm_ipld_encoding:: tuple:: * ;
14
13
use fvm_ipld_encoding:: Cbor ;
15
14
#[ cfg( feature = "m2-native" ) ]
16
15
use fvm_ipld_encoding:: CborStore ;
17
16
use fvm_shared:: address:: { Address , Protocol } ;
17
+ use fvm_shared:: error:: ExitCode ;
18
18
use fvm_shared:: { ActorID , HAMT_BIT_WIDTH } ;
19
19
20
20
/// State is reponsible for creating
@@ -28,12 +28,15 @@ pub struct State {
28
28
}
29
29
30
30
impl State {
31
- pub fn new < BS : Blockstore > ( store : & BS , network_name : String ) -> anyhow :: Result < Self > {
31
+ pub fn new < BS : Blockstore > ( store : & BS , network_name : String ) -> Result < Self , ActorError > {
32
32
let empty_map = make_empty_map :: < _ , ( ) > ( store, HAMT_BIT_WIDTH )
33
33
. flush ( )
34
- . map_err ( |e| anyhow ! ( "failed to create empty map: {}" , e ) ) ?;
34
+ . context_code ( ExitCode :: USR_ILLEGAL_STATE , "failed to create empty map" ) ?;
35
35
#[ cfg( feature = "m2-native" ) ]
36
- let installed_actors = store. put_cbor ( & Vec :: < Cid > :: new ( ) , Code :: Blake2b256 ) ?;
36
+ let installed_actors = store. put_cbor ( & Vec :: < Cid > :: new ( ) , Code :: Blake2b256 ) . context_code (
37
+ ExitCode :: USR_ILLEGAL_STATE ,
38
+ "failed to create installed actors object" ,
39
+ ) ?;
37
40
Ok ( Self {
38
41
address_map : empty_map,
39
42
next_id : FIRST_NON_SINGLETON_ADDR ,
@@ -52,22 +55,26 @@ impl State {
52
55
& mut self ,
53
56
store : & BS ,
54
57
addr : & Address ,
55
- ) -> anyhow :: Result < ActorID > {
58
+ ) -> Result < ActorID , ActorError > {
56
59
let id = self . next_id ;
57
60
self . next_id += 1 ;
58
61
59
- let mut map = make_map_with_root_and_bitwidth ( & self . address_map , store, HAMT_BIT_WIDTH ) ?;
60
- let is_new = map. set_if_absent ( addr. to_bytes ( ) . into ( ) , id) ?;
62
+ let mut map = make_map_with_root_and_bitwidth ( & self . address_map , store, HAMT_BIT_WIDTH )
63
+ . context_code ( ExitCode :: USR_ILLEGAL_STATE , "failed to load address map" ) ?;
64
+ let is_new = map
65
+ . set_if_absent ( addr. to_bytes ( ) . into ( ) , id)
66
+ . context_code ( ExitCode :: USR_ILLEGAL_STATE , "failed to set map key" ) ?;
61
67
if !is_new {
62
68
// this is impossible today as the robust address is a hash of unique inputs
63
69
// but in close future predictable address generation will make this possible
64
- return Err ( anyhow ! ( actor_error!(
70
+ return Err ( actor_error ! (
65
71
forbidden,
66
72
"robust address {} is already allocated in the address map" ,
67
73
addr
68
- ) ) ) ;
74
+ ) ) ;
69
75
}
70
- self . address_map = map. flush ( ) ?;
76
+ self . address_map =
77
+ map. flush ( ) . context_code ( ExitCode :: USR_ILLEGAL_STATE , "failed to store address map" ) ?;
71
78
72
79
Ok ( id)
73
80
}
@@ -79,37 +86,45 @@ impl State {
79
86
store : & BS ,
80
87
addr : & Address ,
81
88
f4addr : & Address ,
82
- ) -> anyhow :: Result < ActorID >
89
+ ) -> Result < ActorID , ActorError >
83
90
where
84
91
BS : Blockstore ,
85
92
{
86
- let mut map = make_map_with_root_and_bitwidth ( & self . address_map , store, HAMT_BIT_WIDTH ) ?;
93
+ let mut map = make_map_with_root_and_bitwidth ( & self . address_map , store, HAMT_BIT_WIDTH )
94
+ . context_code ( ExitCode :: USR_ILLEGAL_STATE , "failed to load address map" ) ?;
87
95
88
96
// Assign a new ID address, or use the one currently mapped to the f4 address. We don't
89
97
// bother checking if the target actor is an embryo here, the FVM will check that when we go to create the actor.
90
98
let f4addr_key = f4addr. to_bytes ( ) . into ( ) ;
91
- let id: u64 = match map. get ( & f4addr_key) ? {
99
+ let id: u64 = match map
100
+ . get ( & f4addr_key)
101
+ . context_code ( ExitCode :: USR_ILLEGAL_STATE , "failed to lookup f4 address in map" ) ?
102
+ {
92
103
Some ( id) => * id,
93
104
None => {
94
105
let id = self . next_id ;
95
106
self . next_id += 1 ;
96
- map. set ( f4addr_key, id) ?;
107
+ map. set ( f4addr_key, id)
108
+ . context_code ( ExitCode :: USR_ILLEGAL_STATE , "failed to set f4 address in map" ) ?;
97
109
id
98
110
}
99
111
} ;
100
112
101
113
// Then go ahead and assign the f2 address.
102
- let is_new = map. set_if_absent ( addr. to_bytes ( ) . into ( ) , id) ?;
114
+ let is_new = map
115
+ . set_if_absent ( addr. to_bytes ( ) . into ( ) , id)
116
+ . context_code ( ExitCode :: USR_ILLEGAL_STATE , "failed to set map key" ) ?;
103
117
if !is_new {
104
118
// this is impossible today as the robust address is a hash of unique inputs
105
119
// but in close future predictable address generation will make this possible
106
- return Err ( anyhow ! ( actor_error!(
120
+ return Err ( actor_error ! (
107
121
forbidden,
108
122
"robust address {} is already allocated in the address map" ,
109
123
addr
110
- ) ) ) ;
124
+ ) ) ;
111
125
}
112
- self . address_map = map. flush ( ) ?;
126
+ self . address_map =
127
+ map. flush ( ) . context_code ( ExitCode :: USR_ILLEGAL_STATE , "failed to store address map" ) ?;
113
128
114
129
Ok ( id)
115
130
}
@@ -128,14 +143,18 @@ impl State {
128
143
& self ,
129
144
store : & BS ,
130
145
addr : & Address ,
131
- ) -> anyhow :: Result < Option < Address > > {
146
+ ) -> Result < Option < Address > , ActorError > {
132
147
if addr. protocol ( ) == Protocol :: ID {
133
148
return Ok ( Some ( * addr) ) ;
134
149
}
135
150
136
- let map = make_map_with_root_and_bitwidth ( & self . address_map , store, HAMT_BIT_WIDTH ) ?;
151
+ let map = make_map_with_root_and_bitwidth ( & self . address_map , store, HAMT_BIT_WIDTH )
152
+ . context_code ( ExitCode :: USR_ILLEGAL_STATE , "failed to load address map" ) ?;
137
153
138
- Ok ( map. get ( & addr. to_bytes ( ) ) ?. copied ( ) . map ( Address :: new_id) )
154
+ let found = map
155
+ . get ( & addr. to_bytes ( ) )
156
+ . context_code ( ExitCode :: USR_ILLEGAL_STATE , "failed to get address entry" ) ?;
157
+ Ok ( found. copied ( ) . map ( Address :: new_id) )
139
158
}
140
159
141
160
/// Check to see if an actor is already installed
@@ -144,8 +163,11 @@ impl State {
144
163
& self ,
145
164
store : & BS ,
146
165
cid : & Cid ,
147
- ) -> anyhow:: Result < bool > {
148
- let installed: Vec < Cid > = match store. get_cbor ( & self . installed_actors ) ? {
166
+ ) -> Result < bool , ActorError > {
167
+ let installed: Vec < Cid > = match store
168
+ . get_cbor ( & self . installed_actors )
169
+ . context_code ( ExitCode :: USR_ILLEGAL_STATE , "failed to load installed actor list" ) ?
170
+ {
149
171
Some ( v) => v,
150
172
None => Vec :: new ( ) ,
151
173
} ;
@@ -158,13 +180,18 @@ impl State {
158
180
& mut self ,
159
181
store : & BS ,
160
182
cid : Cid ,
161
- ) -> anyhow:: Result < ( ) > {
162
- let mut installed: Vec < Cid > = match store. get_cbor ( & self . installed_actors ) ? {
183
+ ) -> Result < ( ) , ActorError > {
184
+ let mut installed: Vec < Cid > = match store
185
+ . get_cbor ( & self . installed_actors )
186
+ . context_code ( ExitCode :: USR_ILLEGAL_STATE , "failed to load installed actor list" ) ?
187
+ {
163
188
Some ( v) => v,
164
189
None => Vec :: new ( ) ,
165
190
} ;
166
191
installed. push ( cid) ;
167
- self . installed_actors = store. put_cbor ( & installed, Code :: Blake2b256 ) ?;
192
+ self . installed_actors = store
193
+ . put_cbor ( & installed, Code :: Blake2b256 )
194
+ . context_code ( ExitCode :: USR_ILLEGAL_STATE , "failed to save installed actor list" ) ?;
168
195
Ok ( ( ) )
169
196
}
170
197
}
0 commit comments