@@ -54,7 +54,7 @@ impl<N: Network> Process<N> {
54
54
// Retrieve the fee stack.
55
55
let fee_stack = self . get_stack( fee. program_id( ) ) ?;
56
56
// Finalize the fee transition.
57
- finalize_operations. extend( finalize_fee_transition( state, store, fee_stack, fee) ?) ;
57
+ finalize_operations. extend( finalize_fee_transition( state, store, & fee_stack, fee) ?) ;
58
58
lap!( timer, "Finalize transition for '{}/{}'" , fee. program_id( ) , fee. function_name( ) ) ;
59
59
60
60
/* Finalize the deployment. */
@@ -116,15 +116,15 @@ impl<N: Network> Process<N> {
116
116
// Finalize the root transition.
117
117
// Note that this will result in all the remaining transitions being finalized, since the number
118
118
// of calls matches the number of transitions.
119
- let mut finalize_operations = finalize_transition( state, store, stack, transition, call_graph) ?;
119
+ let mut finalize_operations = finalize_transition( state, store, & stack, transition, call_graph) ?;
120
120
121
121
/* Finalize the fee. */
122
122
123
123
if let Some ( fee) = fee {
124
124
// Retrieve the fee stack.
125
125
let fee_stack = self . get_stack( fee. program_id( ) ) ?;
126
126
// Finalize the fee transition.
127
- finalize_operations. extend( finalize_fee_transition( state, store, fee_stack, fee) ?) ;
127
+ finalize_operations. extend( finalize_fee_transition( state, store, & fee_stack, fee) ?) ;
128
128
lap!( timer, "Finalize transition for '{}/{}'" , fee. program_id( ) , fee. function_name( ) ) ;
129
129
}
130
130
@@ -150,7 +150,7 @@ impl<N: Network> Process<N> {
150
150
// Retrieve the stack.
151
151
let stack = self . get_stack( fee. program_id( ) ) ?;
152
152
// Finalize the fee transition.
153
- let result = finalize_fee_transition( state, store, stack, fee) ;
153
+ let result = finalize_fee_transition( state, store, & stack, fee) ;
154
154
finish!( timer, "Finalize transition for '{}/{}'" , fee. program_id( ) , fee. function_name( ) ) ;
155
155
// Return the result.
156
156
result
@@ -162,7 +162,7 @@ impl<N: Network> Process<N> {
162
162
fn finalize_fee_transition < N : Network , P : FinalizeStorage < N > > (
163
163
state : FinalizeGlobalState ,
164
164
store : & FinalizeStore < N , P > ,
165
- stack : & Stack < N > ,
165
+ stack : & Arc < Stack < N > > ,
166
166
fee : & Fee < N > ,
167
167
) -> Result < Vec < FinalizeOperation < N > > > {
168
168
// Construct the call graph.
@@ -187,7 +187,7 @@ fn finalize_fee_transition<N: Network, P: FinalizeStorage<N>>(
187
187
fn finalize_transition < N : Network , P : FinalizeStorage < N > > (
188
188
state : FinalizeGlobalState ,
189
189
store : & FinalizeStore < N , P > ,
190
- stack : & Stack < N > ,
190
+ stack : & Arc < Stack < N > > ,
191
191
transition : & Transition < N > ,
192
192
call_graph : HashMap < N :: TransitionID , Vec < N :: TransitionID > > ,
193
193
) -> Result < Vec < FinalizeOperation < N > > > {
@@ -226,23 +226,26 @@ fn finalize_transition<N: Network, P: FinalizeStorage<N>>(
226
226
states. push ( initialize_finalize_state ( state, future, stack, * transition. id ( ) , nonce) ?) ;
227
227
228
228
// While there are active finalize states, finalize them.
229
- ' outer: while let Some ( FinalizeState {
230
- mut counter,
231
- finalize,
232
- mut registers,
233
- stack,
234
- mut call_counter,
235
- mut awaited,
236
- } ) = states. pop ( )
229
+ ' outer: while let Some ( FinalizeState { mut counter, mut registers, stack, mut call_counter, mut awaited } ) =
230
+ states. pop ( )
237
231
{
232
+ // Get the finalize logic.
233
+ let Some ( finalize) = stack. get_function_ref ( registers. function_name ( ) ) ?. finalize_logic ( ) else {
234
+ bail ! (
235
+ "The function '{}/{}' does not have an associated finalize block" ,
236
+ stack. program_id( ) ,
237
+ registers. function_name( )
238
+ )
239
+ } ;
238
240
// Evaluate the commands.
239
241
while counter < finalize. commands ( ) . len ( ) {
240
242
// Retrieve the command.
241
243
let command = & finalize. commands ( ) [ counter] ;
242
244
// Finalize the command.
243
245
match & command {
244
246
Command :: BranchEq ( branch_eq) => {
245
- let result = try_vm_runtime ! ( || branch_to( counter, branch_eq, finalize, stack, & registers) ) ;
247
+ let result =
248
+ try_vm_runtime ! ( || branch_to( counter, branch_eq, finalize. positions( ) , & stack, & registers) ) ;
246
249
match result {
247
250
Ok ( Ok ( new_counter) ) => {
248
251
counter = new_counter;
@@ -254,7 +257,8 @@ fn finalize_transition<N: Network, P: FinalizeStorage<N>>(
254
257
}
255
258
}
256
259
Command :: BranchNeq ( branch_neq) => {
257
- let result = try_vm_runtime ! ( || branch_to( counter, branch_neq, finalize, stack, & registers) ) ;
260
+ let result =
261
+ try_vm_runtime ! ( || branch_to( counter, branch_neq, finalize. positions( ) , & stack, & registers) ) ;
258
262
match result {
259
263
Ok ( Ok ( new_counter) ) => {
260
264
counter = new_counter;
@@ -300,14 +304,20 @@ fn finalize_transition<N: Network, P: FinalizeStorage<N>>(
300
304
nonce += 1 ;
301
305
302
306
// Set up the finalize state for the await.
303
- let callee_state =
304
- match try_vm_runtime ! ( || setup_await( state, await_, stack, & registers, transition_id, nonce) ) {
305
- Ok ( Ok ( callee_state) ) => callee_state,
306
- // If the evaluation fails, bail and return the error.
307
- Ok ( Err ( error) ) => bail ! ( "'finalize' failed to evaluate command ({command}): {error}" ) ,
308
- // If the evaluation fails, bail and return the error.
309
- Err ( _) => bail ! ( "'finalize' failed to evaluate command ({command})" ) ,
310
- } ;
307
+ let callee_state = match try_vm_runtime ! ( || setup_await(
308
+ state,
309
+ await_,
310
+ & stack,
311
+ & registers,
312
+ transition_id,
313
+ nonce
314
+ ) ) {
315
+ Ok ( Ok ( callee_state) ) => callee_state,
316
+ // If the evaluation fails, bail and return the error.
317
+ Ok ( Err ( error) ) => bail ! ( "'finalize' failed to evaluate command ({command}): {error}" ) ,
318
+ // If the evaluation fails, bail and return the error.
319
+ Err ( _) => bail ! ( "'finalize' failed to evaluate command ({command})" ) ,
320
+ } ;
311
321
312
322
// Increment the call counter.
313
323
call_counter += 1 ;
@@ -317,7 +327,7 @@ fn finalize_transition<N: Network, P: FinalizeStorage<N>>(
317
327
awaited. insert ( await_. register ( ) . clone ( ) ) ;
318
328
319
329
// Aggregate the caller state.
320
- let caller_state = FinalizeState { counter, finalize , registers, stack, call_counter, awaited } ;
330
+ let caller_state = FinalizeState { counter, registers, stack, call_counter, awaited } ;
321
331
322
332
// Push the caller state onto the stack.
323
333
states. push ( caller_state) ;
@@ -327,7 +337,7 @@ fn finalize_transition<N: Network, P: FinalizeStorage<N>>(
327
337
continue ' outer;
328
338
}
329
339
_ => {
330
- let result = try_vm_runtime ! ( || command. finalize( stack, store, & mut registers) ) ;
340
+ let result = try_vm_runtime ! ( || command. finalize( stack. deref ( ) , store, & mut registers) ) ;
331
341
match result {
332
342
// If the evaluation succeeds with an operation, add it to the list.
333
343
Ok ( Ok ( Some ( finalize_operation) ) ) => finalize_operations. push ( finalize_operation) ,
@@ -361,39 +371,34 @@ fn finalize_transition<N: Network, P: FinalizeStorage<N>>(
361
371
}
362
372
363
373
// A helper struct to track the execution of a finalize block.
364
- struct FinalizeState < ' a , N : Network > {
374
+ struct FinalizeState < N : Network > {
365
375
// A counter for the index of the commands.
366
376
counter : usize ,
367
- // The finalize logic.
368
- finalize : & ' a Finalize < N > ,
369
377
// The registers.
370
378
registers : FinalizeRegisters < N > ,
371
379
// The stack.
372
- stack : & ' a Stack < N > ,
380
+ stack : Arc < Stack < N > > ,
373
381
// Call counter.
374
382
call_counter : usize ,
375
383
// Awaited futures.
376
384
awaited : HashSet < Register < N > > ,
377
385
}
378
386
379
387
// A helper function to initialize the finalize state.
380
- fn initialize_finalize_state < ' a , N : Network > (
388
+ fn initialize_finalize_state < N : Network > (
381
389
state : FinalizeGlobalState ,
382
390
future : & Future < N > ,
383
- stack : & ' a Stack < N > ,
391
+ stack : & Arc < Stack < N > > ,
384
392
transition_id : N :: TransitionID ,
385
393
nonce : u64 ,
386
- ) -> Result < FinalizeState < ' a , N > > {
387
- // Get the finalize logic and the stack.
388
- let ( finalize, stack) = match stack. program_id ( ) == future. program_id ( ) {
389
- true => ( stack. get_function_ref ( future. function_name ( ) ) ?. finalize_logic ( ) , stack) ,
390
- false => {
391
- let stack = stack. get_external_stack ( future. program_id ( ) ) ?. as_ref ( ) ;
392
- ( stack. get_function_ref ( future. function_name ( ) ) ?. finalize_logic ( ) , stack)
393
- }
394
+ ) -> Result < FinalizeState < N > > {
395
+ // Get the stack.
396
+ let stack = match stack. program_id ( ) == future. program_id ( ) {
397
+ true => stack. clone ( ) ,
398
+ false => stack. get_external_stack ( future. program_id ( ) ) ?,
394
399
} ;
395
- // Check that the finalize logic exists.
396
- let finalize = match finalize {
400
+ // Get the finalize logic and check that it exists.
401
+ let finalize = match stack . get_function_ref ( future . function_name ( ) ) ? . finalize_logic ( ) {
397
402
Some ( finalize) => finalize,
398
403
None => bail ! (
399
404
"The function '{}/{}' does not have an associated finalize block" ,
@@ -414,25 +419,25 @@ fn initialize_finalize_state<'a, N: Network>(
414
419
finalize. inputs ( ) . iter ( ) . map ( |i| i. register ( ) ) . zip_eq ( future. arguments ( ) . iter ( ) ) . try_for_each (
415
420
|( register, input) | {
416
421
// Assign the input value to the register.
417
- registers. store ( stack, register, Value :: from ( input) )
422
+ registers. store ( stack. deref ( ) , register, Value :: from ( input) )
418
423
} ,
419
424
) ?;
420
425
421
- Ok ( FinalizeState { counter : 0 , finalize , registers, stack, call_counter : 0 , awaited : Default :: default ( ) } )
426
+ Ok ( FinalizeState { counter : 0 , registers, stack, call_counter : 0 , awaited : Default :: default ( ) } )
422
427
}
423
428
424
429
// A helper function that sets up the await operation.
425
430
#[ inline]
426
- fn setup_await < ' a , N : Network > (
431
+ fn setup_await < N : Network > (
427
432
state : FinalizeGlobalState ,
428
433
await_ : & Await < N > ,
429
- stack : & ' a Stack < N > ,
434
+ stack : & Arc < Stack < N > > ,
430
435
registers : & FinalizeRegisters < N > ,
431
436
transition_id : N :: TransitionID ,
432
437
nonce : u64 ,
433
- ) -> Result < FinalizeState < ' a , N > > {
438
+ ) -> Result < FinalizeState < N > > {
434
439
// Retrieve the input as a future.
435
- let future = match registers. load ( stack, & Operand :: Register ( await_. register ( ) . clone ( ) ) ) ? {
440
+ let future = match registers. load ( stack. deref ( ) , & Operand :: Register ( await_. register ( ) . clone ( ) ) ) ? {
436
441
Value :: Future ( future) => future,
437
442
_ => bail ! ( "The input to 'await' is not a future" ) ,
438
443
} ;
@@ -445,16 +450,16 @@ fn setup_await<'a, N: Network>(
445
450
fn branch_to < N : Network , const VARIANT : u8 > (
446
451
counter : usize ,
447
452
branch : & Branch < N , VARIANT > ,
448
- finalize : & Finalize < N > ,
453
+ positions : & HashMap < Identifier < N > , usize > ,
449
454
stack : & Stack < N > ,
450
- registers : & FinalizeRegisters < N > ,
455
+ registers : & impl RegistersLoad < N > ,
451
456
) -> Result < usize > {
452
457
// Retrieve the inputs.
453
458
let first = registers. load ( stack, branch. first ( ) ) ?;
454
459
let second = registers. load ( stack, branch. second ( ) ) ?;
455
460
456
461
// A helper to get the index corresponding to a position.
457
- let get_position_index = |position : & Identifier < N > | match finalize . positions ( ) . get ( position) {
462
+ let get_position_index = |position : & Identifier < N > | match positions. get ( position) {
458
463
Some ( index) if * index > counter => Ok ( * index) ,
459
464
Some ( _) => bail ! ( "Cannot branch to an earlier position '{position}' in the program" ) ,
460
465
None => bail ! ( "The position '{position}' does not exist." ) ,
0 commit comments