Skip to content

handleNewBlockPow

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

Renamed from handleNewBlock to handleNewBlockPow. Uses return err without errDecode wrapping, consistent with upstream v1.17.3, which no longer wraps handler errors in errDecode. The pre-purge revival is otherwise intact — sanityCheck, the uncle-hash and tx-root checks with their log.Warn-and-return-nil handling and karalabe's TODO, the ReceivedAt/ReceivedFrom stamping, markBlock — but the decode around it is NOT pre-purge: see the rawNewBlockPacket entry for why, and for the two checks that were re-expressed against the encoded form via the shared hashBodyParts helper rather than against a materialized types.Block.

3-way merge — purge → getc ← upstream

pre-purge≈ adapted (origin inferred by similarity)fork-only
func handleNewBlockPow(backend Backend, msg Decoder, peer *Peer) error {
// Retrieve the propagated block, leaving its body encoded for now
ann := new(rawNewBlockPacket)
if err := msg.Decode(ann); err != nil {
return err
}
if err := ann.sanityCheck(); err != nil {
return err
}
// Bound what the body may expand into. Decoding into rlp.RawList only counts
// the items, so this runs before any transaction or uncle is materialized.
if txs := ann.Block.Transactions.Len(); txs > maxBlockTransactions {
return fmt.Errorf("too many transactions in propagated block: %d > %d", txs, maxBlockTransactions)
}
if uncles := ann.Block.Uncles.Len(); uncles > maxBlockUncles {
return fmt.Errorf("too many uncles in propagated block: %d > %d", uncles, maxBlockUncles)
}
// Check the body against the header on the encoded form, so a block that is
// not what it claims to be is dropped without being materialized either.
header := ann.Block.Header
roots := hashBodyParts([]BlockBody{ann.Block.body()})
if hash := roots.UncleHashes[0]; hash != header.UncleHash {
log.Warn("Propagated block has invalid uncles", "have", hash, "exp", header.UncleHash)
return nil // TODO(karalabe): return error eventually, but wait a few releases
}
if hash := roots.TransactionRoots[0]; hash != header.TxHash {
log.Warn("Propagated block has invalid body", "have", hash, "exp", header.TxHash)
return nil // TODO(karalabe): return error eventually, but wait a few releases
}
// Bounded and self-consistent, so it is safe to materialize now.
txs, err := ann.Block.Transactions.Items()
if err != nil {
return fmt.Errorf("NewBlock: %w", err)
}
uncles, err := ann.Block.Uncles.Items()
if err != nil {
return fmt.Errorf("NewBlock: %w", err)
}
block := types.NewBlockWithHeader(header).WithBody(types.Body{Transactions: txs, Uncles: uncles})
block.ReceivedAt = time.Now()
block.ReceivedFrom = peer
// Mark the peer as owning the block
peer.markBlock(block.Hash())
return backend.Handle(peer, &NewBlockPacket{Block: block, TD: ann.TD})
core-geth validation — +34 -12 | | | |---|---| | File | [`handlers.go`](https://github.com/etclabscore/core-geth/blob/v1.12.20/eth/protocols/eth/handlers.go) | | Symbol | `handleNewBlock` | | Ref | `v1.12.20` |
--- a/core-geth/eth/protocols/eth/handlers.go
+++ b/etc/eth/protocols/eth/handlers_pow.go
@@ -1,25 +1,47 @@
-func handleNewBlock(backend Backend, msg Decoder, peer *Peer) error {
-   // Retrieve and decode the propagated block
-   ann := new(NewBlockPacket)
+func handleNewBlockPow(backend Backend, msg Decoder, peer *Peer) error {
+   // Retrieve the propagated block, leaving its body encoded for now
+   ann := new(rawNewBlockPacket)
    if err := msg.Decode(ann); err != nil {
-       return fmt.Errorf("%w: message %v: %v", errDecode, msg, err)
+       return err
    }
    if err := ann.sanityCheck(); err != nil {
        return err
    }
-   if hash := types.CalcUncleHash(ann.Block.Uncles()); hash != ann.Block.UncleHash() {
-       log.Warn("Propagated block has invalid uncles", "have", hash, "exp", ann.Block.UncleHash())
+   // Bound what the body may expand into. Decoding into rlp.RawList only counts
+   // the items, so this runs before any transaction or uncle is materialized.
+   if txs := ann.Block.Transactions.Len(); txs > maxBlockTransactions {
+       return fmt.Errorf("too many transactions in propagated block: %d > %d", txs, maxBlockTransactions)
+   }
+   if uncles := ann.Block.Uncles.Len(); uncles > maxBlockUncles {
+       return fmt.Errorf("too many uncles in propagated block: %d > %d", uncles, maxBlockUncles)
+   }
+   // Check the body against the header on the encoded form, so a block that is
+   // not what it claims to be is dropped without being materialized either.
+   header := ann.Block.Header
+   roots := hashBodyParts([]BlockBody{ann.Block.body()})
+   if hash := roots.UncleHashes[0]; hash != header.UncleHash {
+       log.Warn("Propagated block has invalid uncles", "have", hash, "exp", header.UncleHash)
        return nil // TODO(karalabe): return error eventually, but wait a few releases
    }
-   if hash := types.DeriveSha(ann.Block.Transactions(), trie.NewStackTrie(nil)); hash != ann.Block.TxHash() {
-       log.Warn("Propagated block has invalid body", "have", hash, "exp", ann.Block.TxHash())
+   if hash := roots.TransactionRoots[0]; hash != header.TxHash {
+       log.Warn("Propagated block has invalid body", "have", hash, "exp", header.TxHash)
        return nil // TODO(karalabe): return error eventually, but wait a few releases
    }
-   ann.Block.ReceivedAt = msg.Time()
-   ann.Block.ReceivedFrom = peer
+   // Bounded and self-consistent, so it is safe to materialize now.
+   txs, err := ann.Block.Transactions.Items()
+   if err != nil {
+       return fmt.Errorf("NewBlock: %w", err)
+   }
+   uncles, err := ann.Block.Uncles.Items()
+   if err != nil {
+       return fmt.Errorf("NewBlock: %w", err)
+   }
+   block := types.NewBlockWithHeader(header).WithBody(types.Body{Transactions: txs, Uncles: uncles})
+   block.ReceivedAt = time.Now()
+   block.ReceivedFrom = peer

    // Mark the peer as owning the block
-   peer.markBlock(ann.Block.Hash())
+   peer.markBlock(block.Hash())

-   return backend.Handle(peer, ann)
+   return backend.Handle(peer, &NewBlockPacket{Block: block, TD: ann.TD})
 }

← eth Protocol