ic_backup/policy/ic_mutation/
mod.rs1use crate::model::{
4 attempt_journal::AttemptJournalRecord,
5 ic_lifecycle_reply::{IcLifecycleReply, IcLifecycleReplyError},
6 ic_mutation::{IcMutationAcknowledgement, IcMutationRequest, IcMutationRequestError},
7 ic_request::IcManagementMethodRecord,
8 ic_snapshot_reply::{IcSnapshotReply, IcSnapshotReplyError},
9};
10use thiserror::Error;
11
12#[derive(Debug)]
14pub enum IcMutationReplyView<'a> {
15 Capture(IcSnapshotReply<'a>),
17 Lifecycle(IcLifecycleReply<'a>),
19}
20
21#[derive(Debug)]
26pub struct IcMutationAcknowledgementView<'a> {
27 acknowledgement: &'a IcMutationAcknowledgement,
28 reply: IcMutationReplyView<'a>,
29}
30impl<'a> IcMutationAcknowledgementView<'a> {
31 #[must_use]
33 pub const fn acknowledgement(&self) -> &'a IcMutationAcknowledgement {
34 self.acknowledgement
35 }
36 #[must_use]
38 pub const fn reply(&self) -> &IcMutationReplyView<'a> {
39 &self.reply
40 }
41}
42
43pub fn validate_acknowledgement<'a>(
51 request: &IcMutationRequest<'a>,
52 journal: &AttemptJournalRecord,
53 acknowledgement: &'a IcMutationAcknowledgement,
54) -> Result<IcMutationAcknowledgementView<'a>, IcMutationAssociationError> {
55 request.validate_journal(journal)?;
56 let input = acknowledgement.input();
57 if input.authority != request.authority().digest() {
58 return Err(IcMutationAssociationError::AuthorityMismatch);
59 }
60 if input.mutation_attempt != request.mutation_attempt() {
61 return Err(IcMutationAssociationError::AttemptMismatch);
62 }
63 if &input.context != request.plan().context() {
64 return Err(IcMutationAssociationError::ContextMismatch);
65 }
66 if input.target != request.payload().target() {
67 return Err(IcMutationAssociationError::TargetMismatch);
68 }
69 let reply = match request.payload().method() {
70 IcManagementMethodRecord::TakeCanisterSnapshot => {
71 IcMutationReplyView::Capture(IcSnapshotReply::decode(request.payload(), &input.reply)?)
72 }
73 _ => IcMutationReplyView::Lifecycle(IcLifecycleReply::decode(
76 request.payload(),
77 &input.reply,
78 )?),
79 };
80 Ok(IcMutationAcknowledgementView {
81 acknowledgement,
82 reply,
83 })
84}
85
86#[derive(Debug, Error)]
88pub enum IcMutationAssociationError {
89 #[error(transparent)]
91 Reservation(#[from] IcMutationRequestError),
92 #[error("IC mutation acknowledgement authority mismatch")]
94 AuthorityMismatch,
95 #[error("IC mutation acknowledgement attempt mismatch")]
97 AttemptMismatch,
98 #[error("IC mutation acknowledgement context mismatch")]
100 ContextMismatch,
101 #[error("IC mutation acknowledgement target mismatch")]
103 TargetMismatch,
104 #[error(transparent)]
106 Snapshot(#[from] IcSnapshotReplyError),
107 #[error(transparent)]
109 Lifecycle(#[from] IcLifecycleReplyError),
110}
111
112#[cfg(test)]
113mod tests;