fix(chain): KeychainTxOutIndex::lookahead_to_target
This commit is contained in:
parent
50c549b5ac
commit
c151d8fd23
@ -326,12 +326,17 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
|
|||||||
self.lookahead
|
self.lookahead
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Store lookahead scripts until `target_index`.
|
/// Store lookahead scripts until `target_index` (inclusive).
|
||||||
///
|
///
|
||||||
/// This does not change the `lookahead` setting.
|
/// This does not change the global `lookahead` setting.
|
||||||
pub fn lookahead_to_target(&mut self, keychain: &K, target_index: u32) {
|
pub fn lookahead_to_target(&mut self, keychain: &K, target_index: u32) {
|
||||||
let next_index = self.next_store_index(keychain);
|
let (next_index, _) = self.next_index(keychain);
|
||||||
if let Some(temp_lookahead) = target_index.checked_sub(next_index).filter(|&v| v > 0) {
|
|
||||||
|
let temp_lookahead = (target_index + 1)
|
||||||
|
.checked_sub(next_index)
|
||||||
|
.filter(|&index| index > 0);
|
||||||
|
|
||||||
|
if let Some(temp_lookahead) = temp_lookahead {
|
||||||
self.replenish_lookahead(keychain, temp_lookahead);
|
self.replenish_lookahead(keychain, temp_lookahead);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -386,3 +386,98 @@ fn test_non_wildcard_derivations() {
|
|||||||
1,
|
1,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Check that calling `lookahead_to_target` stores the expected spks.
|
||||||
|
#[test]
|
||||||
|
fn lookahead_to_target() {
|
||||||
|
#[derive(Default)]
|
||||||
|
struct TestCase {
|
||||||
|
lookahead: u32, // Global lookahead value
|
||||||
|
external_last_revealed: Option<u32>, // Last revealed index for external keychain
|
||||||
|
internal_last_revealed: Option<u32>, // Last revealed index for internal keychain
|
||||||
|
external_target: Option<u32>, // Call `lookahead_to_target(External, u32)`
|
||||||
|
internal_target: Option<u32>, // Call `lookahead_to_target(Internal, u32)`
|
||||||
|
}
|
||||||
|
|
||||||
|
let test_cases = &[
|
||||||
|
TestCase {
|
||||||
|
lookahead: 0,
|
||||||
|
external_target: Some(100),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
TestCase {
|
||||||
|
lookahead: 10,
|
||||||
|
internal_target: Some(99),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
TestCase {
|
||||||
|
lookahead: 100,
|
||||||
|
internal_target: Some(9),
|
||||||
|
external_target: Some(10),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
TestCase {
|
||||||
|
lookahead: 12,
|
||||||
|
external_last_revealed: Some(2),
|
||||||
|
internal_last_revealed: Some(2),
|
||||||
|
internal_target: Some(15),
|
||||||
|
external_target: Some(13),
|
||||||
|
},
|
||||||
|
TestCase {
|
||||||
|
lookahead: 13,
|
||||||
|
external_last_revealed: Some(100),
|
||||||
|
internal_last_revealed: Some(21),
|
||||||
|
internal_target: Some(120),
|
||||||
|
external_target: Some(130),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
for t in test_cases {
|
||||||
|
let (mut index, _, _) = init_txout_index(t.lookahead);
|
||||||
|
|
||||||
|
if let Some(last_revealed) = t.external_last_revealed {
|
||||||
|
let _ = index.reveal_to_target(&TestKeychain::External, last_revealed);
|
||||||
|
}
|
||||||
|
if let Some(last_revealed) = t.internal_last_revealed {
|
||||||
|
let _ = index.reveal_to_target(&TestKeychain::Internal, last_revealed);
|
||||||
|
}
|
||||||
|
|
||||||
|
let keychain_test_cases = [
|
||||||
|
(
|
||||||
|
TestKeychain::External,
|
||||||
|
t.external_last_revealed,
|
||||||
|
t.external_target,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
TestKeychain::Internal,
|
||||||
|
t.internal_last_revealed,
|
||||||
|
t.internal_target,
|
||||||
|
),
|
||||||
|
];
|
||||||
|
for (keychain, last_revealed, target) in keychain_test_cases {
|
||||||
|
if let Some(target) = target {
|
||||||
|
let original_last_stored_index = match last_revealed {
|
||||||
|
Some(last_revealed) => Some(last_revealed + t.lookahead),
|
||||||
|
None => t.lookahead.checked_sub(1),
|
||||||
|
};
|
||||||
|
let exp_last_stored_index = match original_last_stored_index {
|
||||||
|
Some(original_last_stored_index) => {
|
||||||
|
Ord::max(target, original_last_stored_index)
|
||||||
|
}
|
||||||
|
None => target,
|
||||||
|
};
|
||||||
|
index.lookahead_to_target(&keychain, target);
|
||||||
|
let keys = index
|
||||||
|
.inner()
|
||||||
|
.all_spks()
|
||||||
|
.range((keychain.clone(), 0)..=(keychain.clone(), u32::MAX))
|
||||||
|
.map(|(k, _)| k.clone())
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
let exp_keys = core::iter::repeat(keychain)
|
||||||
|
.zip(0_u32..=exp_last_stored_index)
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
assert_eq!(keys, exp_keys);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user