Documentation
¶
Overview ¶
Package client is the native Go HTTP client for a Debuglet dispatcher. It runs on the researcher's machine, talks to the dispatcher's existing HTTP API and supports TEST-funded submissions only. It never imports server internals; it shares the dispatcher's HTTP types through pkg/wire.
The guest-side WASI SDK is the separate package pkg/debuglet.
Index ¶
- Constants
- Variables
- func IsEvidence(prefix []byte) bool
- func IsTransportError(err error) bool
- func PacketDigest(items []EvidencePacket) string
- func WriteEvidence(w io.Writer, ev Evidence) error
- type APICredential
- type Account
- type Allowance
- type AttributionCandidate
- type AttributionCandidates
- type AttributionKey
- type AttributionKeys
- type AttributionSchedule
- type CancellationDocument
- type CaptureError
- type CapturedPacket
- type Client
- func (c *Client) Allowance(ctx context.Context) (Allowance, error)
- func (c *Client) AttributionCandidates(ctx context.Context, ip string, at time.Time) (AttributionCandidates, error)
- func (c *Client) AttributionKeys(ctx context.Context, executorID, chainID string, fromEpoch, toEpoch int64) (AttributionKeys, error)
- func (c *Client) Cancel(ctx context.Context, id, executorID string) error
- func (c *Client) CancelDeviceLogin(ctx context.Context, login DeviceLogin) error
- func (c *Client) Cancellation(ctx context.Context, id string) (CancellationDocument, error)
- func (c *Client) Connection(ctx context.Context) (ConnectionInfo, error)
- func (c *Client) CreateAccount(ctx context.Context, name string) (Account, error)
- func (c *Client) CredentialStatus(ctx context.Context) (CredentialStatus, error)
- func (c *Client) DeleteProfile(ctx context.Context, id string) error
- func (c *Client) DiscoverExecutors(ctx context.Context, filter ExecutorFilter) ([]Node, error)
- func (c *Client) ExecutorEarnings(ctx context.Context, executorID string) (ExecutorEarnings, error)
- func (c *Client) Export(ctx context.Context, id string) (Result, error)
- func (c *Client) Login(ctx context.Context, accountKey string) (Session, error)
- func (c *Client) Logout(ctx context.Context) error
- func (c *Client) Logs(ctx context.Context, id string, options LogOptions) (LogPage, error)
- func (c *Client) Measurement(ctx context.Context, id string) (Measurement, error)
- func (c *Client) MeasurementRuns(ctx context.Context, id string, limit, offset int64) (Measurement, error)
- func (c *Client) MeasurementTemplates(ctx context.Context) ([]MeasurementTemplate, error)
- func (c *Client) Measurements(ctx context.Context, opts MeasurementOptions) (MeasurementPage, error)
- func (c *Client) Nodes(ctx context.Context) ([]Node, error)
- func (c *Client) Orders(ctx context.Context, page OrdersPage) (OrderHistory, error)
- func (c *Client) PollDeviceLogin(ctx context.Context, login DeviceLogin) (DeviceLoginPoll, error)
- func (c *Client) Probes(ctx context.Context, statuses ...string) ([]Node, error)
- func (c *Client) Profile(ctx context.Context, id string) (Profile, error)
- func (c *Client) Profiles(ctx context.Context) ([]ProfileSummary, error)
- func (c *Client) Quote(ctx context.Context, batch *PreparedBatch) (Quote, error)
- func (c *Client) Recover(ctx context.Context, recoveryCode string) (Account, error)
- func (c *Client) Recovery(ctx context.Context, id string) (RecoveryDocument, error)
- func (c *Client) RendezvousTEST(ctx context.Context, server, peer Request, opts RendezvousOptions) (result RendezvousResult, failure error)
- func (c *Client) RetryTEST(ctx context.Context, parentID, requestID string, batch *PreparedBatch) (Submission, error)
- func (c *Client) RunDetail(ctx context.Context, id string) (RunDetail, error)
- func (c *Client) SaveProfile(ctx context.Context, id string, config ProfileConfig) (Profile, error)
- func (c *Client) SelectExecutor(ctx context.Context, id string, filter ExecutorFilter) (Node, error)
- func (c *Client) StartDeviceLogin(ctx context.Context, label string, scopes []string) (DeviceLogin, error)
- func (c *Client) Status(ctx context.Context, id string) (State, error)
- func (c *Client) SubmitTEST(ctx context.Context, batch *PreparedBatch) (Submission, error)
- func (c *Client) Verify(ctx context.Context, packets []CapturedPacket, opts VerifyOptions) (VerifyReport, error)
- func (c *Client) Version(ctx context.Context) (ServerVersion, error)
- func (c *Client) Whoami(ctx context.Context) (User, error)
- func (c *Client) WithCredential(token string) (*Client, error)
- type ConnectionInfo
- type ControlBinding
- type CredentialStatus
- type DeviceLogin
- type DeviceLoginPoll
- type Economics
- type Evidence
- type EvidenceCandidate
- type EvidenceChain
- type EvidenceDispatcher
- type EvidenceGroup
- type EvidenceKey
- type EvidenceLookup
- type EvidenceMismatchError
- type EvidencePacket
- type EvidencePackets
- type EvidenceReceipt
- type EvidenceSchedule
- type EvidenceTool
- type ExecutorEarnings
- type ExecutorFilter
- type HTTPError
- type IncompleteOutputError
- type LogEntry
- type LogOptions
- type LogPage
- type Measurement
- type MeasurementOptions
- type MeasurementPage
- type MeasurementTemplate
- type Node
- type Options
- type OrderHistory
- type OrdersPage
- type OutputStatus
- type Policy
- type PreparedBatch
- type Profile
- type ProfileConfig
- type ProfileSummary
- type Quote
- type RateLimitedError
- type RecoveryDocument
- type RecoveryObservation
- type RecoveryObserver
- type RendezvousOptions
- type RendezvousResult
- type RendezvousRun
- type Request
- type Result
- type RetainedRun
- type RetryLink
- type RunDetail
- type ServerVersion
- type Session
- type State
- type Submission
- type SubmissionError
- type User
- type Verdict
- type VerifyCounts
- type VerifyGroup
- type VerifyMethod
- type VerifyOptions
- type VerifyReport
- type VerifySplit
Constants ¶
const ( TagSpecVersionLegacy = wire.TagSpecVersionLegacy TagSpecVersionV1 = wire.TagSpecVersionV1 )
Tag specification versions of an AttributionSchedule: a legacy chain is unsupported under tag spec v1.
const ( // MaxCaptureBytes bounds a capture read by ReadCapture. MaxCaptureBytes = 64 << 20 // MaxCapturePackets bounds the packets ReadCapture returns. MaxCapturePackets = 1_000_000 )
Capture limits (docs/verification.md#limits). A larger capture is rejected, never truncated, so a verdict always covers the whole capture it names.
const ( // CodeInvalidRequest is a malformed or incomplete request. CodeInvalidRequest = "invalid_request" // CodeInvalidPolicy is a policy that cannot be priced or scheduled. CodeInvalidPolicy = "invalid_policy" // CodeUnknownExecutor names an executor that is not registered. CodeUnknownExecutor = "unknown_executor" // CodeIntentMismatch is a submission whose debuglets differ from the ones // the payment intent was created for. CodeIntentMismatch = "intent_mismatch" // CodePaymentIncomplete is a submission for a transaction that is not paid. CodePaymentIncomplete = "payment_incomplete" // CodeUnsupportedPaymentMethod is a payment method the API does not admit. CodeUnsupportedPaymentMethod = "unsupported_payment_method" // CodePaymentsDisabled is a chain payment method while blockchain payments // are disabled. CodePaymentsDisabled = "payments_disabled" // CodeUnsupportedAPIVersion is APIVersion being unavailable on that server. CodeUnsupportedAPIVersion = "unsupported_api_version" // It is the failure a client answers by logging in again. CodeUnauthorized = "unauthorized" // CodeForbidden is an authenticated account that may not perform the // operation. Logging in again does not help; another account is needed. CodeForbidden = "forbidden" // CodeNotFound is a debuglet, user or executor that does not exist. CodeNotFound = "not_found" // CodeIdentityConflict refuses an unsafe sign-in method change. CodeIdentityConflict = "identity_conflict" // CodeCapacityExhausted is a batch the scheduler cannot admit. CodeCapacityExhausted = "capacity_exhausted" // CodeAccountQuota is a request exceeding the account's configured // run, reserved concurrency or queued-byte allowance. CodeAccountQuota = "account_quota_exceeded" // CodePayloadDeleted means the requested payload was deleted; the run's // identity and original outcome are still retained. CodePayloadDeleted = "payload_deleted" // CodePayloadNotDeletable means completed output or confirmed executor // retirement is missing, so the payload must remain retained. CodePayloadNotDeletable = "payload_not_deletable" // CodeCancelRefused is a cancellation the dispatcher did not accept. CodeCancelRefused = "cancel_refused" // CodeMethodNotAllowed is a method the route does not serve. CodeMethodNotAllowed = "method_not_allowed" // CodeUnsupportedMediaType is a body representation the route does not read. CodeUnsupportedMediaType = "unsupported_media_type" // CodePayloadTooLarge is a body beyond the accepted size. CodePayloadTooLarge = "payload_too_large" // CodeInternal is a failure inside the dispatcher, with no detail exposed. CodeInternal = "internal_error" CodeUnavailable = "service_unavailable" // CodeRateLimited is a client address over the rate limit of a public // route; retry later. CodeRateLimited = "rate_limited" // CodeAllowanceExceeded is a TEST intent whose price the account's // remaining usage allowance does not cover. CodeAllowanceExceeded = "allowance_exceeded" // CodeConflict is a request whose idempotency key already names a // different request. CodeConflict = "conflict" // CodeAllowanceOutOfRange is an account whose allowance history cannot be // represented in 64-bit integers; an operator has to reconcile it. CodeAllowanceOutOfRange = "allowance_out_of_range" )
Documented failure codes of the dispatcher's HTTP API. They are the stable part of an error: a client selects behaviour by comparing HTTPError.Code against these values instead of matching on Message. A dispatcher may add a code within a contract major version, so treat an unknown code as a plain failure of the status it arrived with.
const ( // EvidenceFormat names the bundle format. EvidenceFormat = "debuglet-verification-evidence" // EvidenceFormatVersion is the bundle format version this client writes // and reads. EvidenceFormatVersion = 1 // MaxEvidenceBytes bounds a bundle read by ReadEvidence. MaxEvidenceBytes = 256 << 20 )
const ( ReasonTagMismatch = "tag_mismatch" // invalid: no packet of the group matches a candidate run ReasonNoRun = "no_run" // invalid: no run was active from the address ReasonNotDisclosed = "not_disclosed" // pending: a needed key is not disclosed yet ReasonNotRetained = "not_retained" // missing: the time is before the retained history ReasonKeysMissing = "keys_missing" // missing: the history lacks a key that should be disclosed ReasonIPv6 = tagspec.UnsupportedIPv6 ReasonNotIPv4 = tagspec.UnsupportedNotIPv4 ReasonTooShort = tagspec.UnsupportedTooShort ReasonMalformed = tagspec.UnsupportedMalformed ReasonFragment = tagspec.UnsupportedFragment ReasonLinkType = "link_type" // no IP packet could be extracted from the frame ReasonTagSpec = "tag_spec" // a candidate tags with another or the pre-v1 tag spec ReasonDisclosureDelay = "disclosure_delay" // a candidate reports a disclosure delay below 2 epochs ReasonSchedule = "schedule" // a candidate's schedule is unusable ReasonBadKey = "bad_key" // a served key does not hash to the chain anchor ReasonNoSigningKey = "no_signing_key" // captured in epoch 0 or after the chain ran out ReasonKeyPublic = "key_public" // every candidate key may have been public at capture time ReasonAmbiguous = "ambiguous" // more than one run reproduces every tag ReasonUnmatched = "unmatched" // no candidate reproduces these packets, but others of their group match ReasonTooManyCandidates = "too_many_candidates" // the lookup named more than 32 runs ReasonWorkCap = "work_cap" // over a verification work cap )
Machine reasons of a group verdict.
const ( // MaxVerifyTagComputations bounds the tag computations of one Verify // (packets × candidates × epochs). Groups beyond it are unsupported. MaxVerifyTagComputations = 1_000_000 // DefaultClockTolerance is the default bound on how far the capture // clock may lag true time. DefaultClockTolerance = time.Second )
Verification limits (docs/verification.md#limits).
const ( DefaultVerifyRequestRate = 10.0 // requests per second DefaultVerifyRequestBurst = 40 )
The dispatcher's documented per-client rate limit of the attribution routes (docs/verification.md#http-api), which Verify paces itself to.
const ( // APIVersion is the minimum dispatcher HTTP contract version required by // this SDK's operations, as major.minor. It is announced on every request // so a server implementing an incompatible contract rejects the request // explicitly instead of answering a shape the client cannot read. A server // written before the contract was versioned ignores the header. APIVersion = "1.3" )
const ServerEndpoint = "{server_endpoint}"
ServerEndpoint is replaced only when it is a complete client argument.
const StateExited = "RunStateExited"
StateExited is the terminal state string reported by the dispatcher. An exited debuglet with an empty Error succeeded; a nonempty Error is a workload failure.
Variables ¶
var ErrEvidenceDigest = errors.New("client: evidence does not check out: the packets do not match the recorded digest")
ErrEvidenceDigest reports packets that do not match the bundle's digest.
var ErrNoAttributionHistory = errors.New("client: verify: the dispatcher does not offer the attribution history (GET /attribution/candidates, API 1.11)")
ErrNoAttributionHistory reports a dispatcher without the public attribution routes (API 1.11): it cannot answer dated lookups.
var ErrNoMatchingExecutor = errors.New("no ready executor matches; check dbl nodes and the requested capability filters")
ErrNoMatchingExecutor reports that no ready executor satisfies a selection.
Functions ¶
func IsEvidence ¶ added in v0.3.0
IsEvidence reports whether data starts like an evidence bundle rather than a capture: a JSON object.
func IsTransportError ¶
IsTransportError reports whether err is a transport failure of the client: a request that was started could not be sent, or no complete response was read, for example after a connection reset or the request deadline. The server may or may not have processed such a request; the predicate does not say whether it reached the server. An *HTTPError, a protocol error, a local validation failure and a context that was already done before the request was started are not transport failures.
func PacketDigest ¶ added in v0.3.0
func PacketDigest(items []EvidencePacket) string
PacketDigest returns the digest of an evidence packet list.
Types ¶
type APICredential ¶ added in v0.3.0
type APICredential struct {
Token string `json:"token"`
CredentialID string `json:"credential_id"`
Audience string `json:"audience"`
Scopes []string `json:"scopes"`
ExpiresAt int64 `json:"expires_at"`
ID string `json:"id"`
Name string `json:"name"`
Role string `json:"role"`
}
APICredential is returned once when a browser has approved a device login. Token is usable only at Audience; it belongs in the client's secure store.
type Account ¶
type Account struct {
ID string `json:"id"`
Name string `json:"name"`
Role string `json:"role"`
AccountKey string `json:"account_key"`
RecoveryCode string `json:"recovery_code"`
}
Account is one account together with the credentials an issuing operation returned for it. AccountKey and RecoveryCode are shown by the dispatcher exactly once, at the operation that minted them, and cannot be read back. Treat both as secrets: store them with owner-only permissions and keep them out of logs, command output and receipts.
type AttributionCandidate ¶ added in v0.3.0
type AttributionCandidate = wire.AttributionCandidate
type AttributionCandidates ¶ added in v0.3.0
type AttributionCandidates = wire.AttributionCandidates
type AttributionKey ¶ added in v0.3.0
type AttributionKey = wire.AttributionKey
type AttributionKeys ¶ added in v0.3.0
type AttributionKeys = wire.AttributionKeys
type AttributionSchedule ¶ added in v0.3.0
type AttributionSchedule = wire.AttributionSchedule
type CancellationDocument ¶ added in v0.3.0
type CancellationDocument = wire.Cancellation
type CaptureError ¶ added in v0.3.0
type CaptureError struct {
// Offset is the byte offset of the offending record, -1 when none.
Offset int64
Msg string
}
CaptureError reports a capture ReadCapture cannot read in full: not a pcap or pcapng file, a malformed or truncated record, or a capture over a limit.
func (*CaptureError) Error ¶ added in v0.3.0
func (e *CaptureError) Error() string
type CapturedPacket ¶ added in v0.3.0
type CapturedPacket struct {
// Data is the IP packet, starting at the IPv4 or IPv6 header, without
// the link-layer header. An IPv4 packet is cut to its Total Length, so
// link-layer padding and trailers are not part of it; a packet the
// capture recorded only partly (snap length) is kept as recorded. Data
// is empty for a frame of a link type ReadCapture does not know.
Data []byte
// CapturedAt is the capture's timestamp of the frame: the capture host's
// clock, which offline verification has to trust.
CapturedAt time.Time
// LinkType is the capture's link-layer header type of the frame.
LinkType uint16
}
CapturedPacket is one frame of a capture.
func ReadCapture ¶ added in v0.3.0
func ReadCapture(r io.Reader) ([]CapturedPacket, error)
ReadCapture reads a pcap (microsecond or nanosecond) or pcapng capture and returns its IP packets in capture order. It understands Ethernet (with VLAN tags), raw IP, Linux cooked (SLL and SLL2) and BSD loopback link types; non-IP frames of those (ARP, LLDP, …) are skipped, and frames of any other link type are returned with empty Data so a verifier can report them unsupported. A capture larger than MaxCaptureBytes or holding more than MaxCapturePackets frames, a record whose length is malformed and a capture that ends inside a record are rejected with a *CaptureError: nothing is silently dropped.
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client talks to one dispatcher endpoint. Create it with New.
func New ¶
New validates endpoint and options and returns a Client. The endpoint is an explicit base URL, optionally with a path prefix that is preserved on every route; plaintext HTTP is accepted only for literal loopback IPs.
func (*Client) Allowance ¶ added in v0.3.0
Allowance returns the authenticated account's usage allowance in TEST units. A dispatcher that does not offer allowances answers 404 with not_found; User.Economics.Allowances tells beforehand.
func (*Client) AttributionCandidates ¶ added in v0.3.0
func (c *Client) AttributionCandidates(ctx context.Context, ip string, at time.Time) (AttributionCandidates, error)
AttributionCandidates lists the runs that were active from ip within one epoch of at, with the schedule of each run's chain. It needs no credential and names runs and executors only, never accounts. An empty answer for a time before RetainedFrom is no evidence either way. This optional API 1.11 route is absent on older dispatchers, which answer 404.
func (*Client) AttributionKeys ¶ added in v0.3.0
func (c *Client) AttributionKeys(ctx context.Context, executorID, chainID string, fromEpoch, toEpoch int64) (AttributionKeys, error)
AttributionKeys returns one page of the disclosed keys of a chain, from fromEpoch towards toEpoch, spanning at most 1024 epochs; NextEpoch names the fromEpoch of the next page while keys beyond this one exist. A toEpoch of zero sets no bound. Undisclosed epochs are absent, and the caller checks every key against the chain's K0 itself. It needs no credential. This optional API 1.11 route is absent on older dispatchers, which answer 404.
func (*Client) Cancel ¶
Cancel asks the dispatcher to abort a debuglet on the given executor. A nil error is an acknowledgement, not proof that execution stopped.
func (*Client) CancelDeviceLogin ¶ added in v0.3.0
func (c *Client) CancelDeviceLogin(ctx context.Context, login DeviceLogin) error
func (*Client) Cancellation ¶ added in v0.3.0
Cancellation inspects a recorded request without retrying it. This optional API 1.9 route is absent on older dispatchers; Cancel remains compatible.
func (*Client) Connection ¶
func (c *Client) Connection(ctx context.Context) (ConnectionInfo, error)
Connection reads optional local-executor connection metadata. Older servers may return an HTTPError with status 404; their ordinary HTTP API remains usable.
func (*Client) CreateAccount ¶
CreateAccount registers an account and returns its first credentials. They are returned exactly once: the dispatcher stores only their digests. The caller is responsible for storing them where only its user can read them.
func (*Client) CredentialStatus ¶ added in v0.3.0
func (c *Client) CredentialStatus(ctx context.Context) (CredentialStatus, error)
func (*Client) DeleteProfile ¶ added in v0.3.0
func (*Client) DiscoverExecutors ¶ added in v0.3.0
DiscoverExecutors fetches a fresh dispatcher snapshot and returns only ready matches. The dispatcher excludes dead bindings and expires capability reports. Discovery does not hold a reservation; normal submission remains authoritative.
func (*Client) ExecutorEarnings ¶ added in v0.3.0
ExecutorEarnings returns what an executor the authenticated account owns has earned and the outbound chain transfers that name it. Another account's executor answers 404 with not_found.
func (*Client) Export ¶ added in v0.3.0
Export reads one result snapshot without waiting for execution or output to finish. An unknown outcome or incomplete output remains a successful export.
func (*Client) Login ¶
Login exchanges an account key for a session. An empty account key asks a dispatcher that serves the local development profile for a credential for its own local account; every other dispatcher refuses it. The returned Session.Token is what Options.Credential takes.
func (*Client) Logout ¶
Logout revokes the session this client presents. The token is refused from then on, before its own expiry. A client without a credential logs nothing out and reports the dispatcher's authentication failure.
func (*Client) Measurement ¶ added in v0.3.0
Measurement returns the first page of a measurement's children.
func (*Client) MeasurementRuns ¶ added in v0.3.0
func (c *Client) MeasurementRuns(ctx context.Context, id string, limit, offset int64) (Measurement, error)
MeasurementRuns pages bounded references; use RunDetail for a child's config.
func (*Client) MeasurementTemplates ¶ added in v0.3.0
func (c *Client) MeasurementTemplates(ctx context.Context) ([]MeasurementTemplate, error)
func (*Client) Measurements ¶ added in v0.3.0
func (c *Client) Measurements(ctx context.Context, opts MeasurementOptions) (MeasurementPage, error)
func (*Client) Orders ¶ added in v0.3.0
func (c *Client) Orders(ctx context.Context, page OrdersPage) (OrderHistory, error)
Orders returns one page of the authenticated account's payment intents, newest first, with their orders and the runs they admitted.
func (*Client) PollDeviceLogin ¶ added in v0.3.0
func (c *Client) PollDeviceLogin(ctx context.Context, login DeviceLogin) (DeviceLoginPoll, error)
PollDeviceLogin must be called no faster than the last returned Interval. slow_down increases that interval; denied/expired/consumed end the login.
func (*Client) Probes ¶ added in v0.3.0
Probes lists the executors whose status is one of statuses (wire.ProbeConnected, ProbeDisconnected, ProbeAbandoned or ProbeNeverConnected), like RIPE Atlas's probe listing; no status lists the connected ones, as Nodes does. Only connected executors can run work. It requires API 1.17: an older dispatcher refuses the request instead of ignoring the filter.
func (*Client) Profiles ¶ added in v0.3.0
func (c *Client) Profiles(ctx context.Context) ([]ProfileSummary, error)
func (*Client) Quote ¶ added in v0.3.0
Quote asks the dispatcher to price batch with the same TEST request body SubmitTEST sends, without creating an intent or reserving anything. A batch the dispatcher would refuse is answered with its problems in the quote's errors and an empty total. A quote is not binding: the dispatcher prices the batch again when SubmitTEST creates its intent, and SubmitTEST does not return that price. A caller that sends the intent itself over HTTP can read the dispatcher's price from the quote field of the intent response.
func (*Client) Recover ¶
Recover consumes a recovery code and returns the replacement credentials of the one account that code belongs to. Every session of that account is revoked by the dispatcher first. A recovery code can name no other account, so recovering never grants ownership of somebody else's.
func (*Client) Recovery ¶ added in v0.3.0
Recovery makes one bounded request for a known run's recovery observation. Unknown classifications and failed workloads are successful inspections; neither an absent row nor a start marker establishes that replay is safe.
func (*Client) RendezvousTEST ¶ added in v0.3.0
func (c *Client) RendezvousTEST(ctx context.Context, server, peer Request, opts RendezvousOptions) (result RendezvousResult, failure error)
RendezvousTEST submits a listener once, waits for its bound endpoint, then submits one client on another executor. It never replays an uncertain request. Both known runs are cancelled and inspected on every exit, under an independent bounded cleanup context. Preserve the returned identities even on error.
func (*Client) RetryTEST ¶ added in v0.3.0
func (c *Client) RetryTEST(ctx context.Context, parentID, requestID string, batch *PreparedBatch) (Submission, error)
RetryTEST explicitly requests one new attempt. Retain requestID and the same prepared request to recover it after a lost response. No request is retried automatically, and the old run is never resumed or modified.
func (*Client) SaveProfile ¶ added in v0.3.0
func (*Client) SelectExecutor ¶ added in v0.3.0
func (c *Client) SelectExecutor(ctx context.Context, id string, filter ExecutorFilter) (Node, error)
SelectExecutor returns one ready match, optionally restricted to an explicit ID. Zero or ambiguous matches are errors. This method never submits work.
func (*Client) StartDeviceLogin ¶ added in v0.3.0
func (c *Client) StartDeviceLogin(ctx context.Context, label string, scopes []string) (DeviceLogin, error)
StartDeviceLogin requests a credential with explicit scopes. It never sends a provider token or chooses an audience from a remote response.
func (*Client) SubmitTEST ¶
func (c *Client) SubmitTEST(ctx context.Context, batch *PreparedBatch) (Submission, error)
SubmitTEST creates a TEST payment intent for the batch and submits it.
func (*Client) Verify ¶ added in v0.3.0
func (c *Client) Verify(ctx context.Context, packets []CapturedPacket, opts VerifyOptions) (VerifyReport, error)
Verify attributes captured packets to Debuglet runs (docs/verification.md). It groups the packets by source address and epoch, looks up the runs that were active from each address at the time in the dispatcher's public attribution history, and checks the tags against the disclosed keys offline: packets never leave this process. Groups whose key is not disclosed yet are pending. It needs no credential, and it fails only when the capture or the dispatcher cannot be read; every group verdict, including invalid ones, is part of the report.
The lookups are paced to the dispatcher's per-client rate limit (opts.RequestRate, opts.RequestBurst). A rate-limited request is retried after the dispatcher's Retry-After until ctx ends, and then Verify fails with a *RateLimitedError: give ctx a deadline.
An offline verdict rests on the capture's timestamps: a key is used only if it was still secret at the capture time plus opts.ClockTolerance.
func (*Client) Version ¶
func (c *Client) Version(ctx context.Context) (ServerVersion, error)
Version reports the dispatcher's version identities. It is a report, not an ABI negotiation: the request itself carries APIVersion, and a server that cannot serve it rejects the request. A server written before the contract was versioned answers with Version only, leaving the other fields empty.
func (*Client) Whoami ¶
Whoami reports the account this client's credential authenticates as. It is the cheapest way to tell a working credential from an expired or revoked one: the latter answers an *HTTPError with CodeUnauthorized.
func (*Client) WithCredential ¶
WithCredential returns a copy of this client that presents the given session token. The endpoint, transport and timeouts are unchanged, so a credential obtained from one dispatcher cannot be attached to another by accident: a different dispatcher means a different Client.
type ConnectionInfo ¶
type ConnectionInfo struct {
SchemaVersion int `json:"schema_version"`
Mode string `json:"mode"`
GRPCAddress string `json:"grpc_address"`
YamuxAddress string `json:"yamux_address"`
}
ConnectionInfo describes the control listeners announced by a local dispatcher. It does not grant access or infer control addresses from an HTTP URL.
type ControlBinding ¶ added in v0.3.0
type ControlBinding = wire.ControlBinding
type CredentialStatus ¶ added in v0.3.0
type CredentialStatus struct {
ID string `json:"id"`
Kind string `json:"kind"`
Audience string `json:"audience"`
Scopes []string `json:"scopes"`
CreatedAt int64 `json:"created_at"`
ExpiresAt int64 `json:"expires_at"`
}
CredentialStatus contains no secret and reflects immediate server-side revocation, rather than trusting the local file's expiry alone.
type DeviceLogin ¶ added in v0.3.0
type DeviceLogin struct {
DeviceCode string `json:"device_code"`
UserCode string `json:"user_code"`
VerificationURI string `json:"verification_uri"`
Audience string `json:"audience"`
Scopes []string `json:"scopes"`
ExpiresAt int64 `json:"expires_at"`
Interval int64 `json:"interval"`
}
DeviceLogin is a short-lived browser approval request. DeviceCode is a secret for polling and cancellation; show only UserCode and VerificationURI.
type DeviceLoginPoll ¶ added in v0.3.0
type DeviceLoginPoll struct {
State string `json:"state"`
Interval int64 `json:"interval,omitempty"`
Credential *APICredential `json:"credential,omitempty"`
}
type Economics ¶ added in v0.3.0
Economics reports the payment features a dispatcher offers an account, as User.Economics.
type Evidence ¶ added in v0.3.0
type Evidence struct {
Format string `json:"format"`
FormatVersion int `json:"format_version"`
CreatedAt time.Time `json:"created_at"`
Tool EvidenceTool `json:"tool"`
TagSpec int `json:"tag_spec"`
Dispatcher EvidenceDispatcher `json:"dispatcher"`
// At is the capture time override the verification used, if any; the
// packets' captured_at already carry it.
At *time.Time `json:"at,omitempty"`
// ClockToleranceMS is the capture clock lag bound applied.
ClockToleranceMS int64 `json:"clock_tolerance_ms"`
Packets EvidencePackets `json:"packets"`
Groups []EvidenceGroup `json:"groups"`
// Lookups are the dispatcher's answers to the candidate lookups, one
// per group formed from them.
Lookups []EvidenceLookup `json:"lookups"`
// Chains carry, per executor chain, its schedule and every disclosed key
// the verification used. Each key hashes to the schedule's k0.
Chains []EvidenceChain `json:"chains"`
// Receipts are the dispatcher's signed receipts of server-assisted
// checks (#341); this client writes none yet.
Receipts []EvidenceReceipt `json:"receipts"`
}
Evidence is a verification evidence bundle.
type EvidenceCandidate ¶ added in v0.3.0
type EvidenceCandidate struct {
ExecutorID string `json:"executor_id"`
RunID string `json:"run_id"`
ActiveFrom time.Time `json:"active_from"`
ActiveTo time.Time `json:"active_to"`
// IPSource is observed or advertised (see AttributionCandidate).
IPSource string `json:"ip_source,omitempty"`
Schedule EvidenceSchedule `json:"schedule"`
DisclosedThrough int64 `json:"disclosed_through"`
}
EvidenceCandidate is one run a lookup named.
type EvidenceChain ¶ added in v0.3.0
type EvidenceChain struct {
ExecutorID string `json:"executor_id"`
Schedule EvidenceSchedule `json:"schedule"`
Keys []EvidenceKey `json:"keys"`
}
EvidenceChain is one chain with the keys a verification used.
type EvidenceDispatcher ¶ added in v0.3.0
EvidenceDispatcher names the dispatcher whose history a bundle records.
type EvidenceGroup ¶ added in v0.3.0
type EvidenceGroup struct {
Verdict Verdict `json:"verdict"`
Reason string `json:"reason,omitempty"`
Method VerifyMethod `json:"method,omitempty"`
Source string `json:"source,omitempty"`
RunID string `json:"run_id,omitempty"`
ExecutorID string `json:"executor_id,omitempty"`
Epoch int64 `json:"epoch,omitempty"`
PendingUntil *time.Time `json:"pending_until,omitempty"`
Packets []int `json:"packets"`
Matched int `json:"matched"`
Unmatched int `json:"unmatched"`
// Split records the group an entry was split from (VerifyGroup.Split).
Split *VerifySplit `json:"split,omitempty"`
Schedule *EvidenceSchedule `json:"schedule,omitempty"`
Keys []EvidenceKey `json:"keys,omitempty"`
}
EvidenceGroup is the recorded verdict of one group. Schedule and Keys are those of the named run's chain for the epochs the verdict used.
type EvidenceKey ¶ added in v0.3.0
EvidenceKey is one disclosed chain key.
type EvidenceLookup ¶ added in v0.3.0
type EvidenceLookup struct {
IP string `json:"ip"`
At time.Time `json:"at"`
RetainedFrom time.Time `json:"retained_from"`
Truncated bool `json:"truncated,omitempty"`
Candidates []EvidenceCandidate `json:"candidates"`
}
EvidenceLookup is the dispatcher's answer to one dated candidate lookup.
type EvidenceMismatchError ¶ added in v0.3.0
EvidenceMismatchError reports a bundle whose recorded verdicts differ from those its own packets, history and keys yield.
func (*EvidenceMismatchError) Error ¶ added in v0.3.0
func (e *EvidenceMismatchError) Error() string
type EvidencePacket ¶ added in v0.3.0
EvidencePacket is one packet: the first 64 bytes of the IP packet (all of a shorter one), and its capture time.
type EvidencePackets ¶ added in v0.3.0
type EvidencePackets struct {
Count int `json:"count"`
// Digest is "sha256:" and the hex SHA-256 over uint16 length ‖ data ‖
// int64 captured_at_ns (big-endian) of every packet in order.
Digest string `json:"digest"`
Items []EvidencePacket `json:"items"`
}
EvidencePackets are the verified packets in order.
type EvidenceReceipt ¶ added in v0.3.0
type EvidenceReceipt struct {
KeyID string `json:"key_id"`
Payload []byte `json:"payload"`
Signature []byte `json:"signature"`
}
EvidenceReceipt is a signed dispatcher receipt (#341).
type EvidenceSchedule ¶ added in v0.3.0
type EvidenceSchedule struct {
// ChainID identifies the chain.
ChainID string `json:"chain_id"`
// K0 is the chain anchor; every key hashes to it.
K0 []byte `json:"k0"`
// T0UnixNs is the start of epoch 0.
T0UnixNs int64 `json:"t0_unix_ns"`
// EpochSeconds is the epoch length I.
EpochSeconds int64 `json:"epoch_seconds"`
// DisclosureDelayEpochs is d; below 2 is refused.
DisclosureDelayEpochs int64 `json:"disclosure_delay_epochs"`
// ChainLength is L; zero is unknown.
ChainLength int64 `json:"chain_length"`
// TagSpec is the executor-reported tag specification version; 0 is the
// unversioned pre-v1 tag, which is unsupported.
TagSpec int64 `json:"tag_spec"`
}
EvidenceSchedule is the public TESLA schedule of one executor chain: the key of epoch e covers [t0 + e·I, t0 + (e+1)·I) and is disclosed from t0 + (e+d)·I.
type EvidenceTool ¶ added in v0.3.0
EvidenceTool names the program that wrote a bundle.
type ExecutorEarnings ¶ added in v0.3.0
type ExecutorEarnings = wire.ExecutorEarnings
ExecutorEarnings is an owned executor's earnings; see Client.ExecutorEarnings.
type ExecutorFilter ¶ added in v0.3.0
type ExecutorFilter struct {
AddressFamilies []string // ipv4 or ipv6 with a fresh successful controlled observation.
ReachableListeners []string // tcp, udp or scion; declared support alone is not a match.
Protocols []string
EnforcementMode string
MinCapacityBPS *int64
// ISDAS requires the executor-reported SCION ISD-AS, such as 1-ff00:0:110.
// Equivalent spellings match; an unknown ISD-AS does not.
ISDAS string
// ASN matches dispatcher-observed control or advertised-host origin. The
// separate, unverified hello claim never adds a match. Country matches display location.
ASN uint32
Country string
}
ExecutorFilter requires every specified observation. Unknown capabilities do not match requested filters. Capacity is advertised total bandwidth, not a reservation or a promise that a particular run can be admitted.
func (ExecutorFilter) Empty ¶ added in v0.3.0
func (f ExecutorFilter) Empty() bool
func (ExecutorFilter) Validate ¶ added in v0.3.0
func (f ExecutorFilter) Validate() error
type HTTPError ¶
type HTTPError struct {
Method string
Path string
StatusCode int
Code string
Message string
FieldErrors []wire.FieldError
// RetryAfter is the delay a 429 or 503 response asked for in its
// Retry-After header; zero when it named none.
RetryAfter time.Duration
// contains filtered or unexported fields
}
HTTPError reports a response the client did not accept: any status other than the one expected for the route, including other 2xx codes. Code is the dispatcher's stable failure code, the field to branch on; Message is a bounded, sanitized diagnostic for a human and must not be parsed. A server that sends no documented envelope leaves Code empty. Unrecognized JSON bodies use a generic diagnostic. Recognized auth_key fields and known submission keys are redacted. Path never contains a query or request body.
type IncompleteOutputError ¶ added in v0.3.0
type IncompleteOutputError struct {
Output OutputStatus
}
IncompleteOutputError means the available prefix was drained without proof of complete output. It says nothing about the workload's success or failure.
func (*IncompleteOutputError) Error ¶ added in v0.3.0
func (e *IncompleteOutputError) Error() string
type LogEntry ¶
LogEntry is one stored output chunk. Output holds the exact guest bytes; Timestamp is the server's opaque string.
type LogOptions ¶
LogOptions selects a log page. After is a cursor (entry ID) that must be >= 0; Limit zero defaults to 100, otherwise it must be within 1..1000.
type Measurement ¶ added in v0.3.0
type Measurement = wire.Measurement
type MeasurementOptions ¶ added in v0.3.0
type MeasurementPage ¶ added in v0.3.0
type MeasurementPage = wire.MeasurementPage
type MeasurementTemplate ¶ added in v0.3.0
type MeasurementTemplate = wire.MeasurementTemplate
type Options ¶
type Options struct {
// HTTPClient supplies transport settings. It is cloned, never mutated,
// and redirects are always rejected. nil uses a fresh client.
HTTPClient *http.Client
// RequestTimeout bounds each request including its body read. Zero
// defaults to 10 s; a negative value is invalid.
RequestTimeout time.Duration
// AllowRemoteTEST permits TEST submissions to endpoints other than a
// literal loopback IP. It is an accident guard, not server authorization:
// an SSH-forwarded loopback endpoint is still an operator-selected remote
// service.
AllowRemoteTEST bool
// Credential is the session token this client presents on every request,
// as an Authorization bearer header. It is obtained from Login and belongs
// to exactly one dispatcher: a Client is bound to one origin and refuses
// redirects, so a credential never travels to another one. It is never
// written to a log, an error message or a returned diagnostic. Empty makes
// unauthenticated requests, which a dispatcher serving the local
// development profile still accepts.
Credential string
}
Options configures a Client. The zero value is valid for a loopback endpoint: a fresh HTTP client, a 10 s per-request timeout and no remote TEST submissions.
type OrderHistory ¶ added in v0.3.0
type OrderHistory = wire.OrderHistory
OrderHistory is one page of Client.Orders.
type OrdersPage ¶ added in v0.3.0
OrdersPage selects one page of Client.Orders. A zero Limit asks for the server's default page size; Before is the Next value of the previous page.
type OutputStatus ¶ added in v0.3.0
type OutputStatus = wire.OutputStatus
OutputStatus records output finality; missing metadata from older servers is unknown.
type PreparedBatch ¶
type PreparedBatch struct {
// contains filtered or unexported fields
}
PreparedBatch is an immutable, validated batch produced by Prepare. The same serialized debuglets array is sent for the payment intent and the submission, so the server's request hash check sees identical values. A zero or nil PreparedBatch is invalid.
func Prepare ¶
func Prepare(requests []Request) (*PreparedBatch, error)
Prepare validates requests and freezes them into one immutable serialized batch used for both submission steps.
type ProfileConfig ¶ added in v0.3.0
type ProfileConfig = wire.ProfileConfig
type ProfileSummary ¶ added in v0.3.0
type ProfileSummary = wire.ProfileSummary
type RateLimitedError ¶ added in v0.3.0
type RateLimitedError struct {
// Throttled counts the requests the dispatcher answered 429.
Throttled int
// UncheckedGroups is how many groups remain without a verdict (at least
// this many when Partial is set: the lookups had not reached every
// packet), and UncheckedPackets how many packets they hold.
UncheckedGroups int
UncheckedPackets int
Partial bool
// Err is the context's error.
Err error
}
RateLimitedError reports a verification that the dispatcher's rate limit held back until its context ended. The groups it names were not checked.
func (*RateLimitedError) Error ¶ added in v0.3.0
func (e *RateLimitedError) Error() string
func (*RateLimitedError) Unwrap ¶ added in v0.3.0
func (e *RateLimitedError) Unwrap() error
type RecoveryDocument ¶ added in v0.3.0
type RecoveryObservation ¶ added in v0.3.0
type RecoveryObservation = wire.RecoveryObservation
type RecoveryObserver ¶ added in v0.3.0
type RecoveryObserver = wire.RecoveryObserver
type RendezvousOptions ¶ added in v0.3.0
type RendezvousResult ¶ added in v0.3.0
type RendezvousResult struct {
Server RendezvousRun `json:"server"`
Client RendezvousRun `json:"client"`
Endpoint string `json:"endpoint"`
}
type RendezvousRun ¶ added in v0.3.0
type Request ¶
Request describes one debuglet in a batch. Wasm holds the guest bytes and encoding/json transmits it as base64.
type RetainedRun ¶ added in v0.3.0
type RetainedRun = wire.RetainedRun
type ServerVersion ¶
ServerVersion reports the dispatcher's independent version identities. Every field beyond Version is empty for older dispatchers.
type Session ¶
type Session struct {
Token string `json:"token"`
CSRFToken string `json:"csrf_token"`
ExpiresAt int64 `json:"expires_at"`
ID string `json:"id"`
Name string `json:"name"`
Role string `json:"role"`
}
Session is an issued session. Token is the bearer credential to put in Options.Credential. CSRFToken is only of interest to a browser client that received the session as a cookie; a native client never needs it. ExpiresAt is Unix seconds.
type Submission ¶
Submission is the result of an accepted TEST submission. IDs are in batch order. No auth key is exposed.
type SubmissionError ¶
type SubmissionError struct {
Stage string
TransactionID string
// AdmittedIDs are durable run identities in request order when a failed
// submission returned a valid complete list. They prove admission, not
// upload, execution, cancellation or completion. Inspect each run.
AdmittedIDs []string
OutcomeUnknown bool
Err error
}
SubmissionError reports a failed SubmitTEST. Stage is "intent" or "submit". TransactionID is retained when the intent had already been created. OutcomeUnknown is set conservatively when the submission may have been accepted by the server although no valid response was observed (transport or read failure after sending, malformed success, an unexpected submission 2xx, or a server 5xx); it is uncertainty, not proof of acceptance. A validated pre-send failure or a 4xx response is a rejection with OutcomeUnknown false, and so is a 503 that carries service_unavailable or payments_disabled at the intent stage: nothing was priced or written.
func (*SubmissionError) Code ¶
func (e *SubmissionError) Code() string
Code returns the dispatcher's failure code when the submission failed on a response that carried one, and "" otherwise. It never changes how the outcome itself is classified: OutcomeUnknown stays the only statement about whether the submission may have been accepted.
func (*SubmissionError) Error ¶
func (e *SubmissionError) Error() string
func (*SubmissionError) Unwrap ¶
func (e *SubmissionError) Unwrap() error
type Verdict ¶ added in v0.3.0
type Verdict string
Verdict is the outcome of one packet group.
const ( // VerdictVerified: every packet carries a valid tag of the named run at // the named epoch (or the epoch before it). VerdictVerified Verdict = "verified" // VerdictInvalid: the history covers the time and no candidate run // reproduces any of the tags (Reason tag_mismatch or no_run). VerdictInvalid Verdict = "invalid" // VerdictPending: the key is not disclosed yet; retry after PendingUntil. VerdictPending Verdict = "pending" // VerdictMissing: the dispatcher holds no schedule or key for the time. // This is no evidence either way. VerdictMissing Verdict = "missing" // VerdictUnsupported: the group cannot be checked; Reason says why. VerdictUnsupported Verdict = "unsupported" )
type VerifyCounts ¶ added in v0.3.0
type VerifyCounts struct {
Verified int `json:"verified"`
Invalid int `json:"invalid"`
Pending int `json:"pending"`
Missing int `json:"missing"`
Unsupported int `json:"unsupported"`
}
VerifyCounts counts groups by verdict.
type VerifyGroup ¶ added in v0.3.0
type VerifyGroup struct {
Verdict Verdict `json:"verdict"`
// Reason is the machine reason of any verdict but verified.
Reason string `json:"reason,omitempty"`
// Detail explains the verdict in a sentence.
Detail string `json:"detail"`
// Method is how the verdict was established; empty when nothing was
// checked.
Method VerifyMethod `json:"method,omitempty"`
// Source is the packets' source address; empty for frames without IP.
Source string `json:"source,omitempty"`
RunID string `json:"run_id,omitempty"`
ExecutorID string `json:"executor_id,omitempty"`
// Epoch is the capture epoch under the run's (or the address's first
// candidate's) schedule; zero when there is none.
Epoch int64 `json:"epoch,omitempty"`
// Time is the capture time of the group's first packet.
Time time.Time `json:"time"`
// PendingUntil is when the last key the group needs is disclosed.
PendingUntil *time.Time `json:"pending_until,omitempty"`
// Packets are indices into the verified packets, in capture order.
Packets []int `json:"packets"`
// Matched counts the packets whose tag some candidate run reproduces,
// Unmatched those it does not; a count of matches is only meaningful
// together with the non-matches (docs/tag-spec.md §7). For an entry of
// a split group they count the entry's own packets; Split has the
// group's.
Matched int `json:"matched"`
Unmatched int `json:"unmatched"`
// Candidates counts the runs the group was checked against.
Candidates int `json:"candidates"`
// AmbiguousRuns lists the runs that each reproduce every tag.
AmbiguousRuns []string `json:"ambiguous_runs,omitempty"`
// FalseMatchBound bounds the probability that packets not sent by the
// run match it by chance: N·C(n,k)·(E·2⁻¹⁶)^k for N candidates, E = 2
// epochs and k of the group's n packets, which is N·(E·2⁻¹⁶)^n for an
// unsplit group (docs/tag-spec.md §7). It underflows to zero for large k.
FalseMatchBound float64 `json:"false_match_bound,omitempty"`
// DisclosedAt is when the latest key the verdict used became due for
// disclosure; packets captured before it (by a trustworthy clock) cannot
// have been forged with that key.
DisclosedAt *time.Time `json:"disclosed_at,omitempty"`
// Split describes the address-and-epoch group this entry was split
// from, when not all its packets reproduce one run; nil otherwise.
Split *VerifySplit `json:"split,omitempty"`
// contains filtered or unexported fields
}
VerifyGroup is the verdict of the packets of one source address in one epoch.
type VerifyMethod ¶ added in v0.3.0
type VerifyMethod string
VerifyMethod names how a group's verdict was established.
const ( // VerifyMethodOffline: the verifier checked the tags itself against // disclosed keys. It shows the packets came from the run only if they // were captured before the disclosure, which rests on the capture's own // timestamps. VerifyMethodOffline VerifyMethod = "offline" // VerifyMethodServer is the server-assisted check of #341; this client // does not perform it yet. VerifyMethodServer VerifyMethod = "server" )
type VerifyOptions ¶ added in v0.3.0
type VerifyOptions struct {
// At, when set, is taken as the capture time of every packet instead of
// the capture's own timestamps.
At time.Time
// Offline never uploads packets: groups whose key is not disclosed yet
// are pending. Server-assisted verification (#341) is not implemented
// yet, so every verification is offline today.
Offline bool
// ClockTolerance bounds how far the capture host's clock may lag true
// time. A key is used only if it was still secret at the capture time
// plus this. Zero is DefaultClockTolerance.
ClockTolerance time.Duration
// RequestRate (requests per second) and RequestBurst pace the history
// requests of Client.Verify as a token bucket, to stay within the
// dispatcher's per-client rate limit. Zero is the documented limit,
// DefaultVerifyRequestRate and DefaultVerifyRequestBurst; a negative
// rate disables pacing. After a 429 every request waits for the
// Retry-After either way.
RequestRate float64
RequestBurst int
}
VerifyOptions tune Verify.
type VerifyReport ¶ added in v0.3.0
type VerifyReport struct {
// TagSpec is the tag specification the tags were checked under.
TagSpec string `json:"tag_spec"`
// CheckedAt is the time verification ran (for VerifyEvidence, the time
// the bundle was created).
CheckedAt time.Time `json:"checked_at"`
// At is the capture time override, if any.
At *time.Time `json:"at,omitempty"`
// Dispatcher is the dispatcher the history came from.
Dispatcher string `json:"dispatcher,omitempty"`
// ClockTolerance is the capture clock lag bound applied.
ClockToleranceMS int64 `json:"clock_tolerance_ms"`
// Packets counts the packets checked.
Packets int `json:"packets"`
Counts VerifyCounts `json:"counts"`
Groups []VerifyGroup `json:"groups"`
// contains filtered or unexported fields
}
VerifyReport is the result of Verify or VerifyEvidence.
func VerifyEvidence ¶ added in v0.3.0
func VerifyEvidence(ctx context.Context, ev Evidence) (VerifyReport, error)
VerifyEvidence checks a bundle again, offline: the packet digest, every key against its chain anchor, and every group's verdict recomputed from the packets, the recorded lookups and keys as of the bundle's creation. It returns the recomputed report, with an *EvidenceMismatchError when a recorded verdict differs. The lookups and schedules are the dispatcher's claims; the bundle does not authenticate them (the operator signature of #71(b) will).
func (VerifyReport) Evidence ¶ added in v0.3.0
func (r VerifyReport) Evidence() Evidence
Evidence returns the evidence bundle of a verification. Tool names this package; a program writing the bundle may replace it.
type VerifySplit ¶ added in v0.3.0
type VerifySplit struct {
// Packets counts the packets of the whole group.
Packets int `json:"packets"`
// Matched counts those some candidate run reproduces, Unmatched those
// no candidate does.
Matched int `json:"matched"`
Unmatched int `json:"unmatched"`
// Runs lists the runs packets were attributed to.
Runs []string `json:"runs"`
}
VerifySplit describes a packet group that was split: its packets of each run, those several runs reproduce (ambiguous) and those no run reproduces (unmatched) are reported as separate entries, each carrying this record, so that every entry's match count can be read against the whole group's (docs/tag-spec.md §7).
Source Files
¶
- attribution.go
- cancellation.go
- capabilities.go
- capture.go
- client.go
- connection.go
- connectivity.go
- device_login.go
- economics.go
- errors.go
- evidence.go
- field_errors.go
- ip_metadata.go
- measurement_details.go
- measurements.go
- models.go
- prepare.go
- recovery.go
- rendezvous.go
- request_version.go
- results.go
- retry.go
- submit.go
- transport.go
- uuid.go
- verify.go
- verify_check.go
- verify_client.go