ic_backup/model/ic_snapshot_upload_observation/
mod.rs1use crate::model::{
4 attempt_journal::{AttemptAuthorityRecord, AttemptJournalRecord},
5 ic_observation::{IcObservationRequestError, ObservationReservation},
6 ic_request::{IcManagementMethodRecord, IcManagementRequestRecord},
7 ic_snapshot_upload::{
8 IcSnapshotUploadAttemptError, IcSnapshotUploadKind, IcSnapshotUploadRequest,
9 original_authority,
10 },
11 operation_plan::OperationPlanRecord,
12};
13use thiserror::Error;
14
15mod settlement;
16pub use settlement::{IcSnapshotUploadAttribution, IcSnapshotUploadSettlement};
17
18#[derive(Debug)]
25pub struct IcSnapshotUploadObservationRequest<'request, 'source> {
26 plan: &'request OperationPlanRecord,
27 mutation: &'request IcSnapshotUploadRequest<'source>,
28 payload: &'request IcManagementRequestRecord,
29 reservation: ObservationReservation,
30}
31
32impl<'request, 'source> IcSnapshotUploadObservationRequest<'request, 'source> {
33 pub fn new(
40 plan: &'request OperationPlanRecord,
41 operation_sequence: u64,
42 journal: &AttemptJournalRecord,
43 mutation: &'request IcSnapshotUploadRequest<'source>,
44 payload: &'request IcManagementRequestRecord,
45 ) -> Result<Self, IcSnapshotUploadObservationError> {
46 if !matches!(mutation.kind(), IcSnapshotUploadKind::Metadata) {
47 return Err(IcSnapshotUploadObservationError::UnsupportedUpload);
48 }
49 if payload.method() != IcManagementMethodRecord::ListCanisterSnapshots {
50 return Err(IcSnapshotUploadObservationError::UnsupportedObservation);
51 }
52 let authority = original_authority(plan, operation_sequence, journal, mutation)?;
53 payload
54 .validate_observation_binding(authority.binding(), &payload.digest())
55 .map_err(IcObservationRequestError::from)?;
56 let reservation = ObservationReservation::new(authority, journal, payload.digest())?;
57 let request = Self {
58 plan,
59 mutation,
60 payload,
61 reservation,
62 };
63 Ok(request)
64 }
65
66 #[must_use]
68 pub const fn plan(&self) -> &OperationPlanRecord {
69 self.plan
70 }
71 #[must_use]
73 pub const fn mutation(&self) -> &'request IcSnapshotUploadRequest<'source> {
74 self.mutation
75 }
76 #[must_use]
78 pub const fn payload(&self) -> &'request IcManagementRequestRecord {
79 self.payload
80 }
81 #[must_use]
83 pub const fn authority(&self) -> &AttemptAuthorityRecord {
84 &self.reservation.authority
85 }
86 #[must_use]
88 pub const fn mutation_attempt(&self) -> u32 {
89 self.reservation.mutation_attempt
90 }
91 #[must_use]
93 pub const fn observation_attempt(&self) -> u32 {
94 self.reservation.observation_attempt
95 }
96 pub fn validate_journal(
100 &self,
101 journal: &AttemptJournalRecord,
102 ) -> Result<(), IcObservationRequestError> {
103 self.reservation.validate(journal)
104 }
105}
106
107#[derive(Debug, Error)]
109pub enum IcSnapshotUploadObservationError {
110 #[error("snapshot upload observation requires metadata intent")]
112 UnsupportedUpload,
113 #[error("snapshot upload observation requires snapshot list")]
115 UnsupportedObservation,
116 #[error(transparent)]
118 Upload(#[from] IcSnapshotUploadAttemptError),
119 #[error(transparent)]
121 Observation(#[from] IcObservationRequestError),
122}
123
124#[cfg(test)]
125mod tests;