datumesh-core
The Rust core of the Datumesh protocol: strict JSON and RFC 8785 canonical bytes, cell URIs, key documents, response envelopes, unit resolution, and offline verification of signed receipts. It implements the specification (SPEC.md and units.md, revision spec-0.2.1) and passes every one of its 339 test vectors.
Example
[]
= "0.3.1"
Verify the receipt of spec/vectors/receipt/stored-number.json against the key documents the vector carries, then recompute it with the descriptor and value the vector's recompute object supplies:
use ;
use ;
It prints verified signed receipt 19a5fe3a744c5792f747fb4c286ce396ab44b95922de4f07937502fe595b6f81, then the same line with recomputed. A resolver that has the descriptor and inputs but cannot evaluate the function (evaluate returns None) leaves the receipt ok at level signed with code E_EVAL_UNAVAILABLE. Passing blob content runs step 7.7.
With feature sign, an engine makes receipts: SigningKey::from_seed (deterministic Ed25519, RFC 8032) and ReceiptBuilder, whose sign checks the members as Receipt::from_json would and derives computed_by from the signer host and the key. Signing the members of every vector receipt with the vector's seed reproduces its payload, signature and hash byte for byte.
What is in the crate
json: strict parsing (SPEC 6.1) and RFC 8785 JCS, including ECMAScript number formatting:parse,Value,Value::to_jcs.Scalar,Cell,CellRef,Descriptor,Receipt,KeyDoc,Envelope, andcanonicalize_*,cell_hash,function_hash,receipt_hash.parse_uri,format_uri,https_url: cell URIs and their HTTPS mapping.verify: SPEC 10.1 steps 1-7, with Ed25519 strictness as step 6 defines it; step 7 through aResolver(MapResolverincluded).SigningKeyandReceiptBuilderbehind the non-defaultsignfeature.keys_from_responseandKeys.fetch_keys(featurefetch) is deprecated since 0.3.1 and removed at 1.0: fetchhttps://<host>/.well-known/datumesh.jsonwith your own HTTP client and pass the status and body tokeys_from_response.testkit(non-default featuretestkit): a conformance kit forResolverimplementations (see below).check_envelope: response envelopes, bound to the request.resolved_unit: the unit of a cell's value.Errorwith anErrorCodefor every code of SPEC 10.2 (plusE_EVAL_UNAVAILABLE, DEFECTS.md RS-28), and a JSON path.
No unsafe, no panics on any input, no global state, no logging, no network outside the deprecated fetch_keys. Builds for wasm32-unknown-unknown, with or without sign and testkit. Minimum Rust version 1.97. The public API is frozen until 1.0 except for additions; API-CHANGES-0.3.0.md lists what changed from 0.2.1, API-CHANGES-0.3.1.md what was added in 0.3.1, and CHANGELOG.md the history.
Testing a resolver
A Resolver (a store, a cache, an engine's lookup) can check itself against the protocol with feature testkit, as a dev-dependency:
[]
= { = "0.3.1", = ["testkit"] }
The kit never writes through the resolver. It gives you Fixtures (descriptors, receipts and the versions of stored cells, all canonical JSON, from the specification's vectors plus a few receipts signed for the kit), you load them, and it verifies receipts through your resolver and looks things up in it:
use Kit;
It checks that verify asks the resolver only for what step 7 reaches (through the Recording wrapper), that what the resolver lacks is E_FN_UNAVAILABLE, E_INPUT_UNAVAILABLE or E_EVAL_UNAVAILABLE and that unknown or malformed hashes give None, that descriptor and receipt return exactly the bytes loaded, and that evaluate gets the receipt's asof; for a time-aware resolver, that a cell with versions at several times gives the latest version with tx <= asof. Each check (check_lazy_calls, check_unavailable, check_bytes, check_asof) can also run on its own. MapResolver passes it (not time-aware).
Repository
crates/datumesh-core: the library.crates/datumesh-cli:datumesh-cli run-vectors(JSON lines in, one result per line out) anddatumesh-cli check [DIR], for the cross-language harness. Not published.spec/: the specification, a git submodule.DEFECTS.md: every place the specification text was not enough to decide something.public-api.txt,public-api-all-features.txt: the public API (cargo public-api -ss) with default features and with--all-features;API-CHANGES-0.3.0.md: the diff against 0.2.1, justified;API-CHANGES-0.3.1.md: the additions in 0.3.1.crates/datumesh-core/src/testkit/data.rs: the kit's fixtures, generated fromspec/(and signed with featuresign) bytests/testkit_data.rs, which fails if they drift.fuzz/: cargo-fuzz targets.wasm-smoke/: the WebAssembly smoke test.tools/gen_tables.py: regenerates the embedded unit list and Unicode 15.1 table fromspec/.
Licensed under Apache-2.0.