Skip to content

Commit 758496d

Browse files
committed
Parameterize MicroSPVClient by ChainListener
1 parent 7546fd6 commit 758496d

File tree

1 file changed

+23
-22
lines changed
  • lightning-block-sync/src

1 file changed

+23
-22
lines changed

lightning-block-sync/src/lib.rs

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -427,14 +427,14 @@ pub(crate) type HeaderCache = std::collections::HashMap<BlockHash, ValidatedBloc
427427
/// This prevents one block source from being able to orphan us on a fork of its own creation by
428428
/// not responding to requests for old headers on that fork. However, if one block source is
429429
/// unreachable this may result in our memory usage growing in accordance with the chain.
430-
pub struct MicroSPVClient<P: Poll> {
430+
pub struct MicroSPVClient<P: Poll, CL: ChainListener> {
431431
chain_tip: ValidatedBlockHeader,
432432
chain_poller: P,
433433
chain_notifier: ChainNotifier,
434+
chain_listener: CL,
434435
}
435436

436-
impl<P: Poll> MicroSPVClient<P> {
437-
437+
impl<P: Poll, CL: ChainListener> MicroSPVClient<P, CL> {
438438
/// Creates a new `MicroSPVClient` with a chain poller for polling one or more block sources and
439439
/// a chain listener for receiving updates of the new chain tip.
440440
///
@@ -447,15 +447,15 @@ impl<P: Poll> MicroSPVClient<P> {
447447
/// useful when you have a block source which is more censorship-resistant than others but
448448
/// which only provides headers. In this case, we can use such source(s) to learn of a censorship
449449
/// attack without giving up privacy by querying a privacy-losing block sources.
450-
pub fn init(chain_tip: ValidatedBlockHeader, chain_poller: P) -> Self {
450+
pub fn init(chain_tip: ValidatedBlockHeader, chain_poller: P, chain_listener: CL) -> Self {
451451
let header_cache = HeaderCache::new();
452452
let chain_notifier = ChainNotifier { header_cache };
453-
Self { chain_tip, chain_poller, chain_notifier }
453+
Self { chain_tip, chain_poller, chain_notifier, chain_listener }
454454
}
455455

456456
/// Check each source for a new best tip and update the chain listener accordingly.
457457
/// Returns true if some blocks were [dis]connected, false otherwise.
458-
pub async fn poll_best_tip<CL: ChainListener>(&mut self, chain_listener: &mut CL) ->
458+
pub async fn poll_best_tip(&mut self) ->
459459
BlockSourceResult<(ChainTip, bool)>
460460
{
461461
let chain_tip = self.chain_poller.poll_chain_tip(self.chain_tip).await?;
@@ -464,7 +464,7 @@ impl<P: Poll> MicroSPVClient<P> {
464464
ChainTip::Better(chain_tip) => {
465465
debug_assert_ne!(chain_tip.block_hash, self.chain_tip.block_hash);
466466
debug_assert!(chain_tip.chainwork > self.chain_tip.chainwork);
467-
self.update_chain_tip(chain_tip, chain_listener).await
467+
self.update_chain_tip(chain_tip).await
468468
},
469469
ChainTip::Worse(chain_tip) => {
470470
debug_assert_ne!(chain_tip.block_hash, self.chain_tip.block_hash);
@@ -477,8 +477,8 @@ impl<P: Poll> MicroSPVClient<P> {
477477

478478
/// Updates the chain tip, syncing the chain listener with any connected or disconnected
479479
/// blocks. Returns whether there were any such blocks.
480-
async fn update_chain_tip<CL: ChainListener>(&mut self, best_chain_tip: ValidatedBlockHeader, chain_listener: &mut CL) -> bool {
481-
match self.chain_notifier.sync_listener(best_chain_tip, &self.chain_tip, &mut self.chain_poller, chain_listener).await {
480+
async fn update_chain_tip(&mut self, best_chain_tip: ValidatedBlockHeader) -> bool {
481+
match self.chain_notifier.sync_listener(best_chain_tip, &self.chain_tip, &mut self.chain_poller, &mut self.chain_listener).await {
482482
Ok(_) => {
483483
self.chain_tip = best_chain_tip;
484484
true
@@ -643,13 +643,13 @@ mod tests {
643643
use bitcoin::blockdata::block::{Block, BlockHeader};
644644
use bitcoin::util::uint::Uint256;
645645
use std::collections::HashMap;
646-
use std::sync::Mutex;
646+
use std::sync::{Arc, Mutex};
647647

648648
struct TestChainListener {
649649
blocks_connected: Mutex<Vec<(BlockHash, u32)>>,
650650
blocks_disconnected: Mutex<Vec<(BlockHash, u32)>>,
651651
}
652-
impl ChainListener for TestChainListener {
652+
impl ChainListener for Arc<TestChainListener> {
653653
fn block_connected(&mut self, block: &Block, height: u32) {
654654
self.blocks_connected.lock().unwrap().push((block.header.block_hash(), height));
655655
}
@@ -882,9 +882,9 @@ mod tests {
882882
};
883883

884884
// Stand up a client at block_1a with all four sources:
885-
let mut chain_listener = TestChainListener {
885+
let chain_listener = Arc::new(TestChainListener {
886886
blocks_connected: Mutex::new(Vec::new()), blocks_disconnected: Mutex::new(Vec::new())
887-
};
887+
});
888888
let mut source_one = &chain_one;
889889
let mut source_two = &chain_two;
890890
let mut source_three = &header_chain;
@@ -894,10 +894,11 @@ mod tests {
894894
poller::ChainMultiplexer::new(
895895
vec![&mut source_one as &mut dyn BlockSource, &mut source_two as &mut dyn BlockSource, &mut source_three as &mut dyn BlockSource],
896896
vec![&mut source_four as &mut dyn BlockSource],
897-
Network::Bitcoin));
897+
Network::Bitcoin),
898+
Arc::clone(&chain_listener));
898899

899900
// Test that we will reorg onto 2b because chain_one knows about 1b + 2b
900-
match client.poll_best_tip(&mut chain_listener).await {
901+
match client.poll_best_tip().await {
901902
Ok((ChainTip::Better(chain_tip), blocks_connected)) => {
902903
assert_eq!(chain_tip.block_hash, block_2b_hash);
903904
assert!(blocks_connected);
@@ -919,7 +920,7 @@ mod tests {
919920
chain_listener.blocks_disconnected.lock().unwrap().clear();
920921

921922
// First test that nothing happens if nothing changes:
922-
match client.poll_best_tip(&mut chain_listener).await {
923+
match client.poll_best_tip().await {
923924
Ok((ChainTip::Common, blocks_connected)) => {
924925
assert!(!blocks_connected);
925926
},
@@ -933,7 +934,7 @@ mod tests {
933934
chain_two.blocks.lock().unwrap().insert(block_3a_hash, block_3a.clone());
934935
*chain_two.best_block.lock().unwrap() = (block_3a_hash, Some(3));
935936

936-
match client.poll_best_tip(&mut chain_listener).await {
937+
match client.poll_best_tip().await {
937938
Ok((ChainTip::Better(chain_tip), blocks_connected)) => {
938939
assert_eq!(chain_tip.block_hash, block_3a_hash);
939940
assert!(blocks_connected);
@@ -957,7 +958,7 @@ mod tests {
957958
// the block header cache.
958959
*chain_one.best_block.lock().unwrap() = (block_3a_hash, Some(3));
959960
*header_chain.best_block.lock().unwrap() = (block_3a_hash, Some(3));
960-
match client.poll_best_tip(&mut chain_listener).await {
961+
match client.poll_best_tip().await {
961962
Ok((ChainTip::Common, blocks_connected)) => {
962963
assert!(!blocks_connected);
963964
},
@@ -976,7 +977,7 @@ mod tests {
976977
*header_chain.best_block.lock().unwrap() = (block_4a_hash, Some(4));
977978
*backup_chain.disallowed.lock().unwrap() = false;
978979

979-
match client.poll_best_tip(&mut chain_listener).await {
980+
match client.poll_best_tip().await {
980981
Ok((ChainTip::Better(chain_tip), blocks_connected)) => {
981982
assert_eq!(chain_tip.block_hash, block_4a_hash);
982983
assert!(!blocks_connected);
@@ -991,7 +992,7 @@ mod tests {
991992
backup_chain.blocks.lock().unwrap().insert(block_4a_hash, block_4a);
992993
*backup_chain.best_block.lock().unwrap() = (block_4a_hash, Some(4));
993994

994-
match client.poll_best_tip(&mut chain_listener).await {
995+
match client.poll_best_tip().await {
995996
Ok((ChainTip::Better(chain_tip), blocks_connected)) => {
996997
assert_eq!(chain_tip.block_hash, block_4a_hash);
997998
assert!(blocks_connected);
@@ -1019,7 +1020,7 @@ mod tests {
10191020
// We'll check the backup chain last, so don't give it 4a, as otherwise we'll connect it:
10201021
*backup_chain.best_block.lock().unwrap() = (block_3a_hash, Some(3));
10211022

1022-
match client.poll_best_tip(&mut chain_listener).await {
1023+
match client.poll_best_tip().await {
10231024
Ok((ChainTip::Better(chain_tip), blocks_disconnected)) => {
10241025
assert_eq!(chain_tip.block_hash, block_5c_hash);
10251026
assert!(blocks_disconnected);
@@ -1034,7 +1035,7 @@ mod tests {
10341035
// Now reset the headers chain to 4a and test that we end up back there.
10351036
*backup_chain.best_block.lock().unwrap() = (block_4a_hash, Some(4));
10361037
*header_chain.best_block.lock().unwrap() = (block_4a_hash, Some(4));
1037-
match client.poll_best_tip(&mut chain_listener).await {
1038+
match client.poll_best_tip().await {
10381039
Ok((ChainTip::Better(chain_tip), blocks_connected)) => {
10391040
assert_eq!(chain_tip.block_hash, block_4a_hash);
10401041
assert!(blocks_connected);

0 commit comments

Comments
 (0)