From 7879b6332132108bdda7476a574eb5ef9cc5f9a3 Mon Sep 17 00:00:00 2001 From: NikVolf Date: Tue, 24 Sep 2019 12:45:23 +0200 Subject: [PATCH] add docs --- src/entry.rs | 11 +++++++++++ src/lib.rs | 8 ++++++++ src/node_data.rs | 18 ++++++++++++++++++ src/tree.rs | 11 +++++++++++ 4 files changed, 48 insertions(+) diff --git a/src/entry.rs b/src/entry.rs index 72582c2..04490b3 100644 --- a/src/entry.rs +++ b/src/entry.rs @@ -2,8 +2,10 @@ use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt}; use crate::{EntryKind, NodeData, Error, EntryLink, MAX_NODE_DATA_SIZE}; +/// Max serialized length of entry data. pub const MAX_ENTRY_SIZE: usize = MAX_NODE_DATA_SIZE + 9; +/// MMR Entry. #[derive(Debug)] pub struct Entry { pub(crate) kind: EntryKind, @@ -11,23 +13,28 @@ pub struct Entry { } impl Entry { + /// Update siblings of the entry (to promote it from leaf to node) pub fn update_siblings(&mut self, left: EntryLink, right: EntryLink) { self.kind = EntryKind::Node(left, right); } + /// Returns if is this node complete (has total of 2^N leaves) pub fn complete(&self) -> bool { let leaves = self.leaf_count(); leaves & (leaves - 1) == 0 } + /// Number of leaves under this node. pub fn leaf_count(&self) -> u64 { self.data.end_height - self.data.start_height + 1 } + /// Is this node a leaf. pub fn is_leaf(&self) -> bool { if let EntryKind::Leaf = self.kind { true } else { false } } + /// Left child pub fn left(&self) -> Result { match self.kind { EntryKind::Leaf => { Err(Error::ExpectedNode) } @@ -35,6 +42,7 @@ impl Entry { } } + /// Right child. pub fn right(&self) -> Result { match self.kind { EntryKind::Leaf => { Err(Error::ExpectedNode) } @@ -42,6 +50,7 @@ impl Entry { } } + /// Read from byte representation. pub fn read(consensus_branch_id: u32, r: &mut R) -> std::io::Result { let kind = { match r.read_u8()? { @@ -67,6 +76,7 @@ impl Entry { }) } + /// Write to byte representation. pub fn write(&self, w: &mut W) -> std::io::Result<()> { match self.kind { EntryKind::Node(EntryLink::Stored(left), EntryLink::Stored(right)) => { @@ -85,6 +95,7 @@ impl Entry { Ok(()) } + /// Convert from byte representation. pub fn from_bytes>(consensus_branch_id: u32, buf: T) -> std::io::Result { let mut cursor = std::io::Cursor::new(buf); Self::read(consensus_branch_id, &mut cursor) diff --git a/src/lib.rs b/src/lib.rs index da0cc5d..c0c781c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,19 +1,25 @@ //! MMR library for Zcash //! //! To be used in zebra and via FFI bindings in zcashd +#![warn(missing_docs)] mod tree; mod node_data; mod entry; + pub use tree::Tree; pub use node_data::{NodeData, MAX_NODE_DATA_SIZE}; pub use entry::{Entry, MAX_ENTRY_SIZE}; +/// Crate-level error type #[derive(Debug)] pub enum Error { + /// Entry expected to be presented in the tree view while it was not. ExpectedInMemory(EntryLink), + /// Entry expected to be a node. ExpectedNode, + /// Entry expected to be a node (specifying for which link this is not true). ExpectedNodeForLink(EntryLink), } @@ -50,7 +56,9 @@ impl std::fmt::Display for EntryLink { #[repr(C)] #[derive(Debug)] pub enum EntryKind { + /// Leaf entry. Leaf, + /// Node entry with children links. Node(EntryLink, EntryLink), } diff --git a/src/node_data.rs b/src/node_data.rs index 0adc0f2..a018daa 100644 --- a/src/node_data.rs +++ b/src/node_data.rs @@ -2,23 +2,36 @@ use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt, ByteOrder}; use bigint::U256; use blake2::Params as Blake2Params; +/// Maximum serialized size of the node metadata. pub const MAX_NODE_DATA_SIZE: usize = 32 + 4 + 4 + 4 + 4 + 32 + 32 + 32 + 9 + 9 + 9; // 171 /// Node metadata. #[repr(C)] #[derive(Debug, Clone, Default)] pub struct NodeData { + /// Consensus branch id, should be provided by deserializing node. pub consensus_branch_id: u32, + /// Subtree commitment - either block hash for leaves or hashsum of children for nodes. pub subtree_commitment: [u8; 32], + /// Start time. pub start_time: u32, + /// End time. pub end_time: u32, + /// Start target. pub start_target: u32, + /// End target. pub end_target: u32, + /// Start sapling tree root. pub start_sapling_root: [u8; 32], + /// End sapling tree root. pub end_sapling_root: [u8; 32], + /// Part of tree total work. pub subtree_total_work: U256, + /// Start height. pub start_height: u64, + /// End height pub end_height: u64, + /// Number of shielded transactions. pub shielded_tx: u64, } @@ -42,6 +55,7 @@ fn personalization(branch_id: u32) -> [u8; 16] { } impl NodeData { + /// Combine two nodes metadata. pub fn combine(left: &NodeData, right: &NodeData) -> NodeData { assert_eq!(left.consensus_branch_id, right.consensus_branch_id); @@ -106,6 +120,7 @@ impl NodeData { Ok(result) } + /// Write to the byte representation. pub fn write(&self, w: &mut W) -> std::io::Result<()> { w.write_all(&self.subtree_commitment)?; w.write_u32::(self.start_time)?; @@ -125,6 +140,7 @@ impl NodeData { Ok(()) } + /// Read from the byte representation. pub fn read(consensus_branch_id: u32, r: &mut R) -> std::io::Result { let mut data = Self::default(); data.consensus_branch_id = consensus_branch_id; @@ -147,6 +163,7 @@ impl NodeData { Ok(data) } + /// Convert to byte representation. pub fn to_bytes(&self) -> Vec { let mut buf = [0u8; MAX_NODE_DATA_SIZE]; let pos = { @@ -158,6 +175,7 @@ impl NodeData { buf[0..pos].to_vec() } + /// Convert from byte representation. pub fn from_bytes>(consensus_branch_id: u32, buf: T) -> std::io::Result { let mut cursor = std::io::Cursor::new(buf); Self::read(consensus_branch_id, &mut cursor) diff --git a/src/tree.rs b/src/tree.rs index b816287..8b65c52 100644 --- a/src/tree.rs +++ b/src/tree.rs @@ -24,6 +24,7 @@ pub struct Tree { } impl Tree { + /// Resolve link originated from this tree pub fn resolve_link(&self, link: EntryLink) -> Result { match link { EntryLink::Generated(index) => { @@ -80,6 +81,12 @@ impl Tree { } } + /// New view into the the tree array representation + /// + /// `length` is total length of the array representation + /// `peaks` is peaks of the mmr tree + /// `extra` is some extra nodes that calculated to be required during next one or more + /// operations on the tree. pub fn new( length: u32, peaks: Vec<(u32, Entry)>, @@ -267,6 +274,7 @@ impl Tree { } } +/// Reference to the node with link attached. #[derive(Debug)] pub struct IndexedNode<'a> { node: &'a Entry, @@ -283,14 +291,17 @@ impl<'a> IndexedNode<'a> { self.node.right().map_err(|e| e.augment(self.link)) } + /// Reference to the entry struct. pub fn node(&self) -> &Entry { self.node } + /// Reference to the entry metadata. pub fn data(&self) -> &NodeData { &self.node.data } + /// Actual link by what this node was resolved. pub fn link(&self) -> EntryLink { self.link }