Skip to content

Commit dfbf3ad

Browse files
committed
Introduce pay_for_bolt11_invoice tests
1 parent 6f09398 commit dfbf3ad

File tree

2 files changed

+126
-69
lines changed

2 files changed

+126
-69
lines changed

lightning/src/ln/bolt11_payment.rs

Lines changed: 0 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -157,60 +157,4 @@ mod tests {
157157
_ => panic!(),
158158
}
159159
}
160-
161-
#[test]
162-
fn payment_metadata_end_to_end() {
163-
use crate::events::Event;
164-
use crate::ln::channelmanager::{PaymentId, Retry};
165-
use crate::ln::functional_test_utils::*;
166-
use crate::ln::msgs::ChannelMessageHandler;
167-
168-
// Test that a payment metadata read from an invoice passed to `pay_invoice` makes it all
169-
// the way out through the `PaymentClaimable` event.
170-
let chanmon_cfgs = create_chanmon_cfgs(2);
171-
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
172-
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
173-
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
174-
create_announced_chan_between_nodes(&nodes, 0, 1);
175-
176-
let payment_metadata = vec![42, 43, 44, 45, 46, 47, 48, 49, 42];
177-
178-
let (payment_hash, payment_secret) =
179-
nodes[1].node.create_inbound_payment(None, 7200, None).unwrap();
180-
181-
let secp_ctx = Secp256k1::new();
182-
let node_secret = nodes[1].keys_manager.backing.get_node_secret_key();
183-
let timestamp = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap();
184-
let invoice = InvoiceBuilder::new(Currency::Bitcoin)
185-
.description("test".into())
186-
.payment_hash(Sha256::from_slice(&payment_hash.0).unwrap())
187-
.payment_secret(payment_secret)
188-
.duration_since_epoch(timestamp)
189-
.min_final_cltv_expiry_delta(144)
190-
.amount_milli_satoshis(50_000)
191-
.payment_metadata(payment_metadata.clone())
192-
.build_signed(|hash| secp_ctx.sign_ecdsa_recoverable(hash, &node_secret))
193-
.unwrap();
194-
195-
let (hash, onion, params) = payment_parameters_from_invoice(&invoice).unwrap();
196-
nodes[0]
197-
.node
198-
.send_payment(hash, onion, PaymentId(hash.0), params, Retry::Attempts(0))
199-
.unwrap();
200-
check_added_monitors(&nodes[0], 1);
201-
let send_event = SendEvent::from_node(&nodes[0]);
202-
nodes[1].node.handle_update_add_htlc(nodes[0].node.get_our_node_id(), &send_event.msgs[0]);
203-
commitment_signed_dance!(nodes[1], nodes[0], &send_event.commitment_msg, false);
204-
205-
expect_pending_htlcs_forwardable!(nodes[1]);
206-
207-
let mut events = nodes[1].node.get_and_clear_pending_events();
208-
assert_eq!(events.len(), 1);
209-
match events.pop().unwrap() {
210-
Event::PaymentClaimable { onion_fields, .. } => {
211-
assert_eq!(Some(payment_metadata), onion_fields.unwrap().payment_metadata);
212-
},
213-
_ => panic!("Unexpected event"),
214-
}
215-
}
216160
}

lightning/src/ln/invoice_utils.rs

Lines changed: 126 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -705,18 +705,21 @@ impl<'a, 'b, L: Deref> WithChannelDetails<'a, 'b, L> where L::Target: Logger {
705705
#[cfg(test)]
706706
mod test {
707707
use super::*;
708+
use std::time::SystemTime;
708709
use core::time::Duration;
709710
use lightning_invoice::{Currency, Description, Bolt11InvoiceDescriptionRef, SignOrCreationError, CreationError};
711+
use bitcoin::key::Secp256k1;
710712
use bitcoin::hashes::{Hash, sha256};
711713
use bitcoin::hashes::sha256::Hash as Sha256;
712714
use bitcoin::network::Network;
715+
use crate::ln::outbound_payment::Bolt11PaymentError;
713716
use crate::sign::PhantomKeysManager;
714-
use crate::events::{MessageSendEvent, MessageSendEventsProvider};
717+
use crate::events::{Event, MessageSendEvent, MessageSendEventsProvider};
715718
use crate::types::payment::{PaymentHash, PaymentPreimage};
716719
use crate::ln::channelmanager::{Bolt11InvoiceParameters, PhantomRouteHints, MIN_FINAL_CLTV_EXPIRY_DELTA, PaymentId, RecipientOnionFields, Retry};
717720
use crate::ln::functional_test_utils::*;
718721
use crate::ln::msgs::ChannelMessageHandler;
719-
use crate::routing::router::{PaymentParameters, RouteParameters};
722+
use crate::routing::router::{PaymentParameters, RouteParameters, RouteParametersConfig};
720723
use crate::util::test_utils;
721724
use crate::util::config::UserConfig;
722725
use std::collections::HashSet;
@@ -750,7 +753,7 @@ mod test {
750753

751754

752755
#[test]
753-
fn test_from_channelmanager() {
756+
fn create_and_pay_for_bolt11_invoice() {
754757
let chanmon_cfgs = create_chanmon_cfgs(2);
755758
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
756759
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
@@ -784,17 +787,10 @@ mod test {
784787
assert_eq!(invoice.route_hints()[0].0[0].htlc_minimum_msat, chan.inbound_htlc_minimum_msat);
785788
assert_eq!(invoice.route_hints()[0].0[0].htlc_maximum_msat, chan.inbound_htlc_maximum_msat);
786789

787-
let payment_params = PaymentParameters::from_node_id(invoice.recover_payee_pub_key(),
788-
invoice.min_final_cltv_expiry_delta() as u32)
789-
.with_bolt11_features(invoice.features().unwrap().clone()).unwrap()
790-
.with_route_hints(invoice.route_hints()).unwrap();
791-
let route_params = RouteParameters::from_payment_params_and_value(
792-
payment_params, invoice.amount_milli_satoshis().unwrap());
793790
let payment_event = {
794-
let payment_hash = PaymentHash(invoice.payment_hash().to_byte_array());
795-
nodes[0].node.send_payment(payment_hash,
796-
RecipientOnionFields::secret_only(*invoice.payment_secret()),
797-
PaymentId(payment_hash.0), route_params, Retry::Attempts(0)).unwrap();
791+
nodes[0].node.pay_for_bolt11_invoice(
792+
&invoice, PaymentId([42; 32]), None, RouteParametersConfig::default(),
793+
Retry::Attempts(0)).unwrap();
798794
check_added_monitors(&nodes[0], 1);
799795

800796
let mut events = nodes[0].node.get_and_clear_pending_msg_events();
@@ -808,6 +804,123 @@ mod test {
808804
assert_eq!(events.len(), 2);
809805
}
810806

807+
#[test]
808+
fn payment_metadata_end_to_end_for_invoice_with_amount() {
809+
// Test that a payment metadata read from an invoice passed to `pay_invoice` makes it all
810+
// the way out through the `PaymentClaimable` event.
811+
let chanmon_cfgs = create_chanmon_cfgs(2);
812+
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
813+
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
814+
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
815+
create_announced_chan_between_nodes(&nodes, 0, 1);
816+
817+
let payment_metadata = vec![42, 43, 44, 45, 46, 47, 48, 49, 42];
818+
819+
let (payment_hash, payment_secret) =
820+
nodes[1].node.create_inbound_payment(None, 7200, None).unwrap();
821+
822+
let secp_ctx = Secp256k1::new();
823+
let node_secret = nodes[1].keys_manager.backing.get_node_secret_key();
824+
let timestamp = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap();
825+
let invoice = InvoiceBuilder::new(Currency::Bitcoin)
826+
.description("test".into())
827+
.payment_hash(Sha256::from_slice(&payment_hash.0).unwrap())
828+
.payment_secret(payment_secret)
829+
.duration_since_epoch(timestamp)
830+
.min_final_cltv_expiry_delta(144)
831+
.amount_milli_satoshis(50_000)
832+
.payment_metadata(payment_metadata.clone())
833+
.build_signed(|hash| secp_ctx.sign_ecdsa_recoverable(hash, &node_secret))
834+
.unwrap();
835+
836+
match nodes[0].node.pay_for_bolt11_invoice(
837+
&invoice, PaymentId(payment_hash.0), Some(100),
838+
RouteParametersConfig::default(), Retry::Attempts(0)
839+
) {
840+
Err(Bolt11PaymentError::InvalidAmount) => (),
841+
_ => panic!("Unexpected result")
842+
};
843+
844+
nodes[0].node.pay_for_bolt11_invoice(
845+
&invoice, PaymentId(payment_hash.0), None,
846+
RouteParametersConfig::default(), Retry::Attempts(0)
847+
).unwrap();
848+
849+
check_added_monitors(&nodes[0], 1);
850+
let send_event = SendEvent::from_node(&nodes[0]);
851+
nodes[1].node.handle_update_add_htlc(nodes[0].node.get_our_node_id(), &send_event.msgs[0]);
852+
commitment_signed_dance!(nodes[1], nodes[0], &send_event.commitment_msg, false);
853+
854+
expect_pending_htlcs_forwardable!(nodes[1]);
855+
856+
let mut events = nodes[1].node.get_and_clear_pending_events();
857+
assert_eq!(events.len(), 1);
858+
match events.pop().unwrap() {
859+
Event::PaymentClaimable { onion_fields, .. } => {
860+
assert_eq!(Some(payment_metadata), onion_fields.unwrap().payment_metadata);
861+
},
862+
_ => panic!("Unexpected event"),
863+
}
864+
}
865+
866+
#[test]
867+
fn payment_metadata_end_to_end_for_invoice_with_no_amount() {
868+
// Test that a payment metadata read from an invoice passed to `pay_invoice` makes it all
869+
// the way out through the `PaymentClaimable` event.
870+
let chanmon_cfgs = create_chanmon_cfgs(2);
871+
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
872+
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
873+
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
874+
create_announced_chan_between_nodes(&nodes, 0, 1);
875+
876+
let payment_metadata = vec![42, 43, 44, 45, 46, 47, 48, 49, 42];
877+
878+
let (payment_hash, payment_secret) =
879+
nodes[1].node.create_inbound_payment(None, 7200, None).unwrap();
880+
881+
let secp_ctx = Secp256k1::new();
882+
let node_secret = nodes[1].keys_manager.backing.get_node_secret_key();
883+
let timestamp = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap();
884+
let invoice = InvoiceBuilder::new(Currency::Bitcoin)
885+
.description("test".into())
886+
.payment_hash(Sha256::from_slice(&payment_hash.0).unwrap())
887+
.payment_secret(payment_secret)
888+
.duration_since_epoch(timestamp)
889+
.min_final_cltv_expiry_delta(144)
890+
.payment_metadata(payment_metadata.clone())
891+
.build_signed(|hash| secp_ctx.sign_ecdsa_recoverable(hash, &node_secret))
892+
.unwrap();
893+
894+
match nodes[0].node.pay_for_bolt11_invoice(
895+
&invoice, PaymentId(payment_hash.0), None,
896+
RouteParametersConfig::default(), Retry::Attempts(0)
897+
) {
898+
Err(Bolt11PaymentError::InvalidAmount) => (),
899+
_ => panic!("Unexpected result")
900+
};
901+
902+
nodes[0].node.pay_for_bolt11_invoice(
903+
&invoice, PaymentId(payment_hash.0), Some(50_000),
904+
RouteParametersConfig::default(), Retry::Attempts(0)
905+
).unwrap();
906+
907+
check_added_monitors(&nodes[0], 1);
908+
let send_event = SendEvent::from_node(&nodes[0]);
909+
nodes[1].node.handle_update_add_htlc(nodes[0].node.get_our_node_id(), &send_event.msgs[0]);
910+
commitment_signed_dance!(nodes[1], nodes[0], &send_event.commitment_msg, false);
911+
912+
expect_pending_htlcs_forwardable!(nodes[1]);
913+
914+
let mut events = nodes[1].node.get_and_clear_pending_events();
915+
assert_eq!(events.len(), 1);
916+
match events.pop().unwrap() {
917+
Event::PaymentClaimable { onion_fields, .. } => {
918+
assert_eq!(Some(payment_metadata), onion_fields.unwrap().payment_metadata);
919+
},
920+
_ => panic!("Unexpected event"),
921+
}
922+
}
923+
811924
fn do_create_invoice_min_final_cltv_delta(with_custom_delta: bool) {
812925
let chanmon_cfgs = create_chanmon_cfgs(2);
813926
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);

0 commit comments

Comments
 (0)