Skip to content

Commit ac85fdc

Browse files
committed
Merge pull request #835 from obscuren/handler_errors
eth, eth/downloader: error handlers and td checks
2 parents 3fef601 + 37770ed commit ac85fdc

File tree

9 files changed

+547
-318
lines changed

9 files changed

+547
-318
lines changed

cmd/geth/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ import _ "net/http/pprof"
4747

4848
const (
4949
ClientIdentifier = "Geth"
50-
Version = "0.9.14"
50+
Version = "0.9.15"
5151
)
5252

5353
var (

core/chain_manager.go

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ func CalcDifficulty(block, parent *types.Header) *big.Int {
4949
}
5050

5151
func CalculateTD(block, parent *types.Block) *big.Int {
52+
if parent == nil {
53+
return block.Difficulty()
54+
}
55+
5256
td := new(big.Int).Add(parent.Td, block.Header().Difficulty)
5357

5458
return td
@@ -89,6 +93,7 @@ type ChainManager struct {
8993
futureBlocks *BlockCache
9094

9195
quit chan struct{}
96+
wg sync.WaitGroup
9297
}
9398

9499
func NewChainManager(blockDb, stateDb common.Database, mux *event.TypeMux) *ChainManager {
@@ -478,6 +483,10 @@ func (self *ChainManager) CalcTotalDiff(block *types.Block) (*big.Int, error) {
478483

479484
func (bc *ChainManager) Stop() {
480485
close(bc.quit)
486+
487+
bc.wg.Wait()
488+
489+
glog.V(logger.Info).Infoln("Chain manager stopped")
481490
}
482491

483492
type queueEvent struct {
@@ -500,22 +509,30 @@ func (self *ChainManager) procFutureBlocks() {
500509
// InsertChain will attempt to insert the given chain in to the canonical chain or, otherwise, create a fork. It an error is returned
501510
// 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).
502511
func (self *ChainManager) InsertChain(chain types.Blocks) (int, error) {
512+
self.wg.Add(1)
513+
defer self.wg.Done()
514+
503515
// A queued approach to delivering events. This is generally faster than direct delivery and requires much less mutex acquiring.
504516
var (
505517
queue = make([]interface{}, len(chain))
506518
queueEvent = queueEvent{queue: queue}
507-
stats struct{ queued, processed int }
519+
stats struct{ queued, processed, ignored int }
508520
tstart = time.Now()
509521
)
510522
for i, block := range chain {
511523
if block == nil {
512524
continue
513525
}
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+
514530
// Call in to the block processor and check for errors. It's likely that if one block fails
515531
// all others will fail too (unless a known block is returned).
516532
logs, err := self.processor.Process(block)
517533
if err != nil {
518534
if IsKnownBlockErr(err) {
535+
stats.ignored++
519536
continue
520537
}
521538

@@ -545,8 +562,6 @@ func (self *ChainManager) InsertChain(chain types.Blocks) (int, error) {
545562
return i, err
546563
}
547564

548-
block.Td = new(big.Int).Set(CalculateTD(block, self.GetBlock(block.ParentHash())))
549-
550565
self.mu.Lock()
551566
{
552567
cblock := self.currentBlock
@@ -589,7 +604,7 @@ func (self *ChainManager) InsertChain(chain types.Blocks) (int, error) {
589604
queueEvent.canonicalCount++
590605

591606
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])
593608
}
594609
} else {
595610
if glog.V(logger.Detail) {
@@ -607,10 +622,10 @@ func (self *ChainManager) InsertChain(chain types.Blocks) (int, error) {
607622

608623
}
609624

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)) {
611626
tend := time.Since(tstart)
612627
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])
614629
}
615630

616631
go self.eventMux.Post(queueEvent)
@@ -654,7 +669,7 @@ func (self *ChainManager) merge(oldBlock, newBlock *types.Block) {
654669

655670
func (self *ChainManager) update() {
656671
events := self.eventMux.Subscribe(queueEvent{})
657-
futureTimer := time.NewTicker(5 * time.Second)
672+
futureTimer := time.Tick(5 * time.Second)
658673
out:
659674
for {
660675
select {
@@ -681,7 +696,7 @@ out:
681696
self.eventMux.Post(event)
682697
}
683698
}
684-
case <-futureTimer.C:
699+
case <-futureTimer:
685700
self.procFutureBlocks()
686701
case <-self.quit:
687702
break out

eth/backend.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ func New(config *Config) (*Ethereum, error) {
219219
}
220220

221221
eth.chainManager = core.NewChainManager(blockDb, stateDb, eth.EventMux())
222-
eth.downloader = downloader.New(eth.chainManager.HasBlock, eth.chainManager.InsertChain)
222+
eth.downloader = downloader.New(eth.chainManager.HasBlock, eth.chainManager.GetBlock)
223223
eth.pow = ethash.New(eth.chainManager)
224224
eth.txPool = core.NewTxPool(eth.EventMux(), eth.chainManager.State, eth.chainManager.GasLimit)
225225
eth.blockProcessor = core.NewBlockProcessor(stateDb, extraDb, eth.pow, eth.txPool, eth.chainManager, eth.EventMux())
@@ -455,6 +455,7 @@ func (s *Ethereum) Stop() {
455455
s.txSub.Unsubscribe() // quits txBroadcastLoop
456456

457457
s.protocolManager.Stop()
458+
s.chainManager.Stop()
458459
s.txPool.Stop()
459460
s.eventMux.Stop()
460461
if s.whisper != nil {

0 commit comments

Comments
 (0)