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 ¶
- func ComputeWinningPoStRandomness(bh *types.BlockHeader, prevBeacon *types.BeaconEntry) ([32]byte, error)
- func VerifyBlockWinningPoSt(ctx context.Context, bh *types.BlockHeader, prevBeacon *types.BeaconEntry, ...) error
- func VerifyBlockWinningPoStWithChallengeRandomness(ctx context.Context, bh *types.BlockHeader, sv StateView, ...) error
- type MinerSectorRef
- type MinerSectorSetView
- type Result
- type StateView
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:
- Derive WinningPoSt randomness (see ComputeWinningPoStRandomness).
- Fetch the miner's active-sector set at the parent tipset.
- Derive the challenged sector index (proofs.GenerateWinningPoStSectorChallenge).
- Extract the challenged sector's CommR + WinningPoSt proof type.
- 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).