@@ -49,6 +49,10 @@ func CalcDifficulty(block, parent *types.Header) *big.Int {
49
49
}
50
50
51
51
func CalculateTD (block , parent * types.Block ) * big.Int {
52
+ if parent == nil {
53
+ return block .Difficulty ()
54
+ }
55
+
52
56
td := new (big.Int ).Add (parent .Td , block .Header ().Difficulty )
53
57
54
58
return td
@@ -89,6 +93,7 @@ type ChainManager struct {
89
93
futureBlocks * BlockCache
90
94
91
95
quit chan struct {}
96
+ wg sync.WaitGroup
92
97
}
93
98
94
99
func NewChainManager (blockDb , stateDb common.Database , mux * event.TypeMux ) * ChainManager {
@@ -478,6 +483,10 @@ func (self *ChainManager) CalcTotalDiff(block *types.Block) (*big.Int, error) {
478
483
479
484
func (bc * ChainManager ) Stop () {
480
485
close (bc .quit )
486
+
487
+ bc .wg .Wait ()
488
+
489
+ glog .V (logger .Info ).Infoln ("Chain manager stopped" )
481
490
}
482
491
483
492
type queueEvent struct {
@@ -500,22 +509,30 @@ func (self *ChainManager) procFutureBlocks() {
500
509
// InsertChain will attempt to insert the given chain in to the canonical chain or, otherwise, create a fork. It an error is returned
501
510
// it will return the index number of the failing block as well an error describing what went wrong (for possible errors see core/errors.go).
502
511
func (self * ChainManager ) InsertChain (chain types.Blocks ) (int , error ) {
512
+ self .wg .Add (1 )
513
+ defer self .wg .Done ()
514
+
503
515
// A queued approach to delivering events. This is generally faster than direct delivery and requires much less mutex acquiring.
504
516
var (
505
517
queue = make ([]interface {}, len (chain ))
506
518
queueEvent = queueEvent {queue : queue }
507
- stats struct { queued , processed int }
519
+ stats struct { queued , processed , ignored int }
508
520
tstart = time .Now ()
509
521
)
510
522
for i , block := range chain {
511
523
if block == nil {
512
524
continue
513
525
}
526
+ // Setting block.Td regardless of error (known for example) prevents errors down the line
527
+ // in the protocol handler
528
+ block .Td = new (big.Int ).Set (CalculateTD (block , self .GetBlock (block .ParentHash ())))
529
+
514
530
// Call in to the block processor and check for errors. It's likely that if one block fails
515
531
// all others will fail too (unless a known block is returned).
516
532
logs , err := self .processor .Process (block )
517
533
if err != nil {
518
534
if IsKnownBlockErr (err ) {
535
+ stats .ignored ++
519
536
continue
520
537
}
521
538
@@ -545,8 +562,6 @@ func (self *ChainManager) InsertChain(chain types.Blocks) (int, error) {
545
562
return i , err
546
563
}
547
564
548
- block .Td = new (big.Int ).Set (CalculateTD (block , self .GetBlock (block .ParentHash ())))
549
-
550
565
self .mu .Lock ()
551
566
{
552
567
cblock := self .currentBlock
@@ -589,7 +604,7 @@ func (self *ChainManager) InsertChain(chain types.Blocks) (int, error) {
589
604
queueEvent .canonicalCount ++
590
605
591
606
if glog .V (logger .Debug ) {
592
- glog .Infof ("inserted block #%d (%d TXs %d UNCs) (%x...)\n " , block .Number (), len (block .Transactions ()), len (block .Uncles ()), block .Hash ().Bytes ()[0 :4 ])
607
+ glog .Infof ("[%v] inserted block #%d (%d TXs %d UNCs) (%x...)\n " , time . Now (). UnixNano () , block .Number (), len (block .Transactions ()), len (block .Uncles ()), block .Hash ().Bytes ()[0 :4 ])
593
608
}
594
609
} else {
595
610
if glog .V (logger .Detail ) {
@@ -607,10 +622,10 @@ func (self *ChainManager) InsertChain(chain types.Blocks) (int, error) {
607
622
608
623
}
609
624
610
- if (stats .queued > 0 || stats .processed > 0 ) && bool (glog .V (logger .Info )) {
625
+ if (stats .queued > 0 || stats .processed > 0 || stats . ignored > 0 ) && bool (glog .V (logger .Info )) {
611
626
tend := time .Since (tstart )
612
627
start , end := chain [0 ], chain [len (chain )- 1 ]
613
- glog .Infof ("imported %d block(s) %d queued in %v. #%v [%x / %x]\n " , stats .processed , stats .queued , tend , end .Number (), start .Hash ().Bytes ()[:4 ], end .Hash ().Bytes ()[:4 ])
628
+ glog .Infof ("imported %d block(s) ( %d queued %d ignored) in %v. #%v [%x / %x]\n " , stats .processed , stats .queued , stats . ignored , tend , end .Number (), start .Hash ().Bytes ()[:4 ], end .Hash ().Bytes ()[:4 ])
614
629
}
615
630
616
631
go self .eventMux .Post (queueEvent )
@@ -654,7 +669,7 @@ func (self *ChainManager) merge(oldBlock, newBlock *types.Block) {
654
669
655
670
func (self * ChainManager ) update () {
656
671
events := self .eventMux .Subscribe (queueEvent {})
657
- futureTimer := time .NewTicker (5 * time .Second )
672
+ futureTimer := time .Tick (5 * time .Second )
658
673
out:
659
674
for {
660
675
select {
681
696
self .eventMux .Post (event )
682
697
}
683
698
}
684
- case <- futureTimer . C :
699
+ case <- futureTimer :
685
700
self .procFutureBlocks ()
686
701
case <- self .quit :
687
702
break out
0 commit comments