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