ETCEngine.VerifyUncles¶
| Source (upstream pre-purge) | Current | |
|---|---|---|
| File | consensus/ethash/consensus.go |
engine.go |
| Symbol | Ethash.VerifyUncles |
ETCEngine.VerifyUncles |
| Ref | dde2da0ef~1 |
etc/v1.17.3-full-node |
Verifies a block's ommers (bounded count, valid recent ancestry, not already included), delegating each uncle header to verifyUncleHeader. Revived from pre-purge ethash.VerifyUncles.
3-way merge — purge → getc ← upstream¶
upstreamcommon≈ adapted (origin inferred by similarity)fork-only
// VerifyUncles verifies that the given block's uncles conform to ETC consensus rules.
// This implementation uses ETC-specific difficulty calculation (with ECIP-1010).
func (e *ETCEngine) VerifyUncles(chain consensus.ChainReader, block *types.Block) error {
// Verify that there are at most 2 uncles included in this block
if len(block.Uncles()) > maxUncles {
return errTooManyUncles
}
if len(block.Uncles()) == 0 {
return nil
}
// Gather the set of past uncles and ancestors
uncles, ancestors := mapset.NewSet[common.Hash](), make(map[common.Hash]*types.Header)
number, parent := block.NumberU64()-1, block.ParentHash()
for i := 0; i < 7; i++ {
ancestorHeader := chain.GetHeader(parent, number)
if ancestorHeader == nil {
break
}
ancestors[parent] = ancestorHeader
// If the ancestor doesn't have any uncles, we don't have to iterate them
if ancestorHeader.UncleHash != types.EmptyUncleHash {
// Need to add those uncles to the banned list too
ancestor := chain.GetBlock(parent, number)
if ancestor == nil {
break
}
for _, uncle := range ancestor.Uncles() {
uncles.Add(uncle.Hash())
}
}
parent, number = ancestorHeader.ParentHash, number-1
}
ancestors[block.Hash()] = block.Header()
uncles.Add(block.Hash())
// Verify each of the uncles that it's recent, but not an ancestor
for _, uncle := range block.Uncles() {
// Make sure every uncle is rewarded only once
hash := uncle.Hash()
if uncles.Contains(hash) {
return errDuplicateUncle
}
uncles.Add(hash)
// Make sure the uncle has a valid ancestry
if ancestors[hash] != nil {
return errUncleIsAncestor
}
if ancestors[uncle.ParentHash] == nil || uncle.ParentHash == block.ParentHash() {
return errDanglingUncle
}
// Use ETC-specific header verification (with ECIP-1010 difficulty)
≈ if err := e.verifyUncleHeader(chain, uncle, ancestors[uncle.ParentHash]); err != nil {
return err
}
}
return nil
}
core-geth validation — +5 -8
| | | |---|---| | File | [`consensus.go`](https://github.com/etclabscore/core-geth/blob/v1.12.20/consensus/ethash/consensus.go) | | Symbol | `Ethash.VerifyUncles` | | Ref | `v1.12.20` |--- a/core-geth/consensus/ethash/consensus.go
+++ b/etc/consensus/etc/engine.go
@@ -1,10 +1,6 @@
-// VerifyUncles verifies that the given block's uncles conform to the consensus
-// rules of the stock Ethereum ethash engine.
-func (ethash *Ethash) VerifyUncles(chain consensus.ChainReader, block *types.Block) error {
- // If we're running a full engine faking, accept any input as valid
- if ethash.config.PowMode == ModeFullFake {
- return nil
- }
+// VerifyUncles verifies that the given block's uncles conform to ETC consensus rules.
+// This implementation uses ETC-specific difficulty calculation (with ECIP-1010).
+func (e *ETCEngine) VerifyUncles(chain consensus.ChainReader, block *types.Block) error {
// Verify that there are at most 2 uncles included in this block
if len(block.Uncles()) > maxUncles {
return errTooManyUncles
@@ -54,7 +50,8 @@
if ancestors[uncle.ParentHash] == nil || uncle.ParentHash == block.ParentHash() {
return errDanglingUncle
}
- if err := ethash.verifyHeader(chain, uncle, ancestors[uncle.ParentHash], true, true, time.Now().Unix()); err != nil {
+ // Use ETC-specific header verification (with ECIP-1010 difficulty)
+ if err := e.verifyUncleHeader(chain, uncle, ancestors[uncle.ParentHash]); err != nil {
return err
}
}