Skip to content

Commit

Permalink
Provide add probing interface to Scorer
Browse files Browse the repository at this point in the history
  • Loading branch information
tnull committed Jun 28, 2022
1 parent e213ba5 commit 585f8d8
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 14 deletions.
87 changes: 73 additions & 14 deletions lightning-invoice/src/payment.rs
Expand Up @@ -104,6 +104,8 @@
//! # ) -> u64 { 0 }
//! # fn payment_path_failed(&mut self, _path: &[&RouteHop], _short_channel_id: u64) {}
//! # fn payment_path_successful(&mut self, _path: &[&RouteHop]) {}
//! # fn probe_failed(&mut self, _path: &[&RouteHop], _short_channel_id: u64) {}
//! # fn probe_successful(&mut self, _path: &[&RouteHop]) {}
//! # }
//! #
//! # struct FakeLogger {}
Expand Down Expand Up @@ -595,8 +597,11 @@ where
// hop and then drop the event instead of handing it up to the user's event
// handler.
if self.payer.payment_is_probe(*payment_hash, *payment_id) {
let scid = if *rejected_by_dest { u64::max_value() } else { *short_channel_id };
self.scorer.lock().payment_path_failed(&path, scid);
if *rejected_by_dest {
self.scorer.lock().probe_successful(&path);
} else {
self.scorer.lock().probe_failed(&path, *short_channel_id);
}
return;
}
}
Expand Down Expand Up @@ -1345,7 +1350,7 @@ mod tests {
.expect_send(Amount::ForInvoice(final_value_msat))
.expect_send(Amount::OnRetry(final_value_msat / 2));
let router = TestRouter {};
let scorer = RefCell::new(TestScorer::new().expect(PaymentPath::Failure {
let scorer = RefCell::new(TestScorer::new().expect(ExpectedPaymentResult::PathFailure {
path: path.clone(), short_channel_id: path[0].short_channel_id,
}));
let logger = TestLogger::new();
Expand Down Expand Up @@ -1381,8 +1386,8 @@ mod tests {
let payer = TestPayer::new().expect_send(Amount::ForInvoice(final_value_msat));
let router = TestRouter {};
let scorer = RefCell::new(TestScorer::new()
.expect(PaymentPath::Success { path: route.paths[0].clone() })
.expect(PaymentPath::Success { path: route.paths[1].clone() })
.expect(ExpectedPaymentResult::PathSuccess { path: route.paths[0].clone() })
.expect(ExpectedPaymentResult::PathSuccess { path: route.paths[1].clone() })
);
let logger = TestLogger::new();
let invoice_payer =
Expand Down Expand Up @@ -1479,13 +1484,15 @@ mod tests {
}

struct TestScorer {
expectations: Option<VecDeque<PaymentPath>>,
expectations: Option<VecDeque<ExpectedPaymentResult>>,
}

#[derive(Debug)]
enum PaymentPath {
Failure { path: Vec<RouteHop>, short_channel_id: u64 },
Success { path: Vec<RouteHop> },
enum ExpectedPaymentResult {
PathFailure { path: Vec<RouteHop>, short_channel_id: u64 },
PathSuccess { path: Vec<RouteHop> },
ProbeFailure { path: Vec<RouteHop>, short_channel_id: u64 },
ProbeSuccess { path: Vec<RouteHop> },
}

impl TestScorer {
Expand All @@ -1495,7 +1502,7 @@ mod tests {
}
}

fn expect(mut self, expectation: PaymentPath) -> Self {
fn expect(mut self, expectation: ExpectedPaymentResult) -> Self {
self.expectations.get_or_insert_with(|| VecDeque::new()).push_back(expectation);
self
}
Expand All @@ -1514,13 +1521,19 @@ mod tests {
fn payment_path_failed(&mut self, actual_path: &[&RouteHop], actual_short_channel_id: u64) {
if let Some(expectations) = &mut self.expectations {
match expectations.pop_front() {
Some(PaymentPath::Failure { path, short_channel_id }) => {
Some(ExpectedPaymentResult::PathFailure { path, short_channel_id }) => {
assert_eq!(actual_path, &path.iter().collect::<Vec<_>>()[..]);
assert_eq!(actual_short_channel_id, short_channel_id);
},
Some(PaymentPath::Success { path }) => {
Some(ExpectedPaymentResult::PathSuccess { path }) => {
panic!("Unexpected successful payment path: {:?}", path)
},
Some(ExpectedPaymentResult::ProbeFailure { path, .. }) => {
panic!("Unexpected failed payment probe: {:?}", path)
},
Some(ExpectedPaymentResult::ProbeSuccess { path }) => {
panic!("Unexpected successful payment probe: {:?}", path)
},
None => panic!("Unexpected payment_path_failed call: {:?}", actual_path),
}
}
Expand All @@ -1529,10 +1542,56 @@ mod tests {
fn payment_path_successful(&mut self, actual_path: &[&RouteHop]) {
if let Some(expectations) = &mut self.expectations {
match expectations.pop_front() {
Some(PaymentPath::Failure { path, .. }) => {
Some(ExpectedPaymentResult::PathFailure { path, .. }) => {
panic!("Unexpected payment path failure: {:?}", path)
},
Some(PaymentPath::Success { path }) => {
Some(ExpectedPaymentResult::PathSuccess { path }) => {
assert_eq!(actual_path, &path.iter().collect::<Vec<_>>()[..]);
},
Some(ExpectedPaymentResult::ProbeFailure { path, .. }) => {
panic!("Unexpected failed payment probe: {:?}", path)
},
Some(ExpectedPaymentResult::ProbeSuccess { path }) => {
panic!("Unexpected successful payment probe: {:?}", path)
},
None => panic!("Unexpected payment_path_successful call: {:?}", actual_path),
}
}
}

fn probe_failed(&mut self, actual_path: &[&RouteHop], actual_short_channel_id: u64) {
if let Some(expectations) = &mut self.expectations {
match expectations.pop_front() {
Some(ExpectedPaymentResult::PathFailure { path, .. }) => {
panic!("Unexpected failed payment path: {:?}", path)
},
Some(ExpectedPaymentResult::PathSuccess { path }) => {
panic!("Unexpected successful payment path: {:?}", path)
},
Some(ExpectedPaymentResult::ProbeFailure { path, short_channel_id }) => {
assert_eq!(actual_path, &path.iter().collect::<Vec<_>>()[..]);
assert_eq!(actual_short_channel_id, short_channel_id);
},
Some(ExpectedPaymentResult::ProbeSuccess { path }) => {
panic!("Unexpected successful payment probe: {:?}", path)
},
None => panic!("Unexpected payment_path_failed call: {:?}", actual_path),
}
}
}
fn probe_successful(&mut self, actual_path: &[&RouteHop]) {
if let Some(expectations) = &mut self.expectations {
match expectations.pop_front() {
Some(ExpectedPaymentResult::PathFailure { path, .. }) => {
panic!("Unexpected payment path failure: {:?}", path)
},
Some(ExpectedPaymentResult::PathSuccess { path }) => {
panic!("Unexpected successful payment path: {:?}", path)
},
Some(ExpectedPaymentResult::ProbeFailure { path, .. }) => {
panic!("Unexpected failed payment probe: {:?}", path)
},
Some(ExpectedPaymentResult::ProbeSuccess { path }) => {
assert_eq!(actual_path, &path.iter().collect::<Vec<_>>()[..]);
},
None => panic!("Unexpected payment_path_successful call: {:?}", actual_path),
Expand Down
8 changes: 8 additions & 0 deletions lightning/src/routing/router.rs
Expand Up @@ -1849,6 +1849,10 @@ fn build_route_from_hops_internal<L: Deref>(
fn payment_path_failed(&mut self, _path: &[&RouteHop], _short_channel_id: u64) {}

fn payment_path_successful(&mut self, _path: &[&RouteHop]) {}

fn probe_failed(&mut self, _path: &[&RouteHop], _short_channel_id: u64) {}

fn probe_successful(&mut self, _path: &[&RouteHop]) {}
}

impl<'a> Writeable for HopScorer {
Expand Down Expand Up @@ -5314,6 +5318,8 @@ mod tests {

fn payment_path_failed(&mut self, _path: &[&RouteHop], _short_channel_id: u64) {}
fn payment_path_successful(&mut self, _path: &[&RouteHop]) {}
fn probe_failed(&mut self, _path: &[&RouteHop], _short_channel_id: u64) {}
fn probe_successful(&mut self, _path: &[&RouteHop]) {}
}

struct BadNodeScorer {
Expand All @@ -5332,6 +5338,8 @@ mod tests {

fn payment_path_failed(&mut self, _path: &[&RouteHop], _short_channel_id: u64) {}
fn payment_path_successful(&mut self, _path: &[&RouteHop]) {}
fn probe_failed(&mut self, _path: &[&RouteHop], _short_channel_id: u64) {}
fn probe_successful(&mut self, _path: &[&RouteHop]) {}
}

#[test]
Expand Down
26 changes: 26 additions & 0 deletions lightning/src/routing/scoring.rs
Expand Up @@ -102,6 +102,12 @@ pub trait Score $(: $supertrait)* {

/// Handles updating channel penalties after successfully routing along a path.
fn payment_path_successful(&mut self, path: &[&RouteHop]);

/// Handles updating channel penalties after a probe over the given path failed.
fn probe_failed(&mut self, path: &[&RouteHop], short_channel_id: u64);

/// Handles updating channel penalties after a probe over the given path succeeded.
fn probe_successful(&mut self, path: &[&RouteHop]);
}

impl<S: Score, T: DerefMut<Target=S> $(+ $supertrait)*> Score for T {
Expand All @@ -118,6 +124,14 @@ impl<S: Score, T: DerefMut<Target=S> $(+ $supertrait)*> Score for T {
fn payment_path_successful(&mut self, path: &[&RouteHop]) {
self.deref_mut().payment_path_successful(path)
}

fn probe_failed(&mut self, path: &[&RouteHop], short_channel_id: u64) {
self.deref_mut().probe_failed(path, short_channel_id)
}

fn probe_successful(&mut self, path: &[&RouteHop]) {
self.deref_mut().probe_successful(path)
}
}
} }

Expand Down Expand Up @@ -241,6 +255,10 @@ impl Score for FixedPenaltyScorer {
fn payment_path_failed(&mut self, _path: &[&RouteHop], _short_channel_id: u64) {}

fn payment_path_successful(&mut self, _path: &[&RouteHop]) {}

fn probe_failed(&mut self, _path: &[&RouteHop], _short_channel_id: u64) {}

fn probe_successful(&mut self, _path: &[&RouteHop]) {}
}

impl Writeable for FixedPenaltyScorer {
Expand Down Expand Up @@ -811,6 +829,14 @@ impl<G: Deref<Target = NetworkGraph<L>>, L: Deref, T: Time> Score for Probabilis
}
}
}

fn probe_failed(&mut self, path: &[&RouteHop], short_channel_id: u64) {
self.payment_path_failed(path, short_channel_id)
}

fn probe_successful(&mut self, path: &[&RouteHop]) {
self.payment_path_failed(path, u64::max_value())
}
}

mod approx {
Expand Down

0 comments on commit 585f8d8

Please sign in to comment.