Skip to main content

aven_protocol/wire/
bootstrap.rs

1//! Bootstrap control messages and bounded staging batches.
2use serde::{Deserialize, Serialize};
3pub mod batch;
4
5/// Refusal limits for the single-vault staging storage profile.
6pub const MAX_STORAGE_BYTES: u64 = 600 * 1_048_576;
7pub const MAX_CHUNKS: u64 = 4096;
8pub const MAX_CANDIDATES: i64 = 1024;
9pub const MAX_REQUEST_BYTES: usize = 1_048_576 + 222;
10pub const STAGING_TTL_SECONDS: i64 = 24 * 60 * 60;
11
12/// Budgets include catalog slices, encrypted manifest, state and selected images.
13/// They cannot change on a declaration retry, even when staging has expired.
14#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
15pub struct Budget {
16    pub bytes: u64,
17    pub chunks: u64,
18}
19
20#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
21pub enum Component {
22    DataCatalog,
23    PrefixCatalog,
24    ImageCatalog,
25    Manifest,
26    State,
27    Image([u8; 32]),
28}
29
30impl Component {
31    pub fn is_catalog(self) -> bool {
32        self.catalog().is_some()
33    }
34
35    pub fn catalog(self) -> Option<usize> {
36        match self {
37            Self::DataCatalog => Some(0),
38            Self::PrefixCatalog => Some(1),
39            Self::ImageCatalog => Some(2),
40            _ => None,
41        }
42    }
43
44    pub fn key(self) -> Vec<u8> {
45        match self {
46            Self::DataCatalog => vec![0],
47            Self::PrefixCatalog => vec![1],
48            Self::ImageCatalog => vec![2],
49            Self::Manifest => vec![3],
50            Self::State => vec![4],
51            Self::Image(id) => std::iter::once(5).chain(id).collect(),
52        }
53    }
54
55    /// The component whose [`Self::key`] is `key`.
56    pub fn from_key(key: &[u8]) -> Option<Self> {
57        Some(match key {
58            [0] => Self::DataCatalog,
59            [1] => Self::PrefixCatalog,
60            [2] => Self::ImageCatalog,
61            [3] => Self::Manifest,
62            [4] => Self::State,
63            [5, id @ ..] => Self::Image(id.try_into().ok()?),
64            _ => return None,
65        })
66    }
67}
68
69#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
70pub enum Presence {
71    Missing,
72    Verified,
73}
74
75#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
76pub struct ComponentStatus {
77    pub component: Component,
78    pub chunks: Vec<Presence>,
79}
80
81#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
82pub struct StagingStatus {
83    pub descriptor_commitment: [u8; 32],
84    pub stream_id: [u8; 32],
85    /// Unix seconds. Expiry denies PUT but does not cancel or erase verified bytes.
86    pub expires_at: i64,
87    pub budget: Budget,
88    /// Bounded by MAX_CHUNKS. Data/image components appear only after their
89    /// catalogs verify; absent describing catalogs are not empty data sets.
90    pub components: Vec<ComponentStatus>,
91}
92
93pub const PATH: &str = "/e2ee/bootstrap/v1";
94pub const REQUEST_LIMIT: usize = crate::base64_bytes::encoded_len(MAX_REQUEST_BYTES) + 4096;
95pub const RESPONSE_LIMIT: usize = 1_048_576;
96
97#[derive(Serialize, Deserialize)]
98#[serde(deny_unknown_fields)]
99pub struct Envelope {
100    pub vault: [u8; 32],
101    pub genesis: [u8; 32],
102    pub operation: Operation,
103}
104
105#[derive(Serialize, Deserialize)]
106#[serde(deny_unknown_fields)]
107pub enum Operation {
108    ClaimSetup {
109        #[serde(with = "crate::base64_bytes")]
110        bytes: Vec<u8>,
111    },
112    ClaimBearer {
113        #[serde(with = "crate::base64_bytes")]
114        bytes: Vec<u8>,
115    },
116    Declare {
117        #[serde(with = "crate::base64_bytes")]
118        descriptor: Vec<u8>,
119        budget: Budget,
120    },
121    Status {
122        bootstrap: [u8; 32],
123    },
124    Ensure {
125        bootstrap: [u8; 32],
126        commitment: [u8; 32],
127    },
128    Cancel {
129        bootstrap: [u8; 32],
130    },
131    Publish {
132        bootstrap: [u8; 32],
133        commitment: [u8; 32],
134        #[serde(with = "crate::base64_bytes")]
135        record: Vec<u8>,
136    },
137}
138
139#[derive(Serialize, Deserialize)]
140#[serde(deny_unknown_fields)]
141pub enum Reply {
142    Claimed {
143        vault: [u8; 32],
144        claim: [u8; 32],
145        genesis: [u8; 32],
146    },
147    Missing,
148    Canceled,
149    Staging(StagingStatus),
150    Stored,
151    Published(#[serde(with = "crate::base64_bytes")] Vec<u8>),
152}