Skip to content

Commit ffc82fa

Browse files
ref(chain): move keychain::ChangeSet into txout_index.rs
We plan to record `Descriptor` additions into persistence. Hence, we need to add `Descriptor`s to the changeset. This depends on `miniscript`. Moving this into `txout_index.rs` makes sense as this is consistent with all the other files. The only reason why this wasn't this way before, is because the changeset didn't need miniscript. Co-Authored-By: Daniela Brozzoni <[email protected]>
1 parent 0a7b60f commit ffc82fa

File tree

4 files changed

+97
-103
lines changed

4 files changed

+97
-103
lines changed

crates/chain/src/indexed_tx_graph.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,7 @@ impl<A, IA: Default> From<tx_graph::ChangeSet<A>> for ChangeSet<A, IA> {
316316
}
317317
}
318318

319+
#[cfg(feature = "miniscript")]
319320
impl<A, K> From<keychain::ChangeSet<K>> for ChangeSet<A, keychain::ChangeSet<K>> {
320321
fn from(indexer: keychain::ChangeSet<K>) -> Self {
321322
Self {

crates/chain/src/keychain.rs

Lines changed: 0 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -10,76 +10,11 @@
1010
//!
1111
//! [`SpkTxOutIndex`]: crate::SpkTxOutIndex
1212
13-
use crate::{collections::BTreeMap, Append};
14-
1513
#[cfg(feature = "miniscript")]
1614
mod txout_index;
1715
#[cfg(feature = "miniscript")]
1816
pub use txout_index::*;
1917

20-
/// Represents updates to the derivation index of a [`KeychainTxOutIndex`].
21-
/// It maps each keychain `K` to its last revealed index.
22-
///
23-
/// It can be applied to [`KeychainTxOutIndex`] with [`apply_changeset`]. [`ChangeSet] are
24-
/// monotone in that they will never decrease the revealed derivation index.
25-
///
26-
/// [`KeychainTxOutIndex`]: crate::keychain::KeychainTxOutIndex
27-
/// [`apply_changeset`]: crate::keychain::KeychainTxOutIndex::apply_changeset
28-
#[derive(Clone, Debug, PartialEq)]
29-
#[cfg_attr(
30-
feature = "serde",
31-
derive(serde::Deserialize, serde::Serialize),
32-
serde(
33-
crate = "serde_crate",
34-
bound(
35-
deserialize = "K: Ord + serde::Deserialize<'de>",
36-
serialize = "K: Ord + serde::Serialize"
37-
)
38-
)
39-
)]
40-
#[must_use]
41-
pub struct ChangeSet<K>(pub BTreeMap<K, u32>);
42-
43-
impl<K> ChangeSet<K> {
44-
/// Get the inner map of the keychain to its new derivation index.
45-
pub fn as_inner(&self) -> &BTreeMap<K, u32> {
46-
&self.0
47-
}
48-
}
49-
50-
impl<K: Ord> Append for ChangeSet<K> {
51-
/// Append another [`ChangeSet`] into self.
52-
///
53-
/// If the keychain already exists, increase the index when the other's index > self's index.
54-
/// If the keychain did not exist, append the new keychain.
55-
fn append(&mut self, mut other: Self) {
56-
self.0.iter_mut().for_each(|(key, index)| {
57-
if let Some(other_index) = other.0.remove(key) {
58-
*index = other_index.max(*index);
59-
}
60-
});
61-
62-
self.0.append(&mut other.0);
63-
}
64-
65-
/// Returns whether the changeset are empty.
66-
fn is_empty(&self) -> bool {
67-
self.0.is_empty()
68-
}
69-
}
70-
71-
impl<K> Default for ChangeSet<K> {
72-
fn default() -> Self {
73-
Self(Default::default())
74-
}
75-
}
76-
77-
impl<K> AsRef<BTreeMap<K, u32>> for ChangeSet<K> {
78-
fn as_ref(&self) -> &BTreeMap<K, u32> {
79-
&self.0
80-
}
81-
}
82-
8318
/// Balance, differentiated into various categories.
8419
#[derive(Debug, PartialEq, Eq, Clone, Default)]
8520
#[cfg_attr(
@@ -135,40 +70,3 @@ impl core::ops::Add for Balance {
13570
}
13671
}
13772
}
138-
139-
#[cfg(test)]
140-
mod test {
141-
use super::*;
142-
143-
#[test]
144-
fn append_keychain_derivation_indices() {
145-
#[derive(Ord, PartialOrd, Eq, PartialEq, Clone, Debug)]
146-
enum Keychain {
147-
One,
148-
Two,
149-
Three,
150-
Four,
151-
}
152-
let mut lhs_di = BTreeMap::<Keychain, u32>::default();
153-
let mut rhs_di = BTreeMap::<Keychain, u32>::default();
154-
lhs_di.insert(Keychain::One, 7);
155-
lhs_di.insert(Keychain::Two, 0);
156-
rhs_di.insert(Keychain::One, 3);
157-
rhs_di.insert(Keychain::Two, 5);
158-
lhs_di.insert(Keychain::Three, 3);
159-
rhs_di.insert(Keychain::Four, 4);
160-
161-
let mut lhs = ChangeSet(lhs_di);
162-
let rhs = ChangeSet(rhs_di);
163-
lhs.append(rhs);
164-
165-
// Exiting index doesn't update if the new index in `other` is lower than `self`.
166-
assert_eq!(lhs.0.get(&Keychain::One), Some(&7));
167-
// Existing index updates if the new index in `other` is higher than `self`.
168-
assert_eq!(lhs.0.get(&Keychain::Two), Some(&5));
169-
// Existing index is unchanged if keychain doesn't exist in `other`.
170-
assert_eq!(lhs.0.get(&Keychain::Three), Some(&3));
171-
// New keychain gets added if the keychain is in `other` but not in `self`.
172-
assert_eq!(lhs.0.get(&Keychain::Four), Some(&4));
173-
}
174-
}

crates/chain/src/keychain/txout_index.rs

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,69 @@ use core::{fmt::Debug, ops::Deref};
1111

1212
use crate::Append;
1313

14+
/// Represents updates to the derivation index of a [`KeychainTxOutIndex`].
15+
/// It maps each keychain `K` to its last revealed index.
16+
///
17+
/// It can be applied to [`KeychainTxOutIndex`] with [`apply_changeset`]. [`ChangeSet] are
18+
/// monotone in that they will never decrease the revealed derivation index.
19+
///
20+
/// [`KeychainTxOutIndex`]: crate::keychain::KeychainTxOutIndex
21+
/// [`apply_changeset`]: crate::keychain::KeychainTxOutIndex::apply_changeset
22+
#[derive(Clone, Debug, PartialEq)]
23+
#[cfg_attr(
24+
feature = "serde",
25+
derive(serde::Deserialize, serde::Serialize),
26+
serde(
27+
crate = "serde_crate",
28+
bound(
29+
deserialize = "K: Ord + serde::Deserialize<'de>",
30+
serialize = "K: Ord + serde::Serialize"
31+
)
32+
)
33+
)]
34+
#[must_use]
35+
pub struct ChangeSet<K>(pub BTreeMap<K, u32>);
36+
37+
impl<K> ChangeSet<K> {
38+
/// Get the inner map of the keychain to its new derivation index.
39+
pub fn as_inner(&self) -> &BTreeMap<K, u32> {
40+
&self.0
41+
}
42+
}
43+
44+
impl<K: Ord> Append for ChangeSet<K> {
45+
/// Append another [`ChangeSet`] into self.
46+
///
47+
/// If the keychain already exists, increase the index when the other's index > self's index.
48+
/// If the keychain did not exist, append the new keychain.
49+
fn append(&mut self, mut other: Self) {
50+
self.0.iter_mut().for_each(|(key, index)| {
51+
if let Some(other_index) = other.0.remove(key) {
52+
*index = other_index.max(*index);
53+
}
54+
});
55+
56+
self.0.append(&mut other.0);
57+
}
58+
59+
/// Returns whether the changeset are empty.
60+
fn is_empty(&self) -> bool {
61+
self.0.is_empty()
62+
}
63+
}
64+
65+
impl<K> Default for ChangeSet<K> {
66+
fn default() -> Self {
67+
Self(Default::default())
68+
}
69+
}
70+
71+
impl<K> AsRef<BTreeMap<K, u32>> for ChangeSet<K> {
72+
fn as_ref(&self) -> &BTreeMap<K, u32> {
73+
&self.0
74+
}
75+
}
76+
1477
/// A convenient wrapper around [`SpkTxOutIndex`] that relates script pubkeys to miniscript public
1578
/// [`Descriptor`]s.
1679
///

crates/chain/tests/test_keychain_txout_index.rs

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ mod common;
55
use bdk_chain::{
66
collections::BTreeMap,
77
indexed_tx_graph::Indexer,
8-
keychain::{self, KeychainTxOutIndex},
8+
keychain::{self, ChangeSet, KeychainTxOutIndex},
99
Append,
1010
};
1111

@@ -42,6 +42,38 @@ fn spk_at_index(descriptor: &Descriptor<DescriptorPublicKey>, index: u32) -> Scr
4242
.script_pubkey()
4343
}
4444

45+
#[test]
46+
fn append_keychain_derivation_indices() {
47+
#[derive(Ord, PartialOrd, Eq, PartialEq, Clone, Debug)]
48+
enum Keychain {
49+
One,
50+
Two,
51+
Three,
52+
Four,
53+
}
54+
let mut lhs_di = BTreeMap::<Keychain, u32>::default();
55+
let mut rhs_di = BTreeMap::<Keychain, u32>::default();
56+
lhs_di.insert(Keychain::One, 7);
57+
lhs_di.insert(Keychain::Two, 0);
58+
rhs_di.insert(Keychain::One, 3);
59+
rhs_di.insert(Keychain::Two, 5);
60+
lhs_di.insert(Keychain::Three, 3);
61+
rhs_di.insert(Keychain::Four, 4);
62+
63+
let mut lhs = ChangeSet(lhs_di);
64+
let rhs = ChangeSet(rhs_di);
65+
lhs.append(rhs);
66+
67+
// Exiting index doesn't update if the new index in `other` is lower than `self`.
68+
assert_eq!(lhs.0.get(&Keychain::One), Some(&7));
69+
// Existing index updates if the new index in `other` is higher than `self`.
70+
assert_eq!(lhs.0.get(&Keychain::Two), Some(&5));
71+
// Existing index is unchanged if keychain doesn't exist in `other`.
72+
assert_eq!(lhs.0.get(&Keychain::Three), Some(&3));
73+
// New keychain gets added if the keychain is in `other` but not in `self`.
74+
assert_eq!(lhs.0.get(&Keychain::Four), Some(&4));
75+
}
76+
4577
#[test]
4678
fn test_set_all_derivation_indices() {
4779
use bdk_chain::indexed_tx_graph::Indexer;

0 commit comments

Comments
 (0)