diff options
author | zelig <viktor.tron@gmail.com> | 2015-04-11 11:58:53 +0800 |
---|---|---|
committer | zelig <viktor.tron@gmail.com> | 2015-04-11 11:58:53 +0800 |
commit | 406feee570d369ba73dc12a049a8e656228be982 (patch) | |
tree | c14b8f80b685099782bd4c34207b176429cf0ed8 | |
parent | f047699afbf4773cc9ab37e61af7d72564a12008 (diff) | |
download | dexon-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.go | 22 |
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 |