diff --git a/chain/src/pipe.rs b/chain/src/pipe.rs index e436acae6..d2cc9f772 100644 --- a/chain/src/pipe.rs +++ b/chain/src/pipe.rs @@ -237,14 +237,17 @@ fn validate_block( } } - // rewind the sum trees up the forking block, providing the height of the - // forked block and the last commitment we want to rewind to let forked_block = ctx.store.get_block(¤t)?; - if forked_block.header.height > 0 { - let last_output = &forked_block.outputs[forked_block.outputs.len() - 1]; - let last_kernel = &forked_block.kernels[forked_block.kernels.len() - 1]; - ext.rewind(forked_block.header.height, last_output, last_kernel)?; - } + + debug!( + LOGGER, + "validate_block: forked_block: {} at {}", + forked_block.header.hash(), + forked_block.header.height, + ); + + // rewind the sum trees up to the forking block + ext.rewind(&forked_block)?; // apply all forked blocks, including this new one for h in hashes { @@ -259,6 +262,26 @@ fn validate_block( || kernel_root.hash != b.header.kernel_root { ext.dump(false); + + debug!( + LOGGER, + "validate_block: utxo roots - {:?}, {:?}", + utxo_root.hash, + b.header.utxo_root, + ); + debug!( + LOGGER, + "validate_block: rproof roots - {:?}, {:?}", + rproof_root.hash, + b.header.range_proof_root, + ); + debug!( + LOGGER, + "validate_block: kernel roots - {:?}, {:?}", + kernel_root.hash, + b.header.kernel_root, + ); + return Err(Error::InvalidRoot); } diff --git a/chain/src/sumtree.rs b/chain/src/sumtree.rs index bd6feef9a..fe118c8a3 100644 --- a/chain/src/sumtree.rs +++ b/chain/src/sumtree.rs @@ -22,8 +22,9 @@ use std::sync::Arc; use util::secp::pedersen::{RangeProof, Commitment}; -use core::core::{Block, Output, SumCommit, TxKernel}; +use core::core::{Block, SumCommit, TxKernel}; use core::core::pmmr::{Backend, HashSum, NoSum, Summable, PMMR}; +use core::core::hash::Hashed; use grin_store; use grin_store::sumtree::PMMRBackend; use types::ChainStore; @@ -297,11 +298,33 @@ impl<'a> Extension<'a> { /// Rewinds the MMRs to the provided position, given the last output and /// last kernel of the block we want to rewind to. - pub fn rewind(&mut self, height: u64, output: &Output, kernel: &TxKernel) -> Result<(), Error> { - let out_pos_rew = self.commit_index.get_output_pos(&output.commitment())?; - let kern_pos_rew = self.commit_index.get_kernel_pos(&kernel.excess)?; + pub fn rewind(&mut self, block: &Block) -> Result<(), Error> { + debug!( + LOGGER, + "Rewind sumtrees to header {} at {}", + block.header.hash(), + block.header.height, + ); + + let out_pos_rew = match block.outputs.last() { + Some(output) => self.commit_index.get_output_pos(&output.commitment())?, + None => 0, + }; + + let kern_pos_rew = match block.kernels.last() { + Some(kernel) => self.commit_index.get_kernel_pos(&kernel.excess)?, + None => 0, + }; + + debug!( + LOGGER, + "Rewind sumtrees to output pos: {}, kernel pos: {}", + out_pos_rew, + kern_pos_rew, + ); + + let height = block.header.height; - debug!(LOGGER, "Rewind sumtrees to {}", out_pos_rew); self.output_pmmr .rewind(out_pos_rew, height as u32) .map_err(&Error::SumTreeErr)?; @@ -311,6 +334,7 @@ impl<'a> Extension<'a> { self.kernel_pmmr .rewind(kern_pos_rew, height as u32) .map_err(&Error::SumTreeErr)?; + self.dump(true); Ok(()) } diff --git a/grin/src/adapters.rs b/grin/src/adapters.rs index 1a2b7d100..72832d080 100644 --- a/grin/src/adapters.rs +++ b/grin/src/adapters.rs @@ -167,8 +167,8 @@ impl NetAdapter for NetToChainAdapter { debug!( LOGGER, - "locate_headers: {:?}", - header, + "locate_headers: common header: {:?}", + header.hash(), ); // looks like we know one, getting as many following headers as allowed diff --git a/grin/src/sync.rs b/grin/src/sync.rs index 58e725254..4fb19f1c2 100644 --- a/grin/src/sync.rs +++ b/grin/src/sync.rs @@ -247,10 +247,9 @@ impl Syncer { if let Some(p) = peer { debug!( LOGGER, - "Asking peer {} for more block headers starting from {} at {}.", + "Asking peer {} for more block headers, locator: {:?}", p.info.addr, - tip.last_block_h, - tip.height + locator, ); p.send_header_request(locator)?; } else { @@ -277,7 +276,7 @@ impl Syncer { /// us the right block headers. fn get_locator(&self, tip: &chain::Tip) -> Result, Error> { // Prepare the heights we want as the latests height minus increasing powers - // of 2 up to max. + // of 2 up to max. let mut heights = vec![tip.height]; let mut tail = (1..p2p::MAX_LOCATORS) .map(|n| 2u64.pow(n)) @@ -288,10 +287,15 @@ impl Syncer { }) .collect::>(); heights.append(&mut tail); + + // Include the genesis block (height 0) here as a fallback to guarantee + // both nodes share at least one common header hash in the locator + heights.push(0); + debug!(LOGGER, "Loc heights: {:?}", heights); // Iteratively travel the header chain back from our head and retain the - // headers at the wanted heights. + // headers at the wanted heights. let mut header = self.chain.get_block_header(&tip.last_block_h)?; let mut locator = vec![]; while heights.len() > 0 {