Skip to content

handleNewBlockhashesPow

Source (upstream pre-purge) Current
File eth/protocols/eth/handlers.go handlers_pow.go
Symbol handleNewBlockhashes handleNewBlockhashesPow
Ref f4d53133f~1 etc/v1.17.4-full-node

Renamed from handleNewBlockhashes to handleNewBlockhashesPow. Uses return err without errDecode wrapping, consistent with upstream v1.17.3, which no longer wraps handler errors in errDecode. Otherwise the pre-purge revival is intact except for one added check, the maxBlockAnnouncements cap — NEW-ETC, since neither upstream nor core-geth ever bounded this message. Its shape is copied from the only protocol-level precedent for capping an unsolicited announcement, upstream's handleTransactions: decode, compare the count, return an error that drops the peer. Note the deliberate difference from the fetcher layer, which on the same kind of excess (hashLimit in the block fetcher, maxTxAnnounces in the tx fetcher) logs at Debug, marks a DOS meter and discards or truncates WITHOUT dropping the peer. Both behaviours are upstream's; they are split by layer, and this check lives at the protocol layer. The two tiers are complementary, the same way maxTransactionAnnouncements sits above maxTxAnnounces for transactions. What this buys is not heap: at ~35 bytes per announcement a 10 MiB message decodes to ~300k entries, and the pipeline that follows (the markBlock loop, Unpack's two slices, handleBlockAnnounces' two more) amplifies it only about 3.5x. It is the work per entry that matters — ~300k chain.HasBlock lookups and ~300k blockFetcher.Notify channel sends before hashLimit discards all but 256 of them. Covered by TestBlockAnnouncementLimit68.

3-way merge — purge → getc ← upstream

pre-purgefork-only
func handleNewBlockhashesPow(backend Backend, msg Decoder, peer *Peer) error {
// A batch of new block announcements just arrived
ann := new(NewBlockHashesPacket)
if err := msg.Decode(ann); err != nil {
return err
}
if len(*ann) > maxBlockAnnouncements {
return fmt.Errorf("too many block announcements: %d > %d", len(*ann), maxBlockAnnouncements)
}
// Mark the hashes as present at the remote node
for _, block := range *ann {
peer.markBlock(block.Hash)
}
// Deliver them all to the backend for queuing
return backend.Handle(peer, ann)
}
core-geth validation — +5 -2 | | | |---|---| | File | [`handlers.go`](https://github.com/etclabscore/core-geth/blob/v1.12.20/eth/protocols/eth/handlers.go) | | Symbol | `handleNewBlockhashes` | | Ref | `v1.12.20` |
--- a/core-geth/eth/protocols/eth/handlers.go
+++ b/etc/eth/protocols/eth/handlers_pow.go
@@ -1,8 +1,11 @@
-func handleNewBlockhashes(backend Backend, msg Decoder, peer *Peer) error {
+func handleNewBlockhashesPow(backend Backend, msg Decoder, peer *Peer) error {
    // A batch of new block announcements just arrived
    ann := new(NewBlockHashesPacket)
    if err := msg.Decode(ann); err != nil {
-       return fmt.Errorf("%w: message %v: %v", errDecode, msg, err)
+       return err
+   }
+   if len(*ann) > maxBlockAnnouncements {
+       return fmt.Errorf("too many block announcements: %d > %d", len(*ann), maxBlockAnnouncements)
    }
    // Mark the hashes as present at the remote node
    for _, block := range *ann {

← eth Protocol