aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorzelig <viktor.tron@gmail.com>2015-04-11 11:58:53 +0800
committerzelig <viktor.tron@gmail.com>2015-04-11 11:58:53 +0800
commit406feee570d369ba73dc12a049a8e656228be982 (patch)
treec14b8f80b685099782bd4c34207b176429cf0ed8
parentf047699afbf4773cc9ab37e61af7d72564a12008 (diff)
downloaddexon-406feee570d369ba73dc12a049a8e656228be982.tar
dexon-406feee570d369ba73dc12a049a8e656228be982.tar.gz
dexon-406feee570d369ba73dc12a049a8e656228be982.tar.bz2
dexon-406feee570d369ba73dc12a049a8e656228be982.tar.lz
dexon-406feee570d369ba73dc12a049a8e656228be982.tar.xz
dexon-406feee570d369ba73dc12a049a8e656228be982.tar.zst
dexon-406feee570d369ba73dc12a049a8e656228be982.zip
bugfixes for headsection deadlocks
- switchC initialised as closed - move select in setChainInfoFromBlock out of peer lock
-rw-r--r--blockpool/peers.go22
1 files changed, 15 insertions, 7 deletions
diff --git a/blockpool/peers.go b/blockpool/peers.go
index 90dc5daef..c6cade460 100644
--- a/blockpool/peers.go
+++ b/blockpool/peers.go
@@ -89,10 +89,12 @@ func (self *peers) newPeer(
peerError: peerError,
currentBlockC: make(chan *types.Block),
headSectionC: make(chan *section),
+ switchC: make(chan bool),
bp: self.bp,
idle: true,
addToBlacklist: self.addToBlacklist,
}
+ close(p.switchC) //! hack :((((
// at creation the peer is recorded in the peer pool
self.peers[id] = p
return
@@ -153,7 +155,8 @@ func (self *peer) setChainInfo(td *big.Int, currentBlockHash common.Hash) {
func (self *peer) setChainInfoFromBlock(block *types.Block) (td *big.Int, currentBlockHash common.Hash) {
self.lock.Lock()
- defer self.lock.Unlock()
+ currentBlockC := self.currentBlockC
+ switchC := self.switchC
hash := block.Hash()
// this happens when block came in a newblock message but
// 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
if currentBlockHash == hash && self.currentBlock == nil {
// signal to head section process
plog.DebugDetailf("AddBlock: head block %s for peer <%s> (head: %s) received\n", hex(hash), self.id, hex(currentBlockHash))
- select {
- case self.currentBlockC <- block:
- case <-self.switchC:
- }
- return self.td, currentBlockHash
+ td = self.td
} else {
plog.DebugDetailf("AddBlock: head block %s for peer <%s> (head: %s) already known", hex(hash), self.id, hex(currentBlockHash))
- return nil, currentBlockHash
}
+ self.lock.Unlock()
+ // this must be called without peerlock.
+ // peerlock held can halt the loop and block on select forever
+ if td != nil {
+ select {
+ case currentBlockC <- block:
+ case <-switchC: // peer is not best peer
+ }
+ }
+ return
}
// this will use the TD given by the first peer to update peer td, this helps second best peer selection