@@ -60,7 +60,7 @@ use synthesizer_program::{FinalizeGlobalState, FinalizeOperation, FinalizeStoreT
60
60
61
61
use aleo_std:: prelude:: { finish, lap, timer} ;
62
62
use indexmap:: { IndexMap , IndexSet } ;
63
- use parking_lot:: RwLock ;
63
+ use parking_lot:: { Mutex , RwLock } ;
64
64
use std:: sync:: Arc ;
65
65
66
66
#[ cfg( not( feature = "serial" ) ) ]
@@ -72,6 +72,10 @@ pub struct VM<N: Network, C: ConsensusStorage<N>> {
72
72
process : Arc < RwLock < Process < N > > > ,
73
73
/// The VM store.
74
74
store : ConsensusStore < N , C > ,
75
+ /// The lock to guarantee atomicity over calls to speculate and finalize.
76
+ atomic_lock : Arc < Mutex < ( ) > > ,
77
+ /// The lock for ensuring there is no concurrency when advancing blocks.
78
+ block_lock : Arc < Mutex < ( ) > > ,
75
79
}
76
80
77
81
impl < N : Network , C : ConsensusStorage < N > > VM < N , C > {
@@ -169,7 +173,12 @@ impl<N: Network, C: ConsensusStorage<N>> VM<N, C> {
169
173
}
170
174
171
175
// Return the new VM.
172
- Ok ( Self { process : Arc :: new ( RwLock :: new ( process) ) , store } )
176
+ Ok ( Self {
177
+ process : Arc :: new ( RwLock :: new ( process) ) ,
178
+ store,
179
+ atomic_lock : Arc :: new ( Mutex :: new ( ( ) ) ) ,
180
+ block_lock : Arc :: new ( Mutex :: new ( ( ) ) ) ,
181
+ } )
173
182
}
174
183
175
184
/// Returns `true` if a program with the given program ID exists.
@@ -310,6 +319,10 @@ impl<N: Network, C: ConsensusStorage<N>> VM<N, C> {
310
319
/// Adds the given block into the VM.
311
320
#[ inline]
312
321
pub fn add_next_block ( & self , block : & Block < N > ) -> Result < ( ) > {
322
+ // Acquire the block lock, which is needed to ensure this function is not called concurrently.
323
+ // Note: This lock must be held for the entire scope of this function.
324
+ let _block_lock = self . block_lock . lock ( ) ;
325
+
313
326
// Construct the finalize state.
314
327
let state = FinalizeGlobalState :: new :: < N > (
315
328
block. round ( ) ,
0 commit comments