rns_core/resource/
assembly.rs1use super::{
3 parts::extract_metadata_owned,
4 proof::{build_proof_data, data_hash_state, finish_with},
5 ResourceAction, ResourceError,
6};
7use crate::{
8 buffer::types::{Compressor, DecompressError},
9 constants::RESOURCE_RANDOM_HASH_SIZE,
10};
11use alloc::{sync::Arc, vec, vec::Vec};
12
13#[derive(Clone, Debug)]
15pub struct AssemblyId(Arc<()>);
16impl AssemblyId {
17 pub(super) fn new() -> Self {
18 Self(Arc::new(()))
19 }
20}
21impl PartialEq for AssemblyId {
22 fn eq(&self, other: &Self) -> bool {
23 Arc::ptr_eq(&self.0, &other.0)
24 }
25}
26impl Eq for AssemblyId {}
27
28pub struct ResourceAssembly {
31 pub(super) id: AssemblyId,
32 pub(super) data: AssemblyData,
33}
34pub struct AssemblyResult {
36 pub(super) id: AssemblyId,
37 pub(super) result: Result<Vec<ResourceAction>, ResourceError>,
38}
39impl ResourceAssembly {
40 pub fn id(&self) -> &AssemblyId {
41 &self.id
42 }
43 pub fn input_capacity(&self) -> usize {
45 self.data.plaintext.capacity()
46 }
47 pub fn max_output_size(&self) -> usize {
49 self.data.limit
50 }
51 pub fn run(self, compressor: &dyn Compressor) -> AssemblyResult {
52 AssemblyResult {
53 id: self.id,
54 result: self.data.run(compressor),
55 }
56 }
57}
58
59pub(super) struct AssemblyData {
60 pub plaintext: Vec<u8>,
61 pub random_hash: [u8; RESOURCE_RANDOM_HASH_SIZE],
62 pub resource_hash: [u8; 32],
63 pub compressed: bool,
64 pub metadata: bool,
65 pub limit: usize,
66}
67impl AssemblyData {
68 pub fn run(self, compressor: &dyn Compressor) -> Result<Vec<ResourceAction>, ResourceError> {
69 let plaintext = self.plaintext;
71 let decompressed = if self.compressed {
72 compressor
73 .decompress_bounded(&plaintext, self.limit)
74 .map_err(|error| match error {
75 DecompressError::TooLarge => ResourceError::TooLarge,
76 DecompressError::InvalidData => ResourceError::DecompressionFailed,
77 })?
78 } else {
79 plaintext
80 };
81 let data_state = data_hash_state(&decompressed);
82 let hash = finish_with(&data_state, &self.random_hash);
83 if hash != self.resource_hash {
84 return Err(ResourceError::HashMismatch);
85 }
86 let proof = build_proof_data(&hash, &finish_with(&data_state, &hash));
88 let (data, metadata) = if self.metadata {
89 let (metadata, data) =
90 extract_metadata_owned(decompressed).ok_or(ResourceError::InvalidPart)?;
91 (data, Some(metadata))
92 } else {
93 (decompressed, None)
94 };
95 Ok(vec![
96 ResourceAction::SendProof(proof),
97 ResourceAction::DataReceived { data, metadata },
98 ResourceAction::Completed,
99 ])
100 }
101}