eth: fix data race accessing peer.td
This commit is contained in:
parent
44147d057d
commit
f86707713c
@ -356,7 +356,7 @@ func (pm *ProtocolManager) importBlock(p *peer, block *types.Block, td *big.Int)
|
|||||||
p.blockHashes.Add(hash)
|
p.blockHashes.Add(hash)
|
||||||
p.SetHead(hash)
|
p.SetHead(hash)
|
||||||
if td != nil {
|
if td != nil {
|
||||||
p.td = td
|
p.SetTd(td)
|
||||||
}
|
}
|
||||||
// Log the block's arrival
|
// Log the block's arrival
|
||||||
_, chainHead, _ := pm.chainman.Status()
|
_, chainHead, _ := pm.chainman.Status()
|
||||||
@ -369,7 +369,7 @@ func (pm *ProtocolManager) importBlock(p *peer, block *types.Block, td *big.Int)
|
|||||||
})
|
})
|
||||||
// If the block's already known or its difficulty is lower than ours, drop
|
// If the block's already known or its difficulty is lower than ours, drop
|
||||||
if pm.chainman.HasBlock(hash) {
|
if pm.chainman.HasBlock(hash) {
|
||||||
p.td = pm.chainman.GetBlock(hash).Td // update the peer's TD to the real value
|
p.SetTd(pm.chainman.GetBlock(hash).Td) // update the peer's TD to the real value
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if td != nil && pm.chainman.Td().Cmp(td) > 0 && new(big.Int).Add(block.Number(), big.NewInt(7)).Cmp(pm.chainman.CurrentBlock().Number()) < 0 {
|
if td != nil && pm.chainman.Td().Cmp(td) > 0 && new(big.Int).Add(block.Number(), big.NewInt(7)).Cmp(pm.chainman.CurrentBlock().Number()) < 0 {
|
||||||
|
41
eth/peer.go
41
eth/peer.go
@ -41,10 +41,10 @@ type peer struct {
|
|||||||
protv, netid int
|
protv, netid int
|
||||||
|
|
||||||
id string
|
id string
|
||||||
td *big.Int
|
|
||||||
|
|
||||||
head common.Hash
|
head common.Hash
|
||||||
headLock sync.RWMutex
|
td *big.Int
|
||||||
|
lock sync.RWMutex
|
||||||
|
|
||||||
genesis, ourHash common.Hash
|
genesis, ourHash common.Hash
|
||||||
ourTd *big.Int
|
ourTd *big.Int
|
||||||
@ -72,8 +72,8 @@ func newPeer(protv, netid int, genesis, head common.Hash, td *big.Int, p *p2p.Pe
|
|||||||
|
|
||||||
// Head retrieves a copy of the current head (most recent) hash of the peer.
|
// Head retrieves a copy of the current head (most recent) hash of the peer.
|
||||||
func (p *peer) Head() (hash common.Hash) {
|
func (p *peer) Head() (hash common.Hash) {
|
||||||
p.headLock.RLock()
|
p.lock.RLock()
|
||||||
defer p.headLock.RUnlock()
|
defer p.lock.RUnlock()
|
||||||
|
|
||||||
copy(hash[:], p.head[:])
|
copy(hash[:], p.head[:])
|
||||||
return hash
|
return hash
|
||||||
@ -81,12 +81,28 @@ func (p *peer) Head() (hash common.Hash) {
|
|||||||
|
|
||||||
// SetHead updates the head (most recent) hash of the peer.
|
// SetHead updates the head (most recent) hash of the peer.
|
||||||
func (p *peer) SetHead(hash common.Hash) {
|
func (p *peer) SetHead(hash common.Hash) {
|
||||||
p.headLock.Lock()
|
p.lock.Lock()
|
||||||
defer p.headLock.Unlock()
|
defer p.lock.Unlock()
|
||||||
|
|
||||||
copy(p.head[:], hash[:])
|
copy(p.head[:], hash[:])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Td retrieves the current total difficulty of a peer.
|
||||||
|
func (p *peer) Td() *big.Int {
|
||||||
|
p.lock.RLock()
|
||||||
|
defer p.lock.RUnlock()
|
||||||
|
|
||||||
|
return new(big.Int).Set(p.td)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetTd updates the current total difficulty of a peer.
|
||||||
|
func (p *peer) SetTd(td *big.Int) {
|
||||||
|
p.lock.Lock()
|
||||||
|
defer p.lock.Unlock()
|
||||||
|
|
||||||
|
p.td.Set(td)
|
||||||
|
}
|
||||||
|
|
||||||
// sendTransactions sends transactions to the peer and includes the hashes
|
// sendTransactions sends transactions to the peer and includes the hashes
|
||||||
// in it's tx hash set for future reference. The tx hash will allow the
|
// in it's tx hash set for future reference. The tx hash will allow the
|
||||||
// manager to check whether the peer has already received this particular
|
// manager to check whether the peer has already received this particular
|
||||||
@ -275,11 +291,14 @@ func (ps *peerSet) BestPeer() *peer {
|
|||||||
ps.lock.RLock()
|
ps.lock.RLock()
|
||||||
defer ps.lock.RUnlock()
|
defer ps.lock.RUnlock()
|
||||||
|
|
||||||
var best *peer
|
var (
|
||||||
|
bestPeer *peer
|
||||||
|
bestTd *big.Int
|
||||||
|
)
|
||||||
for _, p := range ps.peers {
|
for _, p := range ps.peers {
|
||||||
if best == nil || p.td.Cmp(best.td) > 0 {
|
if td := p.Td(); bestPeer == nil || td.Cmp(bestTd) > 0 {
|
||||||
best = p
|
bestPeer, bestTd = p, td
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return best
|
return bestPeer
|
||||||
}
|
}
|
||||||
|
@ -208,7 +208,7 @@ func (pm *ProtocolManager) synchronise(peer *peer) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Make sure the peer's TD is higher than our own. If not drop.
|
// Make sure the peer's TD is higher than our own. If not drop.
|
||||||
if peer.td.Cmp(pm.chainman.Td()) <= 0 {
|
if peer.Td().Cmp(pm.chainman.Td()) <= 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// FIXME if we have the hash in our chain and the TD of the peer is
|
// FIXME if we have the hash in our chain and the TD of the peer is
|
||||||
|
Loading…
Reference in New Issue
Block a user