Skip to content

Commit d2779ed

Browse files
authored
eth, p2p: reserve half peer slots for snap peers during snap sync (#22171)
* eth, p2p: reserve half peer slots for snap peers during snap sync * eth: less logging * eth: rework the eth/snap peer reservation logic * eth: rework the eth/snap peer reservation logic (again)
1 parent adf130d commit d2779ed

File tree

4 files changed

+37
-3
lines changed

4 files changed

+37
-3
lines changed

eth/handler.go

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -250,9 +250,20 @@ func (h *handler) runEthPeer(peer *eth.Peer, handler eth.Handler) error {
250250
peer.Log().Debug("Ethereum handshake failed", "err", err)
251251
return err
252252
}
253+
reject := false // reserved peer slots
254+
if atomic.LoadUint32(&h.snapSync) == 1 && !peer.SupportsCap("snap", 1) {
255+
// If we are running snap-sync, we want to reserve roughly half the peer
256+
// slots for peers supporting the snap protocol.
257+
// The logic here is; we only allow up to 5 more non-snap peers than snap-peers.
258+
if all, snp := h.peers.Len(), h.peers.SnapLen(); all-snp > snp+5 {
259+
reject = true
260+
}
261+
}
253262
// Ignore maxPeers if this is a trusted peer
254-
if h.peers.Len() >= h.maxPeers && !peer.Peer.Info().Network.Trusted {
255-
return p2p.DiscTooManyPeers
263+
if !peer.Peer.Info().Network.Trusted {
264+
if reject || h.peers.Len() >= h.maxPeers {
265+
return p2p.DiscTooManyPeers
266+
}
256267
}
257268
peer.Log().Debug("Ethereum peer connected", "name", peer.Name())
258269

eth/peerset.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ func (ps *peerSet) ethPeersWithoutTransaction(hash common.Hash) []*ethPeer {
259259
}
260260

261261
// Len returns if the current number of `eth` peers in the set. Since the `snap`
262-
// peers are tied to the existnce of an `eth` connection, that will always be a
262+
// peers are tied to the existence of an `eth` connection, that will always be a
263263
// subset of `eth`.
264264
func (ps *peerSet) Len() int {
265265
ps.lock.RLock()
@@ -268,6 +268,15 @@ func (ps *peerSet) Len() int {
268268
return len(ps.ethPeers)
269269
}
270270

271+
// SnapLen returns if the current number of `snap` peers in the set. Since the `snap`
272+
// peers are tied to the existence of an `eth` connection, that will always be a
273+
// subset of `eth`.
274+
func (ps *peerSet) SnapLen() int {
275+
ps.lock.RLock()
276+
defer ps.lock.RUnlock()
277+
return len(ps.snapPeers)
278+
}
279+
271280
// ethPeerWithHighestTD retrieves the known peer with the currently highest total
272281
// difficulty.
273282
func (ps *peerSet) ethPeerWithHighestTD() *eth.Peer {

eth/sync.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,10 @@ func (h *handler) doSync(op *chainSyncOp) error {
329329
log.Info("Fast sync complete, auto disabling")
330330
atomic.StoreUint32(&h.fastSync, 0)
331331
}
332+
if atomic.LoadUint32(&h.snapSync) == 1 {
333+
log.Info("Snap sync complete, auto disabling")
334+
atomic.StoreUint32(&h.snapSync, 0)
335+
}
332336
// If we've successfully finished a sync cycle and passed any required checkpoint,
333337
// enable accepting transactions from the network.
334338
head := h.chain.CurrentBlock()

p2p/peer.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,16 @@ func (p *Peer) Caps() []Cap {
158158
return p.rw.caps
159159
}
160160

161+
// SupportsCap returns true if the peer supports the given protocol/version
162+
func (p *Peer) SupportsCap(protocol string, version uint) bool {
163+
for _, cap := range p.rw.caps {
164+
if cap.Name == protocol {
165+
return version <= cap.Version
166+
}
167+
}
168+
return false
169+
}
170+
161171
// RemoteAddr returns the remote address of the network connection.
162172
func (p *Peer) RemoteAddr() net.Addr {
163173
return p.rw.fd.RemoteAddr()

0 commit comments

Comments
 (0)