From 9f24087f9988e746ee5b602c2276641b576f7cb6 Mon Sep 17 00:00:00 2001 From: Daniel Liu <139250065@qq.com> Date: Thu, 16 Jul 2026 20:16:20 +0800 Subject: [PATCH] fix(eth): filter BFT broadcast to xdpos2+ peers only PeersWithoutVote, PeersWithoutTimeout and PeersWithoutSyncInfo now skip peers whose protocol version is below xdpos2 (100). BFT messages use opcodes 0xe0-0xe2 which are only defined in the 227-length xdpos2 protocol; sending them to eth/63 or eth/62 peers would always fail and trigger a spurious removePeer. --- eth/peer.go | 21 ++++++++++++--------- eth/protocol.go | 8 ++++---- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/eth/peer.go b/eth/peer.go index a0be36675725..4144dbdb5bb3 100644 --- a/eth/peer.go +++ b/eth/peer.go @@ -535,45 +535,48 @@ func (ps *peerSet) PeersWithoutTx(hash common.Hash) []*peer { return list } -// PeersWithoutVote retrieves a list of peers that do not have a given block in -// their set of known hashes. +// PeersWithoutVote retrieves a list of peers that do not have a given vote in +// their set of known hashes. Only peers supporting the XDC BFT protocol +// (version >= xdc100) are returned. func (ps *peerSet) PeersWithoutVote(hash common.Hash) []*peer { ps.lock.RLock() defer ps.lock.RUnlock() list := make([]*peer, 0, len(ps.peers)) for _, p := range ps.peers { - if !p.knownVote.Contains(hash) { + if p.version >= xdc100 && !p.knownVote.Contains(hash) { list = append(list, p) } } return list } -// PeersWithoutTimeout retrieves a list of peers that do not have a given block in -// their set of known hashes. +// PeersWithoutTimeout retrieves a list of peers that do not have a given timeout in +// their set of known hashes. Only peers supporting the XDC BFT protocol +// (version >= xdc100) are returned. func (ps *peerSet) PeersWithoutTimeout(hash common.Hash) []*peer { ps.lock.RLock() defer ps.lock.RUnlock() list := make([]*peer, 0, len(ps.peers)) for _, p := range ps.peers { - if !p.knownTimeout.Contains(hash) { + if p.version >= xdc100 && !p.knownTimeout.Contains(hash) { list = append(list, p) } } return list } -// PeersWithoutSyncInfo retrieves a list of peers that do not have a given block in -// their set of known hashes. +// PeersWithoutSyncInfo retrieves a list of peers that do not have a given sync +// info in their set of known hashes. Only peers supporting the XDC BFT protocol +// (version >= xdc100) are returned. func (ps *peerSet) PeersWithoutSyncInfo(hash common.Hash) []*peer { ps.lock.RLock() defer ps.lock.RUnlock() list := make([]*peer, 0, len(ps.peers)) for _, p := range ps.peers { - if !p.knownSyncInfo.Contains(hash) { + if p.version >= xdc100 && !p.knownSyncInfo.Contains(hash) { list = append(list, p) } } diff --git a/eth/protocol.go b/eth/protocol.go index ca3583647e22..2903b4a49089 100644 --- a/eth/protocol.go +++ b/eth/protocol.go @@ -33,17 +33,17 @@ import ( const ( eth62 = 62 eth63 = 63 - xdpos2 = 100 + xdc100 = 100 ) // protocolName is the official short name of the protocol used during capability negotiation. var protocolName = "eth" // ProtocolVersions are the supported versions of the eth protocol (first is primary). -var ProtocolVersions = []uint{xdpos2, eth63} +var ProtocolVersions = []uint{xdc100, eth63} // protocolLengths are the number of implemented message corresponding to different protocol versions. -var protocolLengths = map[uint]uint64{xdpos2: 227, eth63: 17, eth62: 8} +var protocolLengths = map[uint]uint64{xdc100: 227, eth63: 17, eth62: 8} const protocolMaxMsgSize = 10 * 1024 * 1024 // Maximum cap on the size of a protocol message @@ -66,7 +66,7 @@ const ( GetReceiptsMsg = 0x0f ReceiptsMsg = 0x10 - // Protocol messages belonging to xdpos2/100 + // Protocol messages belonging to xdc/100 VoteMsg = 0xe0 TimeoutMsg = 0xe1 SyncInfoMsg = 0xe2