use ln::channelmanager::ChannelDetails;
use ln::features::{ChannelFeatures, InvoiceFeatures, NodeFeatures};
use ln::msgs::{DecodeError, ErrorAction, LightningError, MAX_VALUE_MSAT};
-use routing::gossip::{DirectedChannelInfoWithUpdate, EffectiveCapacity, ReadOnlyNetworkGraph, NodeId, RoutingFees};
+use routing::gossip::{DirectedChannelInfoWithUpdate, EffectiveCapacity, ReadOnlyNetworkGraph, NetworkGraph, NodeId, RoutingFees};
use routing::scoring::{ChannelUsage, Score};
use util::ser::{Writeable, Readable, Writer};
use util::logger::{Level, Logger};
/// [`ChannelManager::list_usable_channels`]: crate::ln::channelmanager::ChannelManager::list_usable_channels
/// [`Event::PaymentPathFailed`]: crate::util::events::Event::PaymentPathFailed
/// [`NetworkGraph`]: crate::routing::gossip::NetworkGraph
-pub fn find_route<L: Deref, S: Score>(
+pub fn find_route<L: Deref, GL: Deref, S: Score>(
our_node_pubkey: &PublicKey, route_params: &RouteParameters,
- network_graph: &ReadOnlyNetworkGraph, first_hops: Option<&[&ChannelDetails]>, logger: L,
+ network_graph: &NetworkGraph<GL>, first_hops: Option<&[&ChannelDetails]>, logger: L,
scorer: &S, random_seed_bytes: &[u8; 32]
) -> Result<Route, LightningError>
-where L::Target: Logger {
- let mut route = get_route(our_node_pubkey, &route_params.payment_params, network_graph, first_hops,
+where L::Target: Logger, GL::Target: Logger {
+ let graph_lock = network_graph.read_only();
+ let mut route = get_route(our_node_pubkey, &route_params.payment_params, &graph_lock, first_hops,
route_params.final_value_msat, route_params.final_cltv_expiry_delta, logger, scorer,
random_seed_bytes)?;
- add_random_cltv_offset(&mut route, &route_params.payment_params, network_graph, random_seed_bytes);
+ add_random_cltv_offset(&mut route, &route_params.payment_params, &graph_lock, random_seed_bytes);
Ok(route)
}
/// exclude the payer, but include the payee). This may be useful, e.g., for probing the chosen path.
///
/// Re-uses logic from `find_route`, so the restrictions described there also apply here.
-pub fn build_route_from_hops<L: Deref>(
+pub fn build_route_from_hops<L: Deref, GL: Deref>(
our_node_pubkey: &PublicKey, hops: &[PublicKey], route_params: &RouteParameters,
- network_graph: &ReadOnlyNetworkGraph, logger: L, random_seed_bytes: &[u8; 32]
+ network_graph: &NetworkGraph<GL>, logger: L, random_seed_bytes: &[u8; 32]
) -> Result<Route, LightningError>
-where L::Target: Logger {
+where L::Target: Logger, GL::Target: Logger {
+ let graph_lock = network_graph.read_only();
let mut route = build_route_from_hops_internal(
- our_node_pubkey, hops, &route_params.payment_params, &network_graph,
+ our_node_pubkey, hops, &route_params.payment_params, &graph_lock,
route_params.final_value_msat, route_params.final_cltv_expiry_delta, logger, random_seed_bytes)?;
- add_random_cltv_offset(&mut route, &route_params.payment_params, &network_graph, random_seed_bytes);
+ add_random_cltv_offset(&mut route, &route_params.payment_params, &graph_lock, random_seed_bytes);
Ok(route)
}
use routing::router::{get_route, build_route_from_hops_internal, add_random_cltv_offset, default_node_features,
PaymentParameters, Route, RouteHint, RouteHintHop, RouteHop, RoutingFees,
DEFAULT_MAX_TOTAL_CLTV_EXPIRY_DELTA, MAX_PATH_LENGTH_ESTIMATE};
- use routing::scoring::{ChannelUsage, Score};
+ use routing::scoring::{ChannelUsage, Score, ProbabilisticScorer, ProbabilisticScoringParameters};
use chain::transaction::OutPoint;
use chain::keysinterface::KeysInterface;
use ln::features::{ChannelFeatures, InitFeatures, InvoiceFeatures, NodeFeatures};
is_usable: true, is_public: true,
inbound_htlc_minimum_msat: None,
inbound_htlc_maximum_msat: None,
+ config: None,
}
}
}
}
}
+
+ #[test]
+ fn avoids_banned_nodes() {
+ let (secp_ctx, network_graph, _, _, logger) = build_line_graph();
+ let (_, our_id, _, nodes) = get_nodes(&secp_ctx);
+
+ let keys_manager = test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
+ let random_seed_bytes = keys_manager.get_secure_random_bytes();
+
+ let scorer_params = ProbabilisticScoringParameters::default();
+ let mut scorer = ProbabilisticScorer::new(scorer_params, Arc::clone(&network_graph), Arc::clone(&logger));
+
+ // First check we can get a route.
+ let payment_params = PaymentParameters::from_node_id(nodes[10]);
+ let route = get_route(&our_id, &payment_params, &network_graph.read_only(), None, 100, 42, Arc::clone(&logger), &scorer, &random_seed_bytes);
+ assert!(route.is_ok());
+
+ // Then check that we can't get a route if we ban an intermediate node.
+ scorer.add_banned(&NodeId::from_pubkey(&nodes[3]));
+ let route = get_route(&our_id, &payment_params, &network_graph.read_only(), None, 100, 42, Arc::clone(&logger), &scorer, &random_seed_bytes);
+ assert!(route.is_err());
+
+ // Finally make sure we can route again, when we remove the ban.
+ scorer.remove_banned(&NodeId::from_pubkey(&nodes[3]));
+ let route = get_route(&our_id, &payment_params, &network_graph.read_only(), None, 100, 42, Arc::clone(&logger), &scorer, &random_seed_bytes);
+ assert!(route.is_ok());
+ }
}
#[cfg(all(test, not(feature = "no-std")))]
is_public: true,
inbound_htlc_minimum_msat: None,
inbound_htlc_maximum_msat: None,
+ config: None,
}
}