pub trait Store: Resolver + Sealed {
Show 21 methods
// Required methods
fn put_descriptor(&self, bytes: &[u8]) -> Result<String>;
fn put_receipt(&self, bytes: &[u8]) -> Result<String>;
fn put_blob(&self, bytes: &[u8]) -> Result<String>;
fn blob(&self, sha256: &str) -> Result<Option<Cow<'_, [u8]>>>;
fn put_version(
&self,
cell_id: &str,
tx: &str,
receipt_hash: &str,
) -> Result<()>;
fn version_asof(&self, cell_id: &str, asof: &str) -> Result<Option<Version>>;
fn versions(
&self,
cell_id: &str,
from: &str,
to: &str,
) -> Result<Vec<Version>>;
fn latest(&self, cell_id: &str) -> Result<Option<Version>>;
fn dependents(&self, receipt_hash: &str) -> Result<Vec<String>>;
fn inputs(&self, receipt_hash: &str) -> Result<Vec<String>>;
fn put_namespace(
&self,
host: &str,
keydoc_bytes: &[u8],
validated_at: &str,
) -> Result<()>;
fn namespace(&self, host: &str) -> Result<Option<Namespace>>;
fn bind_name(&self, fn_name: &str, fn_hash: &str, tx: &str) -> Result<()>;
fn resolve_name(&self, fn_name: &str, asof: &str) -> Result<Option<String>>;
fn resolve_binding(
&self,
fn_name: &str,
asof: &str,
) -> Result<Option<Binding>>;
fn put_computed(
&self,
cell_id: &str,
tx: &str,
receipt_hash: &str,
) -> Result<()>;
fn computed_asof(
&self,
cell_id: &str,
asof: &str,
) -> Result<Option<Version>>;
fn stored_asof(&self, cell_id: &str, asof: &str) -> Result<Option<Version>>;
fn cell_dependents(&self, cell_id: &str) -> Result<Vec<String>>;
// Provided methods
fn computed_asof_with_receipt(
&self,
cell_id: &str,
asof: &str,
) -> Result<Option<(Version, Cow<'_, [u8]>)>> { ... }
fn stored_asof_with_receipt(
&self,
cell_id: &str,
asof: &str,
) -> Result<Option<(Version, Cow<'_, [u8]>)>> { ... }
}Expand description
A Datumesh store: a Resolver that can also be written to.
Instants are SPEC 3.3 instants (YYYY-MM-DDTHH:MM:SS.ffffffZ), hashes and cell ids 64
lowercase hex digits, hosts DNS names and function names fully qualified. Every method,
read or write, refuses anything else with the core’s error code (Error::Invalid),
and reports a database failure as Error::Database (or Error::PoolTimeout): a read
answers Ok(None) / Ok(vec![]) only when the store really holds nothing.
The Resolver methods keep the core’s Option signatures: there a malformed argument
or a database failure is None (logged with tracing when it is a failure), which
verify reports as unavailable.
Only this crate implements Store (it is sealed, since 0.3.0): the store is the trust
boundary, where every receipt is verified against its host’s key document before it is
kept, and what a store answers is relied on as checked. An implementation elsewhere
could answer anything. Store stays object-safe (Arc<dyn Store + Send + Sync>). Even a complete implementation that
delegates every method to a PgStore is refused (E0277: the private supertrait is
not implemented; tests/sealed.rs checks that this is the only error):
use std::borrow::Cow;
use datumesh_core::{Cell, Scalar};
use datumesh_store::{Binding, Namespace, PgStore, Resolver, Result, Store, Version};
struct Wrapper(PgStore);
impl Resolver for Wrapper {
fn descriptor(&self, h: &str) -> Option<Cow<'_, [u8]>> { self.0.descriptor(h) }
fn receipt(&self, h: &str) -> Option<Cow<'_, [u8]>> { self.0.receipt(h) }
fn evaluate(&self, c: &Cell, a: &str) -> Option<Scalar> { self.0.evaluate(c, a) }
}
impl Store for Wrapper {
fn put_descriptor(&self, b: &[u8]) -> Result<String> { self.0.put_descriptor(b) }
fn put_receipt(&self, b: &[u8]) -> Result<String> { self.0.put_receipt(b) }
fn put_blob(&self, b: &[u8]) -> Result<String> { self.0.put_blob(b) }
fn blob(&self, s: &str) -> Result<Option<Cow<'_, [u8]>>> { self.0.blob(s) }
fn put_version(&self, c: &str, t: &str, r: &str) -> Result<()> { self.0.put_version(c, t, r) }
fn version_asof(&self, c: &str, a: &str) -> Result<Option<Version>> { self.0.version_asof(c, a) }
fn versions(&self, c: &str, f: &str, t: &str) -> Result<Vec<Version>> { self.0.versions(c, f, t) }
fn latest(&self, c: &str) -> Result<Option<Version>> { self.0.latest(c) }
fn dependents(&self, r: &str) -> Result<Vec<String>> { self.0.dependents(r) }
fn inputs(&self, r: &str) -> Result<Vec<String>> { self.0.inputs(r) }
fn put_namespace(&self, h: &str, k: &[u8], v: &str) -> Result<()> { self.0.put_namespace(h, k, v) }
fn namespace(&self, h: &str) -> Result<Option<Namespace>> { self.0.namespace(h) }
fn bind_name(&self, n: &str, f: &str, t: &str) -> Result<()> { self.0.bind_name(n, f, t) }
fn resolve_name(&self, n: &str, a: &str) -> Result<Option<String>> { self.0.resolve_name(n, a) }
fn resolve_binding(&self, n: &str, a: &str) -> Result<Option<Binding>> { self.0.resolve_binding(n, a) }
fn put_computed(&self, c: &str, t: &str, r: &str) -> Result<()> { self.0.put_computed(c, t, r) }
fn computed_asof(&self, c: &str, a: &str) -> Result<Option<Version>> { self.0.computed_asof(c, a) }
fn stored_asof(&self, c: &str, a: &str) -> Result<Option<Version>> { self.0.stored_asof(c, a) }
fn cell_dependents(&self, c: &str) -> Result<Vec<String>> { self.0.cell_dependents(c) }
}Required Methods§
Sourcefn put_descriptor(&self, bytes: &[u8]) -> Result<String>
fn put_descriptor(&self, bytes: &[u8]) -> Result<String>
Stores a descriptor (checked and canonicalised by the core); returns its function hash. Idempotent.
Sourcefn put_receipt(&self, bytes: &[u8]) -> Result<String>
fn put_receipt(&self, bytes: &[u8]) -> Result<String>
Stores a receipt that verifies (SPEC 10.1 steps 1-6) against the key document stored
for its signer host with put_namespace, in canonical form,
with an edge to each of its inputs; returns its hash. A receipt that does not verify
is refused with verify’s code (no key document for the host: E_KEY_UNAVAILABLE).
Idempotent: bytes whose canonical form is the stored copy return its hash without
checking the signature again (it verified when stored), even if the key has since
been revoked. Other bytes with a stored hash are verified first, then refused as
Error::Conflict.
Sourcefn put_blob(&self, bytes: &[u8]) -> Result<String>
fn put_blob(&self, bytes: &[u8]) -> Result<String>
Stores blob content; returns its SHA-256 (lowercase hex). Idempotent.
Sourcefn put_version(&self, cell_id: &str, tx: &str, receipt_hash: &str) -> Result<()>
fn put_version(&self, cell_id: &str, tx: &str, receipt_hash: &str) -> Result<()>
Appends a version: from tx on, cell_id has the value of receipt receipt_hash,
which must be stored, of that cell and at that tx. tx must be later than the cell’s
latest version (Error::NotLater).
Sourcefn version_asof(&self, cell_id: &str, asof: &str) -> Result<Option<Version>>
fn version_asof(&self, cell_id: &str, asof: &str) -> Result<Option<Version>>
The cell’s latest version with tx <= asof.
Sourcefn versions(&self, cell_id: &str, from: &str, to: &str) -> Result<Vec<Version>>
fn versions(&self, cell_id: &str, from: &str, to: &str) -> Result<Vec<Version>>
The cell’s versions with from <= tx <= to, in tx order.
Sourcefn dependents(&self, receipt_hash: &str) -> Result<Vec<String>>
fn dependents(&self, receipt_hash: &str) -> Result<Vec<String>>
The stored receipts that list receipt_hash among their inputs, by hash.
Sourcefn inputs(&self, receipt_hash: &str) -> Result<Vec<String>>
fn inputs(&self, receipt_hash: &str) -> Result<Vec<String>>
The inputs of a stored receipt, by hash (whether or not they are stored).
Sourcefn put_namespace(
&self,
host: &str,
keydoc_bytes: &[u8],
validated_at: &str,
) -> Result<()>
fn put_namespace( &self, host: &str, keydoc_bytes: &[u8], validated_at: &str, ) -> Result<()>
Records a host’s key document, checked as a 200 response for that host would be
(SPEC 9.2, 9.3), validated at validated_at. Re-validation replaces the document; a
validated_at earlier than the recorded one is Error::NotLater. Receipts already
stored are not re-checked: they verified when they were stored (and putting one again
stays idempotent).
Sourcefn bind_name(&self, fn_name: &str, fn_hash: &str, tx: &str) -> Result<()>
fn bind_name(&self, fn_name: &str, fn_hash: &str, tx: &str) -> Result<()>
Appends a binding: from tx on, the fully qualified function name fn_name means
fn_hash, whose descriptor must be stored. tx must be later than the name’s latest
binding (Error::NotLater).
Sourcefn resolve_name(&self, fn_name: &str, asof: &str) -> Result<Option<String>>
fn resolve_name(&self, fn_name: &str, asof: &str) -> Result<Option<String>>
The function hash fn_name meant as of asof: the hash of
resolve_binding’s binding.
Sourcefn resolve_binding(&self, fn_name: &str, asof: &str) -> Result<Option<Binding>>
fn resolve_binding(&self, fn_name: &str, asof: &str) -> Result<Option<Binding>>
The binding of fn_name that answers as of asof: the one with the latest tx <= asof, with its function hash and its tx, when it began; None before the first.
A name bound again to a hash it meant before (even the hash of the binding before
it) begins again: the later binding’s tx. Since 0.3.0.
Sourcefn put_computed(
&self,
cell_id: &str,
tx: &str,
receipt_hash: &str,
) -> Result<()>
fn put_computed( &self, cell_id: &str, tx: &str, receipt_hash: &str, ) -> Result<()>
Records that receipt_hash (stored, a receipt of cell_id at tx) is a computed
version of the cell. Insert-only, in any order (an older version may be added after a
newer one): tx need not be later than anything. The version’s asof is the
receipt’s. Idempotent for the same (cell_id, tx, asof, receipt_hash); another receipt
for an existing (cell_id, tx, asof) is Error::Conflict (its hash is the receipt
refused) and the stored one is kept. The receipt is checked as for
put_version: Error::NotFound when it is not stored,
Error::Mismatch when it is of another cell or at another tx. Since 0.2.0.
Sourcefn computed_asof(&self, cell_id: &str, asof: &str) -> Result<Option<Version>>
fn computed_asof(&self, cell_id: &str, asof: &str) -> Result<Option<Version>>
The computed version that answers as of asof: the one with the greatest asof <=
asof (between equal asof, the greatest tx), or None. Since 0.2.0.
Sourcefn stored_asof(&self, cell_id: &str, asof: &str) -> Result<Option<Version>>
fn stored_asof(&self, cell_id: &str, asof: &str) -> Result<Option<Version>>
The stored version that answers as of asof: the latest version (by tx) with tx <= asof whose receipt’s asof is also <= asof, or None. A version whose receipt is
late-signed (asof later than tx) answers only from its asof on; until then the
version before it answers. (version_asof keeps its tx-only
meaning.) Since 0.2.0.
Provided Methods§
Sourcefn computed_asof_with_receipt(
&self,
cell_id: &str,
asof: &str,
) -> Result<Option<(Version, Cow<'_, [u8]>)>>
fn computed_asof_with_receipt( &self, cell_id: &str, asof: &str, ) -> Result<Option<(Version, Cow<'_, [u8]>)>>
computed_asof and the bytes of the version’s receipt (as
receipt returns them), which is what a caller reads next.
The default asks for the two in turn (a receipt that cannot be read then is
Error::NotFound); PgStore answers both with one query. Since 0.2.0.
Sourcefn stored_asof_with_receipt(
&self,
cell_id: &str,
asof: &str,
) -> Result<Option<(Version, Cow<'_, [u8]>)>>
fn stored_asof_with_receipt( &self, cell_id: &str, asof: &str, ) -> Result<Option<(Version, Cow<'_, [u8]>)>>
stored_asof and the bytes of the version’s receipt, as
computed_asof_with_receipt does. Since 0.2.0.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".