Function lightning_block_sync::init::synchronize_listeners
source · [−]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);
}