Skip to main content

coven_protocol/
store_commit.rs

1//! Signed, hash-addressed Store commit protocol objects.
2
3use std::collections::BTreeMap;
4use std::collections::BTreeSet;
5use std::fmt;
6use std::str::FromStr;
7
8use serde::{Deserialize, Serialize};
9
10use super::membership::{
11    verify_membership_entry, AuthorHead, AuthorStreamId, MembershipChange, MembershipCoord,
12    MembershipEntry, MembershipEntryRef, MembershipGrantCreationAuthority, MembershipGrantId,
13    MembershipHeadRef, StoreMembershipConflictResolution, StoreMembershipConflictResolutionRef,
14};
15use crate::circle::{
16    AccessLeafId, CircleBootstrapCoverageRef, CircleBootstrapRef, CircleControlCoord,
17    CircleEpochId, CircleId, CircleMetadataCoord, CircleMetadataHeadRef,
18    CircleRosterConflictResolutionRef, CircleRosterCoord, CircleRosterHeadRef,
19};
20use crate::circle_control::StoreMembershipStateRef;
21use crate::objects::ObjectSlot;
22use crate::objects::{ExactObjectRef, ProviderDeviceBinding};
23use crate::write::WriteId;
24use coven_keys::encryption::KeyFingerprint;
25use coven_keys::keys::{self, UserKeypair};
26
27mod ack_snapshot;
28mod batch_commit;
29mod circle_ack;
30mod circle_snapshot;
31mod device_join;
32pub mod device_join_exchange;
33pub mod device_join_journal;
34mod device_state;
35mod heads;
36mod identifiers;
37mod membership_rollup;
38mod operation_refs;
39mod packages;
40mod protocol_root;
41mod publication;
42mod registration;
43mod retained_history;
44mod signed;
45mod validation;
46
47pub use ack_snapshot::*;
48pub use batch_commit::*;
49pub use circle_ack::*;
50pub use circle_snapshot::*;
51pub use device_join::*;
52pub use device_state::*;
53pub use heads::*;
54pub use identifiers::*;
55pub use membership_rollup::*;
56pub use packages::*;
57pub use protocol_root::*;
58pub use publication::*;
59pub use registration::*;
60pub use retained_history::*;
61pub use signed::{Signed, SignedBody};
62pub use validation::*;
63
64mod ordered_map_entries {
65    use std::collections::BTreeMap;
66
67    use serde::{Deserialize, Deserializer, Serialize, Serializer};
68
69    pub(super) fn serialize<K, V, S>(map: &BTreeMap<K, V>, serializer: S) -> Result<S::Ok, S::Error>
70    where
71        K: Ord + Serialize,
72        V: Serialize,
73        S: Serializer,
74    {
75        map.iter().collect::<Vec<_>>().serialize(serializer)
76    }
77
78    pub(super) fn deserialize<'de, K, V, D>(deserializer: D) -> Result<BTreeMap<K, V>, D::Error>
79    where
80        K: Ord + Deserialize<'de>,
81        V: Deserialize<'de>,
82        D: Deserializer<'de>,
83    {
84        let entries = Vec::<(K, V)>::deserialize(deserializer)?;
85        let entry_count = entries.len();
86        let map = entries.into_iter().collect::<BTreeMap<_, _>>();
87        if map.len() != entry_count {
88            return Err(serde::de::Error::custom(
89                "ordered map entries contain a duplicate key",
90            ));
91        }
92        Ok(map)
93    }
94}
95
96pub const STORE_PROTOCOL_VERSION: u32 = 1;
97
98pub(crate) const STORE_PROTOCOL_ROOT_SEMANTIC_PATH: &str = "store-v1/store-protocol-root";
99#[cfg(any(test, feature = "test-utils"))]
100pub const STORE_PROTOCOL_ROOT_LOGICAL_KEY: &str = "store-v1/store-protocol-root.json";
101pub(crate) const STORE_CANDIDATE_PREFIX: &str = "store-v1/candidates/";
102pub(crate) const STORE_HEAD_PREFIX: &str = "store-v1/heads/";
103pub(crate) const STORE_ACK_PREFIX: &str = "store-v1/acks/";
104pub(crate) const STORE_DEVICE_REGISTRATION_PREFIX: &str = "store-v1/devices/";
105pub(crate) const STORE_DEVICE_JOIN_ABANDONMENT_PREFIX: &str = "store-v1/device-join-abandonments/";
106pub(crate) const STORE_DEVICE_JOIN_CLEANUP_RECEIPT_PREFIX: &str =
107    "store-v1/device-join-cleanup-receipts/";
108pub(crate) const STORE_DEVICE_EXCLUSION_PROPOSAL_PREFIX: &str =
109    "store-v1/device-exclusion-proposals/";
110pub(crate) const STORE_DEVICE_EXCLUSION_OUTCOME_PREFIX: &str =
111    "store-v1/device-exclusion-outcomes/";
112pub(crate) const STORE_PROVIDER_ACCESS_GRANT_PREFIX: &str = "store-v1/provider-access/grants/";
113pub(crate) const STORE_OWNER_RECOVERY_PREFIX: &str = "store-v1/recovery/";
114pub(crate) const STORE_SNAPSHOT_META_PREFIX: &str = "store-v1/snapshots/";
115pub(crate) const STORE_SNAPSHOT_IMAGE_PREFIX: &str = "store-v1/snapshot-images/";
116pub(crate) const STORE_MEMBERSHIP_ENTRY_PREFIX: &str = "store-v1/membership/entries/";
117pub(crate) const STORE_MEMBERSHIP_HEAD_PREFIX: &str = "store-v1/membership/heads/";
118pub(crate) const STORE_MEMBERSHIP_ROLLUP_PREFIX: &str = "store-v1/membership-rollups/";
119
120const STORE_PROTOCOL_ROOT_DOMAIN: &[u8] = b"coven.store-protocol-root.v1\0";
121const COMMIT_DOMAIN: &[u8] = b"coven.store-batch-commit.v1\0";
122const HEAD_DOMAIN: &[u8] = b"coven.store-device-head.v1\0";
123const REGISTRATION_DOMAIN: &[u8] = b"coven.store-device-registration.v1\0";
124const DEVICE_READINESS_DOMAIN: &[u8] = b"coven.device-readiness.v1\0";
125const DEVICE_EXCLUSION_PROPOSAL_DOMAIN: &[u8] = b"coven.store-device-exclusion-proposal.v1\0";
126const DEVICE_EXCLUSION_DOMAIN: &[u8] = b"coven.store-device-exclusion.v1\0";
127const DEVICE_EXCLUSION_CANCELLATION_DOMAIN: &[u8] =
128    b"coven.store-device-exclusion-cancellation.v1\0";
129const OWNER_RECOVERY_NODE_DOMAIN: &[u8] = b"coven.owner-recovery-node.v1\0";
130const ACK_DOMAIN: &[u8] = b"coven.store-ack.v1\0";
131const CIRCLE_ACK_DOMAIN: &[u8] = b"coven.circle-ack.v1\0";
132const CIRCLE_SNAPSHOT_DOMAIN: &[u8] = b"coven.circle-snapshot-meta.v1\0";
133const SNAPSHOT_DOMAIN: &[u8] = b"coven.snapshot-meta.v1\0";
134const MEMBERSHIP_ROLLUP_DOMAIN: &[u8] = b"coven.store-membership-rollup.v1\0";
135const CANDIDATE_FAMILY_DOMAIN: &[u8] = b"coven.candidate-family.v1\0";
136const STREAM_ACTIVATION_ID_DOMAIN: &[u8] = b"coven.stream-activation-id.v1\0";
137const AUTHOR_STREAM_ID_DOMAIN: &[u8] = b"coven.author-stream-id.v1\0";
138const STORE_PUBLICATION_ENTRY_DOMAIN: &[u8] = b"coven.store-publication-entry.v1\0";
139const STORE_CURRENT_PUBLICATION_DOMAIN: &[u8] = b"coven.store-current-publication.v1\0";
140
141#[cfg(test)]
142#[path = "store_commit/tests.rs"]
143mod tests;