Merge pull request #561 from ethersphere/frontier/blockpool
bugfix with idle too long triggered after peer switch
This commit is contained in:
commit
7f0c2545a9
|
@ -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) {
|
||||||
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:
|
||||||
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) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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() {
|
||||||
|
|
||||||
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:
|
||||||
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 (
|
||||||
// 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) {
|
||||||
}
|
}
|
||||||
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 {
|
||||||
|
|
Loading…
Reference in New Issue