verify

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Sep 29, 2026 License: Apache-2.0 Imports: 8 Imported by: 0

Documentation

Overview

Package verify is what a reader shares with every other reader: the outcome vocabulary it reports (codes.go), the verdict on one transaction against the reader's own headers (Check), and the check every carrier a host answers gets before a reader believes it (VerifyCarrier).

An application's own algorithm (which outputs it asks for, what its records say about each other, what it pins) stays with the application. What it hands this package is the carrier's parameters and its own expectations of the payload, through CarrierSpec.

Nothing here reaches the network except through the chain tracker it is handed, and a nil tracker is refused rather than replaced by a default.

Index

Constants

This section is empty.

Variables

View Source
var ErrNoTracker = errors.New("verify: no chain tracker; refusing to verify against a default")

ErrNoTracker is Check handed no chain tracker. The SDK would dial a public service in its place, so a reader that forgot its own header source would quietly trust someone else's.

Functions

func VerifyCarrier

func VerifyCarrier(ctx context.Context, items []Item, want [32]byte, what string, spec CarrierSpec, t chaintracker.ChainTracker) (c *carrier.Carrier, code Code, reason string, steps []Step)

VerifyCarrier is the check every carrier a reader is handed gets: the host answered one output, it decodes as a carrier, its commitment is the one asked for, it validates (the payload's rules, unmineable shape, lock derivation, field signature), it meets the caller's expectations, and its funding parent is proven in the reader's own header source.

The commitment is checked before anything the carrier says about itself: a host answering a different carrier than the one asked for is the case this exists for, and every later check would pass on a valid carrier that is simply not the one wanted. The expectations come after Validate and before the proof, so a carrier refused on its content costs the reader no header lookup.

what labels the carrier in every reason and names the step a pass records. On a pass c is the carrier, code is Verified and steps holds that one step. A refusal returns its code and reason with one step named after the code. Error is no verdict: the reader could not decide, and it records no step.

Types

type CarrierSpec

type CarrierSpec struct {
	Params   carrier.Params
	Classify carrier.Classify
	// IdentityOf returns the identity key bytes the payload names. It runs
	// just before Validate, which parses them only after the finality
	// checks, so it reads the bytes and does not judge them. An error
	// refuses the carrier as REFUSED-DECODE with the label and the error.
	IdentityOf func(payload []byte) ([]byte, error)
	// Expect runs after Validate and before Check: the caller's own rules
	// (for example a kind, then an identity). A non-empty Code refuses with
	// that code and reason, before any header-source call. The reason is
	// used as given, so a caller that wants the label in it writes it.
	Expect func(payload []byte) (Code, string)
}

CarrierSpec is what makes a carrier an application's: the carrier's own parameters and classifier, where the payload names its identity, and the application's expectations of the payload at the position it was asked for. Every field is required.

type Code

type Code string

Code is the one-word outcome of a verification. One uppercase token per outcome, so a caller or script can branch on it without parsing prose, and so two independent readers can be compared line for line.

const (
	// Verified is every step passed with a proof against the reader's own
	// headers.
	Verified Code = "VERIFIED"
	// VerifiedUnmined is every step passed but the token carries no proof
	// yet; its ancestry verified instead. OK counts it as a pass, so a caller
	// that does not accept unmined state checks for it itself. An
	// application's verification algorithm produces it; this package never
	// does.
	VerifiedUnmined Code = "VERIFIED-UNMINED"
	// RecordPending is a verified token whose carrier the host has not
	// served: the commitment is on the chain and the record is not here yet.
	// An application's verification algorithm produces it; this package
	// never does.
	RecordPending Code = "RECORD-PENDING"

	// Unsupported is a store whose entry uses a feature this build does not
	// implement. It is never the record's verdict: the record verified, and
	// one store is unreadable here. An application's verification algorithm
	// produces it; this package never does.
	Unsupported Code = "UNSUPPORTED"

	// NoToken is a host answer that holds nothing to verify.
	NoToken Code = "NO-TOKEN"
	// RefusedDecode is an answer that does not decode, or breaks its payload's rules.
	RefusedDecode Code = "REFUSED-DECODE"
	// RefusedKeyDerive is a lock that is not the key the identity derives.
	RefusedKeyDerive Code = "REFUSED-KEY-DERIVE"
	// RefusedSig is a field signature or an input script that does not verify.
	RefusedSig Code = "REFUSED-SIG"
	// RefusedKey is an unexpected identity; an application's verification algorithm produces it.
	RefusedKey Code = "REFUSED-KEY"
	// RefusedSeq is a sequence out of order; an application's verification algorithm produces it.
	RefusedSeq Code = "REFUSED-SEQ"
	// RefusedFork is more than one answer where the question allows one.
	RefusedFork Code = "REFUSED-FORK"
	// RefusedExpired is a record not valid now; an application's verification algorithm produces it.
	RefusedExpired Code = "REFUSED-EXPIRED"
	// RefusedBump is a transaction with no proof the reader's header source holds.
	RefusedBump Code = "REFUSED-BUMP"
	// RefusedCommit is an answer that does not match its commitment.
	RefusedCommit Code = "REFUSED-COMMIT"
	// RefusedWitness is a mismatched witness; an application's verification algorithm produces it.
	RefusedWitness Code = "REFUSED-WITNESS"
	// RefusedMineable is a carrier that could be mined.
	RefusedMineable Code = "REFUSED-MINEABLE"
	// RefusedRetired is a retired identity; an application's verification algorithm produces it.
	RefusedRetired Code = "REFUSED-RETIRED"
	// Error is not a verdict: the reader could not decide, typically because
	// the header source did not answer. A caller reports it apart from every
	// REFUSED-* code, so an outage is never read as a forgery.
	Error Code = "ERROR"
)

func (Code) OK

func (c Code) OK() bool

OK reports whether the code is a pass.

type Item

type Item struct {
	Beef        []byte
	OutputIndex uint32
}

Item is one output a host answered: its BEEF and the output index.

type Step

type Step struct {
	Name   string
	OK     bool
	Detail string
}

Step is one check and its verdict, for the verbose trace.

type Verdict

type Verdict int

Verdict classifies what spv.Verify reported. The SDK reports a proof the tracker rejected, a failing script and a missing ancestor all as errors, and a tracker that could not answer as an error too; only the last is a reason to stop without a verdict, so they are told apart here.

const (
	// Passed is a transaction proven against the tracker, through its own
	// proof or its ancestry.
	Passed Verdict = iota
	// ProofRefused is a proof, the transaction's or an ancestor's, that the
	// tracker does not hold.
	ProofRefused
	// ScriptRefused is an input that does not satisfy the output it spends.
	ScriptRefused
	// AncestryMissing is an unproven transaction whose BEEF lacks a parent it
	// spends from.
	AncestryMissing
	// Transport is no verdict: the tracker could not answer, or there was
	// none to ask.
	Transport
)

func Check

Check runs SPV over tx against the tracker and says which way it went. The error carries the SDK's detail for every verdict but Passed.

Jump to

Keyboard shortcuts

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