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,10 +28,10 @@ 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
36
let installed_actors = store. put_cbor ( & Vec :: < Cid > :: new ( ) , Code :: Blake2b256 ) ?;
37
37
Ok ( Self {
@@ -52,22 +52,26 @@ impl State {
52
52
& mut self ,
53
53
store : & BS ,
54
54
addr : & Address ,
55
- ) -> anyhow :: Result < ActorID > {
55
+ ) -> Result < ActorID , ActorError > {
56
56
let id = self . next_id ;
57
57
self . next_id += 1 ;
58
58
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) ?;
59
+ let mut map = make_map_with_root_and_bitwidth ( & self . address_map , store, HAMT_BIT_WIDTH )
60
+ . context_code ( ExitCode :: USR_ILLEGAL_STATE , "failed to load address map" ) ?;
61
+ let is_new = map
62
+ . set_if_absent ( addr. to_bytes ( ) . into ( ) , id)
63
+ . context_code ( ExitCode :: USR_ILLEGAL_STATE , "failed to set map key" ) ?;
61
64
if !is_new {
62
65
// this is impossible today as the robust address is a hash of unique inputs
63
66
// but in close future predictable address generation will make this possible
64
- return Err ( anyhow ! ( actor_error!(
67
+ return Err ( actor_error ! (
65
68
forbidden,
66
69
"robust address {} is already allocated in the address map" ,
67
70
addr
68
- ) ) ) ;
71
+ ) ) ;
69
72
}
70
- self . address_map = map. flush ( ) ?;
73
+ self . address_map =
74
+ map. flush ( ) . context_code ( ExitCode :: USR_ILLEGAL_STATE , "failed to store address map" ) ?;
71
75
72
76
Ok ( id)
73
77
}
@@ -79,37 +83,45 @@ impl State {
79
83
store : & BS ,
80
84
addr : & Address ,
81
85
f4addr : & Address ,
82
- ) -> anyhow :: Result < ActorID >
86
+ ) -> Result < ActorID , ActorError >
83
87
where
84
88
BS : Blockstore ,
85
89
{
86
- let mut map = make_map_with_root_and_bitwidth ( & self . address_map , store, HAMT_BIT_WIDTH ) ?;
90
+ let mut map = make_map_with_root_and_bitwidth ( & self . address_map , store, HAMT_BIT_WIDTH )
91
+ . context_code ( ExitCode :: USR_ILLEGAL_STATE , "failed to load address map" ) ?;
87
92
88
93
// Assign a new ID address, or use the one currently mapped to the f4 address. We don't
89
94
// bother checking if the target actor is an embryo here, the FVM will check that when we go to create the actor.
90
95
let f4addr_key = f4addr. to_bytes ( ) . into ( ) ;
91
- let id: u64 = match map. get ( & f4addr_key) ? {
96
+ let id: u64 = match map
97
+ . get ( & f4addr_key)
98
+ . context_code ( ExitCode :: USR_ILLEGAL_STATE , "failed to lookup f4 address in map" ) ?
99
+ {
92
100
Some ( id) => * id,
93
101
None => {
94
102
let id = self . next_id ;
95
103
self . next_id += 1 ;
96
- map. set ( f4addr_key, id) ?;
104
+ map. set ( f4addr_key, id)
105
+ . context_code ( ExitCode :: USR_ILLEGAL_STATE , "failed to set f4 address in map" ) ?;
97
106
id
98
107
}
99
108
} ;
100
109
101
110
// Then go ahead and assign the f2 address.
102
- let is_new = map. set_if_absent ( addr. to_bytes ( ) . into ( ) , id) ?;
111
+ let is_new = map
112
+ . set_if_absent ( addr. to_bytes ( ) . into ( ) , id)
113
+ . context_code ( ExitCode :: USR_ILLEGAL_STATE , "failed to set map key" ) ?;
103
114
if !is_new {
104
115
// this is impossible today as the robust address is a hash of unique inputs
105
116
// but in close future predictable address generation will make this possible
106
- return Err ( anyhow ! ( actor_error!(
117
+ return Err ( actor_error ! (
107
118
forbidden,
108
119
"robust address {} is already allocated in the address map" ,
109
120
addr
110
- ) ) ) ;
121
+ ) ) ;
111
122
}
112
- self . address_map = map. flush ( ) ?;
123
+ self . address_map =
124
+ map. flush ( ) . context_code ( ExitCode :: USR_ILLEGAL_STATE , "failed to store address map" ) ?;
113
125
114
126
Ok ( id)
115
127
}
@@ -128,14 +140,18 @@ impl State {
128
140
& self ,
129
141
store : & BS ,
130
142
addr : & Address ,
131
- ) -> anyhow :: Result < Option < Address > > {
143
+ ) -> Result < Option < Address > , ActorError > {
132
144
if addr. protocol ( ) == Protocol :: ID {
133
145
return Ok ( Some ( * addr) ) ;
134
146
}
135
147
136
- let map = make_map_with_root_and_bitwidth ( & self . address_map , store, HAMT_BIT_WIDTH ) ?;
148
+ let map = make_map_with_root_and_bitwidth ( & self . address_map , store, HAMT_BIT_WIDTH )
149
+ . context_code ( ExitCode :: USR_ILLEGAL_STATE , "failed to load address map" ) ?;
137
150
138
- Ok ( map. get ( & addr. to_bytes ( ) ) ?. copied ( ) . map ( Address :: new_id) )
151
+ let found = map
152
+ . get ( & addr. to_bytes ( ) )
153
+ . context_code ( ExitCode :: USR_ILLEGAL_STATE , "failed to get address entry" ) ?;
154
+ Ok ( found. copied ( ) . map ( Address :: new_id) )
139
155
}
140
156
141
157
/// Check to see if an actor is already installed
@@ -144,7 +160,7 @@ impl State {
144
160
& self ,
145
161
store : & BS ,
146
162
cid : & Cid ,
147
- ) -> anyhow :: Result < bool > {
163
+ ) -> Result < bool , ActorError > {
148
164
let installed: Vec < Cid > = match store. get_cbor ( & self . installed_actors ) ? {
149
165
Some ( v) => v,
150
166
None => Vec :: new ( ) ,
@@ -158,7 +174,7 @@ impl State {
158
174
& mut self ,
159
175
store : & BS ,
160
176
cid : Cid ,
161
- ) -> anyhow :: Result < ( ) > {
177
+ ) -> Result < ( ) , ActorError > {
162
178
let mut installed: Vec < Cid > = match store. get_cbor ( & self . installed_actors ) ? {
163
179
Some ( v) => v,
164
180
None => Vec :: new ( ) ,
0 commit comments