diff --git a/chain/src/chain.rs b/chain/src/chain.rs index af78f230f..6816ed55a 100644 --- a/chain/src/chain.rs +++ b/chain/src/chain.rs @@ -425,9 +425,6 @@ impl Chain { return Ok(()); } - // We want to validate the full kernel history here for completeness. - let skip_kernel_hist = false; - let mut txhashset = self.txhashset.write().unwrap(); // Now create an extension from the txhashset and validate against the @@ -435,7 +432,7 @@ impl Chain { // ensure the view is consistent. txhashset::extending_readonly(&mut txhashset, |extension| { extension.rewind(&header, &header)?; - extension.validate(&header, skip_rproofs, skip_kernel_hist, &NoStatus)?; + extension.validate(&header, skip_rproofs, &NoStatus)?; Ok(()) }) } @@ -546,17 +543,23 @@ impl Chain { let mut txhashset = txhashset::TxHashSet::open(self.db_root.clone(), self.store.clone(), Some(&header))?; - // validate against a read-only extension first (some of the validation - // runs additional rewinds) + // Validate against a read-only extension first. + // The kernel history validation requires a read-only extension + // due to the internal rewind behavior. debug!(LOGGER, "chain: txhashset_write: rewinding and validating (read-only)"); txhashset::extending_readonly(&mut txhashset, |extension| { extension.rewind(&header, &header)?; - extension.validate(&header, false, false, status)?; + extension.validate(&header, false, status)?; + + // Now validate kernel sums at each historical header height + // so we know we can trust the kernel history. + extension.validate_kernel_history(&header)?; + Ok(()) })?; // all good, prepare a new batch and update all the required records - debug!(LOGGER, "chain: txhashset_write: rewinding and validating a 2nd time (writeable)"); + debug!(LOGGER, "chain: txhashset_write: rewinding a 2nd time (writeable)"); let mut batch = self.store.batch()?; txhashset::extending(&mut txhashset, &mut batch, |extension| { extension.rewind(&header, &header)?; diff --git a/chain/src/txhashset.rs b/chain/src/txhashset.rs index 1806d89a4..d38d8316d 100644 --- a/chain/src/txhashset.rs +++ b/chain/src/txhashset.rs @@ -869,7 +869,6 @@ impl<'a> Extension<'a> { &mut self, header: &BlockHeader, skip_rproofs: bool, - skip_kernel_hist: bool, status: &T, ) -> Result<((Commitment, Commitment)), Error> where @@ -897,12 +896,6 @@ impl<'a> Extension<'a> { self.verify_rangeproofs(status)?; } - // Verify kernel roots for all past headers, need to be last as it rewinds - // a lot without resetting - if !skip_kernel_hist { - self.verify_kernel_history(header)?; - } - Ok((output_sum, kernel_sum)) } @@ -1035,7 +1028,7 @@ impl<'a> Extension<'a> { // header, rewind and check each root. This fixes a potential weakness in // fast sync where a reorg past the horizon could allow a whole rewrite of // the kernel set. - fn verify_kernel_history(&mut self, header: &BlockHeader) -> Result<(), Error> { + pub fn validate_kernel_history(&mut self, header: &BlockHeader) -> Result<(), Error> { assert!(self.rollback, "verified kernel history on writeable txhashset extension"); let mut current = header.clone();