diff options
author | zelig <viktor.tron@gmail.com> | 2015-04-02 23:30:48 +0800 |
---|---|---|
committer | zelig <viktor.tron@gmail.com> | 2015-04-02 23:30:48 +0800 |
commit | 5cb1b41440209b03a1c5ec6c639207fd336e67e3 (patch) | |
tree | 7536772fefaeb39e751d5cc938ee4aab05f5bb1d | |
parent | dd1791c9fd87b3744dc0747153e41fe893cc727b (diff) | |
download | dexon-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.go | 9 |
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) |