Skip to content

TestVerifyUncleHeaderVerifiesSeal

NEW-ETC — no upstream or core-geth original.

File verifyseal_etc_test.go
Symbol TestVerifyUncleHeaderVerifiesSeal
Ref etc/v1.17.4-full-node

NEW-ETC regression guard for the seal check in verifyUncleHeader. Uses ethash.NewFakeFailer (fails the seal at one block number, no DAG) so it asserts purely that verifyUncleHeader routes through VerifySeal — the drift the mapping cross-check for verifyUncleHeader is meant to catch, now enforced by an automated test.

// TestVerifyUncleHeaderVerifiesSeal checks that verifyUncleHeader verifies the uncle's
// PoW seal. NewFakeFailer fails the seal at exactly one block number (no DAG), so the
// test asserts the routing through VerifySeal independently of the ethash algorithm.
func TestVerifyUncleHeaderVerifiesSeal(t *testing.T) {
    config := params.ClassicChainConfig

    // Pre-Homestead frontier parent; block 2 stays on the frontier difficulty rule.
    parent := &types.Header{
        Number:     big.NewInt(1),
        Time:       1000,
        Difficulty: big.NewInt(131072),
        GasLimit:   5000,
        UncleHash:  types.EmptyUncleHash,
    }
    uncle := &types.Header{
        Number:   big.NewInt(2),
        Time:     parent.Time + 13,
        GasLimit: parent.GasLimit,
    }
    // Difficulty must equal the engine's expectation so validation reaches the
    // seal check rather than short-circuiting on an invalid-difficulty error.
    uncle.Difficulty = CalcDifficultyETC(config, uncle.Time, parent)

    // verifyUncleHeader never dereferences the chain reader (CalcDifficulty keys off
    // the engine's own config), so nil is a valid argument here.

    // Seal verifier rigged to fail at the uncle's number: only surfaces if
    // verifyUncleHeader actually verifies the seal.
    failing := &ETCEngine{inner: ethash.NewFakeFailer(uncle.Number.Uint64()), config: config}
    if err := failing.verifyUncleHeader(nil, uncle, parent); err == nil {
        t.Fatal("verifyUncleHeader accepted an uncle with an invalid PoW seal; the seal is not being verified")
    }

    // Control: identical uncle, seal verifier that fails at a different number. It
    // must validate, proving the rejection above came from the seal check and not
    // from another field (difficulty, gas limit, timestamp, number, ...).
    passing := &ETCEngine{inner: ethash.NewFakeFailer(uncle.Number.Uint64() + 1000), config: config}
    if err := passing.verifyUncleHeader(nil, uncle, parent); err != nil {
        t.Fatalf("verifyUncleHeader rejected an otherwise-valid uncle: %v", err)
    }
}

← Consensus & Ethash