aboutsummaryrefslogtreecommitdiffstats
path: root/blockpool/peers.go
diff options
context:
space:
mode:
authorzelig <viktor.tron@gmail.com>2015-04-09 03:33:54 +0800
committerzelig <viktor.tron@gmail.com>2015-04-09 20:58:35 +0800
commite55747a074c7f280029b94c94418d60dff5d6773 (patch)
tree86057299276182a7703af41b39d366ef5b27caf4 /blockpool/peers.go
parent262714fc6c269e0a3aa39892954b03db9418e649 (diff)
downloadgo-tangerine-e55747a074c7f280029b94c94418d60dff5d6773.tar
go-tangerine-e55747a074c7f280029b94c94418d60dff5d6773.tar.gz
go-tangerine-e55747a074c7f280029b94c94418d60dff5d6773.tar.bz2
go-tangerine-e55747a074c7f280029b94c94418d60dff5d6773.tar.lz
go-tangerine-e55747a074c7f280029b94c94418d60dff5d6773.tar.xz
go-tangerine-e55747a074c7f280029b94c94418d60dff5d6773.tar.zst
go-tangerine-e55747a074c7f280029b94c94418d60dff5d6773.zip
fix deadlock issue in AddBlock
- add peer switch channel arg to activateChain - no peer locking within - proper locking in AddBlock - fixes deadlock issue - comment out TD check and skip incorrect TD test again for hotfix
Diffstat (limited to 'blockpool/peers.go')
-rw-r--r--blockpool/peers.go31
1 files changed, 17 insertions, 14 deletions
diff --git a/blockpool/peers.go b/blockpool/peers.go
index d95c348a8..7e6d281bb 100644
--- a/blockpool/peers.go
+++ b/blockpool/peers.go
@@ -114,10 +114,8 @@ func (self *peers) addToBlacklist(id string) {
self.blacklist[id] = time.Now()
}
-// suspended checks if peer is still suspended
+// suspended checks if peer is still suspended, caller should hold peers.lock
func (self *peers) suspended(id string) (s bool) {
- self.lock.Lock()
- defer self.lock.Unlock()
if suspendedAt, ok := self.blacklist[id]; ok {
if s = suspendedAt.Add(self.bp.Config.PeerSuspensionInterval).After(time.Now()); !s {
// no longer suspended, delete entry
@@ -205,13 +203,14 @@ func (self *peers) addPeer(
peerError func(*errs.Error),
) (best bool, suspended bool) {
+ self.lock.Lock()
+ defer self.lock.Unlock()
+
var previousBlockHash common.Hash
if self.suspended(id) {
suspended = true
return
}
- self.lock.Lock()
- defer self.lock.Unlock()
p, found := self.peers[id]
if found {
// when called on an already connected peer, it means a newBlockMsg is received
@@ -255,7 +254,7 @@ func (self *peers) addPeer(
p.headSectionC <- nil
if entry := self.bp.get(previousBlockHash); entry != nil {
plog.DebugDetailf("addPeer: <%s> previous head : %v found in pool, activate", id, hex(previousBlockHash))
- self.bp.activateChain(entry.section, p, nil)
+ self.bp.activateChain(entry.section, p, p.switchC, nil)
p.sections = append(p.sections, previousBlockHash)
}
}
@@ -265,8 +264,8 @@ func (self *peers) addPeer(
currentTD := self.bp.getTD()
bestpeer := self.best
if bestpeer != nil {
- bestpeer.lock.Lock()
- defer bestpeer.lock.Unlock()
+ bestpeer.lock.RLock()
+ defer bestpeer.lock.RUnlock()
currentTD = self.best.td
}
if td.Cmp(currentTD) > 0 {
@@ -362,14 +361,14 @@ func (self *BlockPool) switchPeer(oldp, newp *peer) {
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)
+ self.activateChain(entry.section, newp, newp.switchC, connected)
connected[hash] = entry.section
sections = append(sections, hash)
}
}
}
plog.DebugDetailf("<%s> section processes (%v non-contiguous sequences, was %v before)", newp.id, len(sections), len(newp.sections))
- // need to lock now that newp is exposed to section processes
+ // need to lock now that newp is exposed to section processesr
newp.lock.Lock()
newp.sections = sections
newp.lock.Unlock()
@@ -457,6 +456,8 @@ func (self *peer) getCurrentBlock(currentBlock *types.Block) {
}
func (self *peer) getBlockHashes() bool {
+ self.lock.Lock()
+ defer self.lock.Unlock()
//if connecting parent is found
if self.bp.hasBlock(self.parentHash) {
plog.DebugDetailf("HeadSection: <%s> parent block %s found in blockchain", self.id, hex(self.parentHash))
@@ -470,10 +471,10 @@ func (self *peer) getBlockHashes() bool {
self.bp.status.badPeers[self.id]++
} else {
// XXX added currentBlock check (?)
- if self.currentBlock != nil && self.currentBlock.Td != nil {
+ if self.currentBlock != nil && self.currentBlock.Td != nil && !self.currentBlock.Queued() {
if self.td.Cmp(self.currentBlock.Td) != 0 {
- //self.addError(ErrIncorrectTD, "on block %x", self.currentBlockHash)
- //self.bp.status.badPeers[self.id]++
+ // self.addError(ErrIncorrectTD, "on block %x", self.currentBlockHash)
+ // self.bp.status.badPeers[self.id]++
}
}
headKey := self.parentHash
@@ -499,7 +500,7 @@ func (self *peer) getBlockHashes() bool {
self.bp.newSection([]*node{n}).activate(self)
} else {
plog.DebugDetailf("HeadSection: <%s> connecting parent %s found in pool...head section [%s] exists...not requesting hashes", self.id, hex(self.parentHash), sectionhex(parent.section))
- self.bp.activateChain(parent.section, self, nil)
+ self.bp.activateChain(parent.section, self, self.switchC, nil)
}
} else {
plog.DebugDetailf("HeadSection: <%s> section [%s] requestBlockHashes", self.id, sectionhex(self.headSection))
@@ -523,6 +524,7 @@ func (self *peer) run() {
self.lock.RLock()
switchC := self.switchC
+ plog.Debugf("HeadSection: <%s> section process for head %s started", self.id, hex(self.currentBlockHash))
self.lock.RUnlock()
self.blockHashesRequestTimer = nil
@@ -589,6 +591,7 @@ LOOP:
plog.Debugf("HeadSection: <%s> (headsection [%s]) quit channel closed : timed out without providing new blocks...quitting", self.id, sectionhex(self.headSection))
}
}
+
if !self.idle {
self.idle = true
self.bp.wg.Done()