pub async fn synchronize_listeners<B: Deref + Sized + Send + Sync, C: Cache, L: Listen + ?Sized>(
    block_source: B,
    network: Network,
    header_cache: &mut C,
    chain_listeners: Vec<(BlockHash, &L)>
) -> BlockSourceResult<ValidatedBlockHeader>where
    B::Target: BlockSource,
Expand description

Performs a one-time sync of chain listeners using a single trusted block source, bringing each listener’s view of the chain from its paired block hash to block_source’s best chain tip.

Upon success, the returned header can be used to initialize SpvClient. In the case of failure, each listener may be left at a different block hash than the one it was originally paired with.

Useful during startup to bring the ChannelManager and each ChannelMonitor in sync before switching to SpvClient. For example:

use bitcoin::hash_types::BlockHash;
use bitcoin::network::constants::Network;

use lightning::chain;
use lightning::chain::Watch;
use lightning::chain::chainmonitor;
use lightning::chain::chainmonitor::ChainMonitor;
use lightning::chain::channelmonitor::ChannelMonitor;
use lightning::chain::chaininterface::BroadcasterInterface;
use lightning::chain::chaininterface::FeeEstimator;
use lightning::chain::keysinterface;
use lightning::chain::keysinterface::KeysInterface;
use lightning::ln::channelmanager::ChannelManager;
use lightning::ln::channelmanager::ChannelManagerReadArgs;
use lightning::util::config::UserConfig;
use lightning::util::logger::Logger;
use lightning::util::ser::ReadableArgs;

use lightning_block_sync::*;

use std::io::Cursor;

async fn init_sync<
	B: BlockSource,
	K: KeysInterface<Signer = S>,
	S: keysinterface::Sign,
	T: BroadcasterInterface,
	F: FeeEstimator,
	L: Logger,
	C: chain::Filter,
	P: chainmonitor::Persist<S>,
>(
	block_source: &B,
	chain_monitor: &ChainMonitor<S, &C, &T, &F, &L, &P>,
	config: UserConfig,
	keys_manager: &K,
	tx_broadcaster: &T,
	fee_estimator: &F,
	logger: &L,
	persister: &P,
) {
	// Read a serialized channel monitor paired with the block hash when it was persisted.
	let serialized_monitor = "...";
	let (monitor_block_hash, mut monitor) = <(BlockHash, ChannelMonitor<S>)>::read(
		&mut Cursor::new(&serialized_monitor), keys_manager).unwrap();

	// Read the channel manager paired with the block hash when it was persisted.
	let serialized_manager = "...";
	let (manager_block_hash, mut manager) = {
		let read_args = ChannelManagerReadArgs::new(
			keys_manager,
			fee_estimator,
			chain_monitor,
			tx_broadcaster,
			logger,
			config,
			vec![&mut monitor],
		);
		<(BlockHash, ChannelManager<S, &ChainMonitor<S, &C, &T, &F, &L, &P>, &T, &K, &F, &L>)>::read(
			&mut Cursor::new(&serialized_manager), read_args).unwrap()
	};

	// Synchronize any channel monitors and the channel manager to be on the best block.
	let mut cache = UnboundedCache::new();
	let mut monitor_listener = (monitor, &*tx_broadcaster, &*fee_estimator, &*logger);
	let listeners = vec![
		(monitor_block_hash, &monitor_listener as &dyn chain::Listen),
		(manager_block_hash, &manager as &dyn chain::Listen),
	];
	let chain_tip = init::synchronize_listeners(
		block_source, Network::Bitcoin, &mut cache, listeners).await.unwrap();

	// Allow the chain monitor to watch any channels.
	let monitor = monitor_listener.0;
	chain_monitor.watch_channel(monitor.get_funding_txo().0, monitor);

	// Create an SPV client to notify the chain monitor and channel manager of block events.
	let chain_poller = poll::ChainPoller::new(block_source, Network::Bitcoin);
	let mut chain_listener = (chain_monitor, &manager);
	let spv_client = SpvClient::new(chain_tip, chain_poller, &mut cache, &chain_listener);
}