Commit 7f0c2545 authored by Felix Lange's avatar Felix Lange

Merge pull request #561 from ethersphere/frontier/blockpool

bugfix with idle too long triggered after peer switch
parents 221f30c3 18d1569c
...@@ -238,12 +238,17 @@ func (self *BlockPool) Start() { ...@@ -238,12 +238,17 @@ func (self *BlockPool) Start() {
case event := <-self.tdSub.Chan(): case event := <-self.tdSub.Chan():
if ev, ok := event.(core.ChainHeadEvent); ok { if ev, ok := event.(core.ChainHeadEvent); ok {
td := ev.Block.Td td := ev.Block.Td
plog.DebugDetailf("td: %v", td) var height *big.Int
if (ev.Block.HeaderHash == common.Hash{}) {
height = ev.Block.Header().Number
}
plog.DebugDetailf("ChainHeadEvent: height: %v, td: %v, hash: %s", height, td, hex(ev.Block.Hash()))
self.setTD(td) self.setTD(td)
self.peers.lock.Lock() self.peers.lock.Lock()
if best := self.peers.best; best != nil { if best := self.peers.best; best != nil {
if td.Cmp(best.td) >= 0 { // only switch if we strictly go above otherwise we may stall if only
if td.Cmp(best.td) > 0 {
self.peers.best = nil self.peers.best = nil
self.switchPeer(best, nil) self.switchPeer(best, nil)
} }
...@@ -706,7 +711,7 @@ func (self *BlockPool) AddBlock(block *types.Block, peerId string) { ...@@ -706,7 +711,7 @@ func (self *BlockPool) AddBlock(block *types.Block, peerId string) {
It activates the section process on incomplete sections with peer. It activates the section process on incomplete sections with peer.
It relinks orphaned sections with their parent if root block (and its parent hash) is known. It relinks orphaned sections with their parent if root block (and its parent hash) is known.
*/ */
func (self *BlockPool) activateChain(sec *section, p *peer, connected map[string]*section) { func (self *BlockPool) activateChain(sec *section, p *peer, connected map[common.Hash]*section) {
p.lock.RLock() p.lock.RLock()
switchC := p.switchC switchC := p.switchC
...@@ -720,7 +725,7 @@ LOOP: ...@@ -720,7 +725,7 @@ LOOP:
plog.DebugDetailf("activateChain: section [%s] activated by peer <%s>", sectionhex(sec), p.id) plog.DebugDetailf("activateChain: section [%s] activated by peer <%s>", sectionhex(sec), p.id)
sec.activate(p) sec.activate(p)
if i > 0 && connected != nil { if i > 0 && connected != nil {
connected[sec.top.hash.Str()] = sec connected[sec.top.hash] = sec
} }
/* /*
Need to relink both complete and incomplete sections Need to relink both complete and incomplete sections
......
...@@ -356,16 +356,16 @@ func (self *BlockPool) switchPeer(oldp, newp *peer) { ...@@ -356,16 +356,16 @@ func (self *BlockPool) switchPeer(oldp, newp *peer) {
} }
var connected = make(map[string]*section) var connected = make(map[common.Hash]*section)
var sections []common.Hash var sections []common.Hash
for _, hash := range newp.sections { for _, hash := range newp.sections {
plog.DebugDetailf("activate chain starting from section [%s]", hex(hash)) plog.DebugDetailf("activate chain starting from section [%s]", hex(hash))
// if section not connected (ie, top of a contiguous sequence of sections) // if section not connected (ie, top of a contiguous sequence of sections)
if connected[hash.Str()] == nil { if connected[hash] == nil {
// if not deleted, then reread from pool (it can be orphaned top half of a split section) // if not deleted, then reread from pool (it can be orphaned top half of a split section)
if entry := self.get(hash); entry != nil { if entry := self.get(hash); entry != nil {
self.activateChain(entry.section, newp, connected) self.activateChain(entry.section, newp, connected)
connected[hash.Str()] = entry.section connected[hash] = entry.section
sections = append(sections, hash) sections = append(sections, hash)
} }
} }
...@@ -531,6 +531,7 @@ func (self *peer) run() { ...@@ -531,6 +531,7 @@ func (self *peer) run() {
self.blocksRequestTimer = time.After(0) self.blocksRequestTimer = time.After(0)
self.headInfoTimer = time.After(self.bp.Config.BlockHashesTimeout) self.headInfoTimer = time.After(self.bp.Config.BlockHashesTimeout)
self.bestIdleTimer = nil
var ping = time.NewTicker(5 * time.Second) var ping = time.NewTicker(5 * time.Second)
...@@ -581,7 +582,7 @@ LOOP: ...@@ -581,7 +582,7 @@ LOOP:
case <-self.bp.quit: case <-self.bp.quit:
break LOOP break LOOP
// quit // best
case <-self.bestIdleTimer: case <-self.bestIdleTimer:
self.peerError(self.bp.peers.errors.New(ErrIdleTooLong, "timed out without providing new blocks (td: %v, head: %s)...quitting", self.td, hex(self.currentBlockHash))) self.peerError(self.bp.peers.errors.New(ErrIdleTooLong, "timed out without providing new blocks (td: %v, head: %s)...quitting", self.td, hex(self.currentBlockHash)))
......
...@@ -14,7 +14,7 @@ import ( ...@@ -14,7 +14,7 @@ import (
// the actual tests // the actual tests
func TestAddPeer(t *testing.T) { func TestAddPeer(t *testing.T) {
test.LogInit() test.LogInit()
_, blockPool, blockPoolTester := newTestBlockPool(t) hashPool, blockPool, blockPoolTester := newTestBlockPool(t)
peer0 := blockPoolTester.newPeer("peer0", 1, 1) peer0 := blockPoolTester.newPeer("peer0", 1, 1)
peer1 := blockPoolTester.newPeer("peer1", 2, 2) peer1 := blockPoolTester.newPeer("peer1", 2, 2)
peer2 := blockPoolTester.newPeer("peer2", 3, 3) peer2 := blockPoolTester.newPeer("peer2", 3, 3)
...@@ -119,7 +119,8 @@ func TestAddPeer(t *testing.T) { ...@@ -119,7 +119,8 @@ func TestAddPeer(t *testing.T) {
} }
peer0.waitBlocksRequests(3) peer0.waitBlocksRequests(3)
newblock := &types.Block{Td: common.Big3} hash := hashPool.IndexesToHashes([]int{0})[0]
newblock := &types.Block{Td: common.Big3, HeaderHash: hash}
blockPool.chainEvents.Post(core.ChainHeadEvent{newblock}) blockPool.chainEvents.Post(core.ChainHeadEvent{newblock})
time.Sleep(100 * time.Millisecond) time.Sleep(100 * time.Millisecond)
if blockPool.peers.best != nil { if blockPool.peers.best != nil {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment