1use super::CloudSyncObjectStorage;
4use coven_protocol::membership::{MembershipEntry, MembershipEntryRef};
5use coven_protocol::objects::{
6 ExactObjectRef, PreparedExactObject, ProtocolObjectContext, ProtocolObjectDomain, StorageError,
7 StoreObjectError,
8};
9use coven_protocol::store_commit::{
10 membership_entry_semantic_prefix, ObjectHash, StoreProtocolError,
11};
12
13pub async fn run_blocking_object_verification<T>(
14 semantic_prefix: &str,
15 object: &ExactObjectRef,
16 verify: Box<dyn FnOnce() -> Result<T, StoreProtocolError> + Send>,
17) -> Result<T, StoreObjectError>
18where
19 T: Send + 'static,
20{
21 coven_foundation::blocking::run(verify)
22 .await
23 .map_err(|source| {
24 StoreObjectError::Storage(StorageError::Blocking {
25 operation: "verify Store object",
26 source,
27 })
28 })?
29 .map_err(|source| StoreObjectError::InvalidObject {
30 semantic_prefix: semantic_prefix.to_string(),
31 key: object.slot().logical_key().to_string(),
32 source: Box::new(source),
33 })
34}
35
36pub async fn prepare_membership_entry(
37 storage: &dyn CloudSyncObjectStorage,
38 store_root_hash: ObjectHash,
39 entry: &MembershipEntry,
40) -> Result<(PreparedExactObject, MembershipEntryRef), StoreObjectError> {
41 let coord = entry.coord();
42 let semantic_prefix = membership_entry_semantic_prefix(
43 &coord.author_pubkey,
44 &coord.author_owner_grant,
45 coord.stream_id,
46 coord.seq,
47 coord.entry_hash,
48 );
49 let context = ProtocolObjectContext::signed_plaintext(
50 store_root_hash,
51 ProtocolObjectDomain::StoreMembershipEntry,
52 );
53 let slot = storage
54 .allocate_protocol_slot(&context, &semantic_prefix, ".json")
55 .await?;
56 let prepared = storage.prepare_protocol_object(
57 &context,
58 slot,
59 &semantic_prefix,
60 serde_json::to_vec(entry).expect("membership entry serialization cannot fail"),
61 )?;
62 let reference = MembershipEntryRef {
63 coord,
64 object: prepared.reference().clone(),
65 };
66 Ok((prepared, reference))
67}