bugfixes for headsection deadlocks
- switchC initialised as closed - move select in setChainInfoFromBlock out of peer lock
This commit is contained in:
		@@ -89,10 +89,12 @@ func (self *peers) newPeer(
 | 
				
			|||||||
		peerError:          peerError,
 | 
							peerError:          peerError,
 | 
				
			||||||
		currentBlockC:      make(chan *types.Block),
 | 
							currentBlockC:      make(chan *types.Block),
 | 
				
			||||||
		headSectionC:       make(chan *section),
 | 
							headSectionC:       make(chan *section),
 | 
				
			||||||
 | 
							switchC:            make(chan bool),
 | 
				
			||||||
		bp:                 self.bp,
 | 
							bp:                 self.bp,
 | 
				
			||||||
		idle:               true,
 | 
							idle:               true,
 | 
				
			||||||
		addToBlacklist:     self.addToBlacklist,
 | 
							addToBlacklist:     self.addToBlacklist,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						close(p.switchC) //! hack :((((
 | 
				
			||||||
	// at creation the peer is recorded in the peer pool
 | 
						// at creation the peer is recorded in the peer pool
 | 
				
			||||||
	self.peers[id] = p
 | 
						self.peers[id] = p
 | 
				
			||||||
	return
 | 
						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) {
 | 
					func (self *peer) setChainInfoFromBlock(block *types.Block) (td *big.Int, currentBlockHash common.Hash) {
 | 
				
			||||||
	self.lock.Lock()
 | 
						self.lock.Lock()
 | 
				
			||||||
	defer self.lock.Unlock()
 | 
						currentBlockC := self.currentBlockC
 | 
				
			||||||
 | 
						switchC := self.switchC
 | 
				
			||||||
	hash := block.Hash()
 | 
						hash := block.Hash()
 | 
				
			||||||
	// this happens when block came in a newblock message but
 | 
						// this happens when block came in a newblock message but
 | 
				
			||||||
	// also if sent in a blockmsg (for instance, if we requested, only if we
 | 
						// 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 {
 | 
						if currentBlockHash == hash && self.currentBlock == nil {
 | 
				
			||||||
		// signal to head section process
 | 
							// signal to head section process
 | 
				
			||||||
		plog.DebugDetailf("AddBlock: head block %s for peer <%s> (head: %s) received\n", hex(hash), self.id, hex(currentBlockHash))
 | 
							plog.DebugDetailf("AddBlock: head block %s for peer <%s> (head: %s) received\n", hex(hash), self.id, hex(currentBlockHash))
 | 
				
			||||||
		select {
 | 
							td = self.td
 | 
				
			||||||
		case self.currentBlockC <- block:
 | 
					 | 
				
			||||||
		case <-self.switchC:
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return self.td, currentBlockHash
 | 
					 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		plog.DebugDetailf("AddBlock: head block %s for peer <%s> (head: %s) already known", hex(hash), self.id, hex(currentBlockHash))
 | 
							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
 | 
					// this will use the TD given by the first peer to update peer td, this helps second best peer selection
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user