Skip to content

Commit f827add

Browse files
committed
[wip] Add multihop correctness test for correct_inflight_map_from_path
1 parent 84fd3e8 commit f827add

File tree

1 file changed

+77
-2
lines changed

1 file changed

+77
-2
lines changed

lightning-invoice/src/payment.rs

Lines changed: 77 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -682,8 +682,8 @@ where
682682
// hardcoded with an inflight value of 0 so that we can correctly represent the first hop
683683
// in our sliding window of two.
684684
let our_node_id: PublicKey = self.payer.node_id();
685-
let reversed_hops_with_payer = core::iter::once((0u64, our_node_id)).chain(
686-
path.split_last().unwrap().1.iter().map(|hop| (hop.fee_msat, hop.pubkey))).rev();
685+
let reversed_hops_with_payer: Vec<(u64, PublicKey)> = core::iter::once((0u64, our_node_id)).chain(
686+
path.split_last().unwrap().1.iter().map(|hop| (hop.fee_msat, hop.pubkey))).rev().collect();
687687
let mut cumulative_msat = path.last().unwrap().fee_msat;
688688

689689
// Taking the reversed vector from above, we zip it with just the reversed hops list to
@@ -1555,6 +1555,32 @@ mod tests {
15551555
invoice_payer.handle_event(&event);
15561556
}
15571557

1558+
#[test]
1559+
fn correct_inflight_map_from_path() {
1560+
let event_handled = core::cell::RefCell::new(false);
1561+
let event_handler = |_: &_| { *event_handled.borrow_mut() = true; };
1562+
1563+
let final_value_msat = 128u64;
1564+
let payer = TestPayer::new()
1565+
.expect_send(Amount::ForInvoice(final_value_msat));
1566+
let router = TestMultiHopRouter {};
1567+
let scorer = RefCell::new(TestScorer::new());
1568+
let logger = TestLogger::new();
1569+
let invoice_payer =
1570+
InvoicePayer::new(&payer, router, &scorer, &logger, event_handler, Retry::Attempts(2));
1571+
1572+
let payment_preimage = PaymentPreimage([1; 32]);
1573+
let invoice = invoice(payment_preimage);
1574+
let payment_hash = PaymentHash(invoice.payment_hash().clone().into_inner());
1575+
1576+
let payment_id = Some(invoice_payer.pay_invoice(&invoice).unwrap());
1577+
1578+
let inflight_map = invoice_payer.create_inflight_map(&payment_hash);
1579+
assert_eq!(inflight_map.get(&(0u64, true)).unwrap().clone(), 158u64);
1580+
assert_eq!(inflight_map.get(&(1u64, true)).unwrap().clone(), 148u64);
1581+
assert_eq!(inflight_map.get(&(2u64, true)).unwrap().clone(), 128u64);
1582+
}
1583+
15581584
struct TestRouter;
15591585

15601586
impl TestRouter {
@@ -1620,6 +1646,55 @@ mod tests {
16201646
}
16211647
}
16221648

1649+
struct TestMultiHopRouter;
1650+
1651+
impl TestMultiHopRouter {
1652+
// Constructs the following route:
1653+
// Alice -(0,10)-> Bob -(0, 20)-> Charlie -(0, 130)-> Dina
1654+
fn route_for_value(final_value_msat: u64) -> Route {
1655+
Route {
1656+
paths: vec![vec![
1657+
RouteHop{
1658+
pubkey: PublicKey::from_slice(&hex::decode("02eec7245d6b7d2ccb30380bfbe2a3648cd7a942653f5aa340edcea1f283686619").unwrap()[..]).unwrap(),
1659+
channel_features: ChannelFeatures::empty(),
1660+
node_features: NodeFeatures::empty(),
1661+
short_channel_id: 0,
1662+
fee_msat: 10,
1663+
cltv_expiry_delta: 0
1664+
},
1665+
RouteHop{
1666+
pubkey: PublicKey::from_slice(&hex::decode("0324653eac434488002cc06bbfb7f10fe18991e35f9fe4302dbea6d2353dc0ab1c").unwrap()[..]).unwrap(),
1667+
channel_features: ChannelFeatures::empty(),
1668+
node_features: NodeFeatures::empty(),
1669+
short_channel_id: 1,
1670+
fee_msat: 20,
1671+
cltv_expiry_delta: 0
1672+
},
1673+
RouteHop{
1674+
pubkey: PublicKey::from_slice(&hex::decode("027f31ebc5462c1fdce1b737ecff52d37d75dea43ce11c74d25aa297165faa2007").unwrap()[..]).unwrap(),
1675+
channel_features: ChannelFeatures::empty(),
1676+
node_features: NodeFeatures::empty(),
1677+
short_channel_id: 2,
1678+
fee_msat: final_value_msat,
1679+
cltv_expiry_delta: 0
1680+
},
1681+
]],
1682+
payment_params: None,
1683+
}
1684+
}
1685+
}
1686+
1687+
impl Router for TestMultiHopRouter {
1688+
fn find_route<S: Score>(
1689+
&self, _payer: &PublicKey, route_params: &RouteParameters, _payment_hash: &PaymentHash,
1690+
_first_hops: Option<&[&ChannelDetails]>, _scorer: &S
1691+
) -> Result<Route, LightningError> {
1692+
Ok(Route {
1693+
payment_params: Some(route_params.payment_params.clone()), ..Self::route_for_value(route_params.final_value_msat)
1694+
})
1695+
}
1696+
}
1697+
16231698
struct TestScorer {
16241699
expectations: Option<VecDeque<TestResult>>,
16251700
}

0 commit comments

Comments
 (0)