extern crate flat_tree as flat;
extern crate random_access_disk as rad;
extern crate random_access_memory as ram;
extern crate random_access_storage as ras;
extern crate sparse_bitfield;
extern crate tree_index;
pub use crypto::Keypair;
pub use feed_builder::FeedBuilder;
pub use storage::{Node, NodeTrait, Storage, Store};
use crypto::{generate_keypair, sign, Hash, Merkle, Signature};
use failure::Error;
use ras::RandomAccessMethods;
use sparse_bitfield::Bitfield;
use std::fmt::Debug;
use std::path::PathBuf;
use std::rc::Rc;
use tree_index::TreeIndex;
pub struct Proof {
pub index: usize,
pub nodes: Vec<Node>,
pub signature: Signature,
}
pub struct Feed<T>
where
T: RandomAccessMethods + Debug,
{
pub(crate) merkle: Merkle,
pub(crate) keypair: Keypair,
pub(crate) storage: Storage<T>,
pub(crate) byte_length: usize,
pub(crate) length: usize,
pub(crate) bitfield: Bitfield,
pub(crate) tree: TreeIndex,
}
impl<T> Feed<T>
where
T: RandomAccessMethods + Debug,
{
pub fn with_storage(storage: ::storage::Storage<T>) -> Result<Self, Error> {
let keypair = generate_keypair(); Ok(FeedBuilder::new(keypair, storage).build()?)
}
#[inline]
pub fn len(&self) -> usize {
self.length
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
pub fn byte_len(&self) -> usize {
self.byte_length
}
pub fn append(&mut self, data: &[u8]) -> Result<(), Error> {
self.merkle.next(data);
let mut offset = 0;
self.storage.write_data(self.byte_length + offset, &data)?;
offset += data.len();
let hash = Hash::from_roots(self.merkle.roots());
let index = self.length;
let signature = sign(&self.keypair, hash.as_bytes());
self.storage.put_signature(index, signature)?;
for node in self.merkle.nodes() {
self.storage.put_node(node)?;
}
self.byte_length += offset;
self.bitfield.set(self.length, true);
self.tree.set(2 * self.length);
self.length += 1;
Ok(())
}
pub fn get(&mut self, index: usize) -> Result<Option<Vec<u8>>, Error> {
if !self.bitfield.get(index) {
return Ok(None);
}
Ok(Some(self.storage.get_data(index)?))
}
pub fn proof(&mut self, index: usize) -> Result<Proof, Error> {
let proof = match self.tree.proof(2 * index, vec![]) {
Some(proof) => proof,
None => bail!("No proof available for index {}", index),
};
let signature = self.storage.get_signature(proof.verified_by / 2 - 1)?;
let mut nodes = Vec::with_capacity(proof.nodes.len());
for index in proof.nodes {
let node = self.storage.get_node(index)?;
nodes.push(node);
}
Ok(Proof {
nodes,
signature,
index,
})
}
pub fn put(
&mut self,
index: usize,
data: &[u8],
proof: Proof
) -> Result<(), Error> {
let mut next = 2 * index;
let mut trusted: Option<usize> = None;
let mut missing = vec![];
let mut i = 0;
loop {
if self.tree.get(next) {
trusted = Some(next);
break;
}
let sibling = flat::sibling(next);
next = flat::parent(next);
if i < proof.nodes.len() && proof.nodes[i].index == sibling {
i += 1;
continue;
}
if !self.tree.get(sibling) {
break;
}
missing.push(sibling);
}
if let None = trusted {
if self.tree.get(next) {
trusted = Some(next);
}
}
let mut missing_nodes = vec![];
for index in missing {
let node = self.storage.get_node(index)?;
missing_nodes.push(node);
}
let mut trusted_node = None;
if let Some(index) = trusted {
let node = self.storage.get_node(index)?;
trusted_node = Some(node);
}
println!("{:?} {:?}", trusted_node, data);
unimplemented!();
}
pub fn signature(&mut self, index: usize) -> Result<Signature, Error> {
ensure!(
index < self.length,
format!("No signature found for index {}", index)
);
Ok(self.storage.next_signature(index)?)
}
pub fn verify(
&mut self,
index: usize,
signature: &Signature,
) -> Result<(), Error> {
let roots = self.root_hashes(index)?;
let roots: Vec<_> = roots.into_iter().map(Rc::new).collect();
let message = Hash::from_roots(&roots);
let message = message.as_bytes();
::crypto::verify(&self.keypair.public, message, signature)?;
Ok(())
}
pub fn root_hashes(&mut self, index: usize) -> Result<Vec<Node>, Error> {
ensure!(
index <= self.length,
format!("Root index bounds exceeded {} > {}", index, self.length)
);
let roots_index = index * 2 + 2;
let mut indexes = vec![];
flat::full_roots(roots_index, &mut indexes);
let mut roots = Vec::with_capacity(indexes.len());
for index in indexes {
let node = self.storage.get_node(index)?;
roots.push(node);
}
Ok(roots)
}
pub fn keypair(&self) -> &Keypair {
&self.keypair
}
}
impl Feed<self::rad::RandomAccessDiskMethods> {
pub fn new(dir: &PathBuf) -> Result<Self, Error> {
let create = |storage: Store| {
let name = match storage {
Store::Tree => "tree",
Store::Data => "data",
Store::Bitfield => "bitfield",
Store::Signatures => "signatures",
};
rad::RandomAccessDisk::new(dir.as_path().join(name))
};
let storage = Storage::new(create)?;
let keypair = generate_keypair(); Ok(FeedBuilder::new(keypair, storage).build()?)
}
}
impl Default for Feed<self::ram::RandomAccessMemoryMethods> {
fn default() -> Self {
let create = |_| ram::RandomAccessMemory::default();
let storage = ::storage::Storage::new(create).unwrap();
Self::with_storage(storage).unwrap()
}
}