Skip to content

Commit 402853a

Browse files
committed
fix(chain): merge_chains now takes account of prev_blockhashes
1 parent ca411cc commit 402853a

1 file changed

Lines changed: 16 additions & 10 deletions

File tree

crates/chain/src/local_chain.rs

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use core::ops::RangeBounds;
66

77
use crate::collections::BTreeMap;
88
use crate::{BlockId, ChainOracle, Merge};
9-
use bdk_core::ToBlockHash;
9+
use bdk_core::{CheckPointEntry, ToBlockHash};
1010
pub use bdk_core::{CheckPoint, CheckPointIter};
1111
use bitcoin::block::Header;
1212
use bitcoin::BlockHash;
@@ -598,14 +598,14 @@ where
598598
{
599599
let mut changeset = ChangeSet::<D>::default();
600600

601-
let mut orig = original_tip.iter();
602-
let mut update = update_tip.iter();
601+
let mut orig = original_tip.entry_iter();
602+
let mut update = update_tip.entry_iter();
603603

604604
let mut curr_orig = None;
605605
let mut curr_update = None;
606606

607-
let mut prev_orig: Option<CheckPoint<D>> = None;
608-
let mut prev_update: Option<CheckPoint<D>> = None;
607+
let mut prev_orig: Option<CheckPointEntry<D>> = None;
608+
let mut prev_update: Option<CheckPointEntry<D>> = None;
609609

610610
let mut point_of_agreement_found = false;
611611

@@ -634,13 +634,18 @@ where
634634
match (curr_orig.as_ref(), curr_update.as_ref()) {
635635
// Update block that doesn't exist in the original chain
636636
(o, Some(u)) if Some(u.height()) > o.map(|o| o.height()) => {
637-
changeset.blocks.insert(u.height(), Some(u.data()));
637+
// Only append to `ChangeSet` when this is an actual checkpoint.
638+
if let Some(data) = u.data() {
639+
changeset.blocks.insert(u.height(), Some(data));
640+
}
638641
prev_update = curr_update.take();
639642
}
640643
// Original block that isn't in the update
641644
(Some(o), u) if Some(o.height()) > u.map(|u| u.height()) => {
642-
// this block might be gone if an earlier block gets invalidated
643-
potentially_invalidated_heights.push(o.height());
645+
if matches!(o, CheckPointEntry::Occupied(_)) {
646+
// this block might be gone if an earlier block gets invalidated
647+
potentially_invalidated_heights.push(o.height());
648+
}
644649
prev_orig_was_invalidated = false;
645650
prev_orig = curr_orig.take();
646651

@@ -671,7 +676,8 @@ where
671676
prev_orig_was_invalidated = false;
672677
// OPTIMIZATION 2 -- if we have the same underlying pointer at this point, we
673678
// can guarantee that no older blocks are introduced.
674-
if o.eq_ptr(u) {
679+
// TODO: Ensure this is correct!
680+
if o.backing_checkpoint().eq_ptr(&u.backing_checkpoint()) {
675681
if is_update_height_superset_of_original {
676682
return Ok((update_tip, changeset));
677683
} else {
@@ -685,7 +691,7 @@ where
685691
} else {
686692
// We have an invalidation height so we set the height to the updated hash and
687693
// also purge all the original chain block hashes above this block.
688-
changeset.blocks.insert(u.height(), Some(u.data()));
694+
changeset.blocks.insert(u.height(), u.data());
689695
for invalidated_height in potentially_invalidated_heights.drain(..) {
690696
changeset.blocks.insert(invalidated_height, None);
691697
}

0 commit comments

Comments
 (0)