From 6a9a584c43db85b311af6c800c2e5ab4f004f914 Mon Sep 17 00:00:00 2001 From: Ignotus Peverell Date: Mon, 8 Jan 2018 01:23:23 +0000 Subject: [PATCH] Fix pruning of last PMMR leaf, additional tests Due to the construction of PMMRs the last element, when its a leaf, can never be pruned as it has no parent yet and it will be needed to calculate that hash. To work around this, we now insert coinbase outputs first to add at least one output of padding. Also changed the `set_sumtree_root` function on chain a bit to allow setting the roots on a fork. Mostly useful for tests. Added new test case to handle both the issue above and spending transactions within a fork. --- chain/src/chain.rs | 8 +- chain/src/pipe.rs | 10 +- chain/src/sumtree.rs | 161 +++++++++++++++----------- chain/tests/mine_simple_chain.rs | 134 +++++++++++++++++---- chain/tests/test_coinbase_maturity.rs | 8 +- grin/src/miner.rs | 2 +- 6 files changed, 224 insertions(+), 99 deletions(-) diff --git a/chain/src/chain.rs b/chain/src/chain.rs index 59e2efcb5..52c7bb8d9 100644 --- a/chain/src/chain.rs +++ b/chain/src/chain.rs @@ -358,11 +358,15 @@ impl Chain { /// Sets the sumtree roots on a brand new block by applying the block on the /// current sumtree state. - pub fn set_sumtree_roots(&self, b: &mut Block) -> Result<(), Error> { + pub fn set_sumtree_roots(&self, b: &mut Block, is_fork: bool) -> Result<(), Error> { let mut sumtrees = self.sumtrees.write().unwrap(); + let store = self.store.clone(); let roots = sumtree::extending(&mut sumtrees, |extension| { // apply the block on the sumtrees and check the resulting root + if is_fork { + pipe::rewind_and_apply_fork(b, store, extension)?; + } extension.apply_block(b)?; extension.force_rollback(); Ok(extension.roots()) @@ -374,7 +378,7 @@ impl Chain { Ok(()) } - /// returs sumtree roots + /// Returns current sumtree roots pub fn get_sumtree_roots( &self, ) -> ( diff --git a/chain/src/pipe.rs b/chain/src/pipe.rs index 0ba3e9771..1c6804b1b 100644 --- a/chain/src/pipe.rs +++ b/chain/src/pipe.rs @@ -393,11 +393,11 @@ fn update_header_head(bh: &BlockHeader, ctx: &mut BlockContext) -> Result