mirror of
https://github.com/mimblewimble/grin.git
synced 2025-02-08 04:11:08 +03:00
Rewind force rollback (#847)
* rewind() vs rewind_readonly() * cleanup comments
This commit is contained in:
parent
eb226beea8
commit
ce2fb6ecb7
2 changed files with 29 additions and 11 deletions
|
@ -419,9 +419,7 @@ impl Chain {
|
||||||
// against the latest block header.
|
// against the latest block header.
|
||||||
// We will rewind the extension internally to the pos for
|
// We will rewind the extension internally to the pos for
|
||||||
// the block header to ensure the view is consistent.
|
// the block header to ensure the view is consistent.
|
||||||
// Force rollback first as this is a "read-only" extension.
|
|
||||||
txhashset::extending(&mut txhashset, |extension| {
|
txhashset::extending(&mut txhashset, |extension| {
|
||||||
extension.force_rollback();
|
|
||||||
extension.validate(&header, skip_rproofs)
|
extension.validate(&header, skip_rproofs)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -471,8 +469,7 @@ impl Chain {
|
||||||
let mut txhashset = self.txhashset.write().unwrap();
|
let mut txhashset = self.txhashset.write().unwrap();
|
||||||
|
|
||||||
let merkle_proof = txhashset::extending(&mut txhashset, |extension| {
|
let merkle_proof = txhashset::extending(&mut txhashset, |extension| {
|
||||||
extension.force_rollback();
|
extension.merkle_proof(output, block_header)
|
||||||
extension.merkle_proof_via_rewind(output, block_header)
|
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
Ok(merkle_proof)
|
Ok(merkle_proof)
|
||||||
|
|
|
@ -471,19 +471,21 @@ impl<'a> Extension<'a> {
|
||||||
/// Note: this relies on the MMR being stable even after pruning/compaction.
|
/// Note: this relies on the MMR being stable even after pruning/compaction.
|
||||||
/// We need the hash of each sibling pos from the pos up to the peak
|
/// We need the hash of each sibling pos from the pos up to the peak
|
||||||
/// including the sibling leaf node which may have been removed.
|
/// including the sibling leaf node which may have been removed.
|
||||||
pub fn merkle_proof_via_rewind(
|
pub fn merkle_proof(
|
||||||
&mut self,
|
&mut self,
|
||||||
output: &OutputIdentifier,
|
output: &OutputIdentifier,
|
||||||
block_header: &BlockHeader,
|
block_header: &BlockHeader,
|
||||||
) -> Result<MerkleProof, Error> {
|
) -> Result<MerkleProof, Error> {
|
||||||
debug!(
|
debug!(
|
||||||
LOGGER,
|
LOGGER,
|
||||||
"txhashset: merkle_proof_via_rewind: rewinding to block {:?}",
|
"txhashset: merkle_proof: output: {:?}, block: {:?}",
|
||||||
|
output.commit,
|
||||||
block_header.hash()
|
block_header.hash()
|
||||||
);
|
);
|
||||||
|
|
||||||
// rewind to the specified block
|
// rewind to the specified block and set the force_rollback flag (read-only)
|
||||||
self.rewind(block_header)?;
|
self.rewind_readonly(block_header)?;
|
||||||
|
|
||||||
// then calculate the Merkle Proof based on the known pos
|
// then calculate the Merkle Proof based on the known pos
|
||||||
let pos = self.get_output_pos(&output.commit)?;
|
let pos = self.get_output_pos(&output.commit)?;
|
||||||
let merkle_proof = self.output_pmmr
|
let merkle_proof = self.output_pmmr
|
||||||
|
@ -506,9 +508,25 @@ impl<'a> Extension<'a> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Rewinds the MMRs to the provided block, using the last output and
|
||||||
|
/// last kernel of the block we want to rewind to.
|
||||||
|
pub fn rewind_readonly(&mut self, block_header: &BlockHeader) -> Result<(), Error> {
|
||||||
|
// first make sure we set the rollback flag (read-only use of the extension)
|
||||||
|
self.force_rollback();
|
||||||
|
|
||||||
|
let hash = block_header.hash();
|
||||||
|
let height = block_header.height;
|
||||||
|
debug!(
|
||||||
|
LOGGER,
|
||||||
|
"Rewinding (readonly) to header {} at {}", hash, height
|
||||||
|
);
|
||||||
|
|
||||||
|
self.rewind(block_header)
|
||||||
|
}
|
||||||
|
|
||||||
/// Rewinds the MMRs to the provided positions, given the output and
|
/// Rewinds the MMRs to the provided positions, given the output and
|
||||||
/// kernel we want to rewind to.
|
/// kernel we want to rewind to.
|
||||||
pub fn rewind_pos(
|
fn rewind_pos(
|
||||||
&mut self,
|
&mut self,
|
||||||
height: u64,
|
height: u64,
|
||||||
out_pos_rew: u64,
|
out_pos_rew: u64,
|
||||||
|
@ -553,9 +571,12 @@ impl<'a> Extension<'a> {
|
||||||
/// Validate the txhashset state against the provided block header.
|
/// Validate the txhashset state against the provided block header.
|
||||||
/// Rewinds to that pos for the header first so we see a consistent
|
/// Rewinds to that pos for the header first so we see a consistent
|
||||||
/// view of the world.
|
/// view of the world.
|
||||||
|
/// Note: this is an expensive operation and sets force_rollback
|
||||||
|
/// so the extension is read-only.
|
||||||
pub fn validate(&mut self, header: &BlockHeader, skip_rproofs: bool) -> Result<(), Error> {
|
pub fn validate(&mut self, header: &BlockHeader, skip_rproofs: bool) -> Result<(), Error> {
|
||||||
// first rewind to the provided header
|
// first rewind to the provided header and
|
||||||
&self.rewind(header)?;
|
// set the force_rollback flag (read-only)
|
||||||
|
&self.rewind_readonly(header)?;
|
||||||
|
|
||||||
// validate all hashes and sums within the trees
|
// validate all hashes and sums within the trees
|
||||||
if let Err(e) = self.output_pmmr.validate() {
|
if let Err(e) = self.output_pmmr.validate() {
|
||||||
|
|
Loading…
Reference in a new issue