aven_protocol/artifact/
staging.rs1use super::catalog::{Artifact, Images};
5use super::{Descriptor, Error, Result, catalog, decode_state_catalog};
6use crate::context::LocalSharedStatePackageContext;
7use crate::wire::bootstrap::Component;
8
9pub struct DeclarationView(Descriptor);
10
11pub struct Binding {
12 pub vault: [u8; 32],
13 pub generation: [u8; 32],
14 pub bootstrap: [u8; 32],
15 pub stream: [u8; 32],
16 pub membership: [u8; 32],
17}
18
19impl DeclarationView {
20 pub fn decode(bytes: &[u8]) -> Result<Self> {
21 Descriptor::decode(bytes).map(Self)
22 }
23
24 pub fn prefix_count(&self) -> u64 {
25 self.0.prefix
26 }
27
28 pub fn prefix_rows(&self, bytes: &[u8]) -> Result<Vec<(u64, String)>> {
29 self.catalog(1, bytes)?;
30 catalog::prefix_decode(bytes, self.0.prefix)
31 }
32
33 pub fn image_rows(&self, bytes: &[u8]) -> Result<Images> {
34 self.catalog(2, bytes)?;
35 Images::decode(bytes)
36 }
37
38 pub fn binding(&self) -> Binding {
39 let d = &self.0;
40 Binding {
41 vault: d.vault,
42 generation: d.generation,
43 bootstrap: d.bootstrap,
44 stream: d.stream,
45 membership: d.membership,
46 }
47 }
48
49 pub fn catalog_lengths(&self, class: usize) -> Result<Vec<u64>> {
50 Ok(self
51 .0
52 .catalogs
53 .get(class)
54 .ok_or(Error::Invalid)?
55 .slice_lengths())
56 }
57
58 pub fn verify_slice(&self, class: usize, index: usize, bytes: &[u8]) -> Result<()> {
59 self.0
60 .catalogs
61 .get(class)
62 .ok_or(Error::Invalid)?
63 .verify_slice(index, bytes)
64 }
65
66 pub fn catalog(&self, class: usize, bytes: &[u8]) -> Result<CatalogView> {
67 self.0
68 .catalogs
69 .get(class)
70 .ok_or(Error::Invalid)?
71 .verify(bytes, class as u8 + 1)?;
72 let catalog = match class {
73 0 => Ok(Catalog::State(decode_state_catalog(bytes)?)),
74 1 => {
75 catalog::prefix_decode(bytes, self.0.prefix)?;
76 Ok(Catalog::Prefix)
77 }
78 2 => Ok(Catalog::Images(Images::decode(bytes)?)),
79 _ => Err(Error::Invalid),
80 }?;
81 Ok(CatalogView(catalog))
82 }
83
84 pub fn artifacts(&self, catalog: Option<&CatalogView>) -> Vec<ArtifactView> {
85 let d = &self.0;
86 let wrap = |component, artifact: Artifact| ArtifactView {
87 component,
88 artifact,
89 context: d.context(),
90 stream: d.stream,
91 bootstrap: d.bootstrap,
92 };
93 match catalog.map(|c| &c.0) {
94 None => vec![wrap(Component::Manifest, d.manifest.clone())],
95 Some(Catalog::State(a)) => vec![wrap(Component::State, a.clone())],
96 Some(Catalog::Images(images)) => images
97 .objects
98 .iter()
99 .map(|i| wrap(Component::Image(i.id), i.artifact.clone()))
100 .collect(),
101 Some(Catalog::Prefix) => Vec::new(),
102 }
103 }
104}
105
106pub struct CatalogView(Catalog);
107
108enum Catalog {
109 State(Artifact),
110 Prefix,
111 Images(Images),
112}
113
114pub struct ArtifactView {
115 pub component: Component,
117 artifact: Artifact,
118 context: LocalSharedStatePackageContext,
119 stream: [u8; 32],
120 bootstrap: [u8; 32],
121}
122
123impl ArtifactView {
124 pub fn lengths(&self) -> Vec<u64> {
125 self.artifact.chunks.iter().map(|c| c.length).collect()
126 }
127
128 pub fn artifact(&self) -> &Artifact {
130 &self.artifact
131 }
132
133 pub fn context(&self) -> LocalSharedStatePackageContext {
134 self.context
135 }
136
137 pub fn stream(&self) -> [u8; 32] {
138 self.stream
139 }
140
141 pub fn identity(&self) -> Result<([u8; 32], u8, u8)> {
143 match self.component {
144 Component::Image(id) => Ok((id, 1, 0)),
145 Component::State => Ok((self.bootstrap, 2, 1)),
146 Component::Manifest => Ok((self.bootstrap, 2, 2)),
147 _ => Err(Error::Invalid),
148 }
149 }
150
151 pub fn verify_chunk(&self, index: usize, bytes: &[u8]) -> Result<()> {
152 let (id, family, class) = self.identity()?;
153 self.artifact
154 .verify_chunk(bytes, index, self.context, self.stream, id, family, class)
155 }
156
157 pub fn verify(&self, records: &[Vec<u8>]) -> Result<()> {
158 let (id, family, class) = self.identity()?;
159 self.artifact
160 .verify(records, self.context, self.stream, id, family, class)
161 }
162}
163
164#[cfg(test)]
165mod tests;