1use super::ownership::*;
2use super::*;
3
4impl RemoteObjectRecord {
5 fn candidate_exclusive_retained_authority(
6 family: CandidateFamilyId,
7 domain: CandidateExclusiveObjectDomain,
8 canonical_signed_bytes: &[u8],
9 stored_bytes: &[u8],
10 owner: StoreBatchCommitRef,
11 ) -> Result<ClosedRemoteObject, RemoteObjectRecordError> {
12 let object = domain.object().clone();
13 let record = Self::CandidateExclusive(CandidateObjectRecord {
14 identity: CandidateExclusiveTarget {
15 family,
16 domain,
17 semantic_hash: ObjectHash::digest(canonical_signed_bytes),
18 object,
19 },
20 payloads: RemoteObjectPayloads::SpooledInline,
21 state: CandidateObjectState::Prepared {
22 ownership: PendingCandidateOwnership {
23 pending: BTreeSet::from([owner]),
24 nonactivated: Vec::new(),
25 },
26 },
27 });
28 record.validate_payload(canonical_signed_bytes)?;
29 ClosedRemoteObject::with_spooled_payloads(record, canonical_signed_bytes, stored_bytes)
30 }
31
32 pub(super) fn candidate_activated_retained_authority(
33 domain: RetainedAuthorityObjectDomain,
34 semantic_hash: ObjectHash,
35 object: ExactObjectRef,
36 canonical_signed_bytes: &[u8],
37 stored_bytes: &[u8],
38 owner: StoreBatchCommitRef,
39 ) -> Result<ClosedRemoteObject, RemoteObjectRecordError> {
40 let record = Self::RetainedAuthority(RetainedAuthorityRecord {
41 identity: RetainedAuthorityObjectRef {
42 domain,
43 semantic_hash,
44 object,
45 },
46 payloads: RemoteObjectPayloads::SpooledInline,
47 state: RetainedAuthorityObjectState::Prepared {
48 ownership: PendingCandidateOwnership {
49 pending: BTreeSet::from([owner]),
50 nonactivated: Vec::new(),
51 },
52 },
53 });
54 record.validate_payload(canonical_signed_bytes)?;
55 ClosedRemoteObject::with_spooled_payloads(record, canonical_signed_bytes, stored_bytes)
56 }
57
58 pub fn candidate_commit(
59 identity: StoreBatchCommitRef,
60 canonical_signed_bytes: &[u8],
61 stored_bytes: &[u8],
62 ) -> Result<ClosedRemoteObject, RemoteObjectRecordError> {
63 let record = Self::CandidateCommit(CandidateCommitRecord {
64 identity,
65 semantic_hash: ObjectHash::digest(canonical_signed_bytes),
66 payloads: RemoteObjectPayloads::SpooledInline,
67 state: CandidateCommitState::Prepared,
68 });
69 record.validate_payload(canonical_signed_bytes)?;
70 ClosedRemoteObject::with_spooled_payloads(record, canonical_signed_bytes, stored_bytes)
71 }
72
73 pub fn candidate_activated_store_head(
74 reference: crate::store_commit::StoreDeviceHeadRef,
75 canonical_signed_bytes: &[u8],
76 stored_bytes: &[u8],
77 owner: StoreBatchCommitRef,
78 ) -> Result<ClosedRemoteObject, RemoteObjectRecordError> {
79 let object = reference.object.clone();
80 let head: crate::store_commit::StoreDeviceHead =
83 serde_json::from_slice(canonical_signed_bytes)?;
84 Self::candidate_activated_retained_authority(
85 RetainedAuthorityObjectDomain::DeviceHead {
86 reference,
87 head_commit: head.commit.clone(),
88 },
89 ObjectHash::digest(canonical_signed_bytes),
90 object,
91 canonical_signed_bytes,
92 stored_bytes,
93 owner,
94 )
95 }
96
97 pub(crate) fn candidate_activated_store_acknowledgement(
98 reference: crate::store_commit::StoreAckRef,
99 canonical_signed_bytes: &[u8],
100 stored_bytes: &[u8],
101 owner: StoreBatchCommitRef,
102 ) -> Result<ClosedRemoteObject, RemoteObjectRecordError> {
103 let object = reference.object.clone();
104 Self::candidate_activated_retained_authority(
105 RetainedAuthorityObjectDomain::Acknowledgement { reference },
106 ObjectHash::digest(canonical_signed_bytes),
107 object,
108 canonical_signed_bytes,
109 stored_bytes,
110 owner,
111 )
112 }
113
114 pub(crate) fn candidate_activated_circle_acknowledgement(
115 reference: CircleAckRef,
116 canonical_semantic_bytes: &[u8],
117 stored_bytes: &[u8],
118 owner: StoreBatchCommitRef,
119 ) -> Result<ClosedRemoteObject, RemoteObjectRecordError> {
120 let object = reference.object.clone();
121 Self::candidate_activated_retained_authority(
122 RetainedAuthorityObjectDomain::CircleAcknowledgement { reference },
123 ObjectHash::digest(canonical_semantic_bytes),
124 object,
125 canonical_semantic_bytes,
126 stored_bytes,
127 owner,
128 )
129 }
130
131 pub fn candidate_activated_store_membership_resolution(
132 reference: crate::membership::StoreMembershipConflictResolutionRef,
133 canonical_semantic_bytes: &[u8],
134 stored_bytes: &[u8],
135 candidate: StoreBatchCommitRef,
136 ) -> Result<ClosedRemoteObject, RemoteObjectRecordError> {
137 let semantic_hash = ObjectHash::digest(canonical_semantic_bytes);
138 let object = reference.object.clone();
139 Self::candidate_activated_retained_authority(
140 RetainedAuthorityObjectDomain::StoreMembershipResolution { reference },
141 semantic_hash,
142 object,
143 canonical_semantic_bytes,
144 stored_bytes,
145 candidate,
146 )
147 }
148
149 pub fn candidate_exclusive_merge_membership_entry(
150 family: CandidateFamilyId,
151 reference: crate::membership::MembershipEntryRef,
152 canonical_signed_bytes: &[u8],
153 stored_bytes: &[u8],
154 owner: StoreBatchCommitRef,
155 ) -> Result<ClosedRemoteObject, RemoteObjectRecordError> {
156 Self::candidate_exclusive_retained_authority(
157 family,
158 CandidateExclusiveObjectDomain::MergeMembershipEntry { family, reference },
159 canonical_signed_bytes,
160 stored_bytes,
161 owner,
162 )
163 }
164
165 pub fn candidate_exclusive_merge_membership_head(
166 family: CandidateFamilyId,
167 reference: crate::membership::MembershipHeadRef,
168 canonical_signed_bytes: &[u8],
169 stored_bytes: &[u8],
170 owner: StoreBatchCommitRef,
171 ) -> Result<ClosedRemoteObject, RemoteObjectRecordError> {
172 Self::candidate_exclusive_retained_authority(
173 family,
174 CandidateExclusiveObjectDomain::MergeMembershipHead { family, reference },
175 canonical_signed_bytes,
176 stored_bytes,
177 owner,
178 )
179 }
180
181 pub(crate) fn candidate_exclusive_merge_membership_wrapped_store_key(
182 family: CandidateFamilyId,
183 reference: crate::wrapped_store_key::WrappedStoreKeyRef,
184 canonical_signed_bytes: &[u8],
185 stored_bytes: &[u8],
186 owner: StoreBatchCommitRef,
187 ) -> Result<ClosedRemoteObject, RemoteObjectRecordError> {
188 Self::candidate_exclusive_retained_authority(
189 family,
190 CandidateExclusiveObjectDomain::MergeMembershipWrappedStoreKey { family, reference },
191 canonical_signed_bytes,
192 stored_bytes,
193 owner,
194 )
195 }
196
197 pub(crate) fn candidate_activated_device_exclusion_proposal(
198 reference: crate::store_commit::StoreDeviceExclusionProposalRef,
199 canonical_signed_bytes: &[u8],
200 stored_bytes: &[u8],
201 owner: StoreBatchCommitRef,
202 ) -> Result<ClosedRemoteObject, RemoteObjectRecordError> {
203 let object = reference.object.clone();
204 let semantic_hash = ObjectHash::digest(canonical_signed_bytes);
205 Self::candidate_activated_retained_authority(
206 RetainedAuthorityObjectDomain::DeviceExclusionProposal { reference },
207 semantic_hash,
208 object,
209 canonical_signed_bytes,
210 stored_bytes,
211 owner,
212 )
213 }
214
215 pub(crate) fn candidate_activated_device_exclusion_outcome(
216 reference: crate::store_commit::StoreDeviceExclusionOutcomeRef,
217 canonical_signed_bytes: &[u8],
218 stored_bytes: &[u8],
219 owner: StoreBatchCommitRef,
220 ) -> Result<ClosedRemoteObject, RemoteObjectRecordError> {
221 let object = reference.object().clone();
222 let semantic_hash = ObjectHash::digest(canonical_signed_bytes);
223 Self::candidate_activated_retained_authority(
224 RetainedAuthorityObjectDomain::DeviceExclusionOutcome { reference },
225 semantic_hash,
226 object,
227 canonical_signed_bytes,
228 stored_bytes,
229 owner,
230 )
231 }
232
233 pub fn candidate_activated_reclaim_evidence(
234 reference: crate::reclaim::ReclaimEvidenceRef,
235 canonical_signed_bytes: &[u8],
236 stored_bytes: &[u8],
237 owner: StoreBatchCommitRef,
238 ) -> Result<ClosedRemoteObject, RemoteObjectRecordError> {
239 let object = reference.object.clone();
240 Self::candidate_activated_retained_authority(
241 RetainedAuthorityObjectDomain::ReclaimEvidence { reference },
242 ObjectHash::digest(canonical_signed_bytes),
243 object,
244 canonical_signed_bytes,
245 stored_bytes,
246 owner,
247 )
248 }
249
250 pub fn candidate_activated_reclaim_authorization(
251 reference: crate::reclaim::ReclaimAuthorizationRef,
252 canonical_signed_bytes: &[u8],
253 stored_bytes: &[u8],
254 owner: StoreBatchCommitRef,
255 ) -> Result<ClosedRemoteObject, RemoteObjectRecordError> {
256 let object = reference.object.clone();
257 Self::candidate_activated_retained_authority(
258 RetainedAuthorityObjectDomain::ReclaimAuthorization { reference },
259 ObjectHash::digest(canonical_signed_bytes),
260 object,
261 canonical_signed_bytes,
262 stored_bytes,
263 owner,
264 )
265 }
266
267 pub fn candidate_activated_reclaim_receipt(
268 reference: crate::reclaim::ReclaimReceiptRef,
269 canonical_signed_bytes: &[u8],
270 stored_bytes: &[u8],
271 owner: StoreBatchCommitRef,
272 ) -> Result<ClosedRemoteObject, RemoteObjectRecordError> {
273 let object = reference.object.clone();
274 Self::candidate_activated_retained_authority(
275 RetainedAuthorityObjectDomain::ReclaimReceipt { reference },
276 ObjectHash::digest(canonical_signed_bytes),
277 object,
278 canonical_signed_bytes,
279 stored_bytes,
280 owner,
281 )
282 }
283
284 pub fn snapshot_activated_blob(
285 stored: &crate::blob::locator::StoredBlobRef,
286 owner: SnapshotObjectOwner,
287 ) -> Result<ClosedRemoteObject, RemoteObjectRecordError> {
288 let locator_bytes = stored.locator().to_bytes();
289 let record = Self::SharedLiveSet(SharedObjectRecord {
290 identity: SharedLiveSetObjectRef {
291 domain: SharedLiveSetObjectDomain::StoredBlob,
292 semantic_hash: ObjectHash::digest(&locator_bytes),
293 object: stored.object().clone(),
294 },
295 payloads: RemoteObjectPayloads::RowBlob { locator_bytes },
296 state: OwnedObjectState::UploadedVerified {
297 ownership: SharedObjectOwnership {
298 pending: BTreeSet::new(),
299 activated: BTreeSet::from([SharedObjectOwner::Snapshot(owner)]),
300 nonactivated: Vec::new(),
301 },
302 },
303 });
304 ClosedRemoteObject::carried(record)
305 }
306
307 pub fn snapshot_activated_image(
308 image: &crate::store_commit::SnapshotImageRef,
309 owner: SnapshotObjectOwner,
310 ) -> Result<ClosedRemoteObject, RemoteObjectRecordError> {
311 let record = Self::SharedLiveSet(SharedObjectRecord {
312 identity: SharedLiveSetObjectRef {
313 domain: SharedLiveSetObjectDomain::StoreSnapshotImage {
314 reference: image.clone(),
315 },
316 semantic_hash: image.image_hash,
317 object: image.object.clone(),
318 },
319 payloads: RemoteObjectPayloads::SpooledExternal,
320 state: OwnedObjectState::UploadedVerified {
321 ownership: SharedObjectOwnership {
322 pending: BTreeSet::new(),
323 activated: BTreeSet::from([SharedObjectOwner::Snapshot(owner)]),
324 nonactivated: Vec::new(),
325 },
326 },
327 });
328 ClosedRemoteObject::carried(record)
329 }
330
331 pub fn snapshot_activated_membership_rollup(
340 rollup: &crate::store_commit::MembershipRollupRef,
341 owner: SnapshotObjectOwner,
342 ) -> Result<ClosedRemoteObject, RemoteObjectRecordError> {
343 let record = Self::SharedLiveSet(SharedObjectRecord {
344 identity: SharedLiveSetObjectRef {
345 domain: SharedLiveSetObjectDomain::StoreMembershipRollup {
346 reference: rollup.clone(),
347 },
348 semantic_hash: rollup.rollup_hash,
349 object: rollup.object.clone(),
350 },
351 payloads: RemoteObjectPayloads::SpooledExternal,
352 state: OwnedObjectState::UploadedVerified {
353 ownership: SharedObjectOwnership {
354 pending: BTreeSet::new(),
355 activated: BTreeSet::from([SharedObjectOwner::Snapshot(owner)]),
356 nonactivated: Vec::new(),
357 },
358 },
359 });
360 ClosedRemoteObject::carried(record)
361 }
362
363 pub fn activated_external_package(
364 domain: SharedLiveSetObjectDomain,
365 package: &crate::audience_package::AudiencePackage,
366 owner: StoreBatchCommitRef,
367 ) -> Result<ClosedRemoteObject, RemoteObjectRecordError> {
368 if !matches!(
369 domain,
370 SharedLiveSetObjectDomain::StorePackage { .. }
371 | SharedLiveSetObjectDomain::CirclePackage { .. }
372 ) {
373 return Err(RemoteObjectRecordError::DomainMismatch);
374 }
375 let canonical_semantic_bytes = package.to_bytes();
376 let object = domain.package_object()?.clone();
377 let record = Self::SharedLiveSet(SharedObjectRecord {
378 identity: SharedLiveSetObjectRef {
379 domain,
380 semantic_hash: ObjectHash::digest(&canonical_semantic_bytes),
381 object,
382 },
383 payloads: RemoteObjectPayloads::SpooledExternal,
384 state: OwnedObjectState::UploadedVerified {
385 ownership: SharedObjectOwnership {
386 pending: BTreeSet::new(),
387 activated: BTreeSet::from([SharedObjectOwner::StoreCommit(owner)]),
388 nonactivated: Vec::new(),
389 },
390 },
391 });
392 record.validate_payload(&canonical_semantic_bytes)?;
393 let hash = ObjectHash::digest(&canonical_semantic_bytes);
394 ClosedRemoteObject::with_payloads(
395 record,
396 BTreeMap::from([(hash, canonical_semantic_bytes)]),
397 )
398 }
399
400 pub fn activated_blob(
401 stored: &crate::blob::locator::StoredBlobRef,
402 owner: StoreBatchCommitRef,
403 ) -> Result<ClosedRemoteObject, RemoteObjectRecordError> {
404 let locator_bytes = stored.locator().to_bytes();
405 let record = Self::SharedLiveSet(SharedObjectRecord {
406 identity: SharedLiveSetObjectRef {
407 domain: SharedLiveSetObjectDomain::StoredBlob,
408 semantic_hash: ObjectHash::digest(&locator_bytes),
409 object: stored.object().clone(),
410 },
411 payloads: RemoteObjectPayloads::RowBlob { locator_bytes },
412 state: OwnedObjectState::UploadedVerified {
413 ownership: SharedObjectOwnership {
414 pending: BTreeSet::new(),
415 activated: BTreeSet::from([SharedObjectOwner::StoreCommit(owner)]),
416 nonactivated: Vec::new(),
417 },
418 },
419 });
420 ClosedRemoteObject::carried(record)
421 }
422
423 pub fn candidate_owned_blob(
424 stored: &crate::blob::locator::StoredBlobRef,
425 owner: StoreBatchCommitRef,
426 uploaded_verified: bool,
427 ) -> Result<ClosedRemoteObject, RemoteObjectRecordError> {
428 let locator_bytes = stored.locator().to_bytes();
429 let ownership = PendingCandidateOwnership {
430 pending: BTreeSet::from([owner]),
431 nonactivated: Vec::new(),
432 };
433 let state = if uploaded_verified {
434 OwnedObjectState::UploadedVerified {
435 ownership: SharedObjectOwnership {
436 pending: ownership.pending,
437 activated: BTreeSet::new(),
438 nonactivated: ownership.nonactivated,
439 },
440 }
441 } else {
442 OwnedObjectState::Prepared { ownership }
443 };
444 let record = Self::SharedLiveSet(SharedObjectRecord {
445 identity: SharedLiveSetObjectRef {
446 domain: SharedLiveSetObjectDomain::StoredBlob,
447 semantic_hash: ObjectHash::digest(&locator_bytes),
448 object: stored.object().clone(),
449 },
450 payloads: RemoteObjectPayloads::RowBlob { locator_bytes },
451 state,
452 });
453 ClosedRemoteObject::carried(record)
454 }
455}