Service integration · Technical · Raw markdown

Verifier and policy

This page is for services and developers who want to measure PCOCs themselves, or to understand what an admission gate measures. Verifying redoes a sample of the making, checks the PCOC's times against Bitcoin's public record, and writes a measurement record. It never says pass or fail. Conforming verifiers follow the same specification and pass the same conformance vectors, and the Rust, C, Go and Java SDKs are cross-checked against each other, so a PCOC is measured the same way by any conforming verifier.

Use the SDK in your language, then apply your policy to the record. Policy is your choice. groundinglab's own settings are in POLICY.md, a recommendation, not part of the specification; How we set groundinglab's admission policy gives the argument and the evidence.

SDK verify

Assumes: an SDK in your language (SDKs) and a PCOC to check (Integrate a producer).

Vectors. The single conformance pack is spec/conformance/pack. Its status is complete. The manifest SHA-256 is 91ded57e5c05b7cb4cd74d313a51d83d2373fa86dc625df41faed9586e9032af. The README names the vectors. The admission gate keeps its own test vectors (anchor window, sign-in origins, a three-leg mock object) in services/admission-gate/tests/vectors.

  1. The split. Section 13 produces the object, section 14 measures it, and section 15 is the admission service (SPEC §2). The verifier writes a measurement record and makes no judgement (sdk/README.md). Accept, refuse and revoke are one relying party's decisions, not pass/fail (services/admission-gate/README.md).
  2. What verify reads. Each index read is a single lookup; the verifier never scans across many heights (Rule A4, §14). The checkpoint measurement reads GET {index}/index/{beacon_height} (admission-gate deploy/gate.toml). Comparing a plant (the Bitcoin output that timestamps waypoints) uses root, txid, vout, block_hash, block_height, never tree_size (§14.3). anchored is recorded only when the inclusion height is in the window, the header is stored, and the plant matches (§14.3, §14.5).
  3. Index options, all opt-in. The hosted index is https://index.groundinglab.io. To run your own: pcoc-index (default bind 127.0.0.1:38081; GET /index, /index/{h}, /index/since), filled by Bari or by pcoc-index rebuild --source esplora / --source rpc from a pruned node, which checks header links (services/index/README.md). Anyone can skip the service and read Bitcoin directly (SPEC §14).
  4. Running it. Each SDK's pcoc verify takes a PCOC file (sdk/README.md), or call the SDK's verify function from your own code, as the SDK examples above do. How many checkpoint comparisons run at once doesn't change the record (Rule A4.3).
  5. Conformance. Compare record on each vector in the pack (SPEC §16.1; spec/conformance/pack/README.md).
  6. The record. One JSON object, with the keys in the order SPEC §14 lists (profile … analysis). No null; tokens are strings; RFC 8785 for verify_record_sha256; one trailing newline. An object of any kind other than v2.2-pcoc-object is recorded as unknown kind, with the kind text it carried (Rule A5). That is a measurement, not a failure; a gate refuses it with reason unknown_kind (Rule B9). The fast record (§15.3) omits checkpoints.legs.result, six_leg and six_leg_runs. Token glossary (§14.1–14.7):
    • shape: match or mismatch, with shape_item from a closed list of 14.
    • anchors: anchored only when in window, header stored and plant match; otherwise not anchored.
    • six_leg: six match/mismatch results; not defined under six legs.
    • N: checkpoints in stages a…b−1 (A4.7).
    • S: T(P_b) − T(I_{a−1}), in seconds (A4.8).
    • delta_h: height_P_b − height_I_a_minus_1, index-confirmed heights only (A4.8).
    • Shared tokens: not defined, not read, n/a, not fetched by design, unknown kind.
  7. Writing a policy. Part B, §15. Inputs §15.1, outputs and states §15.2: outcomes provisional, accept, refuse, revoke, held; states received, provisional, accepted, refused, revoked, held. held is a measurement not yet read, waiting for a retry, not a negative; how often a gate retries is its held_retry_seconds setting. A negative after any grant is revoke. Two-phase async §15.3. Every setting a policy chooses is a lever in §15.4, with its unit and allowed range. Version 2.3 gives no lever a default. §15.5 is how to measure a leg-rate floor. A policy sets the values.
  8. Example: gl-admit-v12, groundinglab's live policy for this specification. These numbers are one relying party's chosen settings, not part of the specification or the measurement: the record (beat 6) is the same whatever a policy sets. Leg-rate floor 1/10 (0.1 legs/s testing, one leg every 10 s on average over the making); at least 6 of the 16 waypoints W_1 … W_16 anchored, any 6; no tip-versus-last-beacon submission deadline; a held submission retried every 600 s; the deep check redoes 18 legs in 3 rounds of 6; no door-session verify cap; a key caught with a fake leg is ignored at this gate with no expiry. Why these values: How we set groundinglab's admission policy. Changing any number means a new id, and startup refuses a changed number under the same id (policy-bind.json). Another relying party may pick other values under its own policy id. GET /v1/policy shows the gate's (gl-admit-v12.toml; POLICY.md).
  9. What not to infer. Log entries are groundinglab's decisions; another party may decide differently. A verify record shows no cost figure; cost is not the verifier's concern. Catch rates and economic security aren't established (STATUS.md). Next: to present an accepted object to a site, see the sign-in wire (Sign-in wire).

Checked against pcoc main at 7b40353. Policy id and the verify command name checked against pcoc main at 797c1ac. Raw markdown.