@@ -184,37 +184,39 @@ impl OrderedBlockWindow {
184
184
/// A representation of a block that has been added to the execution pipeline. It might either be in ordered
185
185
/// or in executed state. In the ordered state, the block is waiting to be executed. In the executed state,
186
186
/// the block has been executed and the output is available.
187
- # [ derive ( Derivative , Clone ) ]
188
- #[ derivative ( Eq , PartialEq ) ]
187
+ /// This struct is not Cloneable, use Arc to share it.
188
+ #[ derive ( Derivative ) ]
189
189
pub struct PipelinedBlock {
190
190
/// Block data that cannot be regenerated.
191
191
block : Block ,
192
192
/// A window of blocks that are needed for execution with the execution pool, EXCLUDING the current block
193
- #[ derivative( PartialEq = "ignore" ) ]
194
193
block_window : OrderedBlockWindow ,
195
- /// Input transactions in the order of execution
194
+ /// Input transactions in the order of execution. DEPRECATED stay for serialization compatibility.
196
195
input_transactions : Vec < SignedTransaction > ,
197
196
/// The state_compute_result is calculated for all the pending blocks prior to insertion to
198
197
/// the tree. The execution results are not persisted: they're recalculated again for the
199
198
/// pending blocks upon restart.
200
- #[ derivative( PartialEq = "ignore" ) ]
201
- state_compute_result : StateComputeResult ,
199
+ state_compute_result : Mutex < StateComputeResult > ,
202
200
randomness : OnceCell < Randomness > ,
203
201
pipeline_insertion_time : OnceCell < Instant > ,
204
- execution_summary : Arc < OnceCell < ExecutionSummary > > ,
205
- #[ derivative( PartialEq = "ignore" ) ]
206
- pre_commit_fut : Arc < Mutex < Option < BoxFuture < ' static , ExecutorResult < ( ) > > > > > ,
207
- // pipeline related fields
208
- #[ derivative( PartialEq = "ignore" ) ]
209
- pipeline_futs : Arc < Mutex < Option < PipelineFutures > > > ,
210
- #[ derivative( PartialEq = "ignore" ) ]
211
- pipeline_tx : Arc < Mutex < Option < PipelineInputTx > > > ,
212
- #[ derivative( PartialEq = "ignore" ) ]
213
- pipeline_abort_handle : Arc < Mutex < Option < Vec < AbortHandle > > > > ,
214
- #[ derivative( PartialEq = "ignore" ) ]
215
- block_qc : Arc < Mutex < Option < Arc < QuorumCert > > > > ,
202
+ execution_summary : OnceCell < ExecutionSummary > ,
203
+ pre_commit_fut : Mutex < Option < BoxFuture < ' static , ExecutorResult < ( ) > > > > ,
204
+ /// pipeline related fields
205
+ pipeline_futs : Mutex < Option < PipelineFutures > > ,
206
+ pipeline_tx : Mutex < Option < PipelineInputTx > > ,
207
+ pipeline_abort_handle : Mutex < Option < Vec < AbortHandle > > > ,
208
+ block_qc : Mutex < Option < Arc < QuorumCert > > > ,
216
209
}
217
210
211
+ impl PartialEq for PipelinedBlock {
212
+ fn eq ( & self , other : & Self ) -> bool {
213
+ self . block == other. block
214
+ && self . input_transactions == other. input_transactions
215
+ && self . randomness . get ( ) == other. randomness . get ( )
216
+ }
217
+ }
218
+ impl Eq for PipelinedBlock { }
219
+
218
220
impl Serialize for PipelinedBlock {
219
221
fn serialize < S > ( & self , serializer : S ) -> Result < S :: Ok , S :: Error >
220
222
where
@@ -265,15 +267,13 @@ impl<'de> Deserialize<'de> for PipelinedBlock {
265
267
266
268
impl PipelinedBlock {
267
269
pub fn set_compute_result (
268
- & mut self ,
269
- compute_result : StateComputeResult ,
270
+ & self ,
271
+ state_compute_result : StateComputeResult ,
270
272
execution_time : Duration ,
271
273
) {
272
- self . state_compute_result = compute_result;
273
-
274
274
let mut to_commit = 0 ;
275
275
let mut to_retry = 0 ;
276
- for txn in self . state_compute_result . compute_status_for_input_txns ( ) {
276
+ for txn in state_compute_result. compute_status_for_input_txns ( ) {
277
277
match txn {
278
278
TransactionStatus :: Keep ( _) => to_commit += 1 ,
279
279
TransactionStatus :: Retry => to_retry += 1 ,
@@ -289,14 +289,14 @@ impl PipelinedBlock {
289
289
to_commit,
290
290
to_retry,
291
291
execution_time,
292
- root_hash : self . state_compute_result . root_hash ( ) ,
293
- gas_used : self
294
- . state_compute_result
292
+ root_hash : state_compute_result. root_hash ( ) ,
293
+ gas_used : state_compute_result
295
294
. execution_output
296
295
. block_end_info
297
296
. as_ref ( )
298
297
. map ( |info| info. block_effective_gas_units ( ) ) ,
299
298
} ;
299
+ * self . state_compute_result . lock ( ) = state_compute_result;
300
300
301
301
// We might be retrying execution, so it might have already been set.
302
302
// Because we use this for statistics, it's ok that we drop the newer value.
@@ -321,23 +321,17 @@ impl PipelinedBlock {
321
321
}
322
322
}
323
323
324
- pub fn set_execution_result (
325
- mut self ,
326
- pipeline_execution_result : PipelineExecutionResult ,
327
- ) -> Self {
324
+ pub fn set_execution_result ( & self , pipeline_execution_result : PipelineExecutionResult ) {
328
325
let PipelineExecutionResult {
329
- input_txns,
326
+ input_txns : _ ,
330
327
result,
331
328
execution_time,
332
329
pre_commit_fut,
333
330
} = pipeline_execution_result;
334
331
335
- self . input_transactions = input_txns;
336
- self . pre_commit_fut = Arc :: new ( Mutex :: new ( Some ( pre_commit_fut) ) ) ;
332
+ * self . pre_commit_fut . lock ( ) = Some ( pre_commit_fut) ;
337
333
338
334
self . set_compute_result ( result, execution_time) ;
339
-
340
- self
341
335
}
342
336
343
337
#[ cfg( any( test, feature = "fuzzing" ) ) ]
@@ -380,6 +374,13 @@ impl Display for PipelinedBlock {
380
374
}
381
375
}
382
376
377
+ /// Safeguard to ensure that the pipeline is aborted when the block is dropped.
378
+ impl Drop for PipelinedBlock {
379
+ fn drop ( & mut self ) {
380
+ let _ = self . abort_pipeline ( ) ;
381
+ }
382
+ }
383
+
383
384
impl PipelinedBlock {
384
385
pub fn new (
385
386
block : Block ,
@@ -390,25 +391,28 @@ impl PipelinedBlock {
390
391
block,
391
392
block_window : OrderedBlockWindow :: empty ( ) ,
392
393
input_transactions,
393
- state_compute_result,
394
+ state_compute_result : Mutex :: new ( state_compute_result ) ,
394
395
randomness : OnceCell :: new ( ) ,
395
396
pipeline_insertion_time : OnceCell :: new ( ) ,
396
- execution_summary : Arc :: new ( OnceCell :: new ( ) ) ,
397
- pre_commit_fut : Arc :: new ( Mutex :: new ( None ) ) ,
398
- pipeline_futs : Arc :: new ( Mutex :: new ( None ) ) ,
399
- pipeline_tx : Arc :: new ( Mutex :: new ( None ) ) ,
400
- pipeline_abort_handle : Arc :: new ( Mutex :: new ( None ) ) ,
401
- block_qc : Arc :: new ( Mutex :: new ( None ) ) ,
397
+ execution_summary : OnceCell :: new ( ) ,
398
+ pre_commit_fut : Mutex :: new ( None ) ,
399
+ pipeline_futs : Mutex :: new ( None ) ,
400
+ pipeline_tx : Mutex :: new ( None ) ,
401
+ pipeline_abort_handle : Mutex :: new ( None ) ,
402
+ block_qc : Mutex :: new ( None ) ,
402
403
}
403
404
}
404
405
406
+ pub fn with_block_window ( self , window : OrderedBlockWindow ) -> Self {
407
+ let mut block = self ;
408
+ block. block_window = window;
409
+ block
410
+ }
411
+
405
412
pub fn new_ordered ( block : Block , window : OrderedBlockWindow ) -> Self {
406
413
let input_transactions = Vec :: new ( ) ;
407
414
let state_compute_result = StateComputeResult :: new_dummy ( ) ;
408
- Self {
409
- block_window : window,
410
- ..Self :: new ( block, input_transactions, state_compute_result)
411
- }
415
+ Self :: new ( block, input_transactions, state_compute_result) . with_block_window ( window)
412
416
}
413
417
414
418
pub fn block ( & self ) -> & Block {
@@ -423,10 +427,6 @@ impl PipelinedBlock {
423
427
self . block ( ) . id ( )
424
428
}
425
429
426
- pub fn input_transactions ( & self ) -> & Vec < SignedTransaction > {
427
- & self . input_transactions
428
- }
429
-
430
430
pub fn epoch ( & self ) -> u64 {
431
431
self . block . epoch ( )
432
432
}
@@ -455,8 +455,8 @@ impl PipelinedBlock {
455
455
self . block ( ) . timestamp_usecs ( )
456
456
}
457
457
458
- pub fn compute_result ( & self ) -> & StateComputeResult {
459
- & self . state_compute_result
458
+ pub fn compute_result ( & self ) -> StateComputeResult {
459
+ self . state_compute_result . lock ( ) . clone ( )
460
460
}
461
461
462
462
pub fn randomness ( & self ) -> Option < & Randomness > {
@@ -468,18 +468,20 @@ impl PipelinedBlock {
468
468
}
469
469
470
470
pub fn block_info ( & self ) -> BlockInfo {
471
+ let compute_result = self . compute_result ( ) ;
471
472
self . block ( ) . gen_block_info (
472
- self . compute_result ( ) . root_hash ( ) ,
473
- self . compute_result ( ) . last_version_or_0 ( ) ,
474
- self . compute_result ( ) . epoch_state ( ) . clone ( ) ,
473
+ compute_result. root_hash ( ) ,
474
+ compute_result. last_version_or_0 ( ) ,
475
+ compute_result. epoch_state ( ) . clone ( ) ,
475
476
)
476
477
}
477
478
478
479
pub fn vote_proposal ( & self ) -> VoteProposal {
480
+ let compute_result = self . compute_result ( ) ;
479
481
VoteProposal :: new (
480
- self . compute_result ( ) . extension_proof ( ) ,
482
+ compute_result. extension_proof ( ) ,
481
483
self . block . clone ( ) ,
482
- self . compute_result ( ) . epoch_state ( ) . clone ( ) ,
484
+ compute_result. epoch_state ( ) . clone ( ) ,
483
485
true ,
484
486
)
485
487
}
@@ -493,15 +495,15 @@ impl PipelinedBlock {
493
495
if self . is_reconfiguration_suffix ( ) {
494
496
return vec ! [ ] ;
495
497
}
496
- self . state_compute_result . subscribable_events ( ) . to_vec ( )
498
+ self . compute_result ( ) . subscribable_events ( ) . to_vec ( )
497
499
}
498
500
499
501
/// The block is suffix of a reconfiguration block if the state result carries over the epoch state
500
502
/// from parent but has no transaction.
501
503
pub fn is_reconfiguration_suffix ( & self ) -> bool {
502
- self . state_compute_result . has_reconfiguration ( )
503
- && self
504
- . state_compute_result
504
+ let state_compute_result = self . compute_result ( ) ;
505
+ state_compute_result . has_reconfiguration ( )
506
+ && state_compute_result
505
507
. compute_status_for_input_txns ( )
506
508
. is_empty ( )
507
509
}
@@ -543,8 +545,8 @@ impl PipelinedBlock {
543
545
* self . pipeline_abort_handle . lock ( ) = Some ( abort_handles) ;
544
546
}
545
547
546
- pub fn pipeline_tx ( & self ) -> Arc < Mutex < Option < PipelineInputTx > > > {
547
- self . pipeline_tx . clone ( )
548
+ pub fn pipeline_tx ( & self ) -> & Mutex < Option < PipelineInputTx > > {
549
+ & self . pipeline_tx
548
550
}
549
551
550
552
pub fn abort_pipeline ( & self ) -> Option < PipelineFutures > {
0 commit comments