commonware_coding/
no_coding.rs

1use crate::Config;
2use commonware_codec::{EncodeSize, RangeCfg, Read, Write};
3use commonware_cryptography::Hasher;
4use std::marker::PhantomData;
5use thiserror::Error;
6
7#[derive(Error, Debug)]
8pub enum Error {
9    #[error("data does not match commitment")]
10    BadData,
11}
12
13/// A trivial scheme which performs no coding at all.
14///
15/// Instead, each shard contains all of the data.
16///
17/// The commitment is simply a hash of that data. This struct is generic
18/// over the choice of [commonware_cryptography::Hasher].
19#[derive(Clone, Copy)]
20pub struct NoCoding<H> {
21    _marker: PhantomData<H>,
22}
23
24impl<H> std::fmt::Debug for NoCoding<H> {
25    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
26        f.debug_struct("NoCoding").finish()
27    }
28}
29
30#[derive(Clone, PartialEq, Eq)]
31#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
32pub struct Shard(Vec<u8>);
33
34impl EncodeSize for Shard {
35    fn encode_size(&self) -> usize {
36        self.0.encode_size()
37    }
38}
39
40impl Write for Shard {
41    fn write(&self, buf: &mut impl bytes::BufMut) {
42        self.0.write(buf)
43    }
44}
45
46impl Read for Shard {
47    type Cfg = crate::CodecConfig;
48
49    fn read_cfg(
50        buf: &mut impl bytes::Buf,
51        cfg: &Self::Cfg,
52    ) -> Result<Self, commonware_codec::Error> {
53        Vec::read_cfg(buf, &(RangeCfg::new(0..=cfg.maximum_shard_size), ())).map(Self)
54    }
55}
56
57#[derive(Clone, PartialEq, Eq)]
58#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
59pub struct ReShard(());
60
61impl EncodeSize for ReShard {
62    fn encode_size(&self) -> usize {
63        0
64    }
65}
66
67impl Write for ReShard {
68    fn write(&self, _buf: &mut impl bytes::BufMut) {}
69}
70
71impl Read for ReShard {
72    type Cfg = crate::CodecConfig;
73
74    fn read_cfg(
75        _buf: &mut impl bytes::Buf,
76        _cfg: &Self::Cfg,
77    ) -> Result<Self, commonware_codec::Error> {
78        Ok(Self(()))
79    }
80}
81
82impl<H: Hasher> crate::Scheme for NoCoding<H> {
83    type Commitment = H::Digest;
84
85    type Shard = Shard;
86
87    type ReShard = ReShard;
88
89    type CheckedShard = ();
90
91    type CheckingData = Vec<u8>;
92
93    type Error = Error;
94
95    fn encode(
96        config: &crate::Config,
97        mut data: impl bytes::Buf,
98        _concurrency: usize,
99    ) -> Result<(Self::Commitment, Vec<Self::Shard>), Self::Error> {
100        let data: Vec<u8> = data.copy_to_bytes(data.remaining()).to_vec();
101        let commitment = H::new().update(&data).finalize();
102        let shards = (0..config.total_shards())
103            .map(|_| Shard(data.clone()))
104            .collect();
105        Ok((commitment, shards))
106    }
107
108    fn reshard(
109        _config: &Config,
110        commitment: &Self::Commitment,
111        _index: u16,
112        shard: Self::Shard,
113    ) -> Result<(Self::CheckingData, Self::CheckedShard, Self::ReShard), Self::Error> {
114        let my_commitment = H::new().update(shard.0.as_slice()).finalize();
115        if &my_commitment != commitment {
116            return Err(Error::BadData);
117        }
118        Ok((shard.0, (), ReShard(())))
119    }
120
121    fn check(
122        _config: &Config,
123        _commitment: &Self::Commitment,
124        _checking_data: &Self::CheckingData,
125        _index: u16,
126        _reshard: Self::ReShard,
127    ) -> Result<Self::CheckedShard, Self::Error> {
128        Ok(())
129    }
130
131    fn decode(
132        _config: &Config,
133        _commitment: &Self::Commitment,
134        checking_data: Self::CheckingData,
135        _shards: &[Self::CheckedShard],
136        _concurrency: usize,
137    ) -> Result<Vec<u8>, Self::Error> {
138        Ok(checking_data)
139    }
140}
141
142impl<H: Hasher> crate::ValidatingScheme for NoCoding<H> {}
143
144#[cfg(all(test, feature = "arbitrary"))]
145mod conformance {
146    use super::*;
147    use commonware_codec::conformance::CodecConformance;
148
149    commonware_conformance::conformance_tests! {
150        CodecConformance<Shard>,
151        CodecConformance<ReShard>
152    }
153}