Skip to content

Commit 0c2522a

Browse files
authored
Merge pull request #78 from MaxFangX/fix-chanman-race-panic
Fix channel manager race panic
2 parents e747233 + 430084f commit 0c2522a

File tree

1 file changed

+38
-41
lines changed

1 file changed

+38
-41
lines changed

src/main.rs

Lines changed: 38 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use lightning::chain;
1717
use lightning::chain::chaininterface::{BroadcasterInterface, ConfirmationTarget, FeeEstimator};
1818
use lightning::chain::keysinterface::{InMemorySigner, KeysInterface, KeysManager, Recipient};
1919
use lightning::chain::{chainmonitor, ChannelMonitorUpdateStatus};
20-
use lightning::chain::{BestBlock, Filter, Watch};
20+
use lightning::chain::{Filter, Watch};
2121
use lightning::ln::channelmanager;
2222
use lightning::ln::channelmanager::{
2323
ChainParameters, ChannelManagerReadArgs, SimpleArcChannelManager,
@@ -458,7 +458,12 @@ async fn start_ldk() {
458458
// Step 7: Read ChannelMonitor state from disk
459459
let mut channelmonitors = persister.read_channelmonitors(keys_manager.clone()).unwrap();
460460

461-
// Step 8: Initialize the ChannelManager
461+
// Step 8: Poll for the best chain tip, which may be used by the channel manager & spv client
462+
let polled_chain_tip = init::validate_best_block_header(bitcoind_client.as_ref())
463+
.await
464+
.expect("Failed to fetch best block header and best block");
465+
466+
// Step 9: Initialize the ChannelManager
462467
let mut user_config = UserConfig::default();
463468
user_config.channel_handshake_limits.force_announced_channel_preference = false;
464469
let mut restarting_node = true;
@@ -481,15 +486,11 @@ async fn start_ldk() {
481486
} else {
482487
// We're starting a fresh node.
483488
restarting_node = false;
484-
let getinfo_resp = bitcoind_client.get_blockchain_info().await;
485-
486-
let chain_params = ChainParameters {
487-
network: args.network,
488-
best_block: BestBlock::new(
489-
getinfo_resp.latest_blockhash,
490-
getinfo_resp.latest_height as u32,
491-
),
492-
};
489+
490+
let polled_best_block = polled_chain_tip.to_best_block();
491+
let polled_best_block_hash = polled_best_block.block_hash();
492+
let chain_params =
493+
ChainParameters { network: args.network, best_block: polled_best_block };
493494
let fresh_channel_manager = channelmanager::ChannelManager::new(
494495
fee_estimator.clone(),
495496
chain_monitor.clone(),
@@ -499,15 +500,14 @@ async fn start_ldk() {
499500
user_config,
500501
chain_params,
501502
);
502-
(getinfo_resp.latest_blockhash, fresh_channel_manager)
503+
(polled_best_block_hash, fresh_channel_manager)
503504
}
504505
};
505506

506-
// Step 9: Sync ChannelMonitors and ChannelManager to chain tip
507+
// Step 10: Sync ChannelMonitors and ChannelManager to chain tip
507508
let mut chain_listener_channel_monitors = Vec::new();
508509
let mut cache = UnboundedCache::new();
509-
let mut chain_tip: Option<poll::ValidatedBlockHeader> = None;
510-
if restarting_node {
510+
let chain_tip = if restarting_node {
511511
let mut chain_listeners = vec![(
512512
channel_manager_blockhash,
513513
&channel_manager as &(dyn chain::Listen + Send + Sync),
@@ -528,19 +528,20 @@ async fn start_ldk() {
528528
&monitor_listener_info.1 as &(dyn chain::Listen + Send + Sync),
529529
));
530530
}
531-
chain_tip = Some(
532-
init::synchronize_listeners(
533-
bitcoind_client.as_ref(),
534-
args.network,
535-
&mut cache,
536-
chain_listeners,
537-
)
538-
.await
539-
.unwrap(),
540-
);
541-
}
542531

543-
// Step 10: Give ChannelMonitors to ChainMonitor
532+
init::synchronize_listeners(
533+
bitcoind_client.as_ref(),
534+
args.network,
535+
&mut cache,
536+
chain_listeners,
537+
)
538+
.await
539+
.unwrap()
540+
} else {
541+
polled_chain_tip
542+
};
543+
544+
// Step 11: Give ChannelMonitors to ChainMonitor
544545
for item in chain_listener_channel_monitors.drain(..) {
545546
let channel_monitor = item.1 .0;
546547
let funding_outpoint = item.2;
@@ -550,7 +551,7 @@ async fn start_ldk() {
550551
);
551552
}
552553

553-
// Step 11: Optional: Initialize the P2PGossipSync
554+
// Step 12: Optional: Initialize the P2PGossipSync
554555
let genesis = genesis_block(args.network).header.block_hash();
555556
let network_graph_path = format!("{}/network_graph", ldk_data_dir.clone());
556557
let network_graph =
@@ -561,7 +562,7 @@ async fn start_ldk() {
561562
logger.clone(),
562563
));
563564

564-
// Step 12: Initialize the PeerManager
565+
// Step 13: Initialize the PeerManager
565566
let channel_manager: Arc<ChannelManager> = Arc::new(channel_manager);
566567
let onion_messenger: Arc<OnionMessenger> = Arc::new(OnionMessenger::new(
567568
Arc::clone(&keys_manager),
@@ -586,7 +587,7 @@ async fn start_ldk() {
586587
));
587588

588589
// ## Running LDK
589-
// Step 13: Initialize networking
590+
// Step 14: Initialize networking
590591

591592
let peer_manager_connection_handler = peer_manager.clone();
592593
let listening_port = args.ldk_peer_listening_port;
@@ -612,26 +613,22 @@ async fn start_ldk() {
612613
}
613614
});
614615

615-
// Step 14: Connect and Disconnect Blocks
616-
if chain_tip.is_none() {
617-
chain_tip = Some(init::validate_best_block_header(bitcoind_client.as_ref()).await.unwrap());
618-
}
616+
// Step 15: Connect and Disconnect Blocks
619617
let channel_manager_listener = channel_manager.clone();
620618
let chain_monitor_listener = chain_monitor.clone();
621619
let bitcoind_block_source = bitcoind_client.clone();
622620
let network = args.network;
623621
tokio::spawn(async move {
624622
let chain_poller = poll::ChainPoller::new(bitcoind_block_source.as_ref(), network);
625623
let chain_listener = (chain_monitor_listener, channel_manager_listener);
626-
let mut spv_client =
627-
SpvClient::new(chain_tip.unwrap(), chain_poller, &mut cache, &chain_listener);
624+
let mut spv_client = SpvClient::new(chain_tip, chain_poller, &mut cache, &chain_listener);
628625
loop {
629626
spv_client.poll_best_tip().await.unwrap();
630627
tokio::time::sleep(Duration::from_secs(1)).await;
631628
}
632629
});
633630

634-
// Step 15: Handle LDK Events
631+
// Step 16: Handle LDK Events
635632
let channel_manager_event_listener = channel_manager.clone();
636633
let keys_manager_listener = keys_manager.clone();
637634
// TODO: persist payment info to disk
@@ -656,15 +653,15 @@ async fn start_ldk() {
656653
));
657654
};
658655

659-
// Step 16: Initialize routing ProbabilisticScorer
656+
// Step 17: Initialize routing ProbabilisticScorer
660657
let scorer_path = format!("{}/scorer", ldk_data_dir.clone());
661658
let scorer = Arc::new(Mutex::new(disk::read_scorer(
662659
Path::new(&scorer_path),
663660
Arc::clone(&network_graph),
664661
Arc::clone(&logger),
665662
)));
666663

667-
// Step 17: Create InvoicePayer
664+
// Step 18: Create InvoicePayer
668665
let router = DefaultRouter::new(
669666
network_graph.clone(),
670667
logger.clone(),
@@ -679,10 +676,10 @@ async fn start_ldk() {
679676
payment::Retry::Timeout(Duration::from_secs(10)),
680677
));
681678

682-
// Step 18: Persist ChannelManager and NetworkGraph
679+
// Step 19: Persist ChannelManager and NetworkGraph
683680
let persister = Arc::new(FilesystemPersister::new(ldk_data_dir.clone()));
684681

685-
// Step 19: Background Processing
682+
// Step 20: Background Processing
686683
let background_processor = BackgroundProcessor::start(
687684
persister,
688685
invoice_payer.clone(),

0 commit comments

Comments
 (0)