@@ -74,6 +74,8 @@ pub struct VM<N: Network, C: ConsensusStorage<N>> {
74
74
store : ConsensusStore < N , C > ,
75
75
/// The lock to guarantee atomicity over calls to speculate and finalize.
76
76
atomic_lock : Arc < Mutex < ( ) > > ,
77
+ /// The lock for ensuring there is no concurrency when advancing blocks.
78
+ block_lock : Arc < Mutex < ( ) > > ,
77
79
}
78
80
79
81
impl < N : Network , C : ConsensusStorage < N > > VM < N , C > {
@@ -171,7 +173,12 @@ impl<N: Network, C: ConsensusStorage<N>> VM<N, C> {
171
173
}
172
174
173
175
// Return the new VM.
174
- Ok ( Self { process : Arc :: new ( RwLock :: new ( process) ) , store, atomic_lock : Arc :: new ( Mutex :: new ( ( ) ) ) } )
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
+ } )
175
182
}
176
183
177
184
/// Returns `true` if a program with the given program ID exists.
@@ -312,6 +319,10 @@ impl<N: Network, C: ConsensusStorage<N>> VM<N, C> {
312
319
/// Adds the given block into the VM.
313
320
#[ inline]
314
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
+
315
326
// Construct the finalize state.
316
327
let state = FinalizeGlobalState :: new :: < N > (
317
328
block. round ( ) ,
0 commit comments