diff options
author | Péter Szilágyi <peterke@gmail.com> | 2015-06-09 19:56:27 +0800 |
---|---|---|
committer | Péter Szilágyi <peterke@gmail.com> | 2015-06-09 19:56:27 +0800 |
commit | f86707713c42da02b70a3a389684e19e902d8759 (patch) | |
tree | 0eb22642f83961147bfef44453b9398bd5409cfd /eth/peer.go | |
parent | 44147d057dd91d8b35dd6f4ed025bdb4baf225eb (diff) | |
download | go-tangerine-f86707713c42da02b70a3a389684e19e902d8759.tar.gz go-tangerine-f86707713c42da02b70a3a389684e19e902d8759.tar.zst go-tangerine-f86707713c42da02b70a3a389684e19e902d8759.zip |
eth: fix data race accessing peer.td
Diffstat (limited to 'eth/peer.go')
-rw-r--r-- | eth/peer.go | 41 |
1 files changed, 30 insertions, 11 deletions
diff --git a/eth/peer.go b/eth/peer.go index 5f5007891..c7045282b 100644 --- a/eth/peer.go +++ b/eth/peer.go @@ -41,10 +41,10 @@ type peer struct { protv, netid int id string - td *big.Int - head common.Hash - headLock sync.RWMutex + head common.Hash + td *big.Int + lock sync.RWMutex genesis, ourHash common.Hash 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. func (p *peer) Head() (hash common.Hash) { - p.headLock.RLock() - defer p.headLock.RUnlock() + p.lock.RLock() + defer p.lock.RUnlock() copy(hash[:], p.head[:]) return hash @@ -81,12 +81,28 @@ func (p *peer) Head() (hash common.Hash) { // SetHead updates the head (most recent) hash of the peer. func (p *peer) SetHead(hash common.Hash) { - p.headLock.Lock() - defer p.headLock.Unlock() + p.lock.Lock() + defer p.lock.Unlock() 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 // 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 @@ -275,11 +291,14 @@ func (ps *peerSet) BestPeer() *peer { ps.lock.RLock() defer ps.lock.RUnlock() - var best *peer + var ( + bestPeer *peer + bestTd *big.Int + ) for _, p := range ps.peers { - if best == nil || p.td.Cmp(best.td) > 0 { - best = p + if td := p.Td(); bestPeer == nil || td.Cmp(bestTd) > 0 { + bestPeer, bestTd = p, td } } - return best + return bestPeer } |