Documentation
¶
Overview ¶
Package verify is the reader's algorithm, docs/committed-record.md §10. Its refusal vocabulary is the library's (package verify of github.com/lightwebinc/bcommon) and is re-exported here under the names readers already use. The SPV verdict and the check every store carrier gets are the library's too; this package drives them with finger's carrier and expectations.
It takes what a host answered and everything the reader already knows (the name's resolved identity key, the pin, its own chain tracker) and returns one outcome. It never reaches the network itself except through the chain tracker it was handed, and it never touches the pin file: the caller acts on the outcome, which keeps the only irreversible local action, re-pinning, out of the code that decides.
Order matters and is the spec's: signatures and derivations are checked before the pin, so the reader never decides who should have signed and then looks for a matching signature.
Index ¶
- Constants
- Variables
- func Head(ref record.Ref) ([32]byte, error)
- type Code
- type Item
- type Options
- type Pin
- type Result
- type Step
- type StoreResult
- func ManifestOf(ctx context.Context, items []Item, identity *ec.PublicKey, ref record.Ref, ...) (*record.Manifest, *StoreResult)
- func MemberOf(ctx context.Context, items []Item, identity *ec.PublicKey, storeName string, ...) *StoreResult
- func SubRecord(ctx context.Context, items []Item, identity *ec.PublicKey, ref record.Ref, ...) *StoreResult
Constants ¶
const ( Verified = bcverify.Verified VerifiedUnmined = bcverify.VerifiedUnmined RecordPending = bcverify.RecordPending Unsupported = bcverify.Unsupported NoToken = bcverify.NoToken RefusedDecode = bcverify.RefusedDecode RefusedKeyDerive = bcverify.RefusedKeyDerive RefusedSig = bcverify.RefusedSig RefusedUnlocking = bcverify.RefusedUnlocking RefusedKey = bcverify.RefusedKey RefusedSeq = bcverify.RefusedSeq RefusedFork = bcverify.RefusedFork RefusedExpired = bcverify.RefusedExpired RefusedBump = bcverify.RefusedBump RefusedCommit = bcverify.RefusedCommit RefusedWitness = bcverify.RefusedWitness RefusedMineable = bcverify.RefusedMineable RefusedRetired = bcverify.RefusedRetired Error = bcverify.Error )
const DefaultSkew = 120 * time.Second
DefaultSkew is the clock allowance on the validity window.
Variables ¶
var ErrNoHead = store.ErrNoHead
ErrNoHead is a ref that commits to a store without naming a member of it. Not a fault: the publisher may intend the store to be found some other way, and a reader has nothing to ask a host for. It is store's own value.
var ErrUnsupported = store.ErrUnsupported
ErrUnsupported is a store whose entry carries a member this version does not define. The record is fine; this one store cannot be read here. It is store's own value, so errors.Is matches under either name.
Functions ¶
Types ¶
type Code ¶
The refusal vocabulary, the answer shape and the trace are the library's, shared by every reader. They are re-exported here so the reader's callers do not change with the move: the types are aliases and the codes the library's own constants, so a code compares equal under either name.
type Item ¶
The refusal vocabulary, the answer shape and the trace are the library's, shared by every reader. They are re-exported here so the reader's callers do not change with the move: the types are aliases and the codes the library's own constants, so a code compares equal under either name.
type Options ¶
type Options struct {
// Tracker answers root questions. Required: a nil tracker would make
// the SDK dial a public service, so it is refused before anything is
// parsed.
Tracker chaintracker.ChainTracker
// Identity is the key the name resolved to. Optional; when set, a record
// for a different identity is refused as REFUSED-KEY even on first
// contact, because the domain and the record then disagree about who
// this is.
Identity *ec.PublicKey
Pin Pin
// Now and Skew bound the validity window check.
Now time.Time
Skew time.Duration
}
Options is everything the reader knows before it looks at the answer.
type Pin ¶
type Pin struct {
// Present is false on first contact.
Present bool
Key [33]byte
// Seq is the highest sequence accepted so far, the anti-rollback anchor.
Seq uint64
// Retired means the address was retired: a pin that refuses.
Retired bool
}
Pin is what the known-keys file says about the address, if anything.
type Result ¶
type Result struct {
Code Code
Reason string
// Err is set only with Code == Error.
Err error
Token *token.Token
TokenTx *transaction.Transaction
TokenIndex uint32
Carrier *carrier.Carrier
Prev *carrier.Carrier
Record *record.Record
Identity *ec.PublicKey
Mined bool
Height uint32
FirstContact bool
// Rotated is set when a verified rotation moved the identity to a new
// key; the caller rewrites the pin.
Rotated bool
Retired bool
Steps []Step
ForkTxid []string
}
Result is the outcome with everything the caller prints or acts on.
type Step ¶
The refusal vocabulary, the answer shape and the trace are the library's, shared by every reader. They are re-exported here so the reader's callers do not change with the move: the types are aliases and the codes the library's own constants, so a code compares equal under either name.
type StoreResult ¶
type StoreResult struct {
Code Code
Reason string
Steps []Step
// Carrier and Record are set on a pass.
Carrier *carrier.Carrier
Record *record.Record
}
StoreResult is the outcome of reading one sub-store member.
func ManifestOf ¶
func ManifestOf(ctx context.Context, items []Item, identity *ec.PublicKey, ref record.Ref, opt Options) (*record.Manifest, *StoreResult)
ManifestOf verifies the head of a store of more than one member and reads its member list. The root the record commits to is recomputed over the members the manifest lists and must equal it: that is a stronger check than an inclusion path per member, because it proves the whole list, and it is why no path is carried. A path proves one member to someone who does not have the list, which is a different question (bcommon/commit still answers it).
func MemberOf ¶
func MemberOf(ctx context.Context, items []Item, identity *ec.PublicKey, storeName string, index int, mem record.Member, opt Options) *StoreResult
MemberOf verifies one member of a store whose manifest already verified. The manifest is bound to the record by the root, so the member's commitment coming from the manifest is as good as coming from the record.
func SubRecord ¶
func SubRecord(ctx context.Context, items []Item, identity *ec.PublicKey, ref record.Ref, opt Options) *StoreResult
SubRecord verifies one sub-store member against the ref that commits to it, spec section 10 step 9. It takes what the host answered to the carrier question, the identity the primary record was verified under, and the ref out of that verified record. The primary record is already trusted by the time this runs, so the ref's root is the anchor and the host is not: the host asserted only that it holds this carrier under this identity, and every claim about membership is checked here.
The checks, in order: exactly one carrier answered; it decodes and validates as a carrier (lock derivation, field signature, unmineable shape); its record is a sub-record under the same identity; its funding parent is proven in the reader's own header source; and its commitment is a member of the store. With Count 1 the root IS the leaf hash of the one member, so membership is one hash and no inclusion path is needed or accepted. A store with more than one member needs a path the record does not carry, and is refused rather than half-read.