Skip to main content

uor_addr/variant/
storage.rs

1//! **`uor_addr::variant::storage` — the cost-model-bearing variant**
2//! (ARCHITECTURE.md "Cost-model-bearing variants" § `uor-addr-storage`).
3//!
4//! Content-addressed-storage realization of UOR-ADDR, binding the
5//! 5th model parameter to a non-default `C: TypedCommitment` per
6//! ADR-048. The κ-derivation surface is **identical** to
7//! [`crate::json`]'s; the only difference is the `C` selection,
8//! which expresses the storage tier's typed-bandwidth admission of
9//! κ-labels as a typed `ObservablePredicate` conjunction per
10//! ADR-047 U6's bandwidth-additivity.
11//!
12//! ## Concrete `C` selection
13//!
14//! ```text
15//! C = AndCommitment<
16//!         EmptyCommitment,
17//!         SingletonCommitment<LexicographicLessEqThreshold>,
18//!     >
19//! ```
20//!
21//! The architectural commitment per ARCHITECTURE.md is
22//! `AndCommitment<EmptyCommitment, PayloadCommitment<K>>` where
23//! `PayloadCommitment<K>` is a K-bit typed-bandwidth admission
24//! predicate. `prism::pipeline` does not currently publish a
25//! `PayloadCommitment<K>` primitive; the closest standing
26//! `ObservablePredicate` from the foundation's published roster is
27//! [`LexicographicLessEqThreshold`] (a big-endian unsigned
28//! threshold comparison; admits κ-labels whose σ-projection's
29//! digest is lexicographically ≤ target). This module binds the
30//! published primitive directly so the variant is **fully working
31//! against the foundation's published surface**; the storage
32//! variant's `accept_prob` is determined by the threshold (K-bit
33//! payload admission is `2^-K`; the shipped 50% threshold is the
34//! corresponding K = 1 case).
35//!
36//! When `PayloadCommitment<K>` lands in `prism::pipeline`, this
37//! module will be retargeted at it; the architectural surface — the
38//! `AndCommitment<EmptyCommitment, …>` shape — does not change.
39//!
40//! ## Threshold selection
41//!
42//! [`STORAGE_THRESHOLD`] is a 32-byte big-endian target that
43//! admits approximately 50% of κ-labels (digest's high byte ≤
44//! `0x7F`). This is the minimum non-trivial threshold demonstrating
45//! the architectural surface admits non-default `C` selections.
46//!
47//! ## Wiki commitments
48//!
49//! - **ADR-048 `C: TypedCommitment`** — the 5th `PrismModel`
50//!   parameter binds the cost-model commitment; the model
51//!   declaration in [`AddressStorageModel`] supplies a non-default
52//!   selection.
53//! - **ADR-047 U6 bandwidth-additivity** — `AndCommitment<A, B>`
54//!   composes via bandwidth-bits addition per the Hardening
55//!   Principle's U6 axiom.
56//! - **QS-06 storage-tier admission** — the κ-label's admission to
57//!   the storage tier is determined by the typed predicate; the
58//!   surface model demonstrates the QS-06 exemplar shape.
59
60use prism::pipeline::{
61    prism_model, AndCommitment, EmptyCommitment, LexicographicLessEqThreshold, SingletonCommitment,
62};
63use prism::vocabulary::DefaultHostTypes;
64
65use crate::bounds::AddrBounds;
66use crate::json::value::JsonCarrier;
67use crate::label::AddressLabel;
68use crate::resolvers::AddressResolverTuple;
69use prism::crypto::Sha256Hasher;
70
71#[allow(unused_imports)]
72use crate::json::verbs::{address_inference, VERB_TERMS_ADDRESS_INFERENCE};
73
74/// **The storage-admission threshold** — a 32-byte big-endian target
75/// admitting approximately 50% of κ-labels. The predicate accepts iff
76/// the digest's big-endian unsigned integer value is ≤ this target.
77///
78/// Approximate accept probability: `(0x7F + 1) / 256 = 0.5` (the
79/// digest's high byte ≤ `0x7F`).
80pub const STORAGE_THRESHOLD: &[u8] = &[
81    0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
82    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
83];
84
85/// **The cost-model commitment type for the storage variant** —
86/// the architectural `AndCommitment<EmptyCommitment, …>` shape.
87pub type StorageCommitment =
88    AndCommitment<EmptyCommitment, SingletonCommitment<LexicographicLessEqThreshold>>;
89
90/// **The storage commitment instance** — used by the model's
91/// `fn commitment()` clause to supply the runtime instance the
92/// catamorphism's `CommitmentEvaluated` trace event consults.
93pub const STORAGE_COMMITMENT_INSTANCE: StorageCommitment = AndCommitment {
94    left: EmptyCommitment,
95    right: SingletonCommitment {
96        predicate: LexicographicLessEqThreshold {
97            target: STORAGE_THRESHOLD,
98        },
99    },
100};
101
102prism_model! {
103    pub struct AddressStorageModel;
104    pub struct AddressStorageRoute;
105    impl PrismModel<
106        DefaultHostTypes,
107        AddrBounds,
108        Sha256Hasher,
109        AddressResolverTuple<Sha256Hasher>,
110        StorageCommitment
111    > for AddressStorageModel {
112        type Input = JsonCarrier<'a>;
113        type Output = AddressLabel;
114        type Route = AddressStorageRoute;
115        fn route(input: Self::Input) -> Self::Output {
116            address_inference(input)
117        }
118        fn commitment() -> StorageCommitment {
119            STORAGE_COMMITMENT_INSTANCE
120        }
121    }
122}
123
124#[cfg(test)]
125mod tests {
126    use super::*;
127    use prism::pipeline::{ObservablePredicate, TypedCommitment};
128
129    #[test]
130    fn storage_commitment_evaluates_predicate_against_digest() {
131        // STORAGE_THRESHOLD admits digests whose high byte ≤ 0x7F.
132        let admitted: [u8; 32] = [0; 32];
133        let rejected: [u8; 32] = [0xFF; 32];
134        let predicate = LexicographicLessEqThreshold {
135            target: STORAGE_THRESHOLD,
136        };
137        assert!(predicate.evaluate(&admitted));
138        assert!(!predicate.evaluate(&rejected));
139    }
140
141    #[test]
142    fn storage_commitment_carries_nontrivial_bandwidth() {
143        // ADR-048: bandwidth_bits = -log2(accept_prob). For the 50%
144        // threshold the accept_prob ≈ 0.5, so bandwidth ≈ 1 bit.
145        let bandwidth = STORAGE_COMMITMENT_INSTANCE.bandwidth_bits();
146        assert!(
147            (0.5..=1.5).contains(&bandwidth),
148            "1-bit bandwidth ± rounding ({bandwidth})"
149        );
150    }
151
152    #[test]
153    fn storage_commitment_is_typed_commitment() {
154        fn assert_is_typed_commitment<C: TypedCommitment>() {}
155        assert_is_typed_commitment::<StorageCommitment>();
156    }
157}