@@ -17,6 +17,7 @@ use std::net::SocketAddr;
17
17
use std:: ops:: Deref ;
18
18
use std:: sync:: { Arc , RwLock , Weak } ;
19
19
use std:: sync:: atomic:: { AtomicBool , Ordering } ;
20
+ use std:: time:: Instant ;
20
21
use rand;
21
22
use rand:: Rng ;
22
23
@@ -30,6 +31,7 @@ use p2p;
30
31
use pool;
31
32
use util:: OneTime ;
32
33
use store;
34
+ use types:: { ChainValidationMode , ServerConfig } ;
33
35
use util:: LOGGER ;
34
36
35
37
// All adapters use `Weak` references instead of `Arc` to avoid cycles that
@@ -51,6 +53,7 @@ pub struct NetToChainAdapter {
51
53
chain : Weak < chain:: Chain > ,
52
54
tx_pool : Arc < RwLock < pool:: TransactionPool < PoolToChainAdapter > > > ,
53
55
peers : OneTime < Weak < p2p:: Peers > > ,
56
+ config : ServerConfig ,
54
57
}
55
58
56
59
impl p2p:: ChainAdapter for NetToChainAdapter {
@@ -334,12 +337,14 @@ impl NetToChainAdapter {
334
337
currently_syncing : Arc < AtomicBool > ,
335
338
chain_ref : Weak < chain:: Chain > ,
336
339
tx_pool : Arc < RwLock < pool:: TransactionPool < PoolToChainAdapter > > > ,
340
+ config : ServerConfig ,
337
341
) -> NetToChainAdapter {
338
342
NetToChainAdapter {
339
343
currently_syncing : currently_syncing,
340
344
chain : chain_ref,
341
345
tx_pool : tx_pool,
342
346
peers : OneTime :: new ( ) ,
347
+ config : config,
343
348
}
344
349
}
345
350
@@ -388,7 +393,7 @@ impl NetToChainAdapter {
388
393
let prev_hash = b. header . previous ;
389
394
let bhash = b. hash ( ) ;
390
395
let chain = w ( & self . chain ) ;
391
- match chain. process_block ( b, self . chain_opts ( ) ) {
396
+ let result = match chain. process_block ( b, self . chain_opts ( ) ) {
392
397
Ok ( _) => true ,
393
398
Err ( chain:: Error :: Orphan ) => {
394
399
// make sure we did not miss the parent block
@@ -415,7 +420,36 @@ impl NetToChainAdapter {
415
420
) ;
416
421
true
417
422
}
423
+ } ;
424
+
425
+ // If we are running in "validate the full chain every block" then
426
+ // panic here if validation fails for any reason.
427
+ // We are out of consensus at this point and want to track the problem
428
+ // down as soon as possible.
429
+ // Skip this if we are currently syncing (too slow).
430
+ if !self . currently_syncing . load ( Ordering :: Relaxed )
431
+ && self . config . chain_validation_mode == ChainValidationMode :: EveryBlock
432
+ {
433
+ let now = Instant :: now ( ) ;
434
+
435
+ debug ! (
436
+ LOGGER ,
437
+ "adapter: process_block: ***** validating full chain state at {}" , bhash,
438
+ ) ;
439
+
440
+ let chain = w ( & self . chain ) ;
441
+ chain
442
+ . validate ( true )
443
+ . expect ( "chain validation failed, hard stop" ) ;
444
+
445
+ debug ! (
446
+ LOGGER ,
447
+ "adapter: process_block: ***** done validating full chain state, took {}s" ,
448
+ now. elapsed( ) . as_secs( ) ,
449
+ ) ;
418
450
}
451
+
452
+ result
419
453
}
420
454
421
455
// After receiving a compact block if we cannot successfully hydrate
0 commit comments