Skip to main content

Crate datumesh_core

Crate datumesh_core 

Source
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. Since spec-0.4.2 a reference may be pinned to a function hash (Reference, parse_reference), and Answer checks (check_answer, check_slice_answer, check_batch) and builds every envelope, trust computed, slice pages and batches included. Since spec-0.4.3 a key document may carry a publisher’s declarations (KeyDocument, Declarations), a computed receipt’s licence follows from its inputs’ (inherit_licence, and on the verifier’s side check_entitlement), an error envelope may say a foreign mesh was unreachable (E_FOREIGN_UNAVAILABLE, ForeignDetail), and names under .invalid are unrooted (is_unrooted). 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"));

Re-exports§

pub use lexical::is_unrooted;

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 Resolver implementations (feature testkit).

Structs§

Answer
An envelope of spec-0.4.2 (5.5), checked or to be written: every outcome, trust label and member, with a slice page (5.6) for the ok answer of the slice endpoint; since 0.3.7 (spec-0.4.3) also E_FOREIGN_UNAVAILABLE with its detail (Answer::foreign_unavailable). As a builder: one constructor per outcome, with_* for the optional members, Answer::to_json for the body and Answer::status for the HTTP status; check the body back with check_answer (or check_slice_answer) to hold it to every rule.
ArgDecl
An argument declaration: {"type", "valid"}, plus unit for 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.
Declaration
One dated entry of a publisher’s declarations (9.2, spec-0.4.3): its function may be computed over inputs under licence while the entry is open, the result carrying that licence (8.5). Entries are dated as keys are, and never removed, only closed.
Declarations
A publisher’s declarations (9.2, spec-0.4.3): per full function name (2.3), the dated entries naming the restricted licences the publisher permits as inputs of that function. Read from the key document of the host of the function’s namespace (KeyDocument). Names are kept in ascending order; each name’s entries in document order.
Descriptor
A function descriptor (7) in its spec-0.3.0 form: signature, code and declared inputs.
Entitlement
The answer of the entitlement check (10.3): whether the receipt’s licence is the one the inheritance rule gives, with the reason. It is not a verification result.
Envelope
A checked envelope.
EnvelopeExtras
The members of a checked envelope that Envelope has no field for, because they were added to SPEC 5.5 after it was frozen (0.3.0): see check_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: the inputs entries the evaluation read (receipt hashes and slice entries), whose receipts and manifests the resolver offers for those the receipt under verification does not list.
FunctionDescriptor
A function descriptor (7) with the optional members of spec-0.4.0: signature.order and argument extent. Absent, it is the Descriptor of spec-0.3.0, byte for byte and hash for hash (From<Descriptor>, to_descriptor).
Inheritance
The result of licence inheritance (8.5): the licence of the receipt to be issued, or a refusal (licence None: the mesh answers unlicensed and signs nothing), with the reason.
InvalidRequest
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.
KeyDocument
A host’s key document (9.2) with its declarations (spec-0.4.3), checked: the keys as a KeyDoc, and the declarations the publisher made for its own functions, which licence inheritance (8.5, crate::inherit_licence) and the entitlement check (10.3, crate::check_entitlement) read. Verification (10.1) reads the keys only: a document with declarations verifies every receipt exactly as the same document without them.
Keys
The keys a verifier has resolved: per host, a key document (with its declarations, since 0.3.7) 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 entry slice:<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 Resolver backed 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’ recompute object describes (SPEC 11): the descriptor goes under the receipt’s cell.fn_hash, the inputs under their hashes, the manifests under their entries, and value (and lineage) under the receipt’s own Cell::id.
MeshDoc
A checked mesh document (9.6): the host’s bindings URL and its known endpoint templates. Unknown members are dropped.
Pending
A pending envelope (5.5, spec-0.4.1): the job, an estimate, the URL to poll and the original request echoed. Build one with Pending::new (a mesh), or get one from check_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.
ReceiptBuilder
The members of a receipt before it is signed; sign is the only way to turn it into a Receipt.
Reference
A cell reference (4.3) with the optional pin of spec-0.4.2: fn_hash, the function the reference is pinned to, whatever its name is bound to (5.1, 5.8). Unpinned, it is the CellRef of spec-0.4.1 (From<CellRef>, Reference::to_cell_ref).
Request
What the client asked for, for the binding of 5.5 step 5.
ResolvedMesh
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.
SigningKey
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.
SlicePage
A slice page (5.6): the ok answer of the slice endpoint.
SliceRequest
A slice request (5.6): the slice id asked for, the asof, the pin, the host asked, and for a following page the key of the last member received (after).
VerifyResult
The outcome of verify.
WrongPublisher
The key document given to check_entitlement is not that of the receipt’s publisher (the host of cell.ns): the caller’s error (10.3), not a reason.

Enums§

AnswerOutcome
The nine outcomes of SPEC 5.5 (spec-0.4.2), pending included.
AnyEnvelope
The answer to a request: a Pending envelope, or one of the eight outcomes an Envelope holds, with its EnvelopeExtras (see check_envelope_any).
Arg
An argument: a typed scalar, or the slice marker "*" (4.2).
Batch
The answer to a batch (5.7).
ErrorCode
One variant per E_* code of SPEC 10.2 (spec-0.4.3). 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 optional extent.
Fault
A formula evaluation fault (SPEC 5.5, 15.11; spec-0.4.0): the optional fault member of a not_covered envelope. The cell has no value, deterministically; this is not missing data. These are formula codes, not verification codes, so they are not ErrorCodes.
ForeignDetail
What failed in reaching a foreign mesh (SPEC 5.5, spec-0.4.3): the detail member, required with E_FOREIGN_UNAVAILABLE (ErrorCode::ForeignUnavailable) and forbidden in every other envelope. The list is closed; it is non-exhaustive only so that later revisions can add to it.
Level
How far a receipt verified.
LicenceReason
The named outcome of licence inheritance (8.5) and of the entitlement check (10.3): a string, not an error code. Three reasons give a licence (entitled), five refuse (not entitled).
Outcome
The eight outcomes of 5.5.
RateSide
One side of a rate: a currency code or an argument reference.
Retrieval
What one HTTPS GET of 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).
TrustLabel
The four trust labels of SPEC 5.5 (spec-0.4.2), computed included.
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 verify asks it only for what step 7 reaches for the receipt at hand:

Functions§

batch_body
A batch answer’s body (5.7): one {envelope, status} per answer, in order.
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), order and extent included (spec-0.4.0; see FunctionDescriptor).
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. None when the URL is not under https://<mesh>/cell/.
check_answer
Checks an envelope (5.5) answering a /cell request or a job URL, of any outcome and trust label, in the order of 5.5: strict JSON, members, HTTP status, the receipt through step 6 of 10.1, the binding to request (cell id, asof, the pin and its echo, the echoed request and job of pending), then trust (with computed against the signer and poll against the host when request names the mesh asked) and superseded_by. Never touches the network.
check_batch
Checks the answer to a batch (5.7) of requests: for 200, an array with one {envelope, status} per request (status an integer 100-599), else E_ENVELOPE for the whole; then each item as an envelope (5.5) with its status against its own request, a failing item reported in its place. Any other status is one envelope of a refusal outcome, with nothing to bind.
check_entitlement
The entitlement check (SPEC 10.3, spec-0.4.3), a pure function of R, L and K: receipt (R, which the caller has verified through step 6 of 10.1), input_licences (L, the licences of R’s input receipts, slice members included, one per receipt, as step 7.5 obtains them) and key_document (K, the checked key document of R’s publisher, the host of R.cell.ns, even when computed_by names another host).
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, then trust and superseded_by. Never touches the network. A not_covered envelope’s fault (spec-0.4.0) is checked and accepted; check_envelope_extras also returns it.
check_envelope_any
Checks a response envelope (5.5) of any of the nine outcomes, pending included (spec-0.4.1), in the order of its procedure, and binds it to request: a pending envelope’s echoed request to the request made (and its job to the job polled, when request has one), any other outcome to the original request’s cell id and asof, whether it answers the /cell request or the job URL. E_JOB_UNKNOWN is accepted only in a bad_request answering a job URL (request with a job). Never touches the network.
check_envelope_extras
check_envelope, also returning the members Envelope has no field for (EnvelopeExtras): the fault of a not_covered envelope, one of the six formula evaluation faults of SPEC 5.5 (E_ENVELOPE for any other value, or on another outcome).
check_slice_answer
Checks an answer of the slice endpoint (5.6) against request: stale and pending are not answers there; ok is a page, checked as 5.6 says (its members, the slice id, next, then each member’s receipt through step 6 of 10.1, membership, asof, trust and key order after after); every other outcome as in 5.5.
fetch_keysDeprecated
Fetches https://<host>/.well-known/datumesh.json and checks it (9.2, 9.3).
format_reference
Writes the one URI of a reference (5.2), its pin as &fn_hash= before &asof=. format_reference(&parse_reference(u, s)?) == u for every accepted u.
format_uri
Writes the one URI of a cell reference (5.2). format_uri(&parse_uri(u, s)?) == u for every accepted u.
function_hash
The function hash of a descriptor given as JSON text (7, 6.3), order and extent included.
https_url
The HTTPS URL of a cell URI on mesh host mesh (5.3): https://<mesh>/cell/<rest>. mesh must be a DNS name (E_CANON_NAME), uri must start with cell:// (E_PARSE_URI).
inherit_licence
Licence inheritance (SPEC 8.5, spec-0.4.3): the licence of a computed receipt for the function function (its full name, cell.ns + "/" + cell.fn) to be issued at issued, from licences, the licences of its input receipts (every receipt hash in inputs and every member of each slice entry’s manifest, one per receipt, repeats allowed), declarations, those of the function’s publisher (the key document of the host of cell.ns, whatever host signs; None or empty when it has none), and mesh_licence, the mesh’s own licence for a cell with no input receipt.
key_document_from_response
keys_from_response, keeping the document’s declarations (spec-0.4.3): the KeyDocument of a 200 response with a valid document, E_KEY_DOC for a 200 with an invalid or missing one, E_KEY_UNAVAILABLE for any other status.
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). body is None when a 200 response carried no document.
parse_reference
Parses a cell URI, pinned or not, against a function signature (5.4, spec-0.4.2), reporting the first failure in the order 5.4 defines: the pin fn_hash=<64 hex> comes after the arguments and before asof, and is checked (E_CANON_HEX) after the arguments’ values and before asof. For a pinned URI, signature is that of the pinned descriptor.
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 what GET https://<host>/.well-known/datumesh.json and GET https://<host>/.well-known/datumesh-mesh.json gave. 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.md 3), from the descriptor and cell JSON texts.
resolved_unit_value
resolved_unit over parsed JSON values.
sha256
SHA-256 of data.
sha256_hex
SHA-256 of data as 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): reject S >= L, non-canonical A or R, points that do not decode, small-order A or R; then accept exactly when the encoding of [S]B - [k]A equals R (the cofactorless equation). Mixed-order keys are accepted.

Type Aliases§

Args
An argument map, keyed by argument name (byte order equals JCS order for names).
Result
Shorthand used throughout the crate.