1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
// Copyright 2018 MaidSafe.net limited.
//
// This SAFE Network Software is licensed to you under The General Public License (GPL), version 3.
// Unless required by applicable law or agreed to in writing, the SAFE Network Software distributed
// under the GPL Licence is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. Please review the Licences for the specific language governing
// permissions and limitations relating to use of the SAFE Network Software.

#![doc(hidden)]

use super::Storage;
use crate::SelfEncryptionError;
use async_trait::async_trait;

use rand::{self, Rng, SeedableRng};
use rand_chacha::ChaChaRng;
use serde::{de::DeserializeOwned, Serialize};
use std::{
    cmp, env,
    fmt::{self, Debug, Formatter},
    thread,
};
use tiny_keccak::{Hasher, Sha3};

pub type TestRng = ChaChaRng;

#[derive(PartialEq, Eq)]
pub struct Blob<'a>(pub &'a [u8]);

impl<'a> Debug for Blob<'a> {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        for byte in self.0[..cmp::min(self.0.len(), 4)].iter() {
            write!(f, "{:02x}", byte)?;
        }
        write!(f, "..")?;
        for byte in self.0[cmp::max(4, self.0.len()) - 4..].iter() {
            write!(f, "{:02x}", byte)?;
        }
        Ok(())
    }
}

struct Entry {
    name: Vec<u8>,
    data: Vec<u8>,
}

#[derive(Default)]
pub struct SimpleStorage {
    entries: Vec<Entry>,
}

impl SimpleStorage {
    pub fn new() -> SimpleStorage {
        SimpleStorage { entries: vec![] }
    }

    pub fn has_chunk(&self, name: &[u8]) -> bool {
        self.entries.iter().any(|entry| entry.name == name)
    }

    pub fn num_entries(&self) -> usize {
        self.entries.len()
    }
}

#[async_trait]
impl Storage for SimpleStorage {
    // type Error = SelfEncryptionError;

    async fn get(&mut self, name: &[u8]) -> Result<Vec<u8>, SelfEncryptionError> {
        match self.entries.iter().find(|entry| entry.name == name) {
            Some(entry) => Ok(entry.data.clone()),
            None => Err(SelfEncryptionError::Storage),
        }
    }

    async fn put(&mut self, name: Vec<u8>, data: Vec<u8>) -> Result<(), SelfEncryptionError> {
        self.entries.push(Entry { name, data });

        Ok(())
    }

    async fn delete(&mut self, name: &[u8]) -> Result<(), SelfEncryptionError> {
        self.entries.retain(|entry| entry.name != name);

        Ok(())
    }

    async fn generate_address(&self, data: &[u8]) -> Result<Vec<u8>, SelfEncryptionError> {
        let mut hasher = Sha3::v256();
        let mut output = [0; 32];
        hasher.update(&data);
        hasher.finalize(&mut output);
        Ok(output.to_vec())
    }
}

// Create new random number generator suitable for tests. To provide repeatable results, the seed
// can be overridden using the "SEED" env variable. If this variable is not provided, a random one
// is used (to support soak testing). The current seed is printed to stdout.
pub fn new_test_rng() -> Result<TestRng, SelfEncryptionError> {
    let seed = if let Ok(seed) = env::var("SEED") {
        seed.parse()?
    } else {
        rand::thread_rng().gen()
    };

    println!(
        "RNG seed for thread {:?}: {}",
        thread::current().name().unwrap(),
        seed
    );

    Ok(TestRng::seed_from_u64(seed))
}

pub fn from_rng(rng: &mut TestRng) -> Result<TestRng, SelfEncryptionError> {
    Ok(TestRng::from_rng(rng)?)
}

pub fn serialise<T: Serialize>(data: &T) -> Result<Vec<u8>, SelfEncryptionError> {
    Ok(bincode::serialize(data)?)
}

pub fn deserialise<T>(data: &[u8]) -> Result<T, SelfEncryptionError>
where
    T: Serialize + DeserializeOwned,
{
    match bincode::deserialize(data) {
        Ok(data) => Ok(data),
        Err(_) => Err(SelfEncryptionError::Deserialise),
    }
}

pub fn random_bytes<T: Rng>(rng: &mut T, size: usize) -> Vec<u8> {
    let mut bytes = vec![0_u8; size];
    rng.fill(bytes.as_mut_slice());
    bytes
}