Function lightning_block_sync::init::synchronize_listeners [−][src]
pub async fn synchronize_listeners<B: BlockSource, C: Cache>(
block_source: &mut B,
network: Network,
header_cache: &mut C,
chain_listeners: Vec<(BlockHash, &mut dyn Listen)>
) -> Result<ValidatedBlockHeader, BlockSourceError>
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::ChainMonitor; use lightning::chain::channelmonitor; 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: channelmonitor::Persist<S>, >( block_source: &mut 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, &mut monitor_listener as &mut dyn chain::Listen), (manager_block_hash, &mut manager as &mut 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); }