diff --git a/blockpool/blockpool.go b/blockpool/blockpool.go index 1ca97e0ca..d9f8e3baa 100644 --- a/blockpool/blockpool.go +++ b/blockpool/blockpool.go @@ -238,12 +238,17 @@ func (self *BlockPool) Start() { case event := <-self.tdSub.Chan(): if ev, ok := event.(core.ChainHeadEvent); ok { 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.peers.lock.Lock() 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.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 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() switchC := p.switchC @@ -720,7 +725,7 @@ LOOP: plog.DebugDetailf("activateChain: section [%s] activated by peer <%s>", sectionhex(sec), p.id) sec.activate(p) if i > 0 && connected != nil { - connected[sec.top.hash.Str()] = sec + connected[sec.top.hash] = sec } /* Need to relink both complete and incomplete sections diff --git a/blockpool/peers.go b/blockpool/peers.go index 1e56f315d..615058e26 100644 --- a/blockpool/peers.go +++ b/blockpool/peers.go @@ -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 for _, hash := range newp.sections { plog.DebugDetailf("activate chain starting from section [%s]", hex(hash)) // 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 entry := self.get(hash); entry != nil { self.activateChain(entry.section, newp, connected) - connected[hash.Str()] = entry.section + connected[hash] = entry.section sections = append(sections, hash) } } @@ -531,6 +531,7 @@ func (self *peer) run() { self.blocksRequestTimer = time.After(0) self.headInfoTimer = time.After(self.bp.Config.BlockHashesTimeout) + self.bestIdleTimer = nil var ping = time.NewTicker(5 * time.Second) @@ -581,7 +582,7 @@ LOOP: case <-self.bp.quit: break LOOP - // quit + // best 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))) diff --git a/blockpool/peers_test.go b/blockpool/peers_test.go index beeb0ad1d..62e059337 100644 --- a/blockpool/peers_test.go +++ b/blockpool/peers_test.go @@ -14,7 +14,7 @@ import ( // the actual tests func TestAddPeer(t *testing.T) { test.LogInit() - _, blockPool, blockPoolTester := newTestBlockPool(t) + hashPool, blockPool, blockPoolTester := newTestBlockPool(t) peer0 := blockPoolTester.newPeer("peer0", 1, 1) peer1 := blockPoolTester.newPeer("peer1", 2, 2) peer2 := blockPoolTester.newPeer("peer2", 3, 3) @@ -119,7 +119,8 @@ func TestAddPeer(t *testing.T) { } 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}) time.Sleep(100 * time.Millisecond) if blockPool.peers.best != nil {