Expand description
Core of the Datumesh protocol: strict JSON and RFC 8785 JCS, canonical forms of scalars, cells, references, descriptors and receipts, cell URIs, key documents, response envelopes, unit resolution and offline receipt verification.
The rules are those of the specification, SPEC.md and units.md at
https://github.com/datumesh-com/datumesh-spec. Section numbers in this documentation
refer to SPEC.md.
Every function that can fail returns an Error carrying one of the codes of SPEC 10.2
(ErrorCode), the JSON path where the failure was found, and a human detail. Nothing in
this crate panics on any input, touches the network (except fetch_keys behind the
fetch feature), keeps global state or logs.
verify runs SPEC 10.1. Keys are an input (Keys); recomputation (step 7) asks a
Resolver for the descriptor, the input receipts, the manifests of slice entries and
the evaluation (with its lineage), lazily (MapResolver holds them in maps). Since
spec-0.4.0 a receipt’s lineage may cite whole slices of cells (Slice, Manifest),
and descriptors may carry signature.order and argument extents (FunctionDescriptor).
Since spec-0.4.1 a mesh may answer pending (check_envelope_any, Pending), and
cross-mesh resolution reads a host’s mesh document (resolve_mesh, MeshDoc); a
verifier needs neither. Feature sign adds SigningKey and
ReceiptBuilder, which make receipts that verify byte for byte like the specification’s.
Feature fetch (fetch_keys) is deprecated since 0.3.1 and removed at 1.0: fetch key
documents with your own HTTP client and pass the response to keys_from_response.
use datumesh_core::{verify, Keys, Level};
let receipt = br#"{"asof":"2024-03-16T09:00:00.000000Z","cell":{"args":{"base":{"type":"string","value":"EUR"},"date":{"type":"date","value":"2024-03-15"},"quote":{"type":"string","value":"USD"}},"fn":"fx_rate","fn_hash":"7b58ecb8fd23b644c87951d0bd609790ff547cbb23fed27186c669ce2ce0aa80","ns":"rates.example.org"},"computed_by":"rates.example.org#d712b32a2cc5cb7c","inputs":[],"issued":"2024-03-16T09:00:00.000000Z","licence":"CC-BY-4.0","proto":"datumesh/1","publisher":"rates.example.org","sig":"ddf61d49ff6593f7b0d94c76f19fefdd27f47778740b3666fc1c3315ec00c5d216f887c4078deb05c83d4d743453c6fecc568473663b3282ac4eda8c3eadcf01","summary":"1 EUR was worth 1.0892 USD at the 15 March 2024 reference rate.","tx":"2024-03-15T16:00:00.000000Z","type":"number","valid":{"date":{"type":"date","value":"2024-03-15"}},"value":"1.0892"}"#;
let key_doc = br#"{"host":"rates.example.org","keys":[{"alg":"ed25519","id":"d712b32a2cc5cb7c","public":"843baeb22bfd0364fb1b7262b367fb3202e7886c69a070fecf8e343fedb1eabf","valid_from":"2020-01-01T00:00:00.000000Z","valid_to":"2024-06-01T00:00:00.000000Z"}],"proto":"datumesh/1"}"#;
let mut keys = Keys::new();
keys.insert_response("rates.example.org", 200, Some(key_doc));
let result = verify(receipt, &keys, None, None);
assert!(result.ok);
assert_eq!(result.level, Some(Level::Signed));
assert_eq!(result.hash.as_deref(), Some("19a5fe3a744c5792f747fb4c286ce396ab44b95922de4f07937502fe595b6f81"));Modules§
- json
- Strict JSON (SPEC 6.1, I-JSON) and the RFC 8785 JSON Canonicalization Scheme (SPEC 6.2).
- lexical
- Lexical forms: names (2), scalars (3), hex, licences, key references (9.1) and units (7.1).
- testkit
- A conformance kit for
Resolverimplementations (featuretestkit).
Structs§
- ArgDecl
- An argument declaration:
{"type", "valid"}, plusunitfor numbers. - Cell
- A cell (4.4): a function, pinned by hash, applied to arguments. May denote a slice.
- CellRef
- A cell reference (4.3): what a cell URI denotes before the function name is resolved.
- Descriptor
- A function descriptor (7) in its
spec-0.3.0form: signature, code and declared inputs. - Envelope
- A checked envelope.
- Envelope
Extras - The members of a checked envelope that
Envelopehas no field for, because they were added to SPEC 5.5 after it was frozen (0.3.0): seecheck_envelope_extras. - Error
- A failure: its code, the JSON path (or URI part) where it was found, and a human detail.
- Evaluation
- What evaluating a cell gave (
Resolver::evaluation): the value and, when the resolver has it, the lineage: theinputsentries the evaluation read (receipt hashes and slice entries), whose receipts and manifests the resolver offers for those the receipt under verification does not list. - Function
Descriptor - A function descriptor (7) with the optional members of
spec-0.4.0:signature.orderand argumentextent. Absent, it is theDescriptorofspec-0.3.0, byte for byte and hash for hash (From<Descriptor>,to_descriptor). - Invalid
Request - A malformed request description (5.5 step 5): the caller’s mistake, not an
E_*code. - Key
- One published key.
- KeyDoc
- A host’s key document (9.2), checked.
- Keys
- The keys a verifier has resolved: per host, a key document or the failure resolving it.
A host that was never resolved behaves as
E_KEY_UNAVAILABLE(SPEC 11). - Manifest
- A slice manifest (15.13,
spec-0.4.0):{"members": [...], "slice": {...}}, the member receipt hashes (ascending, unique, at most 1,048,576) and the slice object. It is fetched by its entryslice:<slice id>:<members hash>, where the members hash is SHA-256 of the canonical bytes of the members array (of[]for an empty slice). - MapResolver
- A
Resolverbacked by maps: descriptors by function hash, receipts by receipt hash, manifests by slice entry, and evaluated values (with lineages) by cell id. It is what the vectors’recomputeobject describes (SPEC 11): the descriptor goes under the receipt’scell.fn_hash, the inputs under their hashes, the manifests under their entries, andvalue(andlineage) under the receipt’s ownCell::id. - MeshDoc
- A checked mesh document (9.6): the host’s bindings URL and its known endpoint templates. Unknown members are dropped.
- Pending
- A
pendingenvelope (5.5,spec-0.4.1): the job, an estimate, the URL to poll and the original request echoed. Build one withPending::new(a mesh), or get one fromcheck_envelope_any(a client). - Quote
- A price quote (
payment_required). - Receipt
- A receipt (8.1) that has passed verification steps 1-4: strict JSON, structure, canonical
form and consistency. Its signature has not been checked; use
crate::verify. - Receipt
Builder - The members of a receipt before it is signed;
signis the only way to turn it into aReceipt. - Request
- What the client asked for, for the binding of 5.5 step 5.
- Resolved
Mesh - A host accepted by cross-mesh resolution: its key document and its mesh document.
- Returns
- The declared return: a type, with a unit exactly when it is
number. - Signature
- A function signature.
- Signing
Key - An Ed25519 signing key, from its 32-byte seed (RFC 8032 5.1.5).
- Slice
- A slice object (4.4,
spec-0.4.0): a cell object with at least one argument open ("*") or bounded by a range object{"hi", "lo", "type"}, or a version slice{"cell", "from", "to"}. Its slice id is SHA-256 of its canonical bytes; for an unbounded slice it is the id of the cell object with the markers. - Verify
Result - The outcome of
verify.
Enums§
- AnyEnvelope
- The answer to a request: a
Pendingenvelope, or one of the eight outcomes anEnvelopeholds, with itsEnvelopeExtras(seecheck_envelope_any). - Arg
- An argument: a typed scalar, or the slice marker
"*"(4.2). - Error
Code - One variant per
E_*code of SPEC 10.2 (spec-0.4.1). Non-exhaustive: codes added by later revisions of the specification are additions. - Extent
- The cells a slice over an argument enumerates (7,
spec-0.4.0): the argument declaration’s optionalextent. - Fault
- A formula evaluation fault (SPEC 5.5, 15.11;
spec-0.4.0): the optionalfaultmember of anot_coveredenvelope. The cell has no value, deterministically; this is not missing data. These are formula codes, not verification codes, so they are notErrorCodes. - Level
- How far a receipt verified.
- Outcome
- The eight outcomes of 5.5.
- Rate
Side - One side of a rate: a currency code or an argument reference.
- Retrieval
- What one HTTPS
GETof a document gave, as the caller’s HTTP client saw it. - Scalar
- A typed scalar value in its one canonical lexical form.
- Trust
- The mesh’s trust label (5.5).
- Type
- One of the six scalar types (3).
- Unit
- A unit in a signature (7.1).
Traits§
- Resolver
- What step 7 of SPEC 10.1 obtains: the descriptor, the input receipts (slice members
included), the manifests of slice entries, and the evaluation. This crate evaluates no
functions and fetches nothing; the caller supplies a resolver, and
verifyasks it only for what step 7 reaches for the receipt at hand:
Functions§
- canonicalize_
cell - Canonical bytes of a cell given as JSON text (4.4, 6.2). Slices are allowed.
- canonicalize_
descriptor - Canonical bytes of a function descriptor given as JSON text (7, 6.2),
orderandextentincluded (spec-0.4.0; seeFunctionDescriptor). - canonicalize_
receipt - The signed payload of a receipt given as JSON text: canonical bytes without
sig(8.3). Runs verification steps 1-4 first. - canonicalize_
ref - Canonical bytes of a cell reference given as JSON text (4.3, 6.2).
- canonicalize_
scalar - Canonical bytes of a typed scalar given as JSON text (4.1, 6.2).
- canonicalize_
slice - Canonical bytes of a slice object given as JSON text (4.4, 6.2;
spec-0.4.0). - cell_
hash - The cell id of a cell given as JSON text: SHA-256 of its canonical bytes (4.4, 6.3).
- cell_
uri_ from_ https - The cell URI served at an HTTPS URL on mesh host
mesh(5.3), by stripping the prefix.Nonewhen the URL is not underhttps://<mesh>/cell/. - check_
envelope - Checks a response envelope (5.5) in the order of its procedure: strict JSON, members,
HTTP status, the receipt through step 6 of 10.1, the binding to
request, thentrustandsuperseded_by. Never touches the network. Anot_coveredenvelope’sfault(spec-0.4.0) is checked and accepted;check_envelope_extrasalso returns it. - check_
envelope_ any - Checks a response envelope (5.5) of any of the nine outcomes,
pendingincluded (spec-0.4.1), in the order of its procedure, and binds it torequest: apendingenvelope’s echoed request to the request made (and itsjobto the job polled, whenrequesthas one), any other outcome to the original request’s cell id andasof, whether it answers the/cellrequest or the job URL.E_JOB_UNKNOWNis accepted only in abad_requestanswering a job URL (requestwith a job). Never touches the network. - check_
envelope_ extras check_envelope, also returning the membersEnvelopehas no field for (EnvelopeExtras): thefaultof anot_coveredenvelope, one of the six formula evaluation faults of SPEC 5.5 (E_ENVELOPEfor any other value, or on another outcome).- fetch_
keys Deprecated - Fetches
https://<host>/.well-known/datumesh.jsonand checks it (9.2, 9.3). - format_
uri - Writes the one URI of a cell reference (5.2).
format_uri(&parse_uri(u, s)?) == ufor every acceptedu. - function_
hash - The function hash of a descriptor given as JSON text (7, 6.3),
orderandextentincluded. - https_
url - The HTTPS URL of a cell URI on mesh host
mesh(5.3):https://<mesh>/cell/<rest>.meshmust be a DNS name (E_CANON_NAME),urimust start withcell://(E_PARSE_URI). - key_id
- The key id of a public key: the first 16 hex digits of SHA-256 over its 32 bytes (9.1).
- keys_
from_ response - Resolves a host’s keys from the HTTPS response to
GET https://<host>/.well-known/datumesh.json(9.3).bodyisNonewhen a 200 response carried no document. - parse_
uri - Parses a cell URI against a function signature (5.4), reporting the first failure in the order 5.4 defines.
- receipt_
hash - The receipt hash (8.3), after steps 1-4.
- receipt_
payload - The canonical bytes of a receipt without
sig(8.3), after steps 1-4. - resolve_
mesh - Cross-mesh resolution of
host(9.6,spec-0.4.1), from whatGET https://<host>/.well-known/datumesh.jsonandGET https://<host>/.well-known/datumesh-mesh.jsongave. Separate from verification, which never needs it; it fetches nothing. In the order of 9.6, the first failure is reported: - resolve_
with - Substitutes a checked cell’s arguments into a checked descriptor’s return unit.
- resolved_
unit - The unit of a cell’s value (7.1,
units.md3), from the descriptor and cell JSON texts. - resolved_
unit_ value resolved_unitover parsed JSON values.- sha256
- SHA-256 of
data. - sha256_
hex - SHA-256 of
dataas 64 lowercase hex digits. - verify
- Verifies a receipt (10.1). Never touches the network and never panics.
- verify_
ed25519 - Verifies an Ed25519 signature with the rules of SPEC 10.1 step 6 (libsodium’s
crypto_sign_verify_detached): rejectS >= L, non-canonicalAorR, points that do not decode, small-orderAorR; then accept exactly when the encoding of[S]B - [k]AequalsR(the cofactorless equation). Mixed-order keys are accepted.