|
10 | 10 | //! |
11 | 11 | //! [`SpkTxOutIndex`]: crate::SpkTxOutIndex |
12 | 12 |
|
13 | | -use crate::{collections::BTreeMap, Append}; |
14 | | - |
15 | 13 | #[cfg(feature = "miniscript")] |
16 | 14 | mod txout_index; |
17 | 15 | use bitcoin::Amount; |
18 | 16 | #[cfg(feature = "miniscript")] |
19 | 17 | pub use txout_index::*; |
20 | 18 |
|
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 | | - |
85 | 19 | /// Balance, differentiated into various categories. |
86 | 20 | #[derive(Debug, PartialEq, Eq, Clone, Default)] |
87 | 21 | #[cfg_attr( |
@@ -137,40 +71,3 @@ impl core::ops::Add for Balance { |
137 | 71 | } |
138 | 72 | } |
139 | 73 | } |
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 | | -} |
0 commit comments