Skip to content

Commit 61db7a7

Browse files
committed
Merge pull request #695 from ethersphere/frontier/blockpool
bugfixes for headsection deadlocks
2 parents f047699 + 406feee commit 61db7a7

File tree

1 file changed

+15
-7
lines changed

1 file changed

+15
-7
lines changed

blockpool/peers.go

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -89,10 +89,12 @@ func (self *peers) newPeer(
8989
peerError: peerError,
9090
currentBlockC: make(chan *types.Block),
9191
headSectionC: make(chan *section),
92+
switchC: make(chan bool),
9293
bp: self.bp,
9394
idle: true,
9495
addToBlacklist: self.addToBlacklist,
9596
}
97+
close(p.switchC) //! hack :((((
9698
// at creation the peer is recorded in the peer pool
9799
self.peers[id] = p
98100
return
@@ -153,7 +155,8 @@ func (self *peer) setChainInfo(td *big.Int, currentBlockHash common.Hash) {
153155

154156
func (self *peer) setChainInfoFromBlock(block *types.Block) (td *big.Int, currentBlockHash common.Hash) {
155157
self.lock.Lock()
156-
defer self.lock.Unlock()
158+
currentBlockC := self.currentBlockC
159+
switchC := self.switchC
157160
hash := block.Hash()
158161
// this happens when block came in a newblock message but
159162
// also if sent in a blockmsg (for instance, if we requested, only if we
@@ -162,15 +165,20 @@ func (self *peer) setChainInfoFromBlock(block *types.Block) (td *big.Int, curren
162165
if currentBlockHash == hash && self.currentBlock == nil {
163166
// signal to head section process
164167
plog.DebugDetailf("AddBlock: head block %s for peer <%s> (head: %s) received\n", hex(hash), self.id, hex(currentBlockHash))
165-
select {
166-
case self.currentBlockC <- block:
167-
case <-self.switchC:
168-
}
169-
return self.td, currentBlockHash
168+
td = self.td
170169
} else {
171170
plog.DebugDetailf("AddBlock: head block %s for peer <%s> (head: %s) already known", hex(hash), self.id, hex(currentBlockHash))
172-
return nil, currentBlockHash
173171
}
172+
self.lock.Unlock()
173+
// this must be called without peerlock.
174+
// peerlock held can halt the loop and block on select forever
175+
if td != nil {
176+
select {
177+
case currentBlockC <- block:
178+
case <-switchC: // peer is not best peer
179+
}
180+
}
181+
return
174182
}
175183

176184
// this will use the TD given by the first peer to update peer td, this helps second best peer selection

0 commit comments

Comments
 (0)