[AI assisted] feat(witness): OpenTimestamps witness profile (4.C)#21
Open
scourtney-godaddy wants to merge 2 commits into
Open
[AI assisted] feat(witness): OpenTimestamps witness profile (4.C)#21scourtney-godaddy wants to merge 2 commits into
scourtney-godaddy wants to merge 2 commits into
Conversation
Adds the second witness profile (after the production-side 4.A Hedera) so the witness-pluggable architecture is demonstrable in the LF reference. Bitcoin-anchored timestamps via the public OpenTimestamps calendar — no infrastructure cost, no operator credentials, runs on a laptop in the demo stack. Two new packages: internal/port/witness.go Defines port.Witness and port.WitnessAttestation. The contract is intentionally narrow: a checkpoint goes in, a backend-specific external proof comes out. Verifiers pick the matching profile to validate ExternalProof. internal/adapter/witness/opentimestamps/witness.go Concrete Witness against an OTS calendar (default https://btc.calendar.opentimestamps.org). Hashes the checkpoint, POSTs the digest, returns the calendar's binary OTS proof bytes in WitnessAttestation.ExternalProof. Includes Upgrade for the pending → finalized transition (404 returns input unchanged so callers can retry; non-404 errors propagate). Verification side intentionally not included: validating an OTS proof requires an SPV-aware Bitcoin verifier or the off-the-shelf ots CLI. A reference verifier would double the package size for marginal LF demonstration value; out-of-band verification is the documented path. The Profile() / ProfileID strings let downstream verifiers route to the right validation procedure. Tests cover the calendar HTTP contract (happy path, 5xx, empty response, context cancellation), the upgrade flow (happy, 404 returns input unchanged, 5xx errors propagate, empty pending rejected), and the configuration escape hatches (WithCalendarURL, WithHTTPClient, WithClock, default URL, trailing slash). The TL service does not yet consume Witness; binding witnesses into the checkpoint flow is a separate piece of operator wiring. This PR ships the contract and one concrete profile so deployments can compose them. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Default was set to btc.calendar.opentimestamps.org, which is not a real public calendar host (DNS does not resolve). The OTS project runs three public calendars: alice.btc.calendar.opentimestamps.org, bob.btc.calendar.opentimestamps.org, and finney.calendar.eternitywall.com. Default now points at alice; bob and finney are documented as operator-rotation alternatives, with the multi-calendar aggregation the OTS reference client does called out as a future amendment. Adds a build-tagged live test (go test -tags=live) that hits the real calendar and asserts a non-empty proof comes back. Verified: a live POST of a SHA-256 digest to https://alice.btc.calendar.opentimestamps.org/digest returns a 207-byte OTS proof with the expected magic bytes. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
BLUF. Implements ANS-4 witness profile 4.C against OpenTimestamps' Bitcoin-anchored calendars. A deployment running this witness publishes an OTS proof per TL checkpoint that any verifier can validate against a Bitcoin node, anchoring TL state in a system outside the TL operator's control.
What lands
internal/port/witness.godefines theWitnessinterface and theWitnessAttestationstruct that any backend returns. The interface stays narrow: a checkpoint goes in, a backend-specific proof comes out under a profile identifier the verifier uses to pick the right validation procedure. JSON-serializable so a TL audit endpoint can round-trip an attestation without losing fidelity.internal/adapter/witness/opentimestamps/witness.gois the concrete OpenTimestamps backend.Profile()returns"4.C-opentimestamps".Attest(ctx, checkpoint)SHA-256s the checkpoint, POSTs the digest tohttps://btc.calendar.opentimestamps.org/digest(overridable viaWithCalendarURL), and wraps the calendar's binary OTS proof in aWitnessAttestation.Upgrade(ctx, pending)POSTs a previously-returned pending proof back to the calendar to swap its calendar commitment for a finalized Bitcoin attestation; a 404 means "no Bitcoin block yet" and returns the input unchanged so a background refresh loop can retry.The split between
AttestandUpgradematches OpenTimestamps' own pattern: producers callAttestat checkpoint time and persist the pending proof; a background loop callsUpgradeon a schedule (typically hourly) until the proof finalizes, then replaces the persisted bytes with the upgraded form. Verifiers run the persisted bytes through the OpenTimestamps reference CLI or any SPV-aware verifier; the witness package itself does no verification.Tests
internal/adapter/witness/opentimestamps/witness_test.gocovers the happy path against anhttptest.Server, the empty-checkpoint guard, calendar 5xx, calendar empty body, context cancellation mid-fetch, the upgrade happy path, the 404 case where the calendar treats the input as still pending, upgrade 5xx, the empty-pending guard, the default calendar URL, the trailing-slash strip on base URLs, and a compile-time interface check that*Witnessstill satisfiesport.Witness.Operational notes
The default calendar is the public OpenTimestamps server. A production deployment should run its own OTS calendar instance and point
WithCalendarURLat it; the public calendar is fine for the demo stack and integration tests but should not be a dependency in a regulated path. Switching is a one-line change at construction time.Test plan
go build ./...cleango test ./internal/adapter/witness/...cleanhttps://btc.calendar.opentimestamps.org/digestreturns a non-empty OTS blobUpgradereturns the input unchanged the first ~10 minutes (no Bitcoin block yet) and returns finalized bytes once a block lands🤖 Generated with Claude Code