Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fail request_refund_payment for unsupported chain #2917

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 9 additions & 2 deletions lightning/src/ln/channelmanager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7830,6 +7830,7 @@ where
/// Errors if:
/// - a duplicate `payment_id` is provided given the caveats in the aforementioned link,
/// - the provided parameters are invalid for the offer,
/// - the offer is for an unsupported chain, or
/// - the parameterized [`Router`] is unable to create a blinded reply path for the invoice
/// request.
///
Expand Down Expand Up @@ -7918,8 +7919,10 @@ where
///
/// # Errors
///
/// Errors if the parameterized [`Router`] is unable to create a blinded payment path or reply
/// path for the invoice.
/// Errors if:
/// - the refund is for an unsupported chain, or
/// - the parameterized [`Router`] is unable to create a blinded payment path or reply path for
/// the invoice.
///
/// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice
pub fn request_refund_payment(&self, refund: &Refund) -> Result<(), Bolt12SemanticError> {
Expand All @@ -7930,6 +7933,10 @@ where
let amount_msats = refund.amount_msats();
let relative_expiry = DEFAULT_RELATIVE_EXPIRY.as_secs() as u32;

if refund.chain() != self.chain_hash {
return Err(Bolt12SemanticError::UnsupportedChain);
}
jkczyz marked this conversation as resolved.
Show resolved Hide resolved

match self.create_inbound_payment(Some(amount_msats), relative_expiry, None) {
Ok((payment_hash, payment_secret)) => {
let payment_paths = self.create_blinded_payment_paths(amount_msats, payment_secret)
Expand Down
56 changes: 56 additions & 0 deletions lightning/src/ln/offers_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
//! Nodes without channels are disconnected and connected as needed to ensure that deterministic
//! blinded paths are used.

use bitcoin::network::constants::Network;
use core::time::Duration;
use crate::blinded_path::BlindedPath;
use crate::events::{Event, MessageSendEventsProvider, PaymentPurpose};
Expand Down Expand Up @@ -732,6 +733,61 @@ fn fails_creating_refund_without_blinded_paths() {
assert!(nodes[0].node.list_recent_payments().is_empty());
}

/// Fails creating an invoice request when the offer contains an unsupported chain.
#[test]
fn fails_creating_invoice_request_for_unsupported_chain() {
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 offer = alice.node
.create_offer_builder("coffee".to_string()).unwrap()
.clear_chains()
.chain(Network::Signet)
.build().unwrap();

let payment_id = PaymentId([1; 32]);
match bob.node.pay_for_offer(&offer, None, None, None, payment_id, Retry::Attempts(0), None) {
Ok(_) => panic!("Expected error"),
Err(e) => assert_eq!(e, Bolt12SemanticError::UnsupportedChain),
}
}

/// Fails requesting a payment when the refund contains an unsupported chain.
#[test]
fn fails_sending_invoice_with_unsupported_chain_for_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 absolute_expiry = Duration::from_secs(u64::MAX);
let payment_id = PaymentId([1; 32]);
let refund = bob.node
.create_refund_builder(
"refund".to_string(), 10_000_000, absolute_expiry, payment_id, Retry::Attempts(0), None
)
.unwrap()
.chain(Network::Signet)
.build().unwrap();

match alice.node.request_refund_payment(&refund) {
Ok(_) => panic!("Expected error"),
Err(e) => assert_eq!(e, Bolt12SemanticError::UnsupportedChain),
}
}

/// Fails creating an invoice request when a blinded reply path cannot be created without exposing
/// the node's id.
#[test]
Expand Down
6 changes: 6 additions & 0 deletions lightning/src/offers/offer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,12 @@ macro_rules! offer_builder_test_methods { (
$return_value
}

#[cfg_attr(c_bindings, allow(dead_code))]
pub(crate) fn clear_chains($($self_mut)* $self: $self_type) -> $return_type {
$self.offer.chains = None;
$return_value
}

#[cfg_attr(c_bindings, allow(dead_code))]
pub(crate) fn clear_paths($($self_mut)* $self: $self_type) -> $return_type {
$self.offer.paths = None;
Expand Down