only apply full rewind to bitmap, not per block
@@ -1119,11 +1119,15 @@ impl<'a> Extension<'a> {
self.rewind_mmrs_to_pos(header.output_mmr_size, header.kernel_mmr_size, &vec![])?;
self.apply_to_bitmap_accumulator(&[header.output_mmr_size])?;
} else {
+ let mut affected_pos = vec![];
let mut current = head_header;
while header.height < current.height {
- self.rewind_single_block(&current, batch)?;
+ let mut affected_pos_single_block = self.rewind_single_block(&current, batch)?;
+ affected_pos.append(&mut affected_pos_single_block);
current = batch.get_previous_header(&current)?;
}
+ // Now apply a single aggregate "affected_pos" to our bitmap accumulator.
+ self.apply_to_bitmap_accumulator(&affected_pos)?;
}
// Update our head to reflect the header we rewound to.
@@ -1132,12 +1136,14 @@ impl<'a> Extension<'a> {
Ok(())
}
- // Rewind the MMRs, the bitmap accumulator and the output_pos index.
+ // Rewind the MMRs and the output_pos index.
+ // Returns a vec of "affected_pos" so we can apply the necessary updates to the bitmap
+ // accumulator in a single pass for all rewound blocks.
fn rewind_single_block(
&mut self,
header: &BlockHeader,
batch: &Batch<'_>,
- ) -> Result<(), Error> {
+ ) -> Result<Vec<u64>, Error> {
// The spent index allows us to conveniently "unspend" everything in a block.
let spent = batch.get_spent_index(&header.hash());
@@ -1165,7 +1171,6 @@ impl<'a> Extension<'a> {
// Treat last_pos as an affected output to ensure we rebuild far enough back.
let mut affected_pos = spent_pos.clone();
affected_pos.push(self.output_pmmr.last_pos);
- self.apply_to_bitmap_accumulator(&affected_pos)?;
// Remove any entries from the output_pos created by the block being rewound.
let block = batch.get_block(&header.hash())?;
@@ -1183,7 +1188,7 @@ impl<'a> Extension<'a> {
}
}
- Ok(())
+ Ok(affected_pos)
}
/// Rewinds the MMRs to the provided positions, given the output and
