Skip to content

Commit

Permalink
[release-v2.0] p2p: Disconnect from peers that sent too few headers
Browse files Browse the repository at this point in the history
The existing full node software (dcrd) always sends batches of 2000
headers when requesting headers during Initial Block Download.

The check added in this commit ensures the wallet disconnects from any
peers that deviate from this behavior. While receiving less than 2000
headers could not cause any consistency or safety issues, it could slow
down sync time.

Backport of 34395a5.
  • Loading branch information
matheusd authored and jrick committed Nov 11, 2024
1 parent 650a7c0 commit 59a4040
Showing 1 changed file with 16 additions and 0 deletions.
16 changes: 16 additions & 0 deletions p2p/peering.go
Original file line number Diff line number Diff line change
Expand Up @@ -1121,6 +1121,22 @@ func (rp *RemotePeer) deleteRequestedHeaders() {
func (rp *RemotePeer) receivedHeaders(ctx context.Context, msg *wire.MsgHeaders) {
const opf = "remotepeer(%v).receivedHeaders"
rp.requestedHeadersMu.Lock()

// Ensure the remote peer sent as many headers as it could. It can only
// send fewer than 2k headers when the last one is >= their advertised
// height (their tip height). This handles cases where a peer might
// drip headers instead of sending a full batch.
tooFewHeaders := len(msg.Headers) > 0 &&
len(msg.Headers) < wire.MaxBlockHeadersPerMsg &&
msg.Headers[len(msg.Headers)-1].Height < uint32(rp.initHeight)
if tooFewHeaders {
op := errors.Opf(opf, rp.raddr)
err := errors.E(op, errors.Protocol, "peer sent too few headers")
rp.Disconnect(err)
rp.requestedHeadersMu.Unlock()
return
}

var prevHash chainhash.Hash
var prevHeight uint32
for i, h := range msg.Headers {
Expand Down

0 comments on commit 59a4040

Please sign in to comment.