use crate::{cdk::types::Principal, ids::IntentResourceKey, model::replay::OperationId};
use serde::{Deserialize, Serialize};
pub const PAYLOAD_BINDING_SCHEMA_VERSION: u32 = 1;
pub const RECEIPT_BACKED_INTENT_SCHEMA_VERSION: u32 = 1;
pub const TERMINAL_EVIDENCE_SCHEMA_VERSION: u32 = 1;
#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct PayloadBinding {
pub schema_version: u32,
pub digest: [u8; 32],
}
impl PayloadBinding {
#[must_use]
pub const fn new(digest: [u8; 32]) -> Self {
Self {
schema_version: PAYLOAD_BINDING_SCHEMA_VERSION,
digest,
}
}
}
#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub enum TerminalEvidenceDecision {
Committed,
RolledBack,
}
#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct TerminalEvidence {
pub source_canister: Principal,
pub schema_version: u32,
pub decision: TerminalEvidenceDecision,
pub fingerprint: [u8; 32],
}
impl TerminalEvidence {
#[must_use]
pub const fn new(
source_canister: Principal,
decision: TerminalEvidenceDecision,
fingerprint: [u8; 32],
) -> Self {
Self {
source_canister,
schema_version: TERMINAL_EVIDENCE_SCHEMA_VERSION,
decision,
fingerprint,
}
}
}
#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub enum ReceiptBackedIntentState {
Pending,
Committed { evidence: TerminalEvidence },
RolledBack { evidence: TerminalEvidence },
}
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct ReceiptBackedIntent {
pub schema_version: u32,
pub operation_id: OperationId,
pub payload_binding: PayloadBinding,
pub resource_key: IntentResourceKey,
pub quantity: u64,
pub state: ReceiptBackedIntentState,
pub revision: u64,
pub created_at_ns: u64,
pub updated_at_ns: u64,
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct BeginLocalIntentInput {
pub resource_key: IntentResourceKey,
pub quantity: u64,
pub ttl_secs: Option<u64>,
pub reservation_limit: Option<u64>,
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct BeginReceiptBackedIntentInput {
pub operation_id: OperationId,
pub payload_binding: PayloadBinding,
pub resource_key: IntentResourceKey,
pub quantity: u64,
pub reservation_limit: u64,
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum BeginReceiptBackedIntentResult {
Created {
revision: u64,
},
ExistingPending {
revision: u64,
},
ExistingCommitted {
revision: u64,
evidence: TerminalEvidence,
},
ExistingRolledBack {
revision: u64,
evidence: TerminalEvidence,
},
BindingConflict,
CapacityExceeded {
current_quantity: u64,
requested_quantity: u64,
limit: u64,
},
StoreCapacityReached {
current_records: u64,
limit: u64,
},
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct SettleReceiptBackedIntentInput {
pub operation_id: OperationId,
pub expected_revision: u64,
pub expected_payload_binding: PayloadBinding,
pub evidence: TerminalEvidence,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum SettleReceiptBackedIntentResult {
Settled {
revision: u64,
state: ReceiptBackedIntentState,
},
AlreadySettled {
revision: u64,
state: ReceiptBackedIntentState,
},
NotFound,
RevisionConflict {
actual_revision: u64,
},
BindingConflict,
}