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