mirror of
https://github.com/Qortal/pirate-librustzcash.git
synced 2025-02-11 17:55:46 +00:00
add docs
This commit is contained in:
parent
ce2416623f
commit
7879b63321
11
src/entry.rs
11
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<EntryLink, Error> {
|
||||
match self.kind {
|
||||
EntryKind::Leaf => { Err(Error::ExpectedNode) }
|
||||
@ -35,6 +42,7 @@ impl Entry {
|
||||
}
|
||||
}
|
||||
|
||||
/// Right child.
|
||||
pub fn right(&self) -> Result<EntryLink, Error> {
|
||||
match self.kind {
|
||||
EntryKind::Leaf => { Err(Error::ExpectedNode) }
|
||||
@ -42,6 +50,7 @@ impl Entry {
|
||||
}
|
||||
}
|
||||
|
||||
/// Read from byte representation.
|
||||
pub fn read<R: std::io::Read>(consensus_branch_id: u32, r: &mut R) -> std::io::Result<Self> {
|
||||
let kind = {
|
||||
match r.read_u8()? {
|
||||
@ -67,6 +76,7 @@ impl Entry {
|
||||
})
|
||||
}
|
||||
|
||||
/// Write to byte representation.
|
||||
pub fn write<W: std::io::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<T: AsRef<[u8]>>(consensus_branch_id: u32, buf: T) -> std::io::Result<Self> {
|
||||
let mut cursor = std::io::Cursor::new(buf);
|
||||
Self::read(consensus_branch_id, &mut cursor)
|
||||
|
@ -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),
|
||||
}
|
||||
|
||||
|
@ -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<W: std::io::Write>(&self, w: &mut W) -> std::io::Result<()> {
|
||||
w.write_all(&self.subtree_commitment)?;
|
||||
w.write_u32::<LittleEndian>(self.start_time)?;
|
||||
@ -125,6 +140,7 @@ impl NodeData {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Read from the byte representation.
|
||||
pub fn read<R: std::io::Read>(consensus_branch_id: u32, r: &mut R) -> std::io::Result<Self> {
|
||||
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<u8> {
|
||||
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<T: AsRef<[u8]>>(consensus_branch_id: u32, buf: T) -> std::io::Result<Self> {
|
||||
let mut cursor = std::io::Cursor::new(buf);
|
||||
Self::read(consensus_branch_id, &mut cursor)
|
||||
|
11
src/tree.rs
11
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<IndexedNode, Error> {
|
||||
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
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user