safe_nd/
blob.rs

1// Copyright 2019 MaidSafe.net limited.
2//
3// This SAFE Network Software is licensed to you under the MIT license <LICENSE-MIT
4// https://opensource.org/licenses/MIT> or the Modified BSD license <LICENSE-BSD
5// https://opensource.org/licenses/BSD-3-Clause>, at your option. This file may not be copied,
6// modified, or distributed except according to those terms. Please review the Licences for the
7// specific language governing permissions and limitations relating to use of the SAFE Network
8// Software.
9
10use crate::{utils, Error, PublicKey, XorName};
11use bincode::serialized_size;
12use serde::{Deserialize, Deserializer, Serialize, Serializer};
13use std::{
14    fmt::{self, Debug, Formatter},
15    u64,
16};
17
18/// Maximum allowed size for a serialised Blob to grow to.
19pub const MAX_BLOB_SIZE_IN_BYTES: u64 = 1024 * 1024 + 10 * 1024;
20
21/// Private Blob: an immutable chunk of data which can be deleted. Can only be fetched
22/// by the listed owner.
23#[derive(Hash, Eq, PartialEq, PartialOrd, Ord, Clone)]
24pub struct PrivateData {
25    /// Network address. Omitted when serialising and calculated from the `value` and `owner` when
26    /// deserialising.
27    address: Address,
28    /// Contained data.
29    value: Vec<u8>,
30    /// Contains a set of owners of this data. DataManagers enforce that a DELETE or OWNED-GET type
31    /// of request is coming from the MaidManager Authority of the owners.
32    owner: PublicKey,
33}
34
35impl PrivateData {
36    /// Creates a new instance of `PrivateData`.
37    pub fn new(value: Vec<u8>, owner: PublicKey) -> Self {
38        let hash_of_value = tiny_keccak::sha3_256(&value);
39        let serialised_contents = utils::serialise(&(hash_of_value, &owner));
40        let address = Address::Private(XorName(tiny_keccak::sha3_256(&serialised_contents)));
41
42        Self {
43            address,
44            value,
45            owner,
46        }
47    }
48
49    /// Returns the value.
50    pub fn value(&self) -> &Vec<u8> {
51        &self.value
52    }
53
54    /// Returns the set of owners.
55    pub fn owner(&self) -> &PublicKey {
56        &self.owner
57    }
58
59    /// Returns the address.
60    pub fn address(&self) -> &Address {
61        &self.address
62    }
63
64    /// Returns the name.
65    pub fn name(&self) -> &XorName {
66        self.address.name()
67    }
68
69    /// Returns size of contained value.
70    pub fn payload_size(&self) -> usize {
71        self.value.len()
72    }
73
74    /// Returns size of this data after serialisation.
75    pub fn serialised_size(&self) -> u64 {
76        serialized_size(self).unwrap_or(u64::MAX)
77    }
78
79    /// Returns `true` if the size is valid.
80    pub fn validate_size(&self) -> bool {
81        self.serialised_size() <= MAX_BLOB_SIZE_IN_BYTES
82    }
83}
84
85impl Serialize for PrivateData {
86    fn serialize<S: Serializer>(&self, serialiser: S) -> Result<S::Ok, S::Error> {
87        (&self.value, &self.owner).serialize(serialiser)
88    }
89}
90
91impl<'de> Deserialize<'de> for PrivateData {
92    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
93        let (value, owner): (Vec<u8>, PublicKey) = Deserialize::deserialize(deserializer)?;
94        Ok(PrivateData::new(value, owner))
95    }
96}
97
98impl Debug for PrivateData {
99    fn fmt(&self, formatter: &mut Formatter) -> fmt::Result {
100        // TODO: Output owners?
101        write!(formatter, "PrivateBlob {:?}", self.name())
102    }
103}
104
105/// Public Blob: an immutable chunk of data which cannot be deleted.
106#[derive(Hash, Clone, Eq, PartialEq, Ord, PartialOrd)]
107pub struct PublicData {
108    /// Network address. Omitted when serialising and calculated from the `value` when
109    /// deserialising.
110    address: Address,
111    /// Contained data.
112    value: Vec<u8>,
113}
114
115impl PublicData {
116    /// Creates a new instance of `Blob`.
117    pub fn new(value: Vec<u8>) -> Self {
118        Self {
119            address: Address::Public(XorName(tiny_keccak::sha3_256(&value))),
120            value,
121        }
122    }
123
124    /// Returns the value.
125    pub fn value(&self) -> &Vec<u8> {
126        &self.value
127    }
128
129    /// Returns the address.
130    pub fn address(&self) -> &Address {
131        &self.address
132    }
133
134    /// Returns the name.
135    pub fn name(&self) -> &XorName {
136        self.address.name()
137    }
138
139    /// Returns size of contained value.
140    pub fn payload_size(&self) -> usize {
141        self.value.len()
142    }
143
144    /// Returns size of this data after serialisation.
145    pub fn serialised_size(&self) -> u64 {
146        serialized_size(self).unwrap_or(u64::MAX)
147    }
148
149    /// Returns true if the size is valid.
150    pub fn validate_size(&self) -> bool {
151        self.serialised_size() <= MAX_BLOB_SIZE_IN_BYTES
152    }
153}
154
155impl Serialize for PublicData {
156    fn serialize<S: Serializer>(&self, serialiser: S) -> Result<S::Ok, S::Error> {
157        self.value.serialize(serialiser)
158    }
159}
160
161impl<'de> Deserialize<'de> for PublicData {
162    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
163        let value: Vec<u8> = Deserialize::deserialize(deserializer)?;
164        Ok(PublicData::new(value))
165    }
166}
167
168impl Debug for PublicData {
169    fn fmt(&self, formatter: &mut Formatter) -> fmt::Result {
170        write!(formatter, "PublicBloblob {:?}", self.name())
171    }
172}
173
174/// Kind of an Blob.
175#[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize, Debug)]
176pub enum Kind {
177    /// Private.
178    Private,
179    /// Public.
180    Pub,
181}
182
183impl Kind {
184    /// Creates `Kind` from a `published` flag.
185    pub fn from_flag(published: bool) -> Self {
186        if published {
187            Kind::Pub
188        } else {
189            Kind::Private
190        }
191    }
192
193    /// Returns true if published.
194    pub fn is_pub(self) -> bool {
195        self == Kind::Pub
196    }
197
198    /// Returns true if unpublished.
199    pub fn is_unpub(self) -> bool {
200        !self.is_pub()
201    }
202}
203
204/// Address of an Blob.
205#[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize, Debug)]
206pub enum Address {
207    /// Private namespace.
208    Private(XorName),
209    /// Public namespace.
210    Public(XorName),
211}
212
213impl Address {
214    /// Constructs an `Address` given `kind` and `name`.
215    pub fn from_kind(kind: Kind, name: XorName) -> Self {
216        match kind {
217            Kind::Pub => Address::Public(name),
218            Kind::Private => Address::Private(name),
219        }
220    }
221
222    /// Returns the kind.
223    pub fn kind(&self) -> Kind {
224        match self {
225            Address::Private(_) => Kind::Private,
226            Address::Public(_) => Kind::Pub,
227        }
228    }
229
230    /// Returns the name.
231    pub fn name(&self) -> &XorName {
232        match self {
233            Address::Private(ref name) | Address::Public(ref name) => name,
234        }
235    }
236
237    /// Returns true if published.
238    pub fn is_pub(&self) -> bool {
239        self.kind().is_pub()
240    }
241
242    /// Returns true if unpublished.
243    pub fn is_unpub(&self) -> bool {
244        self.kind().is_unpub()
245    }
246
247    /// Returns the Address serialised and encoded in z-base-32.
248    pub fn encode_to_zbase32(&self) -> String {
249        utils::encode(&self)
250    }
251
252    /// Creates from z-base-32 encoded string.
253    pub fn decode_from_zbase32<T: AsRef<str>>(encoded: T) -> Result<Self, Error> {
254        utils::decode(encoded)
255    }
256}
257
258/// Object storing an Blob variant.
259#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize, Debug)]
260pub enum Data {
261    /// Private Blob.
262    Private(PrivateData),
263    /// Public Blob.
264    Public(PublicData),
265}
266
267impl Data {
268    /// Returns the address.
269    pub fn address(&self) -> &Address {
270        match self {
271            Data::Private(data) => data.address(),
272            Data::Public(data) => data.address(),
273        }
274    }
275
276    /// Returns the name.
277    pub fn name(&self) -> &XorName {
278        self.address().name()
279    }
280
281    /// Returns the owner if private blob.
282    pub fn owner(&self) -> Option<&PublicKey> {
283        match self {
284            Data::Private(data) => Some(data.owner()),
285            _ => None,
286        }
287    }
288
289    /// Returns the kind.
290    pub fn kind(&self) -> Kind {
291        self.address().kind()
292    }
293
294    /// Returns true if published.
295    pub fn is_pub(&self) -> bool {
296        self.kind().is_pub()
297    }
298
299    /// Returns true if unpublished.
300    pub fn is_unpub(&self) -> bool {
301        self.kind().is_unpub()
302    }
303
304    /// Returns the value.
305    pub fn value(&self) -> &Vec<u8> {
306        match self {
307            Data::Private(data) => data.value(),
308            Data::Public(data) => data.value(),
309        }
310    }
311
312    /// Returns `true` if the size is valid.
313    pub fn validate_size(&self) -> bool {
314        match self {
315            Data::Private(data) => data.validate_size(),
316            Data::Public(data) => data.validate_size(),
317        }
318    }
319
320    /// Returns size of this data after serialisation.
321    pub fn serialised_size(&self) -> u64 {
322        match self {
323            Data::Private(data) => data.serialised_size(),
324            Data::Public(data) => data.serialised_size(),
325        }
326    }
327}
328
329impl From<PrivateData> for Data {
330    fn from(data: PrivateData) -> Self {
331        Data::Private(data)
332    }
333}
334
335impl From<PublicData> for Data {
336    fn from(data: PublicData) -> Self {
337        Data::Public(data)
338    }
339}
340
341#[cfg(test)]
342mod tests {
343    use super::{utils, Address, PrivateData, PublicData, PublicKey, XorName};
344    use bincode::deserialize as deserialise;
345    use hex::encode;
346    use rand::{self, Rng, SeedableRng};
347    use rand_xorshift::XorShiftRng;
348    use std::{env, iter, thread};
349    use threshold_crypto::SecretKey;
350    use unwrap::unwrap;
351
352    #[test]
353    fn deterministic_name() {
354        let data1 = b"Hello".to_vec();
355        let data2 = b"Goodbye".to_vec();
356
357        let owner1 = PublicKey::Bls(SecretKey::random().public_key());
358        let owner2 = PublicKey::Bls(SecretKey::random().public_key());
359
360        let idata1 = PrivateData::new(data1.clone(), owner1);
361        let idata2 = PrivateData::new(data1, owner2);
362        let idata3 = PrivateData::new(data2.clone(), owner1);
363        let idata3_clone = PrivateData::new(data2, owner1);
364
365        assert_eq!(idata3, idata3_clone);
366
367        assert_ne!(idata1.name(), idata2.name());
368        assert_ne!(idata1.name(), idata3.name());
369        assert_ne!(idata2.name(), idata3.name());
370    }
371
372    #[test]
373    fn deterministic_test() {
374        let value = "immutable data value".to_owned().into_bytes();
375        let blob = PublicData::new(value);
376        let blob_name = encode(blob.name().0.as_ref());
377        let expected_name = "fac2869677ee06277633c37ac7e8e5c655f3d652f707c7a79fab930d584a3016";
378
379        assert_eq!(&expected_name, &blob_name);
380    }
381
382    #[test]
383    fn serialisation() {
384        let mut rng = get_rng();
385        let len = rng.gen_range(1, 10_000);
386        let value = iter::repeat_with(|| rng.gen()).take(len).collect();
387        let blob = PublicData::new(value);
388        let serialised = utils::serialise(&blob);
389        let parsed = unwrap!(deserialise(&serialised));
390        assert_eq!(blob, parsed);
391    }
392
393    fn get_rng() -> XorShiftRng {
394        let env_var_name = "RANDOM_SEED";
395        let seed = env::var(env_var_name)
396            .ok()
397            .map(|value| {
398                unwrap!(
399                    value.parse::<u64>(),
400                    "Env var 'RANDOM_SEED={}' is not a valid u64.",
401                    value
402                )
403            })
404            .unwrap_or_else(rand::random);
405        println!(
406            "To replay this '{}', set env var {}={}",
407            unwrap!(thread::current().name()),
408            env_var_name,
409            seed
410        );
411        XorShiftRng::seed_from_u64(seed)
412    }
413
414    #[test]
415    fn zbase32_encode_decode_idata_address() {
416        let name = XorName(rand::random());
417        let address = Address::Public(name);
418        let encoded = address.encode_to_zbase32();
419        let decoded = unwrap!(self::Address::decode_from_zbase32(&encoded));
420        assert_eq!(address, decoded);
421    }
422}