Skip to content

Commit 197cbc4

Browse files
committed
Pass effective capacity to scorer
Scorers could benefit from having the channel's EffectiveCapacity rather than a u64 msat value. For instance, ProbabilisticScorer can give a more accurate penalty when given the ExactLiquidity variant. Pass a struct wrapping the effective capacity, the proposed amount, and any in-flight HTLC value.
1 parent 435a325 commit 197cbc4

File tree

3 files changed

+404
-160
lines changed

3 files changed

+404
-160
lines changed

lightning-invoice/src/payment.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,9 @@
3838
//! # use lightning::ln::{PaymentHash, PaymentPreimage, PaymentSecret};
3939
//! # use lightning::ln::channelmanager::{ChannelDetails, PaymentId, PaymentSendFailure};
4040
//! # use lightning::ln::msgs::LightningError;
41-
//! # use lightning::routing::scoring::Score;
4241
//! # use lightning::routing::network_graph::NodeId;
4342
//! # use lightning::routing::router::{Route, RouteHop, RouteParameters};
43+
//! # use lightning::routing::scoring::{ChannelUsage, Score};
4444
//! # use lightning::util::events::{Event, EventHandler, EventsProvider};
4545
//! # use lightning::util::logger::{Logger, Record};
4646
//! # use lightning::util::ser::{Writeable, Writer};
@@ -90,7 +90,7 @@
9090
//! # }
9191
//! # impl Score for FakeScorer {
9292
//! # fn channel_penalty_msat(
93-
//! # &self, _short_channel_id: u64, _send_amt: u64, _chan_amt: u64, _source: &NodeId, _target: &NodeId
93+
//! # &self, _short_channel_id: u64, _source: &NodeId, _target: &NodeId, _usage: ChannelUsage
9494
//! # ) -> u64 { 0 }
9595
//! # fn payment_path_failed(&mut self, _path: &[&RouteHop], _short_channel_id: u64) {}
9696
//! # fn payment_path_successful(&mut self, _path: &[&RouteHop]) {}
@@ -604,6 +604,7 @@ mod tests {
604604
use lightning::ln::msgs::{ChannelMessageHandler, ErrorAction, LightningError};
605605
use lightning::routing::network_graph::NodeId;
606606
use lightning::routing::router::{PaymentParameters, Route, RouteHop};
607+
use lightning::routing::scoring::ChannelUsage;
607608
use lightning::util::test_utils::TestLogger;
608609
use lightning::util::errors::APIError;
609610
use lightning::util::events::{Event, EventsProvider, MessageSendEvent, MessageSendEventsProvider};
@@ -1444,7 +1445,7 @@ mod tests {
14441445

14451446
impl Score for TestScorer {
14461447
fn channel_penalty_msat(
1447-
&self, _short_channel_id: u64, _send_amt: u64, _chan_amt: u64, _source: &NodeId, _target: &NodeId
1448+
&self, _short_channel_id: u64, _source: &NodeId, _target: &NodeId, _usage: ChannelUsage
14481449
) -> u64 { 0 }
14491450

14501451
fn payment_path_failed(&mut self, actual_path: &[&RouteHop], actual_short_channel_id: u64) {

lightning/src/routing/router.rs

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use bitcoin::secp256k1::PublicKey;
1717
use ln::channelmanager::ChannelDetails;
1818
use ln::features::{ChannelFeatures, InvoiceFeatures, NodeFeatures};
1919
use ln::msgs::{DecodeError, ErrorAction, LightningError, MAX_VALUE_MSAT};
20-
use routing::scoring::Score;
20+
use routing::scoring::{ChannelUsage, Score};
2121
use routing::network_graph::{DirectedChannelInfoWithUpdate, EffectiveCapacity, NetworkGraph, ReadOnlyNetworkGraph, NodeId, RoutingFees};
2222
use util::ser::{Writeable, Readable};
2323
use util::logger::{Level, Logger};
@@ -1066,10 +1066,16 @@ where L::Target: Logger {
10661066
}
10671067
}
10681068

1069-
let available_liquidity_msat = htlc_maximum_msat - used_liquidity_msat;
1070-
let path_penalty_msat = $next_hops_path_penalty_msat.saturating_add(
1071-
scorer.channel_penalty_msat(short_channel_id, amount_to_transfer_over_msat,
1072-
available_liquidity_msat, &$src_node_id, &$dest_node_id));
1069+
let channel_usage = ChannelUsage {
1070+
amount_msat: amount_to_transfer_over_msat,
1071+
inflight_htlc_msat: used_liquidity_msat,
1072+
effective_capacity: $candidate.effective_capacity(),
1073+
};
1074+
let channel_penalty_msat = scorer.channel_penalty_msat(
1075+
short_channel_id, &$src_node_id, &$dest_node_id, channel_usage
1076+
);
1077+
let path_penalty_msat = $next_hops_path_penalty_msat
1078+
.saturating_add(channel_penalty_msat);
10731079
let new_graph_node = RouteGraphNode {
10741080
node_id: $src_node_id,
10751081
lowest_fee_to_peer_through_node: total_fee_msat,
@@ -1306,10 +1312,18 @@ where L::Target: Logger {
13061312
hop_used = false;
13071313
}
13081314

1309-
let amount_to_transfer_msat = final_value_msat + aggregate_next_hops_fee_msat;
1310-
let capacity_msat = candidate.effective_capacity().as_msat();
1315+
let used_liquidity_msat = used_channel_liquidities
1316+
.get(&(hop.short_channel_id, source < target)).copied().unwrap_or(0);
1317+
let channel_usage = ChannelUsage {
1318+
amount_msat: final_value_msat + aggregate_next_hops_fee_msat,
1319+
inflight_htlc_msat: used_liquidity_msat,
1320+
effective_capacity: candidate.effective_capacity(),
1321+
};
1322+
let channel_penalty_msat = scorer.channel_penalty_msat(
1323+
hop.short_channel_id, &source, &target, channel_usage
1324+
);
13111325
aggregate_next_hops_path_penalty_msat = aggregate_next_hops_path_penalty_msat
1312-
.saturating_add(scorer.channel_penalty_msat(hop.short_channel_id, amount_to_transfer_msat, capacity_msat, &source, &target));
1326+
.saturating_add(channel_penalty_msat);
13131327

13141328
aggregate_next_hops_cltv_delta = aggregate_next_hops_cltv_delta
13151329
.saturating_add(hop.cltv_expiry_delta as u32);
@@ -1777,7 +1791,7 @@ mod tests {
17771791
use routing::router::{get_route, add_random_cltv_offset, default_node_features,
17781792
PaymentParameters, Route, RouteHint, RouteHintHop, RouteHop, RoutingFees,
17791793
DEFAULT_MAX_TOTAL_CLTV_EXPIRY_DELTA, MAX_PATH_LENGTH_ESTIMATE};
1780-
use routing::scoring::Score;
1794+
use routing::scoring::{ChannelUsage, Score};
17811795
use chain::transaction::OutPoint;
17821796
use chain::keysinterface::KeysInterface;
17831797
use ln::features::{ChannelFeatures, InitFeatures, InvoiceFeatures, NodeFeatures};
@@ -5169,7 +5183,7 @@ mod tests {
51695183
fn write<W: Writer>(&self, _w: &mut W) -> Result<(), ::io::Error> { unimplemented!() }
51705184
}
51715185
impl Score for BadChannelScorer {
5172-
fn channel_penalty_msat(&self, short_channel_id: u64, _send_amt: u64, _capacity_msat: u64, _source: &NodeId, _target: &NodeId) -> u64 {
5186+
fn channel_penalty_msat(&self, short_channel_id: u64, _: &NodeId, _: &NodeId, _: ChannelUsage) -> u64 {
51735187
if short_channel_id == self.short_channel_id { u64::max_value() } else { 0 }
51745188
}
51755189

@@ -5187,7 +5201,7 @@ mod tests {
51875201
}
51885202

51895203
impl Score for BadNodeScorer {
5190-
fn channel_penalty_msat(&self, _short_channel_id: u64, _send_amt: u64, _capacity_msat: u64, _source: &NodeId, target: &NodeId) -> u64 {
5204+
fn channel_penalty_msat(&self, _: u64, _: &NodeId, target: &NodeId, _: ChannelUsage) -> u64 {
51915205
if *target == self.node_id { u64::max_value() } else { 0 }
51925206
}
51935207

0 commit comments

Comments
 (0)