verify_cut_through and test coverage (#3424)

* fix inconsistent verify_cut_through() logic

* add test coverage for chain::process_block() and cut_through logic

* fix comment
This commit is contained in:
Antioch Peverell
2020-08-18 20:09:54 +01:00
committed by GitHub
parent 6a012d7e5b
commit 29cffe9b3c
7 changed files with 508 additions and 22 deletions
+18 -1
View File
@@ -486,7 +486,8 @@ impl Chain {
Ok(())
}
fn new_ctx<'a>(
/// Build a new block processing context.
pub fn new_ctx<'a>(
&self,
opts: Options,
batch: store::Batch<'a>,
@@ -691,6 +692,22 @@ impl Chain {
})
}
/// Sets prev_root on a brand new block header by applying the previous header to the header MMR.
pub fn set_prev_root_only(&self, header: &mut BlockHeader) -> Result<(), Error> {
let mut header_pmmr = self.header_pmmr.write();
let prev_root =
txhashset::header_extending_readonly(&mut header_pmmr, &self.store(), |ext, batch| {
let prev_header = batch.get_previous_header(header)?;
pipe::rewind_and_apply_header_fork(&prev_header, ext, batch)?;
ext.root()
})?;
// Set the prev_root on the header.
header.prev_root = prev_root;
Ok(())
}
/// Sets the txhashset roots on a brand new block by applying the block on
/// the current txhashset state.
pub fn set_txhashset_roots(&self, b: &mut Block) -> Result<(), Error> {
+3 -1
View File
@@ -588,7 +588,9 @@ pub fn rewind_and_apply_fork(
Ok(fork_point)
}
/// Validate block inputs against utxo.
/// Validate block inputs and outputs against utxo.
/// Every input must spend an unspent output.
/// No duplicate outputs created.
fn validate_utxo(
block: &Block,
ext: &mut txhashset::ExtensionPair<'_>,
+32
View File
@@ -766,6 +766,38 @@ where
}
}
/// Start a new readonly header MMR extension.
/// This MMR can be extended individually beyond the other (output, rangeproof and kernel) MMRs
/// to allow headers to be validated before we receive the full block data.
pub fn header_extending_readonly<'a, F, T>(
handle: &'a mut PMMRHandle<BlockHeader>,
store: &ChainStore,
inner: F,
) -> Result<T, Error>
where
F: FnOnce(&mut HeaderExtension<'_>, &Batch<'_>) -> Result<T, Error>,
{
let batch = store.batch()?;
// Note: Extending either the sync_head or header_head MMR here.
// Use underlying MMR to determine the "head".
let head = match handle.head_hash() {
Ok(hash) => {
let header = batch.get_block_header(&hash)?;
Tip::from_header(&header)
}
Err(_) => Tip::default(),
};
let pmmr = PMMR::at(&mut handle.backend, handle.last_pos);
let mut extension = HeaderExtension::new(pmmr, head);
let res = inner(&mut extension, &batch);
handle.backend.discard();
res
}
/// Start a new header MMR unit of work.
/// This MMR can be extended individually beyond the other (output, rangeproof and kernel) MMRs
/// to allow headers to be validated before we receive the full block data.