extern crate ed25519_dalek;
extern crate failure;
extern crate flat_tree as flat;
extern crate merkle_tree_stream as merkle_stream;
extern crate random_access_disk as rad;
extern crate random_access_memory as ram;
extern crate random_access_storage as ras;
extern crate sleep_parser;
mod data;
mod node;
mod persist;
pub use self::data::Data;
pub use self::merkle_stream::Node as NodeTrait;
pub use self::node::Node;
pub use self::persist::Persist;
use self::ed25519_dalek::Signature;
use self::failure::Error;
use self::ras::RandomAccessMethods;
use self::sleep_parser::*;
use std::fmt::Debug;
use std::ops::Range;
const HEADER_OFFSET: usize = 32;
#[derive(Debug)]
pub enum Store {
Tree,
Data,
Bitfield,
Signatures,
}
#[derive(Debug)]
pub struct Storage<T>
where
T: RandomAccessMethods + Debug,
{
tree: ras::RandomAccess<T>,
data: ras::RandomAccess<T>,
bitfield: ras::RandomAccess<T>,
signatures: ras::RandomAccess<T>,
}
impl<T> Storage<T>
where
T: RandomAccessMethods + Debug,
{
pub fn new<Cb>(create: Cb) -> Result<Self, Error>
where
Cb: Fn(Store) -> ras::RandomAccess<T>,
{
let mut instance = Self {
tree: create(Store::Tree),
data: create(Store::Data),
bitfield: create(Store::Bitfield),
signatures: create(Store::Signatures),
};
let header = create_bitfield();
instance.bitfield.write(0, &header.to_vec())?;
let header = create_signatures();
instance.signatures.write(0, &header.to_vec())?;
let header = create_tree();
instance.tree.write(0, &header.to_vec())?;
Ok(instance)
}
#[inline]
pub fn write_data(
&mut self,
offset: usize,
data: &[u8],
) -> Result<(), Error> {
self.data.write(offset, &data)
}
pub fn put_data(
&mut self,
index: usize,
data: &[u8],
nodes: &[Node],
) -> Result<(), Error> {
if data.is_empty() {
return Ok(());
}
let range = self.data_offset(index, nodes)?;
ensure!(
range.len() == data.len(),
format!("length `{:?} != {:?}`", range.len(), data.len())
);
self.data.write(range.start, data)
}
#[inline]
pub fn get_data(&mut self, index: usize) -> Result<Vec<u8>, Error> {
let cached_nodes = Vec::new(); let range = self.data_offset(index, &cached_nodes)?;
self.data.read(range.start, range.len())
}
pub fn next_signature(&mut self, index: usize) -> Result<Signature, Error> {
let bytes = self.signatures.read(HEADER_OFFSET + 64 * index, 64)?;
if not_zeroes(&bytes) {
Ok(Signature::from_bytes(&bytes)?)
} else {
Ok(self.next_signature(index + 1)?)
}
}
#[inline]
pub fn get_signature(&mut self, index: usize) -> Result<Signature, Error> {
let bytes = self.signatures.read(HEADER_OFFSET + 64 * index, 64)?;
ensure!(not_zeroes(&bytes), "No signature found");
Ok(Signature::from_bytes(&bytes)?)
}
#[inline]
pub fn put_signature(
&mut self,
index: usize,
signature: Signature,
) -> Result<(), Error> {
self
.signatures
.write(HEADER_OFFSET + 64 * index, &signature.to_bytes())
}
pub fn data_offset(
&mut self,
index: usize,
cached_nodes: &[Node],
) -> Result<Range<usize>, Error> {
let mut roots = Vec::new(); flat::full_roots(2 * index, &mut roots);
let mut offset = 0;
let mut pending = roots.len();
let block_index = 2 * index;
if pending == 0 {
let len = match find_node(&cached_nodes, block_index) {
Some(node) => node.len(),
None => (self.get_node(block_index)?).len(),
};
return Ok(offset..offset + len);
}
for root in roots {
let node = self.get_node(root)?;
offset += node.len();
pending -= 1;
if pending > 0 {
continue;
}
let len = match find_node(&cached_nodes, block_index) {
Some(node) => node.len(),
None => (self.get_node(block_index)?).len(),
};
return Ok(offset..offset + len);
}
panic!("Loop executed without finding max value");
}
#[inline]
pub fn get_node(&mut self, index: usize) -> Result<Node, Error> {
let buf = self.tree.read(HEADER_OFFSET + 40 * index, 40)?;
let node = Node::from_bytes(index, &buf)?;
Ok(node)
}
#[inline]
pub fn put_node(&mut self, node: &Node) -> Result<(), Error> {
let index = node.index();
let buf = node.to_bytes()?;
self.tree.write(HEADER_OFFSET + 40 * index, &buf)
}
#[inline]
pub fn put_bitfield(
&mut self,
offset: usize,
data: &[u8],
) -> Result<(), Error> {
self.bitfield.write(HEADER_OFFSET + offset, data)
}
pub fn open_key(&mut self) {
unimplemented!();
}
}
#[inline]
fn find_node(nodes: &[Node], index: usize) -> Option<&Node> {
for node in nodes {
if node.index() == index {
return Some(node);
}
}
None
}
#[inline]
fn not_zeroes(bytes: &[u8]) -> bool {
for byte in bytes {
if *byte != 0 {
return true;
}
}
false
}
#[test]
fn should_detect_zeroes() {
let nums = vec![0; 10];
assert!(!not_zeroes(&nums));
let nums = vec![1; 10];
assert!(not_zeroes(&nums));
}