aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorzelig <viktor.tron@gmail.com>2015-04-02 23:30:48 +0800
committerzelig <viktor.tron@gmail.com>2015-04-02 23:30:48 +0800
commit5cb1b41440209b03a1c5ec6c639207fd336e67e3 (patch)
tree7536772fefaeb39e751d5cc938ee4aab05f5bb1d
parentdd1791c9fd87b3744dc0747153e41fe893cc727b (diff)
downloaddexon-5cb1b41440209b03a1c5ec6c639207fd336e67e3.tar.gz
dexon-5cb1b41440209b03a1c5ec6c639207fd336e67e3.tar.zst
dexon-5cb1b41440209b03a1c5ec6c639207fd336e67e3.zip
proper locking to prevent "parent unknown" INVALID blocks due to race in peer head info update
-rw-r--r--blockpool/peers.go9
1 files changed, 4 insertions, 5 deletions
diff --git a/blockpool/peers.go b/blockpool/peers.go
index 802081780..285fa45b1 100644
--- a/blockpool/peers.go
+++ b/blockpool/peers.go
@@ -133,13 +133,10 @@ func (self *peer) addError(code int, format string, params ...interface{}) {
self.addToBlacklist(self.id)
}
+// caller must hold peer lock
func (self *peer) setChainInfo(td *big.Int, c common.Hash) {
- self.lock.Lock()
- defer self.lock.Unlock()
-
self.td = td
self.currentBlockHash = c
-
self.currentBlock = nil
self.parentHash = common.Hash{}
self.headSection = nil
@@ -171,7 +168,7 @@ func (self *peers) requestBlocks(attempts int, hashes []common.Hash) {
defer self.lock.RUnlock()
peerCount := len(self.peers)
// on first attempt use the best peer
- if attempts == 0 {
+ if attempts == 0 && self.best != nil {
plog.DebugDetailf("request %v missing blocks from best peer <%s>", len(hashes), self.best.id)
self.best.requestBlocks(hashes)
return
@@ -224,6 +221,7 @@ func (self *peers) addPeer(
if found {
// when called on an already connected peer, it means a newBlockMsg is received
// peer head info is updated
+ p.lock.Lock()
if p.currentBlockHash != currentBlockHash {
previousBlockHash = p.currentBlockHash
plog.Debugf("addPeer: Update peer <%s> with td %v and current block %s (was %v)", id, td, hex(currentBlockHash), hex(previousBlockHash))
@@ -233,6 +231,7 @@ func (self *peers) addPeer(
self.status.values.NewBlocks++
self.status.lock.Unlock()
}
+ p.lock.Unlock()
} else {
p = self.newPeer(td, currentBlockHash, id, requestBlockHashes, requestBlocks, peerError)