From 4202cfbcdefb0c90573e560ce763d9190b4ec4f9 Mon Sep 17 00:00:00 2001 From: Hanh Date: Mon, 21 Jun 2021 22:04:45 +0800 Subject: [PATCH] code complete --- src/builder.rs | 78 ++++++++++++++++++++++---------------------------- src/lib.rs | 3 +- src/main.rs | 50 ++++++++++++++++++++++++++++++-- 3 files changed, 85 insertions(+), 46 deletions(-) diff --git a/src/builder.rs b/src/builder.rs index 261c5ce..83c8c50 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -133,18 +133,14 @@ impl CTreeBuilder { Self::get_opt(commitments, index, offset).unwrap() } - fn adjusted_start(&self) -> usize { - if self.offset.is_some() { + fn adjusted_start(&self, prev: &Option, depth: usize) -> usize { + if depth != 0 && prev.is_some() { self.start - 1 } else { self.start } } - fn adjusted_end(&self, commitments: &[Node]) -> usize { - self.start + commitments.len() - } - fn clone_trimmed(&self, mut depth: usize) -> CTree { if depth == 0 { return CTree::new() @@ -199,18 +195,11 @@ impl Builder for WitnessBuilder { let offset = context.offset; let depth = context.depth; - if depth == 1 { - context.offset.map(|c| println!("{}", hex::encode(c.repr))); - for c in commitments.iter() { - println!("{}", hex::encode(c.repr)); - } - println!("==="); - } - let tree = &mut self.witness.tree; + let right = if depth != 0 { context.right } else { None }; if self.inside { - let rp = self.p - context.adjusted_start(); + let rp = self.p - context.adjusted_start(&offset, depth); if depth == 0 { if self.p % 2 == 1 { tree.left = Some(*CTreeBuilder::get(commitments, rp - 1, &offset)); @@ -230,11 +219,9 @@ impl Builder for WitnessBuilder { } let p1 = self.p + 1; - let has_p1 = p1 >= context.adjusted_start() && p1 < context.adjusted_end(commitments); - // println!("D{}: {} {} {} {}", depth, p1, context.start, context.start + commitments.len(), context.offset.is_some()); + let has_p1 = p1 >= context.adjusted_start(&right, depth) && p1 < context.start + commitments.len(); if has_p1 { - let p1 = CTreeBuilder::get(commitments, p1 - context.adjusted_start(), &offset); - println!("P1 {} {}", depth, hex::encode(p1.repr)); + let p1 = CTreeBuilder::get(commitments, p1 - context.adjusted_start(&right, depth), &right); if depth == 0 { if tree.right.is_none() { self.witness.filled.push(*p1); @@ -260,32 +247,36 @@ impl Builder for WitnessBuilder { let tree = &self.witness.tree; let mut num_filled = self.witness.filled.len(); - let mut depth = 0; - loop { - let is_none = if depth == 0 { // check if this level is occupied - tree.right.is_none() - } else { - depth > tree.parents.len() || tree.parents[depth - 1].is_none() - }; - if is_none { - if num_filled > 0 { - num_filled -= 1; // we filled it - } - else { - break - } - } - depth += 1; - // loop terminates because we are eventually going to run out of ancestors and filled + if self.witness.position + 1 == context.next_tree.get_position() { + self.witness.cursor = CTree::new(); } + else { + let mut depth = 0; + loop { + let is_none = if depth == 0 { // check if this level is occupied + tree.right.is_none() + } else { + depth > tree.parents.len() || tree.parents[depth - 1].is_none() + }; + if is_none { + if num_filled > 0 { + num_filled -= 1; // we filled it + } else { + break + } + } + depth += 1; + // loop terminates because we are eventually going to run out of ancestors and filled + } - self.witness.cursor = context.clone_trimmed(depth - 1); + self.witness.cursor = context.clone_trimmed(depth - 1); + } self.witness } } #[allow(dead_code)] -fn advance_tree( +pub fn advance_tree( prev_tree: CTree, prev_witnesses: &[Witness], mut commitments: &mut [Node], @@ -330,9 +321,9 @@ mod tests { #[test] fn test_advance_tree() { - const NUM_NODES: usize = 10; - const NUM_CHUNKS: usize = 5; - const WITNESS_PERCENT: f64 = 100.0; // percentage of notes that are ours + const NUM_NODES: usize = 1000; + const NUM_CHUNKS: usize = 50; + const WITNESS_PERCENT: f64 = 1.0; // percentage of notes that are ours const DEBUG_PRINT: bool = true; let witness_freq = (100.0 / WITNESS_PERCENT) as usize; @@ -341,6 +332,7 @@ mod tests { let mut ws: Vec> = vec![]; let mut ws2: Vec = vec![]; for i in 0..NUM_CHUNKS { + println!("{}", i); let mut nodes: Vec<_> = vec![]; for j in 0..NUM_NODES { let mut bb = [0u8; 32]; @@ -351,8 +343,8 @@ mod tests { for w in ws.iter_mut() { w.append(node).unwrap(); } - // if v % witness_freq == 0 { - if v == 37 { + if v % witness_freq == 0 { + // if v == 499 { let w = IncrementalWitness::from_tree(&tree1); ws.push(w); ws2.push(Witness::new(v)); diff --git a/src/lib.rs b/src/lib.rs index 11a2ffe..d6aaf3a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -13,7 +13,8 @@ mod scan; mod builder; pub use crate::chain::{LWD_URL, get_latest_height, download_chain, calculate_tree_state_v2, DecryptNode}; -pub use crate::commitment::NotePosition; +pub use crate::commitment::{NotePosition, Witness, CTree}; +pub use crate::builder::advance_tree; pub use crate::lw_rpc::compact_tx_streamer_client::CompactTxStreamerClient; pub use crate::lw_rpc::*; pub use crate::scan::scan_all; diff --git a/src/main.rs b/src/main.rs index f6c5049..5216247 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,9 +1,13 @@ use zcash_client_backend::encoding::decode_extended_full_viewing_key; -use sync::{NETWORK, scan_all}; +use sync::{NETWORK, scan_all, Witness, CTree, advance_tree}; use zcash_primitives::consensus::Parameters; +use zcash_primitives::merkle_tree::{CommitmentTree, IncrementalWitness}; +use zcash_primitives::sapling::Node; +use std::time::Instant; #[tokio::main] -async fn main() { +#[allow(dead_code)] +async fn main_scan() { dotenv::dotenv().unwrap(); env_logger::init(); @@ -16,3 +20,45 @@ async fn main() { scan_all(&vec![ivk]).await.unwrap(); } + +fn test_advance_tree() { + const NUM_NODES: usize = 1000; + const NUM_CHUNKS: usize = 50; + const WITNESS_PERCENT: f64 = 1.0; // percentage of notes that are ours + let witness_freq = (100.0 / WITNESS_PERCENT) as usize; + + let mut _tree1: CommitmentTree = CommitmentTree::empty(); + let mut tree2 = CTree::new(); + let mut _ws: Vec> = vec![]; + let mut ws2: Vec = vec![]; + let start = Instant::now(); + for i in 0..NUM_CHUNKS { + eprintln!("{}, {}", i, start.elapsed().as_millis()); + let mut nodes: Vec<_> = vec![]; + for j in 0..NUM_NODES { + let mut bb = [0u8; 32]; + let v = i * NUM_NODES + j; + bb[0..8].copy_from_slice(&v.to_be_bytes()); + let node = Node::new(bb); + // tree1.append(node).unwrap(); + // for w in ws.iter_mut() { + // w.append(node).unwrap(); + // } + if v % witness_freq == 0 { + // let w = IncrementalWitness::from_tree(&tree1); + // ws.push(w); + ws2.push(Witness::new(v)); + } + nodes.push(node); + } + let (new_tree, new_witnesses) = advance_tree(tree2, &ws2, &mut nodes); + tree2 = new_tree; + ws2 = new_witnesses; + } + + println!("# witnesses = {}", ws2.len()); +} + +fn main() { + test_advance_tree(); +}