fullvalidate

package
v1.9.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 23, 2026 License: Apache-2.0, MIT Imports: 12 Imported by: 0

Documentation

Overview

Package fullvalidate implements the pure-Go, full-node block-validation pipeline for Lantern's Full node tier (issue #90, part of the #87 full-node epic).

What this is

A Lantern Full node follows and serves the whole chain. On top of the Phase-1 structural/beacon checks in chain/header.ValidateHeader, a Full node also has the chain STATE resident (via the F3-anchored, CID-verified cache), so it can look up a block's worker key and miner power and run the remaining consensus checks that a light client cannot. This package is that second pass.

It lifts the Lotus filcns block-validation check set MINUS the two filecoin-ffi (Rust) calls:

  • VerifyWinningPoSt (Groth16/BLS12-381 SNARK) -> deferred to proofs/winningpost (#88)
  • TipSetState (FVM message re-execution) -> deferred to Stage C wazero (#89)

Everything this package DOES run is pure-Go BLS / arithmetic that Lantern already ships (crypto/sigs, chain/beacon, chain/types.ElectionProof):

  • block signature over the worker key (crypto/sigs.CheckBlockSignature)
  • election-proof VRF (VerifyVRF over drand-derived base)
  • ticket VRF (VerifyVRF)
  • win-count vs miner/total quality-adjusted power (ElectionProof.ComputeWinCount)
  • claimed-winner sanity (WinCount >= 1)

Trust model

With this package a Full node independently re-verifies the VRF/signature/ win-count consensus of every ingested block. It still TRUSTS F3 finality for the WinningPoSt SNARK and the FVM state transition it does not natively run. That boot/finality trust is a multi-source, BLS-verified, 2/3-power quorum - strictly stronger than a single-source snapshot import. #88 and #89 close the two remaining ffi gaps to make the node fully trustless.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ComputeWinningPoStRandomness

func ComputeWinningPoStRandomness(
	bh *types.BlockHeader,
	prevBeacon *types.BeaconEntry,
) ([32]byte, error)

ComputeWinningPoStRandomness derives the 32-byte challenge randomness that filecoin-ffi's VerifyWinningPoSt (and now proofs.VerifyWinningPoStByType) takes as input. Matches Lotus filcns.

Formula:

rbase = bh.BeaconEntries[last] if any, else prevBeacon
rand  = DrawRandomnessFromBase(
          rbase.Data,
          DomainSeparationTag_WinningPoStChallengeSeed,
          bh.Height,
          CBOR(bh.Miner),
        )

Exposed as a top-level helper so callers writing test vectors can drive the verifier without reconstructing the whole block-validation path.

func VerifyBlockWinningPoSt

func VerifyBlockWinningPoSt(
	ctx context.Context,
	bh *types.BlockHeader,
	prevBeacon *types.BeaconEntry,
	sv StateView,
	msv MinerSectorSetView,
	vkCacheDir string,
) error

VerifyBlockWinningPoSt runs pure-Go WinningPoSt SNARK verification against a block's proof, deriving the challenge randomness from the parent-epoch beacon per Lotus filcns. Returns nil on success.

Steps:

  1. Derive WinningPoSt randomness (see ComputeWinningPoStRandomness).
  2. Fetch the miner's active-sector set at the parent tipset.
  3. Derive the challenged sector index (proofs.GenerateWinningPoStSectorChallenge).
  4. Extract the challenged sector's CommR + WinningPoSt proof type.
  5. Load the verifying key from vkCacheDir and run proofs.VerifyWinningPoStByType (Groth16 pairing check over BLS12-381).

The block header's WinPoStProof slice is expected to carry exactly one PoSt proof for a WinningPoSt (single-partition, unlike WindowPoSt).

func VerifyBlockWinningPoStWithChallengeRandomness

func VerifyBlockWinningPoStWithChallengeRandomness(
	ctx context.Context,
	bh *types.BlockHeader,
	sv StateView,
	msv MinerSectorSetView,
	rand [32]byte,
	vkCacheDir string,
) error

VerifyBlockWinningPoStWithChallengeRandomness is the lower half of VerifyBlockWinningPoSt: given an already-drawn 32-byte challenge randomness, it runs steps (2)-(5). Tests use it to drive the verifier with the hardcoded randomness of a shipped proof fixture, without reconstructing a synthetic block-header/beacon whose DrawRandomnessFromBase would have to reproduce that exact 32-byte value.

Types

type MinerSectorRef

type MinerSectorRef struct {
	SectorNumber abi.SectorNumber
	SealedCID    cid.Cid
	SealProof    abi.RegisteredSealProof
}

MinerSectorRef is the minimum sector metadata WinningPoSt verification needs from parent-tipset state: the sector number, its sealed-sector CID (whose multihash digest is the CommR), and its seal proof type (which implies the WinningPoSt proof type and sector size).

type MinerSectorSetView

type MinerSectorSetView interface {
	MinerActiveSectors(ctx context.Context, miner address.Address) ([]MinerSectorRef, error)
}

MinerSectorSetView is the extra read surface WinningPoSt verify needs on top of StateView. A Full node exposes it separately so that the basic consensus checks in ValidateBlockConsensus don't require it (a deployment can F3-trust WinningPoSt while still running signature/VRF/win-count checks pure-Go).

The returned slice MUST be the miner's ACTIVE, non-faulty sectors at the parent tipset, sorted by SectorNumber ascending. This mirrors Lotus's GetSectorsForWinningPoSt which iterates the proving-sectors bitfield in bit-index order (i.e., sector-number order).

type Result

type Result struct {
	SignatureOK         bool
	ElectionVRFOK       bool
	TicketVRFOK         bool
	EligibilityOK       bool
	WinCountOK          bool
	WinningPoStVerified bool // #88: pure-Go SNARK verify (not yet)
	StateReExecuted     bool // #89: pure-Go FVM (not yet)
}

Result reports which checks ran. WinningPoStVerified / StateReExecuted stay false until #88 / #89 land; a caller can see exactly how much was trustlessly verified versus F3-trusted.

func ValidateBlockConsensus

func ValidateBlockConsensus(
	ctx context.Context,
	bh *types.BlockHeader,
	prevBeacon *types.BeaconEntry,
	sv StateView,
) (Result, error)

ValidateBlockConsensus runs the pure-Go consensus checks a Full node can do with resident state. It assumes chain/header.ValidateHeader already passed (structural + beacon + parent linkage). `prevBeacon` is the latest beacon entry from the parent epoch, used when the block carries no entries of its own. `sv` reads the PARENT state.

It does NOT run WinningPoSt SNARK verify or FVM re-execution; those remain F3-trusted until #88/#89.

type StateView

type StateView interface {
	// WorkerKey resolves miner -> its current worker's pubkey address
	// (BLS/secp), i.e. StateMinerInfo(miner).Worker then StateAccountKey.
	WorkerKey(ctx context.Context, miner address.Address) (address.Address, error)

	// MinerQAPower returns (thisMinerQAPower, networkTotalQAPower) so the
	// win-count can be recomputed. Matches StateMinerPower semantics.
	MinerQAPower(ctx context.Context, miner address.Address) (minerPow, totalPow abi.StoragePower, err error)
}

StateView is the read surface a Full node exposes over its resident, F3-anchored, CID-verified state. It is deliberately small: the pipeline only needs the worker key and the power split to validate a block's consensus.

Both methods take the block's Miner address and are resolved against the PARENT tipset's state (the state the block was produced on top of).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL