feat(chain): Add initial_changeset to graphs

Add `initial_changeset` to TxGraph and IndexedTxGraph
This commit is contained in:
Daniela Brozzoni 2023-08-16 17:39:35 +02:00
parent ea50b6a932
commit 80f5ecf3be
No known key found for this signature in database
GPG Key ID: 7DE4F1FDCED0AB87
8 changed files with 49 additions and 9 deletions

View File

@ -59,6 +59,13 @@ impl<A: Anchor, I: Indexer> IndexedTxGraph<A, I> {
self.graph.apply_changeset(changeset.graph); self.graph.apply_changeset(changeset.graph);
} }
/// Determines the [`ChangeSet`] between `self` and an empty [`IndexedTxGraph`].
pub fn initial_changeset(&self) -> ChangeSet<A, I::ChangeSet> {
let graph = self.graph.initial_changeset();
let indexer = self.index.initial_changeset();
ChangeSet { graph, indexer }
}
} }
impl<A: Anchor, I: Indexer> IndexedTxGraph<A, I> impl<A: Anchor, I: Indexer> IndexedTxGraph<A, I>
@ -232,6 +239,9 @@ pub trait Indexer {
/// Apply changeset to itself. /// Apply changeset to itself.
fn apply_changeset(&mut self, changeset: Self::ChangeSet); fn apply_changeset(&mut self, changeset: Self::ChangeSet);
/// Determines the [`ChangeSet`] between `self` and an empty [`Indexer`].
fn initial_changeset(&self) -> Self::ChangeSet;
/// Determines whether the transaction should be included in the index. /// Determines whether the transaction should be included in the index.
fn is_tx_relevant(&self, tx: &Transaction) -> bool; fn is_tx_relevant(&self, tx: &Transaction) -> bool;
} }

View File

@ -20,6 +20,7 @@ mod txout_index;
pub use txout_index::*; pub use txout_index::*;
/// Represents updates to the derivation index of a [`KeychainTxOutIndex`]. /// Represents updates to the derivation index of a [`KeychainTxOutIndex`].
/// It maps each keychain `K` to its last revealed index.
/// ///
/// It can be applied to [`KeychainTxOutIndex`] with [`apply_changeset`]. [`ChangeSet] are /// It can be applied to [`KeychainTxOutIndex`] with [`apply_changeset`]. [`ChangeSet] are
/// monotone in that they will never decrease the revealed derivation index. /// monotone in that they will never decrease the revealed derivation index.

View File

@ -98,6 +98,10 @@ impl<K: Clone + Ord + Debug> Indexer for KeychainTxOutIndex<K> {
self.scan(tx) self.scan(tx)
} }
fn initial_changeset(&self) -> Self::ChangeSet {
super::ChangeSet(self.last_revealed.clone())
}
fn apply_changeset(&mut self, changeset: Self::ChangeSet) { fn apply_changeset(&mut self, changeset: Self::ChangeSet) {
self.apply_changeset(changeset) self.apply_changeset(changeset)
} }

View File

@ -66,6 +66,8 @@ impl<I: Clone + Ord> Indexer for SpkTxOutIndex<I> {
Default::default() Default::default()
} }
fn initial_changeset(&self) -> Self::ChangeSet {}
fn apply_changeset(&mut self, _changeset: Self::ChangeSet) { fn apply_changeset(&mut self, _changeset: Self::ChangeSet) {
// This applies nothing. // This applies nothing.
} }

View File

@ -438,6 +438,11 @@ impl<A: Clone + Ord> TxGraph<A> {
changeset changeset
} }
/// Determines the [`ChangeSet`] between `self` and an empty [`TxGraph`].
pub fn initial_changeset(&self) -> ChangeSet<A> {
Self::default().determine_changeset(self.clone())
}
/// Applies [`ChangeSet`] to [`TxGraph`]. /// Applies [`ChangeSet`] to [`TxGraph`].
pub fn apply_changeset(&mut self, changeset: ChangeSet<A>) { pub fn apply_changeset(&mut self, changeset: ChangeSet<A>) {
for tx in changeset.txs { for tx in changeset.txs {

View File

@ -65,16 +65,20 @@ fn insert_relevant_txs() {
let txs = [tx_c, tx_b, tx_a]; let txs = [tx_c, tx_b, tx_a];
let changeset = indexed_tx_graph::ChangeSet {
graph: tx_graph::ChangeSet {
txs: txs.clone().into(),
..Default::default()
},
indexer: keychain::ChangeSet([((), 9_u32)].into()),
};
assert_eq!( assert_eq!(
graph.insert_relevant_txs(txs.iter().map(|tx| (tx, None)), None), graph.insert_relevant_txs(txs.iter().map(|tx| (tx, None)), None),
indexed_tx_graph::ChangeSet { changeset,
graph: tx_graph::ChangeSet { );
txs: txs.into(),
..Default::default() assert_eq!(graph.initial_changeset(), changeset,);
},
indexer: keychain::ChangeSet([((), 9_u32)].into()),
}
)
} }
#[test] #[test]

View File

@ -43,6 +43,8 @@ fn spk_at_index(descriptor: &Descriptor<DescriptorPublicKey>, index: u32) -> Scr
#[test] #[test]
fn test_set_all_derivation_indices() { fn test_set_all_derivation_indices() {
use bdk_chain::indexed_tx_graph::Indexer;
let (mut txout_index, _, _) = init_txout_index(); let (mut txout_index, _, _) = init_txout_index();
let derive_to: BTreeMap<_, _> = let derive_to: BTreeMap<_, _> =
[(TestKeychain::External, 12), (TestKeychain::Internal, 24)].into(); [(TestKeychain::External, 12), (TestKeychain::Internal, 24)].into();
@ -56,6 +58,7 @@ fn test_set_all_derivation_indices() {
keychain::ChangeSet::default(), keychain::ChangeSet::default(),
"no changes if we set to the same thing" "no changes if we set to the same thing"
); );
assert_eq!(txout_index.initial_changeset().as_inner(), &derive_to);
} }
#[test] #[test]

View File

@ -141,7 +141,7 @@ fn insert_txouts() {
changeset, changeset,
ChangeSet { ChangeSet {
txs: [update_txs.clone()].into(), txs: [update_txs.clone()].into(),
txouts: update_ops.into(), txouts: update_ops.clone().into(),
anchors: [(conf_anchor, update_txs.txid()), (unconf_anchor, h!("tx2"))].into(), anchors: [(conf_anchor, update_txs.txid()), (unconf_anchor, h!("tx2"))].into(),
last_seen: [(h!("tx2"), 1000000)].into() last_seen: [(h!("tx2"), 1000000)].into()
} }
@ -186,6 +186,17 @@ fn insert_txouts() {
)] )]
.into() .into()
); );
// Check that the initial_changeset is correct
assert_eq!(
graph.initial_changeset(),
ChangeSet {
txs: [update_txs.clone()].into(),
txouts: update_ops.into_iter().chain(original_ops).collect(),
anchors: [(conf_anchor, update_txs.txid()), (unconf_anchor, h!("tx2"))].into(),
last_seen: [(h!("tx2"), 1000000)].into()
}
);
} }
#[test] #[test]