X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning-invoice%2Fsrc%2Fpayment.rs;h=476d12a34751e885c43980453ede2db9288d0cd5;hb=refs%2Fheads%2F2022-07-warnings;hp=d6a3abb0ddf60c8f8c0d47af92c30a7ca695e904;hpb=36817e0539378b34f3d07d99e88443107c813200;p=rust-lightning diff --git a/lightning-invoice/src/payment.rs b/lightning-invoice/src/payment.rs index d6a3abb0..476d12a3 100644 --- a/lightning-invoice/src/payment.rs +++ b/lightning-invoice/src/payment.rs @@ -38,9 +38,9 @@ //! # use lightning::ln::{PaymentHash, PaymentPreimage, PaymentSecret}; //! # use lightning::ln::channelmanager::{ChannelDetails, PaymentId, PaymentSendFailure}; //! # use lightning::ln::msgs::LightningError; -//! # use lightning::routing::scoring::Score; -//! # use lightning::routing::network_graph::NodeId; +//! # use lightning::routing::gossip::NodeId; //! # use lightning::routing::router::{Route, RouteHop, RouteParameters}; +//! # use lightning::routing::scoring::{ChannelUsage, Score}; //! # use lightning::util::events::{Event, EventHandler, EventsProvider}; //! # use lightning::util::logger::{Logger, Record}; //! # use lightning::util::ser::{Writeable, Writer}; @@ -90,10 +90,12 @@ //! # } //! # impl Score for FakeScorer { //! # fn channel_penalty_msat( -//! # &self, _short_channel_id: u64, _send_amt: u64, _chan_amt: u64, _source: &NodeId, _target: &NodeId +//! # &self, _short_channel_id: u64, _source: &NodeId, _target: &NodeId, _usage: ChannelUsage //! # ) -> 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 {} @@ -584,6 +586,18 @@ where .map_or(1, |attempts| attempts.count + 1); log_trace!(self.logger, "Payment {} succeeded (attempts: {})", log_bytes!(payment_hash.0), attempts); }, + Event::ProbeSuccessful { payment_hash, path, .. } => { + log_trace!(self.logger, "Probe payment {} of {}msat was successful", log_bytes!(payment_hash.0), path.last().unwrap().fee_msat); + let path = path.iter().collect::>(); + self.scorer.lock().probe_successful(&path); + }, + Event::ProbeFailed { payment_hash, path, short_channel_id, .. } => { + if let Some(short_channel_id) = short_channel_id { + log_trace!(self.logger, "Probe payment {} of {}msat failed at channel {}", log_bytes!(payment_hash.0), path.last().unwrap().fee_msat, *short_channel_id); + let path = path.iter().collect::>(); + self.scorer.lock().probe_failed(&path, *short_channel_id); + } + }, _ => {}, } @@ -602,8 +616,9 @@ mod tests { use lightning::ln::features::{ChannelFeatures, NodeFeatures, InitFeatures}; use lightning::ln::functional_test_utils::*; use lightning::ln::msgs::{ChannelMessageHandler, ErrorAction, LightningError}; - use lightning::routing::network_graph::NodeId; + use lightning::routing::gossip::NodeId; use lightning::routing::router::{PaymentParameters, Route, RouteHop}; + use lightning::routing::scoring::ChannelUsage; use lightning::util::test_utils::TestLogger; use lightning::util::errors::APIError; use lightning::util::events::{Event, EventsProvider, MessageSendEvent, MessageSendEventsProvider}; @@ -1295,7 +1310,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(TestResult::PaymentFailure { path: path.clone(), short_channel_id: path[0].short_channel_id, })); let logger = TestLogger::new(); @@ -1331,8 +1346,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(TestResult::PaymentSuccess { path: route.paths[0].clone() }) + .expect(TestResult::PaymentSuccess { path: route.paths[1].clone() }) ); let logger = TestLogger::new(); let invoice_payer = @@ -1415,13 +1430,13 @@ mod tests { } struct TestScorer { - expectations: Option>, + expectations: Option>, } #[derive(Debug)] - enum PaymentPath { - Failure { path: Vec, short_channel_id: u64 }, - Success { path: Vec }, + enum TestResult { + PaymentFailure { path: Vec, short_channel_id: u64 }, + PaymentSuccess { path: Vec }, } impl TestScorer { @@ -1431,7 +1446,7 @@ mod tests { } } - fn expect(mut self, expectation: PaymentPath) -> Self { + fn expect(mut self, expectation: TestResult) -> Self { self.expectations.get_or_insert_with(|| VecDeque::new()).push_back(expectation); self } @@ -1444,17 +1459,17 @@ mod tests { impl Score for TestScorer { fn channel_penalty_msat( - &self, _short_channel_id: u64, _send_amt: u64, _chan_amt: u64, _source: &NodeId, _target: &NodeId + &self, _short_channel_id: u64, _source: &NodeId, _target: &NodeId, _usage: ChannelUsage ) -> u64 { 0 } 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(TestResult::PaymentFailure { path, short_channel_id }) => { assert_eq!(actual_path, &path.iter().collect::>()[..]); assert_eq!(actual_short_channel_id, short_channel_id); }, - Some(PaymentPath::Success { path }) => { + Some(TestResult::PaymentSuccess { path }) => { panic!("Unexpected successful payment path: {:?}", path) }, None => panic!("Unexpected payment_path_failed call: {:?}", actual_path), @@ -1465,16 +1480,43 @@ 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(TestResult::PaymentFailure { path, .. }) => { panic!("Unexpected payment path failure: {:?}", path) }, - Some(PaymentPath::Success { path }) => { + Some(TestResult::PaymentSuccess { path }) => { assert_eq!(actual_path, &path.iter().collect::>()[..]); }, None => panic!("Unexpected payment_path_successful call: {:?}", actual_path), } } } + + fn probe_failed(&mut self, actual_path: &[&RouteHop], _: u64) { + if let Some(expectations) = &mut self.expectations { + match expectations.pop_front() { + Some(TestResult::PaymentFailure { path, .. }) => { + panic!("Unexpected failed payment path: {:?}", path) + }, + Some(TestResult::PaymentSuccess { path }) => { + panic!("Unexpected successful payment path: {:?}", 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(TestResult::PaymentFailure { path, .. }) => { + panic!("Unexpected payment path failure: {:?}", path) + }, + Some(TestResult::PaymentSuccess { path }) => { + panic!("Unexpected successful payment path: {:?}", path) + }, + None => panic!("Unexpected payment_path_successful call: {:?}", actual_path), + } + } + } } impl Drop for TestScorer {