]> Untitled Git - bdk/commitdiff
feat(chain): Add `initial_changeset` to graphs
authorDaniela Brozzoni <danielabrozzoni@protonmail.com>
Wed, 16 Aug 2023 15:39:35 +0000 (17:39 +0200)
committerDaniela Brozzoni <danielabrozzoni@protonmail.com>
Fri, 18 Aug 2023 09:52:31 +0000 (11:52 +0200)
Add `initial_changeset` to TxGraph and IndexedTxGraph

crates/chain/src/indexed_tx_graph.rs
crates/chain/src/keychain.rs
crates/chain/src/keychain/txout_index.rs
crates/chain/src/spk_txout_index.rs
crates/chain/src/tx_graph.rs
crates/chain/tests/test_indexed_tx_graph.rs
crates/chain/tests/test_keychain_txout_index.rs
crates/chain/tests/test_tx_graph.rs

index 671d82c92ded7489a363d0fcec5e241b555f8262..6dc2e9943babf2919e9ba3eaa3c1089ff374f627 100644 (file)
@@ -59,6 +59,13 @@ impl<A: Anchor, I: Indexer> IndexedTxGraph<A, I> {
 
         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>
@@ -232,6 +239,9 @@ pub trait Indexer {
     /// Apply changeset to itself.
     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.
     fn is_tx_relevant(&self, tx: &Transaction) -> bool;
 }
index 1a2adab8816267274cb0d7846b076e849ff15ba8..64d68d81e99975a4806780fd99cece3a10e6a115 100644 (file)
@@ -20,6 +20,7 @@ mod txout_index;
 pub use txout_index::*;
 
 /// 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
 /// monotone in that they will never decrease the revealed derivation index.
index 456fb4c0c249f56591ae3c8e2c9bd5f64ce1970d..9b38a7ade4eb0e89c4cdc84fe92054129e111239 100644 (file)
@@ -98,6 +98,10 @@ impl<K: Clone + Ord + Debug> Indexer for KeychainTxOutIndex<K> {
         self.scan(tx)
     }
 
+    fn initial_changeset(&self) -> Self::ChangeSet {
+        super::ChangeSet(self.last_revealed.clone())
+    }
+
     fn apply_changeset(&mut self, changeset: Self::ChangeSet) {
         self.apply_changeset(changeset)
     }
index e9e5e16a5845696d01eeb2bd768a3bed2a6bdc82..db749f44c7cfa1684326cf8597d20c97f2bb7a55 100644 (file)
@@ -66,6 +66,8 @@ impl<I: Clone + Ord> Indexer for SpkTxOutIndex<I> {
         Default::default()
     }
 
+    fn initial_changeset(&self) -> Self::ChangeSet {}
+
     fn apply_changeset(&mut self, _changeset: Self::ChangeSet) {
         // This applies nothing.
     }
index a7714dd8580493d3a964acba1546afa0b88a2cbb..5912921a920652dd8f465e1e3ef2bc9896430701 100644 (file)
@@ -438,6 +438,11 @@ impl<A: Clone + Ord> TxGraph<A> {
         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`].
     pub fn apply_changeset(&mut self, changeset: ChangeSet<A>) {
         for tx in changeset.txs {
index 85c79950adb808231c1daf33774660446d17858f..84506ec118b07f9fb7483ea29f722feb036007eb 100644 (file)
@@ -65,16 +65,20 @@ fn insert_relevant_txs() {
 
     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!(
         graph.insert_relevant_txs(txs.iter().map(|tx| (tx, None)), None),
-        indexed_tx_graph::ChangeSet {
-            graph: tx_graph::ChangeSet {
-                txs: txs.into(),
-                ..Default::default()
-            },
-            indexer: keychain::ChangeSet([((), 9_u32)].into()),
-        }
-    )
+        changeset,
+    );
+
+    assert_eq!(graph.initial_changeset(), changeset,);
 }
 
 #[test]
index 937dd6e7890cf1ba73c8c3012145d955dc11d331..96a1afd1ac1eaea654d6b85064e2aa0867c788bd 100644 (file)
@@ -43,6 +43,8 @@ fn spk_at_index(descriptor: &Descriptor<DescriptorPublicKey>, index: u32) -> Scr
 
 #[test]
 fn test_set_all_derivation_indices() {
+    use bdk_chain::indexed_tx_graph::Indexer;
+
     let (mut txout_index, _, _) = init_txout_index();
     let derive_to: BTreeMap<_, _> =
         [(TestKeychain::External, 12), (TestKeychain::Internal, 24)].into();
@@ -56,6 +58,7 @@ fn test_set_all_derivation_indices() {
         keychain::ChangeSet::default(),
         "no changes if we set to the same thing"
     );
+    assert_eq!(txout_index.initial_changeset().as_inner(), &derive_to);
 }
 
 #[test]
index e3c7d7ff47d49ed75d700ce1aefbb51cfb2506e7..26475f762997aedeb88c9962a905740651096672 100644 (file)
@@ -141,7 +141,7 @@ fn insert_txouts() {
         changeset,
         ChangeSet {
             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(),
             last_seen: [(h!("tx2"), 1000000)].into()
         }
@@ -186,6 +186,17 @@ fn insert_txouts() {
         )]
         .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]