Add a random per-path CLTV offset for privacy.

This commit is contained in:
Elias Rohrer 2022-03-09 11:13:47 -06:00
parent 1a734492d9
commit e92b5a7ebd
13 changed files with 460 additions and 136 deletions

View file

@ -459,7 +459,8 @@ pub fn do_test(data: &[u8], logger: &Arc<dyn Logger>) {
final_value_msat,
final_cltv_expiry_delta: 42,
};
let route = match find_route(&our_id, &params, &network_graph, None, Arc::clone(&logger), &scorer) {
let random_seed_bytes: [u8; 32] = keys_manager.get_secure_random_bytes();
let route = match find_route(&our_id, &params, &network_graph, None, Arc::clone(&logger), &scorer, &random_seed_bytes) {
Ok(route) => route,
Err(_) => return,
};
@ -482,7 +483,8 @@ pub fn do_test(data: &[u8], logger: &Arc<dyn Logger>) {
final_value_msat,
final_cltv_expiry_delta: 42,
};
let mut route = match find_route(&our_id, &params, &network_graph, None, Arc::clone(&logger), &scorer) {
let random_seed_bytes: [u8; 32] = keys_manager.get_secure_random_bytes();
let mut route = match find_route(&our_id, &params, &network_graph, None, Arc::clone(&logger), &scorer, &random_seed_bytes) {
Ok(route) => route,
Err(_) => return,
};

View file

@ -250,6 +250,7 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
}
}
let scorer = FixedPenaltyScorer::with_penalty(0);
let random_seed_bytes: [u8; 32] = [get_slice!(1)[0]; 32];
for target in node_pks.iter() {
let route_params = RouteParameters {
payment_params: PaymentParameters::from_node_id(*target).with_route_hints(last_hops.clone()),
@ -258,7 +259,7 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
};
let _ = find_route(&our_pubkey, &route_params, &net_graph,
first_hops.map(|c| c.iter().collect::<Vec<_>>()).as_ref().map(|a| a.as_slice()),
Arc::clone(&logger), &scorer);
Arc::clone(&logger), &scorer, &random_seed_bytes);
}
},
}

View file

@ -669,13 +669,15 @@ mod tests {
#[test]
fn test_invoice_payer() {
let keys_manager = test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
let random_seed_bytes = keys_manager.get_secure_random_bytes();
let nodes = create_nodes(2, "test_invoice_payer".to_string());
// Initiate the background processors to watch each node.
let data_dir = nodes[0].persister.get_data_dir();
let persister = move |node: &ChannelManager<InMemorySigner, Arc<ChainMonitor>, Arc<test_utils::TestBroadcaster>, Arc<KeysManager>, Arc<test_utils::TestFeeEstimator>, Arc<test_utils::TestLogger>>| FilesystemPersister::persist_manager(data_dir.clone(), node);
let router = DefaultRouter::new(Arc::clone(&nodes[0].network_graph), Arc::clone(&nodes[0].logger));
let scorer = Arc::new(Mutex::new(test_utils::TestScorer::with_penalty(0)));
let router = DefaultRouter::new(Arc::clone(&nodes[0].network_graph), Arc::clone(&nodes[0].logger), random_seed_bytes);
let invoice_payer = Arc::new(InvoicePayer::new(Arc::clone(&nodes[0].node), router, scorer, Arc::clone(&nodes[0].logger), |_: &_| {}, RetryAttempts(2)));
let event_handler = Arc::clone(&invoice_payer);
let bg_processor = BackgroundProcessor::start(persister, event_handler, nodes[0].chain_monitor.clone(), nodes[0].node.clone(), nodes[0].net_graph_msg_handler.clone(), nodes[0].peer_manager.clone(), nodes[0].logger.clone());

View file

@ -4,7 +4,7 @@ use {CreationError, Currency, DEFAULT_EXPIRY_TIME, Invoice, InvoiceBuilder, Sign
use payment::{Payer, Router};
use bech32::ToBase32;
use bitcoin_hashes::Hash;
use bitcoin_hashes::{Hash, sha256};
use crate::prelude::*;
use lightning::chain;
use lightning::chain::chaininterface::{BroadcasterInterface, FeeEstimator};
@ -22,6 +22,7 @@ use secp256k1::key::PublicKey;
use core::convert::TryInto;
use core::ops::Deref;
use core::time::Duration;
use sync::Mutex;
#[cfg(feature = "std")]
/// Utility to create an invoice that can be paid to one of multiple nodes, or a "phantom invoice."
@ -224,12 +225,15 @@ where
pub struct DefaultRouter<G: Deref<Target = NetworkGraph>, L: Deref> where L::Target: Logger {
network_graph: G,
logger: L,
random_seed_bytes: Mutex<[u8; 32]>,
}
impl<G: Deref<Target = NetworkGraph>, L: Deref> DefaultRouter<G, L> where L::Target: Logger {
/// Creates a new router using the given [`NetworkGraph`] and [`Logger`].
pub fn new(network_graph: G, logger: L) -> Self {
Self { network_graph, logger }
/// Creates a new router using the given [`NetworkGraph`], a [`Logger`], and a randomness source
/// `random_seed_bytes`.
pub fn new(network_graph: G, logger: L, random_seed_bytes: [u8; 32]) -> Self {
let random_seed_bytes = Mutex::new(random_seed_bytes);
Self { network_graph, logger, random_seed_bytes }
}
}
@ -239,7 +243,12 @@ where L::Target: Logger {
&self, payer: &PublicKey, params: &RouteParameters, _payment_hash: &PaymentHash,
first_hops: Option<&[&ChannelDetails]>, scorer: &S
) -> Result<Route, LightningError> {
find_route(payer, params, &*self.network_graph, first_hops, &*self.logger, scorer)
let random_seed_bytes = {
let mut locked_random_seed_bytes = self.random_seed_bytes.lock().unwrap();
*locked_random_seed_bytes = sha256::Hash::hash(&*locked_random_seed_bytes).into_inner();
*locked_random_seed_bytes
};
find_route(payer, params, &*self.network_graph, first_hops, &*self.logger, scorer, &random_seed_bytes)
}
}
@ -299,6 +308,7 @@ mod test {
use lightning::util::enforcing_trait_impls::EnforcingSigner;
use lightning::util::events::{MessageSendEvent, MessageSendEventsProvider, Event};
use lightning::util::test_utils;
use lightning::chain::keysinterface::KeysInterface;
use utils::create_invoice_from_channelmanager_and_duration_since_epoch;
#[test]
@ -327,9 +337,10 @@ mod test {
let network_graph = node_cfgs[0].network_graph;
let logger = test_utils::TestLogger::new();
let scorer = test_utils::TestScorer::with_penalty(0);
let random_seed_bytes = chanmon_cfgs[1].keys_manager.get_secure_random_bytes();
let route = find_route(
&nodes[0].node.get_our_node_id(), &route_params, network_graph,
Some(&first_hops.iter().collect::<Vec<_>>()), &logger, &scorer,
Some(&first_hops.iter().collect::<Vec<_>>()), &logger, &scorer, &random_seed_bytes
).unwrap();
let payment_event = {
@ -415,9 +426,10 @@ mod test {
let network_graph = node_cfgs[0].network_graph;
let logger = test_utils::TestLogger::new();
let scorer = test_utils::TestScorer::with_penalty(0);
let random_seed_bytes = chanmon_cfgs[1].keys_manager.get_secure_random_bytes();
let route = find_route(
&nodes[0].node.get_our_node_id(), &params, network_graph,
Some(&first_hops.iter().collect::<Vec<_>>()), &logger, &scorer,
Some(&first_hops.iter().collect::<Vec<_>>()), &logger, &scorer, &random_seed_bytes
).unwrap();
let (payment_event, fwd_idx) = {
let mut payment_hash = PaymentHash([0; 32]);

View file

@ -6844,6 +6844,7 @@ mod tests {
use util::errors::APIError;
use util::events::{Event, MessageSendEvent, MessageSendEventsProvider};
use util::test_utils;
use chain::keysinterface::KeysInterface;
#[cfg(feature = "std")]
#[test]
@ -7097,6 +7098,7 @@ mod tests {
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known());
let scorer = test_utils::TestScorer::with_penalty(0);
let random_seed_bytes = chanmon_cfgs[1].keys_manager.get_secure_random_bytes();
// To start (1), send a regular payment but don't claim it.
let expected_route = [&nodes[1]];
@ -7110,7 +7112,7 @@ mod tests {
};
let route = find_route(
&nodes[0].node.get_our_node_id(), &route_params, nodes[0].network_graph, None,
nodes[0].logger, &scorer
nodes[0].logger, &scorer, &random_seed_bytes
).unwrap();
nodes[0].node.send_spontaneous_payment(&route, Some(payment_preimage)).unwrap();
check_added_monitors!(nodes[0], 1);
@ -7141,7 +7143,7 @@ mod tests {
let payment_preimage = PaymentPreimage([42; 32]);
let route = find_route(
&nodes[0].node.get_our_node_id(), &route_params, nodes[0].network_graph, None,
nodes[0].logger, &scorer
nodes[0].logger, &scorer, &random_seed_bytes
).unwrap();
let (payment_hash, _) = nodes[0].node.send_spontaneous_payment(&route, Some(payment_preimage)).unwrap();
check_added_monitors!(nodes[0], 1);
@ -7202,9 +7204,10 @@ mod tests {
let network_graph = nodes[0].network_graph;
let first_hops = nodes[0].node.list_usable_channels();
let scorer = test_utils::TestScorer::with_penalty(0);
let random_seed_bytes = chanmon_cfgs[1].keys_manager.get_secure_random_bytes();
let route = find_route(
&payer_pubkey, &route_params, network_graph, Some(&first_hops.iter().collect::<Vec<_>>()),
nodes[0].logger, &scorer
nodes[0].logger, &scorer, &random_seed_bytes
).unwrap();
let test_preimage = PaymentPreimage([42; 32]);
@ -7245,9 +7248,10 @@ mod tests {
let network_graph = nodes[0].network_graph;
let first_hops = nodes[0].node.list_usable_channels();
let scorer = test_utils::TestScorer::with_penalty(0);
let random_seed_bytes = chanmon_cfgs[1].keys_manager.get_secure_random_bytes();
let route = find_route(
&payer_pubkey, &route_params, network_graph, Some(&first_hops.iter().collect::<Vec<_>>()),
nodes[0].logger, &scorer
nodes[0].logger, &scorer, &random_seed_bytes
).unwrap();
let test_preimage = PaymentPreimage([42; 32]);
@ -7331,7 +7335,7 @@ mod tests {
pub mod bench {
use chain::Listen;
use chain::chainmonitor::{ChainMonitor, Persist};
use chain::keysinterface::{KeysManager, InMemorySigner};
use chain::keysinterface::{KeysManager, KeysInterface, InMemorySigner};
use ln::channelmanager::{BestBlock, ChainParameters, ChannelManager, PaymentHash, PaymentPreimage};
use ln::features::{InitFeatures, InvoiceFeatures};
use ln::functional_test_utils::*;
@ -7340,7 +7344,7 @@ pub mod bench {
use routing::router::{PaymentParameters, get_route};
use util::test_utils;
use util::config::UserConfig;
use util::events::{Event, MessageSendEvent, MessageSendEventsProvider, PaymentPurpose};
use util::events::{Event, MessageSendEvent, MessageSendEventsProvider};
use bitcoin::hashes::Hash;
use bitcoin::hashes::sha256::Hash as Sha256;
@ -7448,8 +7452,11 @@ pub mod bench {
let payment_params = PaymentParameters::from_node_id($node_b.get_our_node_id())
.with_features(InvoiceFeatures::known());
let scorer = test_utils::TestScorer::with_penalty(0);
let route = get_route(&$node_a.get_our_node_id(), &payment_params, &dummy_graph,
Some(&usable_channels.iter().map(|r| r).collect::<Vec<_>>()), 10_000, TEST_FINAL_CLTV, &logger_a, &scorer).unwrap();
let seed = [3u8; 32];
let keys_manager = KeysManager::new(&seed, 42, 42);
let random_seed_bytes = keys_manager.get_secure_random_bytes();
let route = get_route(&$node_a.get_our_node_id(), &payment_params, &dummy_graph.read_only(),
Some(&usable_channels.iter().map(|r| r).collect::<Vec<_>>()), 10_000, TEST_FINAL_CLTV, &logger_a, &scorer, &random_seed_bytes).unwrap();
let mut payment_preimage = PaymentPreimage([0; 32]);
payment_preimage.0[0..8].copy_from_slice(&payment_count.to_le_bytes());

View file

@ -10,7 +10,7 @@
//! A bunch of useful utilities for building networks of nodes and exchanging messages between
//! nodes for functional tests.
use chain::{BestBlock, Confirm, Listen, Watch};
use chain::{BestBlock, Confirm, Listen, Watch, keysinterface::KeysInterface};
use chain::channelmonitor::ChannelMonitor;
use chain::transaction::OutPoint;
use ln::{PaymentPreimage, PaymentHash, PaymentSecret};
@ -1094,15 +1094,18 @@ macro_rules! get_route_and_payment_hash {
$crate::get_route_and_payment_hash!($send_node, $recv_node, vec![], $recv_value, TEST_FINAL_CLTV)
}};
($send_node: expr, $recv_node: expr, $last_hops: expr, $recv_value: expr, $cltv: expr) => {{
use $crate::chain::keysinterface::KeysInterface;
let (payment_preimage, payment_hash, payment_secret) = $crate::get_payment_preimage_hash!($recv_node, Some($recv_value));
let payment_params = $crate::routing::router::PaymentParameters::from_node_id($recv_node.node.get_our_node_id())
.with_features($crate::ln::features::InvoiceFeatures::known())
.with_route_hints($last_hops);
let scorer = $crate::util::test_utils::TestScorer::with_penalty(0);
let keys_manager = $crate::util::test_utils::TestKeysInterface::new(&[0u8; 32], bitcoin::network::constants::Network::Testnet);
let random_seed_bytes = keys_manager.get_secure_random_bytes();
let route = $crate::routing::router::get_route(
&$send_node.node.get_our_node_id(), &payment_params, $send_node.network_graph,
&$send_node.node.get_our_node_id(), &payment_params, &$send_node.network_graph.read_only(),
Some(&$send_node.node.list_usable_channels().iter().collect::<Vec<_>>()),
$recv_value, $cltv, $send_node.logger, &scorer
$recv_value, $cltv, $send_node.logger, &scorer, &random_seed_bytes
).unwrap();
(route, payment_hash, payment_preimage, payment_secret)
}}
@ -1557,11 +1560,15 @@ pub const TEST_FINAL_CLTV: u32 = 70;
pub fn route_payment<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_route: &[&Node<'a, 'b, 'c>], recv_value: u64) -> (PaymentPreimage, PaymentHash, PaymentSecret) {
let payment_params = PaymentParameters::from_node_id(expected_route.last().unwrap().node.get_our_node_id())
.with_features(InvoiceFeatures::known());
let network_graph = origin_node.network_graph.read_only();
let scorer = test_utils::TestScorer::with_penalty(0);
let seed = [0u8; 32];
let keys_manager = test_utils::TestKeysInterface::new(&seed, Network::Testnet);
let random_seed_bytes = keys_manager.get_secure_random_bytes();
let route = get_route(
&origin_node.node.get_our_node_id(), &payment_params, &origin_node.network_graph,
&origin_node.node.get_our_node_id(), &payment_params, &network_graph,
Some(&origin_node.node.list_usable_channels().iter().collect::<Vec<_>>()),
recv_value, TEST_FINAL_CLTV, origin_node.logger, &scorer).unwrap();
recv_value, TEST_FINAL_CLTV, origin_node.logger, &scorer, &random_seed_bytes).unwrap();
assert_eq!(route.paths.len(), 1);
assert_eq!(route.paths[0].len(), expected_route.len());
for (node, hop) in expected_route.iter().zip(route.paths[0].iter()) {
@ -1575,10 +1582,14 @@ pub fn route_payment<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_route:
pub fn route_over_limit<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_route: &[&Node<'a, 'b, 'c>], recv_value: u64) {
let payment_params = PaymentParameters::from_node_id(expected_route.last().unwrap().node.get_our_node_id())
.with_features(InvoiceFeatures::known());
let network_graph = origin_node.network_graph.read_only();
let scorer = test_utils::TestScorer::with_penalty(0);
let seed = [0u8; 32];
let keys_manager = test_utils::TestKeysInterface::new(&seed, Network::Testnet);
let random_seed_bytes = keys_manager.get_secure_random_bytes();
let route = get_route(
&origin_node.node.get_our_node_id(), &payment_params, origin_node.network_graph,
None, recv_value, TEST_FINAL_CLTV, origin_node.logger, &scorer).unwrap();
&origin_node.node.get_our_node_id(), &payment_params, &network_graph,
None, recv_value, TEST_FINAL_CLTV, origin_node.logger, &scorer, &random_seed_bytes).unwrap();
assert_eq!(route.paths.len(), 1);
assert_eq!(route.paths[0].len(), expected_route.len());
for (node, hop) in expected_route.iter().zip(route.paths[0].iter()) {

View file

@ -16,7 +16,7 @@ use chain::{Confirm, Listen, Watch};
use chain::channelmonitor;
use chain::channelmonitor::{ChannelMonitor, CLTV_CLAIM_BUFFER, LATENCY_GRACE_PERIOD_BLOCKS, ANTI_REORG_DELAY};
use chain::transaction::OutPoint;
use chain::keysinterface::BaseSign;
use chain::keysinterface::{BaseSign, KeysInterface};
use ln::{PaymentPreimage, PaymentSecret, PaymentHash};
use ln::channel::{commitment_tx_base_weight, COMMITMENT_TX_WEIGHT_PER_HTLC, CONCURRENT_INBOUND_HTLC_FEE_BUFFER, FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE, MIN_AFFORDABLE_HTLC_COUNT};
use ln::channelmanager::{ChannelManager, ChannelManagerReadArgs, PaymentId, RAACommitmentOrder, PaymentSendFailure, BREAKDOWN_TIMEOUT, MIN_CLTV_EXPIRY_DELTA, PAYMENT_EXPIRY_BLOCKS };
@ -7441,8 +7441,9 @@ fn test_check_htlc_underpaying() {
create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known());
let scorer = test_utils::TestScorer::with_penalty(0);
let random_seed_bytes = chanmon_cfgs[1].keys_manager.get_secure_random_bytes();
let payment_params = PaymentParameters::from_node_id(nodes[1].node.get_our_node_id()).with_features(InvoiceFeatures::known());
let route = get_route(&nodes[0].node.get_our_node_id(), &payment_params, nodes[0].network_graph, None, 10_000, TEST_FINAL_CLTV, nodes[0].logger, &scorer).unwrap();
let route = get_route(&nodes[0].node.get_our_node_id(), &payment_params, &nodes[0].network_graph.read_only(), None, 10_000, TEST_FINAL_CLTV, nodes[0].logger, &scorer, &random_seed_bytes).unwrap();
let (_, our_payment_hash, _) = get_payment_preimage_hash!(nodes[0]);
let our_payment_secret = nodes[1].node.create_inbound_payment_for_hash(our_payment_hash, Some(100_000), 7200).unwrap();
nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap();
@ -7844,12 +7845,13 @@ fn test_bump_penalty_txn_on_revoked_htlcs() {
// Lock HTLC in both directions (using a slightly lower CLTV delay to provide timely RBF bumps)
let payment_params = PaymentParameters::from_node_id(nodes[1].node.get_our_node_id()).with_features(InvoiceFeatures::known());
let scorer = test_utils::TestScorer::with_penalty(0);
let route = get_route(&nodes[0].node.get_our_node_id(), &payment_params, &nodes[0].network_graph, None,
3_000_000, 50, nodes[0].logger, &scorer).unwrap();
let random_seed_bytes = chanmon_cfgs[1].keys_manager.get_secure_random_bytes();
let route = get_route(&nodes[0].node.get_our_node_id(), &payment_params, &nodes[0].network_graph.read_only(), None,
3_000_000, 50, nodes[0].logger, &scorer, &random_seed_bytes).unwrap();
let payment_preimage = send_along_route(&nodes[0], route, &[&nodes[1]], 3_000_000).0;
let payment_params = PaymentParameters::from_node_id(nodes[0].node.get_our_node_id()).with_features(InvoiceFeatures::known());
let route = get_route(&nodes[1].node.get_our_node_id(), &payment_params, nodes[1].network_graph, None,
3_000_000, 50, nodes[0].logger, &scorer).unwrap();
let route = get_route(&nodes[1].node.get_our_node_id(), &payment_params, &nodes[1].network_graph.read_only(), None,
3_000_000, 50, nodes[0].logger, &scorer, &random_seed_bytes).unwrap();
send_along_route(&nodes[1], route, &[&nodes[0]], 3_000_000);
let revoked_local_txn = get_local_commitment_txn!(nodes[1], chan.2);
@ -9618,10 +9620,11 @@ fn test_dup_htlc_second_fail_panic() {
let payment_params = PaymentParameters::from_node_id(nodes[1].node.get_our_node_id())
.with_features(InvoiceFeatures::known());
let scorer = test_utils::TestScorer::with_penalty(0);
let random_seed_bytes = chanmon_cfgs[1].keys_manager.get_secure_random_bytes();
let route = get_route(
&nodes[0].node.get_our_node_id(), &payment_params, &nodes[0].network_graph,
&nodes[0].node.get_our_node_id(), &payment_params, &nodes[0].network_graph.read_only(),
Some(&nodes[0].node.list_usable_channels().iter().collect::<Vec<_>>()),
10_000, TEST_FINAL_CLTV, nodes[0].logger, &scorer).unwrap();
10_000, TEST_FINAL_CLTV, nodes[0].logger, &scorer, &random_seed_bytes).unwrap();
let (_, our_payment_hash, our_payment_secret) = get_payment_preimage_hash!(&nodes[1]);
@ -9690,7 +9693,8 @@ fn test_keysend_payments_to_public_node() {
final_cltv_expiry_delta: 40,
};
let scorer = test_utils::TestScorer::with_penalty(0);
let route = find_route(&payer_pubkey, &route_params, network_graph, None, nodes[0].logger, &scorer).unwrap();
let random_seed_bytes = chanmon_cfgs[1].keys_manager.get_secure_random_bytes();
let route = find_route(&payer_pubkey, &route_params, network_graph, None, nodes[0].logger, &scorer, &random_seed_bytes).unwrap();
let test_preimage = PaymentPreimage([42; 32]);
let (payment_hash, _) = nodes[0].node.send_spontaneous_payment(&route, Some(test_preimage)).unwrap();
@ -9724,9 +9728,10 @@ fn test_keysend_payments_to_private_node() {
let network_graph = nodes[0].network_graph;
let first_hops = nodes[0].node.list_usable_channels();
let scorer = test_utils::TestScorer::with_penalty(0);
let random_seed_bytes = chanmon_cfgs[1].keys_manager.get_secure_random_bytes();
let route = find_route(
&payer_pubkey, &route_params, network_graph, Some(&first_hops.iter().collect::<Vec<_>>()),
nodes[0].logger, &scorer
nodes[0].logger, &scorer, &random_seed_bytes
).unwrap();
let test_preimage = PaymentPreimage([42; 32]);

View file

@ -610,10 +610,11 @@ macro_rules! get_phantom_route {
}
])]);
let scorer = test_utils::TestScorer::with_penalty(0);
let network_graph = $nodes[0].network_graph.read_only();
(get_route(
&$nodes[0].node.get_our_node_id(), &payment_params, $nodes[0].network_graph,
&$nodes[0].node.get_our_node_id(), &payment_params, &network_graph,
Some(&$nodes[0].node.list_usable_channels().iter().collect::<Vec<_>>()),
$amt, TEST_FINAL_CLTV, $nodes[0].logger, &scorer
$amt, TEST_FINAL_CLTV, $nodes[0].logger, &scorer, &[0u8; 32]
).unwrap(), phantom_route_hint.phantom_scid)
}
}}

View file

@ -14,6 +14,7 @@
use chain::{ChannelMonitorUpdateErr, Confirm, Listen, Watch};
use chain::channelmonitor::{ANTI_REORG_DELAY, ChannelMonitor, LATENCY_GRACE_PERIOD_BLOCKS};
use chain::transaction::OutPoint;
use chain::keysinterface::KeysInterface;
use ln::channelmanager::{BREAKDOWN_TIMEOUT, ChannelManager, ChannelManagerReadArgs, PaymentId, PaymentSendFailure};
use ln::features::{InitFeatures, InvoiceFeatures};
use ln::msgs;
@ -27,6 +28,7 @@ use util::ser::{ReadableArgs, Writeable};
use io;
use bitcoin::{Block, BlockHeader, BlockHash};
use bitcoin::network::constants::Network;
use prelude::*;
@ -730,10 +732,12 @@ fn get_ldk_payment_preimage() {
let payment_params = PaymentParameters::from_node_id(nodes[1].node.get_our_node_id())
.with_features(InvoiceFeatures::known());
let scorer = test_utils::TestScorer::with_penalty(0);
let keys_manager = test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
let random_seed_bytes = keys_manager.get_secure_random_bytes();
let route = get_route(
&nodes[0].node.get_our_node_id(), &payment_params, &nodes[0].network_graph,
&nodes[0].node.get_our_node_id(), &payment_params, &nodes[0].network_graph.read_only(),
Some(&nodes[0].node.list_usable_channels().iter().collect::<Vec<_>>()),
amt_msat, TEST_FINAL_CLTV, nodes[0].logger, &scorer).unwrap();
amt_msat, TEST_FINAL_CLTV, nodes[0].logger, &scorer, &random_seed_bytes).unwrap();
let _payment_id = nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret)).unwrap();
check_added_monitors!(nodes[0], 1);

View file

@ -25,6 +25,7 @@ use util::config::UserConfig;
use bitcoin::blockdata::script::Builder;
use bitcoin::blockdata::opcodes;
use bitcoin::network::constants::Network;
use regex;
@ -77,6 +78,8 @@ fn updates_shutdown_wait() {
let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2, InitFeatures::known(), InitFeatures::known());
let logger = test_utils::TestLogger::new();
let scorer = test_utils::TestScorer::with_penalty(0);
let keys_manager = test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
let random_seed_bytes = keys_manager.get_secure_random_bytes();
let (payment_preimage, _, _) = route_payment(&nodes[0], &[&nodes[1], &nodes[2]], 100000);
@ -92,9 +95,9 @@ fn updates_shutdown_wait() {
let (_, payment_hash, payment_secret) = get_payment_preimage_hash!(nodes[0]);
let payment_params_1 = PaymentParameters::from_node_id(nodes[1].node.get_our_node_id()).with_features(InvoiceFeatures::known());
let route_1 = get_route(&nodes[0].node.get_our_node_id(), &payment_params_1, nodes[0].network_graph, None, 100000, TEST_FINAL_CLTV, &logger, &scorer).unwrap();
let route_1 = get_route(&nodes[0].node.get_our_node_id(), &payment_params_1, &nodes[0].network_graph.read_only(), None, 100000, TEST_FINAL_CLTV, &logger, &scorer, &random_seed_bytes).unwrap();
let payment_params_2 = PaymentParameters::from_node_id(nodes[0].node.get_our_node_id()).with_features(InvoiceFeatures::known());
let route_2 = get_route(&nodes[1].node.get_our_node_id(), &payment_params_2, nodes[1].network_graph, None, 100000, TEST_FINAL_CLTV, &logger, &scorer).unwrap();
let route_2 = get_route(&nodes[1].node.get_our_node_id(), &payment_params_2, &nodes[1].network_graph.read_only(), None, 100000, TEST_FINAL_CLTV, &logger, &scorer, &random_seed_bytes).unwrap();
unwrap_send_err!(nodes[0].node.send_payment(&route_1, payment_hash, &Some(payment_secret)), true, APIError::ChannelUnavailable {..}, {});
unwrap_send_err!(nodes[1].node.send_payment(&route_2, payment_hash, &Some(payment_secret)), true, APIError::ChannelUnavailable {..}, {});

View file

@ -674,6 +674,21 @@ impl ChannelInfo {
};
Some((DirectedChannelInfo { channel: self, direction }, source))
}
/// Returns a [`DirectedChannelInfo`] for the channel directed from the given `source` to a
/// returned `target`, or `None` if `source` is not one of the channel's counterparties.
pub fn as_directed_from(&self, source: &NodeId) -> Option<(DirectedChannelInfo, &NodeId)> {
let (direction, target) = {
if source == &self.node_one {
(self.one_to_two.as_ref(), &self.node_two)
} else if source == &self.node_two {
(self.two_to_one.as_ref(), &self.node_one)
} else {
return None;
}
};
Some((DirectedChannelInfo { channel: self, direction }, target))
}
}
impl fmt::Display for ChannelInfo {

File diff suppressed because it is too large Load diff

View file

@ -20,6 +20,7 @@
//! # use lightning::routing::network_graph::NetworkGraph;
//! # use lightning::routing::router::{RouteParameters, find_route};
//! # use lightning::routing::scoring::{ProbabilisticScorer, ProbabilisticScoringParameters, Scorer, ScoringParameters};
//! # use lightning::chain::keysinterface::{KeysManager, KeysInterface};
//! # use lightning::util::logger::{Logger, Record};
//! # use secp256k1::key::PublicKey;
//! #
@ -40,8 +41,9 @@
//! ..ProbabilisticScoringParameters::default()
//! };
//! let scorer = ProbabilisticScorer::new(params, &network_graph);
//! # let random_seed_bytes = [42u8; 32];
//!
//! let route = find_route(&payer, &route_params, &network_graph, None, &logger, &scorer);
//! let route = find_route(&payer, &route_params, &network_graph, None, &logger, &scorer, &random_seed_bytes);
//! # }
//! ```
//!