coven_protocol/
circle_activation.rs1use std::collections::{BTreeMap, BTreeSet};
2
3use serde::{Deserialize, Serialize};
4
5use crate::circle::{
6 AccessEnvelope, CircleAccessDisposition, CircleAccessLeaf, CircleBootstrapRef, CircleControl,
7 CircleControlCoord, CircleEpochCloseId, CircleId, CircleMetadata, PreparedAccessLeaf,
8 PreparedCircleAccess, PreparedCircleControl,
9};
10use crate::circle_roster::CircleMaterializedRoster;
11use crate::store_commit::{
12 CandidateFamilyId, CircleAccessObjectRef, CircleControlRef, CirclePackageRef, ObjectHash,
13 StoreBatchCommit, StoreBatchCommitRef, StoreDeviceRegistration, StoreDeviceRegistrationRef,
14 StreamActivation, StreamActivationId, VerifiedStoreBatchCommit,
15};
16use coven_keys::encryption::{EncryptionService, KeyFingerprint, MasterKeyring};
17
18#[derive(Debug, thiserror::Error)]
26pub enum CircleStateError {
27 #[error("invalid Circle state: {0}")]
28 Invariant(String),
29 #[error("invalid Circle state protocol: {0}")]
30 Protocol(#[from] crate::store_commit::StoreProtocolError),
31 #[error("{operation}: {source}")]
32 Json {
33 operation: &'static str,
34 #[source]
35 source: serde_json::Error,
36 },
37 #[error("{operation} for Circle {circle_id}: {source}")]
38 Encryption {
39 operation: &'static str,
40 circle_id: crate::circle::CircleId,
41 #[source]
42 source: coven_keys::encryption::EncryptionError,
43 },
44}
45
46mod access;
47mod activations;
48mod current_state;
49
50pub use access::{
51 CircleEpochAccess, LocalCircleExclusion, VerifiedCircleAccess, VerifiedCircleActive,
52 VerifiedCircleImage, VerifiedCircleReference,
53};
54pub use activations::{
55 VerifiedCircleActivations, VerifiedStreamActivationPrefix, VerifiedStreamActivations,
56};
57#[cfg(any(test, feature = "test-utils"))]
58pub use current_state::CircleCurrentControl;
59pub use current_state::{CircleAuthoringState, CircleCurrentState};
60
61pub fn verify_control_context_for_verified_commit(
62 reference: &CircleControlRef,
63 control: &PreparedCircleControl,
64 verified: &VerifiedStoreBatchCommit,
65) -> Result<(), CircleStateError> {
66 verified.reference().verify_commit(verified.value())?;
67 let commit = verified.value();
68 let author = verified.author();
69 let device_matches = control.value.value.order.device_id == author.device_id.to_string();
70 if !control.verify()
71 || reference.circle_id() != control.value.circle_id
72 || reference.control() != &control.coord
73 || control.value.store_root_hash != commit.store_root_hash
74 || control.value.author_pubkey != author.author_pubkey
75 || !device_matches
76 {
77 return Err(CircleStateError::Invariant(
78 "circle control context differs from its Store reference and commit".to_string(),
79 ));
80 }
81 Ok(())
82}
83
84#[cfg(test)]
85mod derived_state_tests;