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 errwithout 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})
}