-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Description
The relevant code is here:
Lines 305 to 324 in 2e0466d
| func (pool *BlockPool) pickIncrAvailablePeer(minHeight int64) *bpPeer { | |
| pool.mtx.Lock() | |
| defer pool.mtx.Unlock() | |
| for _, peer := range pool.peers { | |
| if peer.didTimeout { | |
| pool.removePeer(peer.id) | |
| continue | |
| } | |
| if peer.numPending >= maxPendingRequestsPerPeer { | |
| continue | |
| } | |
| if peer.height < minHeight { | |
| continue | |
| } | |
| peer.incrPending() | |
| return peer | |
| } | |
| return nil | |
| } |
Note that the algorithm for selecting a peer from whom next block is pulled is chosen by iterating over peers and picking a first peer that satisfies the following condition:
peer.numPending < maxPendingRequestsPerPeer and peer.height >= height, where height is the height of the block we are missing and want to pull in.
This algorithm might lead to the request placement that is not optimal. In case iteration over map is deterministic and always returns the same sequence, it will send request to the first peer from the list (if peer's height is greater than height) until maxPendingRequestsPerPeer - 1 requests are sent, and no request will be sent to other peers. Then it will start sending requests to a second peer, etc.
There are several different approaches how the problem of request for block placement can be made that might lead to better fast sync time, for example, randomly picking peer, or ensuring that requests are sent uniformly to all peers that have blocks, or taking into account how fast we are getting blocks from our peers and giving preference to faster peers, or sending one request at a time to each peer initially and then based on response tine adapting, etc.