From: Matt Corallo Date: Wed, 15 Nov 2023 16:37:50 +0000 (+0000) Subject: Add simple, partially-tested, once-a-minute probing X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=commitdiff_plain;h=f47b6f50b85ef3770173cc8e4bcddd3662cb5d5e;p=ldk-sample Add simple, partially-tested, once-a-minute probing --- diff --git a/src/main.rs b/src/main.rs index 6480805..1d6edb4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,6 +12,7 @@ use bitcoin::blockdata::transaction::Transaction; use bitcoin::consensus::encode; use bitcoin::network::constants::Network; use bitcoin::BlockHash; +use bitcoin::secp256k1::PublicKey; use bitcoin_bech32::WitnessProgram; use disk::{INBOUND_PAYMENTS_FNAME, OUTBOUND_PAYMENTS_FNAME}; use lightning::chain::{chainmonitor, ChannelMonitorUpdateStatus}; @@ -28,8 +29,9 @@ use lightning::ln::{ChannelId, PaymentHash, PaymentPreimage, PaymentSecret}; use lightning::onion_message::{DefaultMessageRouter, SimpleArcOnionMessenger}; use lightning::routing::gossip; use lightning::routing::gossip::{NodeId, P2PGossipSync}; -use lightning::routing::router::DefaultRouter; +use lightning::routing::router::{DefaultRouter, RouteParameters, PaymentParameters, ScorerAccountingForInFlightHtlcs}; use lightning::routing::scoring::ProbabilisticScoringFeeParameters; +use lightning::routing::scoring::ProbabilisticScorer; use lightning::sign::{EntropySource, InMemorySigner, KeysManager, SpendableOutputDescriptor}; use lightning::util::config::UserConfig; use lightning::util::persist::{self, KVStore, MonitorUpdatingPersister}; @@ -176,6 +178,48 @@ pub(crate) type BumpTxEventHandler = BumpTransactionEventHandler< Arc, >; +fn send_rand_probe( + channel_manager: &ChannelManager, graph: &NetworkGraph, + logger: &disk::FilesystemLogger, + scorer: &RwLock, Arc>> +) { + let rcpt = { + let lck = graph.read_only(); + if lck.nodes().is_empty() { return; } + let mut it = lck.nodes().unordered_iter().skip(::rand::random::() % lck.nodes().len()); + it.next().unwrap().0.clone() + }; + let amt = ::rand::random::() % 500_000_000; + if let Ok(pk) = bitcoin::secp256k1::PublicKey::from_slice(rcpt.as_slice()) { + send_probe(channel_manager, pk, graph, logger, amt, scorer); + } +} + +fn send_probe( + channel_manager: &ChannelManager, recipient: PublicKey, graph: &NetworkGraph, + logger: &disk::FilesystemLogger, amt_msat: u64, + scorer: &RwLock, Arc>> +) { + let chans = channel_manager.list_usable_channels(); + let chan_refs = chans.iter().map(|a| a).collect::>(); + let mut payment_params = PaymentParameters::from_node_id(recipient, 144); + payment_params.max_path_count = 1; + let in_flight_htlcs = channel_manager.compute_inflight_htlcs(); + let scorer = scorer.read().unwrap(); + let inflight_scorer = ScorerAccountingForInFlightHtlcs::new(&scorer, &in_flight_htlcs); + let score_params: ProbabilisticScoringFeeParameters = Default::default(); + let route_res = lightning::routing::router::find_route( + &channel_manager.get_our_node_id(), + &RouteParameters::from_payment_params_and_value(payment_params, amt_msat), + &graph, Some(&chan_refs), logger, &inflight_scorer, &score_params, &[32; 32] + ); + if let Ok(route) = route_res { + for path in route.paths { + let _ = channel_manager.send_probe(path); + } + } +} + async fn handle_ldk_events( channel_manager: &Arc, bitcoind_client: &BitcoindClient, network_graph: &NetworkGraph, keys_manager: &KeysManager, @@ -1015,6 +1059,19 @@ async fn start_ldk() { Arc::clone(&channel_manager), )); + // Regularly probe + let probing_cm = Arc::clone(&channel_manager); + let probing_graph = Arc::clone(&network_graph); + let probing_logger = Arc::clone(&logger); + let probing_scorer = Arc::clone(&scorer); + tokio::spawn(async move { + let mut interval = tokio::time::interval(Duration::from_secs(1)); + loop { + interval.tick().await; + send_rand_probe(&*probing_cm, &*probing_graph, &*probing_logger, &*probing_scorer); + } + }); + // Start the CLI. let cli_channel_manager = Arc::clone(&channel_manager); let cli_persister = Arc::clone(&persister);