From 341a3c9f4dff292fa66fd5ca2de0325b437a4f31 Mon Sep 17 00:00:00 2001 From: Ignotus Peverell Date: Sat, 24 Feb 2018 23:39:26 +0000 Subject: [PATCH] Minor cleanup, range proof pmmr validation and tests --- chain/src/sumtree.rs | 53 ++++++++------------------------ chain/tests/mine_simple_chain.rs | 7 ++++- core/src/core/transaction.rs | 7 ++--- store/src/types.rs | 10 ------ 4 files changed, 20 insertions(+), 57 deletions(-) diff --git a/chain/src/sumtree.rs b/chain/src/sumtree.rs index 82c714f3d..9872bbaf2 100644 --- a/chain/src/sumtree.rs +++ b/chain/src/sumtree.rs @@ -379,7 +379,6 @@ impl<'a> Extension<'a> { // Now prune the utxo_pmmr, rproof_pmmr and their storage. // Input is not valid if we cannot prune successfully (to spend an unspent output). - // TODO: rm log, skip list for utxo and range proofs match self.utxo_pmmr.prune(pos, height as u32) { Ok(true) => { self.rproof_pmmr @@ -628,7 +627,7 @@ impl<'a> Extension<'a> { Ok((sum_kernel, fees)) } - /// Sums all our UTXO commitments + /// Sums all our UTXO commitments, checking range proofs at the same time fn sum_utxos(&self) -> Result { let mut sum_utxo = None; let mut utxo_count = 0; @@ -636,11 +635,19 @@ impl<'a> Extension<'a> { for n in 1..self.utxo_pmmr.unpruned_size()+1 { if pmmr::bintree_postorder_height(n) == 0 { if let Some((_,output)) = self.utxo_pmmr.get(n, true) { - if n == 1 { - sum_utxo = Some(output.expect("not a leaf node").commit); + let out = output.expect("not a leaf node"); + let commit = out.commit.clone(); + match self.rproof_pmmr.get(n, true) { + Some((_, Some(rp))) => out.to_output(rp).verify_proof()?, + res => { + return Err(Error::OutputNotFound); + } + } + if let None = sum_utxo { + sum_utxo = Some(commit); } else { let secp = secp.lock().unwrap(); - sum_utxo = Some(secp.commit_sum(vec![sum_utxo.unwrap(), output.expect("not a leaf node").commit], vec![])?); + sum_utxo = Some(secp.commit_sum(vec![sum_utxo.unwrap(), commit], vec![])?); } utxo_count += 1; } @@ -651,42 +658,6 @@ impl<'a> Extension<'a> { } } -/*fn store_element(file_store: &mut FlatFileStore, data: T) - -> Result<(), String> -where - T: ser::Readable + ser::Writeable + Clone -{ - file_store.append(vec![data]) -} - -fn read_element_at_pmmr_index(file_store: &FlatFileStore, pos: u64) -> Option -where - T: ser::Readable + ser::Writeable + Clone -{ - let leaf_index = pmmr::leaf_index(pos); - // flat files are zero indexed - file_store.get(leaf_index - 1) -} - -fn _remove_element_at_pmmr_index(file_store: &mut FlatFileStore, pos: u64) - -> Result<(), String> -where - T: ser::Readable + ser::Writeable + Clone -{ - let leaf_index = pmmr::leaf_index(pos); - // flat files are zero indexed - file_store.remove(vec![leaf_index - 1]) -} - -fn rewind_to_pmmr_index(file_store: &mut FlatFileStore, pos: u64) -> Result<(), String> -where - T: ser::Readable + ser::Writeable + Clone -{ - let leaf_index = pmmr::leaf_index(pos); - // flat files are zero indexed - file_store.rewind(leaf_index - 1) -}*/ - /// Output and kernel MMR indexes at the end of the provided block. /// This requires us to know the "last" output processed in the block /// and needs to be consistent with how we originally processed diff --git a/chain/tests/mine_simple_chain.rs b/chain/tests/mine_simple_chain.rs index 6cb4ce579..12d4c72ff 100644 --- a/chain/tests/mine_simple_chain.rs +++ b/chain/tests/mine_simple_chain.rs @@ -117,8 +117,9 @@ fn mine_empty_chain() { // now check the block height index let header_by_height = chain.get_header_by_height(n).unwrap(); assert_eq!(header_by_height.hash(), bhash); + + chain.validate().unwrap(); } - chain.validate().unwrap(); } #[test] @@ -281,6 +282,7 @@ fn spend_in_fork() { let next = prepare_block_tx(&kc, &fork_head, &chain, 7, vec![&tx1]); let prev_main = next.header.clone(); chain.process_block(next.clone(), chain::Options::SKIP_POW).unwrap(); + chain.validate().unwrap(); println!("tx 1 processed, should have 6 outputs or 396 bytes in file, first skipped"); @@ -296,6 +298,7 @@ fn spend_in_fork() { let next = prepare_block_tx(&kc, &prev_main, &chain, 9, vec![&tx2]); let prev_main = next.header.clone(); chain.process_block(next, chain::Options::SKIP_POW).unwrap(); + chain.validate().unwrap(); println!("tx 2 processed"); /*panic!("Stop");*/ @@ -308,6 +311,7 @@ fn spend_in_fork() { let fork_next = prepare_fork_block_tx(&kc, &prev_fork, &chain, 8, vec![&tx2]); let prev_fork = fork_next.header.clone(); chain.process_block(fork_next, chain::Options::SKIP_POW).unwrap(); + chain.validate().unwrap(); // check state let head = chain.head_header().unwrap(); @@ -320,6 +324,7 @@ fn spend_in_fork() { let fork_next = prepare_fork_block(&kc, &prev_fork, &chain, 10); let prev_fork = fork_next.header.clone(); chain.process_block(fork_next, chain::Options::SKIP_POW).unwrap(); + chain.validate().unwrap(); // check state let head = chain.head_header().unwrap(); diff --git a/core/src/core/transaction.rs b/core/src/core/transaction.rs index 5e42f718d..523d00be6 100644 --- a/core/src/core/transaction.rs +++ b/core/src/core/transaction.rs @@ -863,15 +863,12 @@ impl OutputStoreable { } /// Return a regular output - pub fn to_output(self) -> Output { + pub fn to_output(self, rproof: RangeProof) -> Output { Output{ features: self.features, commit: self.commit, switch_commit_hash: self.switch_commit_hash, - proof: RangeProof{ - proof:[0; secp::constants::MAX_PROOF_SIZE], - plen: 0, - }, + proof: rproof, } } } diff --git a/store/src/types.rs b/store/src/types.rs index f2bbff371..2096fb7a0 100644 --- a/store/src/types.rs +++ b/store/src/types.rs @@ -43,7 +43,6 @@ pub struct AppendOnlyFile { buffer_start: usize, buffer: Vec, buffer_start_bak: usize, - unflushed_data_size: usize, } impl AppendOnlyFile { @@ -61,7 +60,6 @@ impl AppendOnlyFile { buffer_start: 0, buffer: vec![], buffer_start_bak: 0, - unflushed_data_size: 0, }; if let Ok(sz) = aof.size() { if sz > 0 { @@ -75,7 +73,6 @@ impl AppendOnlyFile { /// Append data to the file. Until the append-only file is synced, data is /// only written to memory. pub fn append(&mut self, buf: &mut Vec) { - self.unflushed_data_size += buf.len(); self.buffer.append(buf); } @@ -102,7 +99,6 @@ impl AppendOnlyFile { self.file.sync_data()?; self.buffer = vec![]; self.mmap = Some(unsafe { memmap::Mmap::map(&self.file)? }); - self.unflushed_data_size = 0; Ok(()) } @@ -114,7 +110,6 @@ impl AppendOnlyFile { self.buffer_start_bak = 0; } self.buffer = vec![]; - self.unflushed_data_size = 0; } /// Read length bytes of data at offset from the file. Leverages the memory @@ -186,11 +181,6 @@ impl AppendOnlyFile { fs::metadata(&self.path).map(|md| md.len()) } - /// Current size of file in bytes + size of unsaved data - pub fn size_with_unsaved(&self) -> u64 { - self.size().unwrap() + self.unflushed_data_size as u64 - } - /// Path of the underlying file pub fn path(&self) -> String { self.path.clone()