eth: fix data race accessing peer.recentHash
This commit is contained in:
		
							parent
							
								
									05cae69d72
								
							
						
					
					
						commit
						44147d057d
					
				| @ -157,7 +157,7 @@ func (pm *ProtocolManager) handle(p *peer) error { | ||||
| 	} | ||||
| 	defer pm.removePeer(p.id) | ||||
| 
 | ||||
| 	if err := pm.downloader.RegisterPeer(p.id, p.recentHash, p.requestHashes, p.requestBlocks); err != nil { | ||||
| 	if err := pm.downloader.RegisterPeer(p.id, p.Head(), p.requestHashes, p.requestBlocks); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	// propagate existing transactions. new transactions appearing
 | ||||
| @ -303,7 +303,7 @@ func (self *ProtocolManager) handleMsg(p *peer) error { | ||||
| 		// Mark the hashes as present at the remote node
 | ||||
| 		for _, hash := range hashes { | ||||
| 			p.blockHashes.Add(hash) | ||||
| 			p.recentHash = hash | ||||
| 			p.SetHead(hash) | ||||
| 		} | ||||
| 		// Schedule all the unknown hashes for retrieval
 | ||||
| 		unknown := make([]common.Hash, 0, len(hashes)) | ||||
| @ -354,7 +354,7 @@ func (pm *ProtocolManager) importBlock(p *peer, block *types.Block, td *big.Int) | ||||
| 
 | ||||
| 	// Mark the block as present at the remote node (don't duplicate already held data)
 | ||||
| 	p.blockHashes.Add(hash) | ||||
| 	p.recentHash = hash | ||||
| 	p.SetHead(hash) | ||||
| 	if td != nil { | ||||
| 		p.td = td | ||||
| 	} | ||||
|  | ||||
							
								
								
									
										31
									
								
								eth/peer.go
									
									
									
									
									
								
							
							
						
						
									
										31
									
								
								eth/peer.go
									
									
									
									
									
								
							| @ -40,9 +40,11 @@ type peer struct { | ||||
| 
 | ||||
| 	protv, netid int | ||||
| 
 | ||||
| 	recentHash common.Hash | ||||
| 	id         string | ||||
| 	td         *big.Int | ||||
| 	id string | ||||
| 	td *big.Int | ||||
| 
 | ||||
| 	head     common.Hash | ||||
| 	headLock sync.RWMutex | ||||
| 
 | ||||
| 	genesis, ourHash common.Hash | ||||
| 	ourTd            *big.Int | ||||
| @ -51,14 +53,14 @@ type peer struct { | ||||
| 	blockHashes *set.Set | ||||
| } | ||||
| 
 | ||||
| func newPeer(protv, netid int, genesis, recentHash common.Hash, td *big.Int, p *p2p.Peer, rw p2p.MsgReadWriter) *peer { | ||||
| func newPeer(protv, netid int, genesis, head common.Hash, td *big.Int, p *p2p.Peer, rw p2p.MsgReadWriter) *peer { | ||||
| 	id := p.ID() | ||||
| 
 | ||||
| 	return &peer{ | ||||
| 		Peer:        p, | ||||
| 		rw:          rw, | ||||
| 		genesis:     genesis, | ||||
| 		ourHash:     recentHash, | ||||
| 		ourHash:     head, | ||||
| 		ourTd:       td, | ||||
| 		protv:       protv, | ||||
| 		netid:       netid, | ||||
| @ -68,6 +70,23 @@ func newPeer(protv, netid int, genesis, recentHash common.Hash, td *big.Int, p * | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // 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() | ||||
| 
 | ||||
| 	copy(hash[:], p.head[:]) | ||||
| 	return 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() | ||||
| 
 | ||||
| 	copy(p.head[:], hash[:]) | ||||
| } | ||||
| 
 | ||||
| // 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
 | ||||
| @ -160,7 +179,7 @@ func (p *peer) handleStatus() error { | ||||
| 	// Set the total difficulty of the peer
 | ||||
| 	p.td = status.TD | ||||
| 	// set the best hash of the peer
 | ||||
| 	p.recentHash = status.CurrentBlock | ||||
| 	p.head = status.CurrentBlock | ||||
| 
 | ||||
| 	return <-errc | ||||
| } | ||||
|  | ||||
| @ -214,14 +214,15 @@ func (pm *ProtocolManager) synchronise(peer *peer) { | ||||
| 	// FIXME if we have the hash in our chain and the TD of the peer is
 | ||||
| 	// much higher than ours, something is wrong with us or the peer.
 | ||||
| 	// Check if the hash is on our own chain
 | ||||
| 	if pm.chainman.HasBlock(peer.recentHash) { | ||||
| 	head := peer.Head() | ||||
| 	if pm.chainman.HasBlock(head) { | ||||
| 		glog.V(logger.Debug).Infoln("Synchronisation canceled: head already known") | ||||
| 		return | ||||
| 	} | ||||
| 	// Get the hashes from the peer (synchronously)
 | ||||
| 	glog.V(logger.Detail).Infof("Attempting synchronisation: %v, 0x%x", peer.id, peer.recentHash) | ||||
| 	glog.V(logger.Detail).Infof("Attempting synchronisation: %v, 0x%x", peer.id, head) | ||||
| 
 | ||||
| 	err := pm.downloader.Synchronise(peer.id, peer.recentHash) | ||||
| 	err := pm.downloader.Synchronise(peer.id, head) | ||||
| 	switch err { | ||||
| 	case nil: | ||||
| 		glog.V(logger.Detail).Infof("Synchronisation completed") | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user