1
1
// Copyright 2019-2022 ChainSafe Systems
2
2
// SPDX-License-Identifier: Apache-2.0, MIT
3
3
4
- use fvm_actor_utils:: receiver:: UniversalReceiverParams ;
5
4
use std:: collections:: BTreeSet ;
6
5
7
- use fil_actors_runtime :: FIRST_EXPORTED_METHOD_NUMBER ;
6
+ use fvm_actor_utils :: receiver :: UniversalReceiverParams ;
8
7
use fvm_ipld_blockstore:: Blockstore ;
9
8
use fvm_ipld_encoding:: ipld_block:: IpldBlock ;
10
9
use fvm_ipld_encoding:: RawBytes ;
11
10
use fvm_shared:: address:: Address ;
12
11
use fvm_shared:: econ:: TokenAmount ;
13
12
use fvm_shared:: error:: ExitCode ;
14
13
use fvm_shared:: MethodNum ;
15
- use fvm_shared:: { HAMT_BIT_WIDTH , METHOD_CONSTRUCTOR } ;
14
+ use fvm_shared:: METHOD_CONSTRUCTOR ;
16
15
use num_derive:: FromPrimitive ;
17
16
use num_traits:: Zero ;
18
17
19
18
use fil_actors_runtime:: cbor:: serialize_vec;
20
19
use fil_actors_runtime:: runtime:: { ActorCode , Primitives , Runtime } ;
20
+ use fil_actors_runtime:: FIRST_EXPORTED_METHOD_NUMBER ;
21
21
use fil_actors_runtime:: {
22
- actor_dispatch, actor_error, extract_send_result, make_empty_map , make_map_with_root ,
23
- resolve_to_actor_id , ActorContext , ActorError , AsActorError , Map , INIT_ACTOR_ADDR ,
22
+ actor_dispatch, actor_error, extract_send_result, resolve_to_actor_id , ActorContext ,
23
+ ActorError , AsActorError , INIT_ACTOR_ADDR ,
24
24
} ;
25
25
26
26
pub use self :: state:: * ;
@@ -97,9 +97,7 @@ impl Actor {
97
97
return Err ( actor_error ! ( illegal_argument; "negative unlock duration disallowed" ) ) ;
98
98
}
99
99
100
- let empty_root = make_empty_map :: < _ , ( ) > ( rt. store ( ) , HAMT_BIT_WIDTH )
101
- . flush ( )
102
- . context_code ( ExitCode :: USR_ILLEGAL_STATE , "failed to create empty map" ) ?;
100
+ let empty_root = PendingTxnMap :: empty ( rt. store ( ) , PENDING_TXN_CONFIG , "empty" ) . flush ( ) ?;
103
101
104
102
let mut st: State = State {
105
103
signers : resolved_signers,
@@ -141,9 +139,12 @@ impl Actor {
141
139
return Err ( actor_error ! ( forbidden, "{} is not a signer" , proposer) ) ;
142
140
}
143
141
144
- let mut ptx = make_map_with_root ( & st. pending_txs , rt. store ( ) )
145
- . context_code ( ExitCode :: USR_ILLEGAL_STATE , "failed to load pending transactions" ) ?;
146
-
142
+ let mut ptx = PendingTxnMap :: load (
143
+ rt. store ( ) ,
144
+ & st. pending_txs ,
145
+ PENDING_TXN_CONFIG ,
146
+ "pending txns" ,
147
+ ) ?;
147
148
let t_id = st. next_tx_id ;
148
149
st. next_tx_id . 0 += 1 ;
149
150
@@ -155,21 +156,12 @@ impl Actor {
155
156
approved : Vec :: new ( ) ,
156
157
} ;
157
158
158
- ptx. set ( t_id. key ( ) , txn. clone ( ) ) . context_code (
159
- ExitCode :: USR_ILLEGAL_STATE ,
160
- "failed to put transaction for propose" ,
161
- ) ?;
162
-
163
- st. pending_txs = ptx. flush ( ) . context_code (
164
- ExitCode :: USR_ILLEGAL_STATE ,
165
- "failed to flush pending transactions" ,
166
- ) ?;
167
-
159
+ ptx. set ( & t_id, txn. clone ( ) ) ?;
160
+ st. pending_txs = ptx. flush ( ) ?;
168
161
Ok ( ( t_id, txn) )
169
162
} ) ?;
170
163
171
164
let ( applied, ret, code) = Self :: approve_transaction ( rt, txn_id, txn) ?;
172
-
173
165
Ok ( ProposeReturn { txn_id, applied, code, ret } )
174
166
}
175
167
@@ -183,9 +175,12 @@ impl Actor {
183
175
if !st. is_signer ( & approver) {
184
176
return Err ( actor_error ! ( forbidden; "{} is not a signer" , approver) ) ;
185
177
}
186
-
187
- let ptx = make_map_with_root ( & st. pending_txs , rt. store ( ) )
188
- . context_code ( ExitCode :: USR_ILLEGAL_STATE , "failed to load pending transactions" ) ?;
178
+ let ptx = PendingTxnMap :: load (
179
+ rt. store ( ) ,
180
+ & st. pending_txs ,
181
+ PENDING_TXN_CONFIG ,
182
+ "pending txns" ,
183
+ ) ?;
189
184
190
185
let txn = get_transaction ( rt, & ptx, params. id , params. proposal_hash ) ?;
191
186
@@ -215,17 +210,16 @@ impl Actor {
215
210
return Err ( actor_error ! ( forbidden; "{} is not a signer" , caller_addr) ) ;
216
211
}
217
212
218
- let mut ptx = make_map_with_root :: < _ , Transaction > ( & st. pending_txs , rt. store ( ) )
219
- . context_code ( ExitCode :: USR_ILLEGAL_STATE , "failed to load pending transactions" ) ?;
213
+ let mut ptx = PendingTxnMap :: load (
214
+ rt. store ( ) ,
215
+ & st. pending_txs ,
216
+ PENDING_TXN_CONFIG ,
217
+ "pending txns" ,
218
+ ) ?;
220
219
221
- let ( _, tx) = ptx
222
- . delete ( & params. id . key ( ) )
223
- . with_context_code ( ExitCode :: USR_ILLEGAL_STATE , || {
224
- format ! ( "failed to pop transaction {:?} for cancel" , params. id)
225
- } ) ?
226
- . ok_or_else ( || {
227
- actor_error ! ( not_found, "no such transaction {:?} to cancel" , params. id)
228
- } ) ?;
220
+ let tx = ptx. delete ( & params. id ) ?. ok_or_else ( || {
221
+ actor_error ! ( not_found, "no such transaction {:?} to cancel" , params. id)
222
+ } ) ?;
229
223
230
224
// Check to make sure transaction proposer is caller address
231
225
if tx. approved . get ( 0 ) != Some ( & caller_addr) {
@@ -241,11 +235,7 @@ impl Actor {
241
235
return Err ( actor_error ! ( illegal_state, "hash does not match proposal params" ) ) ;
242
236
}
243
237
244
- st. pending_txs = ptx. flush ( ) . context_code (
245
- ExitCode :: USR_ILLEGAL_STATE ,
246
- "failed to flush pending transactions" ,
247
- ) ?;
248
-
238
+ st. pending_txs = ptx. flush ( ) ?;
249
239
Ok ( ( ) )
250
240
} )
251
241
}
@@ -416,21 +406,18 @@ impl Actor {
416
406
}
417
407
418
408
let st = rt. transaction ( |st : & mut State , rt| {
419
- let mut ptx = make_map_with_root ( & st. pending_txs , rt. store ( ) )
420
- . context_code ( ExitCode :: USR_ILLEGAL_STATE , "failed to load pending transactions" ) ?;
409
+ let mut ptx = PendingTxnMap :: load (
410
+ rt. store ( ) ,
411
+ & st. pending_txs ,
412
+ PENDING_TXN_CONFIG ,
413
+ "pending txns" ,
414
+ ) ?;
421
415
422
416
// update approved on the transaction
423
417
txn. approved . push ( rt. message ( ) . caller ( ) ) ;
424
418
425
- ptx. set ( tx_id. key ( ) , txn. clone ( ) )
426
- . with_context_code ( ExitCode :: USR_ILLEGAL_STATE , || {
427
- format ! ( "failed to put transaction {} for approval" , tx_id. 0 )
428
- } ) ?;
429
-
430
- st. pending_txs = ptx. flush ( ) . context_code (
431
- ExitCode :: USR_ILLEGAL_STATE ,
432
- "failed to flush pending transactions" ,
433
- ) ?;
419
+ ptx. set ( & tx_id, txn. clone ( ) ) ?;
420
+ st. pending_txs = ptx. flush ( ) ?;
434
421
435
422
// Go implementation holds reference to state after transaction so this must be cloned
436
423
// to match to handle possible exit code inconsistency
@@ -493,18 +480,14 @@ fn execute_transaction_if_approved(
493
480
applied = true ;
494
481
495
482
rt. transaction ( |st : & mut State , rt| {
496
- let mut ptx = make_map_with_root :: < _ , Transaction > ( & st. pending_txs , rt. store ( ) )
497
- . context_code ( ExitCode :: USR_ILLEGAL_STATE , "failed to load pending transactions" ) ?;
498
-
499
- ptx. delete ( & txn_id. key ( ) ) . context_code (
500
- ExitCode :: USR_ILLEGAL_STATE ,
501
- "failed to delete transaction for cleanup" ,
502
- ) ?;
503
-
504
- st. pending_txs = ptx. flush ( ) . context_code (
505
- ExitCode :: USR_ILLEGAL_STATE ,
506
- "failed to flush pending transactions" ,
483
+ let mut ptx = PendingTxnMap :: load (
484
+ rt. store ( ) ,
485
+ & st. pending_txs ,
486
+ PENDING_TXN_CONFIG ,
487
+ "pending txns" ,
507
488
) ?;
489
+ ptx. delete ( & txn_id) ?;
490
+ st. pending_txs = ptx. flush ( ) ?;
508
491
Ok ( ( ) )
509
492
} ) ?;
510
493
}
@@ -514,7 +497,7 @@ fn execute_transaction_if_approved(
514
497
515
498
fn get_transaction < ' m , BS , RT > (
516
499
rt : & RT ,
517
- ptx : & ' m Map < ' _ , BS , Transaction > ,
500
+ ptx : & ' m PendingTxnMap < BS > ,
518
501
txn_id : TxnID ,
519
502
proposal_hash : Vec < u8 > ,
520
503
) -> Result < & ' m Transaction , ActorError >
@@ -523,10 +506,7 @@ where
523
506
RT : Runtime ,
524
507
{
525
508
let txn = ptx
526
- . get ( & txn_id. key ( ) )
527
- . with_context_code ( ExitCode :: USR_ILLEGAL_STATE , || {
528
- format ! ( "failed to load transaction {:?} for approval" , txn_id)
529
- } ) ?
509
+ . get ( & txn_id) ?
530
510
. ok_or_else ( || actor_error ! ( not_found, "no such transaction {:?} for approval" , txn_id) ) ?;
531
511
532
512
if !proposal_hash. is_empty ( ) {
0 commit comments