Skip to content

Commit b990293

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 66abc73 commit b990293

File tree

4 files changed

+99
-104
lines changed

4 files changed

+99
-104
lines changed

crates/chain/src/indexed_tx_graph.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,7 @@ impl<A, IA: Default> From<tx_graph::ChangeSet<A>> for ChangeSet<A, IA> {
320320
}
321321
}
322322

323+
#[cfg(feature = "miniscript")]
323324
impl<A, K> From<keychain::ChangeSet<K>> for ChangeSet<A, keychain::ChangeSet<K>> {
324325
fn from(indexer: keychain::ChangeSet<K>) -> Self {
325326
Self {

crates/chain/src/keychain.rs

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

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

crates/chain/src/keychain/txout_index.rs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,71 @@ use core::{
1313

1414
use crate::Append;
1515

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

1883
/// [`KeychainTxOutIndex`] controls how script pubkeys are revealed for multiple keychains, and

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

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

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

0 commit comments

Comments
 (0)