be careful not to disconnect syncing peers in fragmented network

This commit is contained in:
Etan Kissling 2024-03-27 16:00:21 +01:00
parent 9f37ffdc62
commit f8be7c326e
No known key found for this signature in database
GPG Key ID: B21DA824C5A3D03D
3 changed files with 20 additions and 10 deletions

View File

@ -208,6 +208,9 @@ proc handleStatus(peer: Peer,
await peer.handlePeer() await peer.handlePeer()
true true
const StatusExpirationTime* = chronos.minutes(2)
## Time time it takes for the peer's status information to expire.
proc updateStatus*(peer: Peer): Future[bool] {.async: (raises: [CancelledError]).} = proc updateStatus*(peer: Peer): Future[bool] {.async: (raises: [CancelledError]).} =
## Request `status` of remote peer ``peer``. ## Request `status` of remote peer ``peer``.
let let

View File

@ -92,10 +92,20 @@ proc discoverBranch(
peer peer
peer_score = peer.getScore() peer_score = peer.getScore()
let let oldPeerHeadSlot = peer.getHeadSlot()
finalizedSlot = self.getFinalizedSlot() if Moment.now() - peer.getStatusLastTime() >= StatusExpirationTime:
peerHeadSlot = peer.getHeadSlot() if not(await peer.updateStatus()):
peer.updateScore(PeerScoreNoStatus)
debug "Failed to update status"
return
let peerHeadSlot = peer.getHeadSlot()
if peerHeadSlot != oldPeerHeadSlot:
peer.updateScore(PeerScoreGoodStatus)
debug "Peer has synced to a new head", oldPeerHeadSlot, peerHeadSlot
let finalizedSlot = self.getFinalizedSlot()
if peerHeadSlot <= finalizedSlot: if peerHeadSlot <= finalizedSlot:
# This peer can sync from different peers, it is useless to us at this time
peer.updateScore(PeerScoreUseless) peer.updateScore(PeerScoreUseless)
debug "Peer's head slot is already finalized", peerHeadSlot, finalizedSlot debug "Peer's head slot is already finalized", peerHeadSlot, finalizedSlot
return return
@ -103,11 +113,14 @@ proc discoverBranch(
var blockRoot = peer.getHeadRoot() var blockRoot = peer.getHeadRoot()
logScope: blockRoot logScope: blockRoot
if self.isBlockKnown(blockRoot): if self.isBlockKnown(blockRoot):
# This peer may be actively syncing from us, only descore if no disconnect
if peer.getScore() >= PeerScoreLowLimit - PeerScoreUseless:
peer.updateScore(PeerScoreUseless) peer.updateScore(PeerScoreUseless)
debug "Peer's head block root is already known" debug "Peer's head block root is already known"
return return
# Many peers disconnect on rate limit, we have to avoid getting hit by it # Many peers disconnect on rate limit, we have to avoid getting hit by it
# to have a chance in picking up branches that don't have good propagation
const const
maxRequestsPerBurst = 15 maxRequestsPerBurst = 15
burstDuration = chronos.seconds(30) burstDuration = chronos.seconds(30)

View File

@ -28,12 +28,6 @@ const
SyncWorkersCount* = 10 SyncWorkersCount* = 10
## Number of sync workers to spawn ## Number of sync workers to spawn
StatusUpdateInterval* = chronos.minutes(1)
## Minimum time between two subsequent calls to update peer's status
StatusExpirationTime* = chronos.minutes(2)
## Time time it takes for the peer's status information to expire.
type type
PeerSyncer*[T] = proc(peer: T) {.gcsafe, raises: [].} PeerSyncer*[T] = proc(peer: T) {.gcsafe, raises: [].}