+ let introduction_node_id = resolve_introduction_node(david, &path);
+ assert_eq!(introduction_node_id, nodes[4].node.get_our_node_id());
+ }
+}
+
+/// Checks that blinded paths are compact for short-lived offers.
+#[test]
+fn creates_short_lived_offer() {
+ let chanmon_cfgs = create_chanmon_cfgs(2);
+ let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
+ let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
+ let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
+
+ create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 10_000_000, 1_000_000_000);
+
+ let alice = &nodes[0];
+ let alice_id = alice.node.get_our_node_id();
+ let bob = &nodes[1];
+
+ let absolute_expiry = alice.node.duration_since_epoch() + MAX_SHORT_LIVED_RELATIVE_EXPIRY;
+ let offer = alice.node
+ .create_offer_builder(Some(absolute_expiry)).unwrap()
+ .build().unwrap();
+ assert_eq!(offer.absolute_expiry(), Some(absolute_expiry));
+ assert!(!offer.paths().is_empty());
+ for path in offer.paths() {
+ let introduction_node_id = resolve_introduction_node(bob, &path);
+ assert_eq!(introduction_node_id, alice_id);
+ assert!(matches!(path.introduction_node, IntroductionNode::DirectedShortChannelId(..)));
+ }
+}
+
+/// Checks that blinded paths are not compact for long-lived offers.
+#[test]
+fn creates_long_lived_offer() {
+ let chanmon_cfgs = create_chanmon_cfgs(2);
+ let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
+ let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
+ let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
+
+ create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 10_000_000, 1_000_000_000);
+
+ let alice = &nodes[0];
+ let alice_id = alice.node.get_our_node_id();
+
+ let absolute_expiry = alice.node.duration_since_epoch() + MAX_SHORT_LIVED_RELATIVE_EXPIRY
+ + Duration::from_secs(1);
+ let offer = alice.node
+ .create_offer_builder(Some(absolute_expiry))
+ .unwrap()
+ .build().unwrap();
+ assert_eq!(offer.absolute_expiry(), Some(absolute_expiry));
+ assert!(!offer.paths().is_empty());
+ for path in offer.paths() {
+ assert_eq!(path.introduction_node, IntroductionNode::NodeId(alice_id));
+ }
+
+ let offer = alice.node
+ .create_offer_builder(None).unwrap()
+ .build().unwrap();
+ assert_eq!(offer.absolute_expiry(), None);
+ assert!(!offer.paths().is_empty());
+ for path in offer.paths() {
+ assert_eq!(path.introduction_node, IntroductionNode::NodeId(alice_id));
+ }
+}
+
+/// Checks that blinded paths are compact for short-lived refunds.
+#[test]
+fn creates_short_lived_refund() {
+ let chanmon_cfgs = create_chanmon_cfgs(2);
+ let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
+ let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
+ let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
+
+ create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 10_000_000, 1_000_000_000);
+
+ let alice = &nodes[0];
+ let bob = &nodes[1];
+ let bob_id = bob.node.get_our_node_id();
+
+ let absolute_expiry = bob.node.duration_since_epoch() + MAX_SHORT_LIVED_RELATIVE_EXPIRY;
+ let payment_id = PaymentId([1; 32]);
+ let refund = bob.node
+ .create_refund_builder(10_000_000, absolute_expiry, payment_id, Retry::Attempts(0), None)
+ .unwrap()
+ .build().unwrap();
+ assert_eq!(refund.absolute_expiry(), Some(absolute_expiry));
+ assert!(!refund.paths().is_empty());
+ for path in refund.paths() {
+ let introduction_node_id = resolve_introduction_node(alice, &path);
+ assert_eq!(introduction_node_id, bob_id);
+ assert!(matches!(path.introduction_node, IntroductionNode::DirectedShortChannelId(..)));
+ }
+}
+
+/// Checks that blinded paths are not compact for long-lived refunds.
+#[test]
+fn creates_long_lived_refund() {
+ let chanmon_cfgs = create_chanmon_cfgs(2);
+ let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
+ let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
+ let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
+
+ create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 10_000_000, 1_000_000_000);
+
+ let bob = &nodes[1];
+ let bob_id = bob.node.get_our_node_id();
+
+ let absolute_expiry = bob.node.duration_since_epoch() + MAX_SHORT_LIVED_RELATIVE_EXPIRY
+ + Duration::from_secs(1);
+ let payment_id = PaymentId([1; 32]);
+ let refund = bob.node
+ .create_refund_builder(10_000_000, absolute_expiry, payment_id, Retry::Attempts(0), None)
+ .unwrap()
+ .build().unwrap();
+ assert_eq!(refund.absolute_expiry(), Some(absolute_expiry));
+ assert!(!refund.paths().is_empty());
+ for path in refund.paths() {
+ assert_eq!(path.introduction_node, IntroductionNode::NodeId(bob_id));