diff --git a/fuzz/src/chanmon_consistency.rs b/fuzz/src/chanmon_consistency.rs index 8472f8fa627..0d145c2cb7b 100644 --- a/fuzz/src/chanmon_consistency.rs +++ b/fuzz/src/chanmon_consistency.rs @@ -35,7 +35,7 @@ use lightning::chain::channelmonitor::{ChannelMonitor, MonitorEvent}; use lightning::chain::transaction::OutPoint; use lightning::chain::chaininterface::{BroadcasterInterface, ConfirmationTarget, FeeEstimator}; use lightning::chain::keysinterface::{KeyMaterial, KeysInterface, InMemorySigner, Recipient}; -use lightning::ln::{PaymentHash, PaymentPreimage, PaymentSecret}; +use lightning::ln::{PaymentHash, PaymentPreimage, PaymentSecret, RecipientInfo}; use lightning::ln::channelmanager::{ChainParameters, ChannelManager, PaymentSendFailure, ChannelManagerReadArgs}; use lightning::ln::channel::FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE; use lightning::ln::features::{ChannelFeatures, InitFeatures, NodeFeatures}; @@ -301,6 +301,7 @@ fn get_payment_secret_hash(dest: &ChanMan, payment_id: &mut u8) -> Option<(Payme fn send_payment(source: &ChanMan, dest: &ChanMan, dest_chan_id: u64, amt: u64, payment_id: &mut u8) -> bool { let (payment_secret, payment_hash) = if let Some((secret, hash)) = get_payment_secret_hash(dest, payment_id) { (secret, hash) } else { return true; }; + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret), payment_metadata: None }; if let Err(err) = source.send_payment(&Route { paths: vec![vec![RouteHop { pubkey: dest.get_our_node_id(), @@ -311,7 +312,7 @@ fn send_payment(source: &ChanMan, dest: &ChanMan, dest_chan_id: u64, amt: u64, p cltv_expiry_delta: 200, }]], payment_params: None, - }, payment_hash, &Some(payment_secret)) { + }, payment_hash, &recipient_info) { check_payment_err(err); false } else { true } @@ -320,6 +321,7 @@ fn send_payment(source: &ChanMan, dest: &ChanMan, dest_chan_id: u64, amt: u64, p fn send_hop_payment(source: &ChanMan, middle: &ChanMan, middle_chan_id: u64, dest: &ChanMan, dest_chan_id: u64, amt: u64, payment_id: &mut u8) -> bool { let (payment_secret, payment_hash) = if let Some((secret, hash)) = get_payment_secret_hash(dest, payment_id) { (secret, hash) } else { return true; }; + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret), payment_metadata: None }; if let Err(err) = source.send_payment(&Route { paths: vec![vec![RouteHop { pubkey: middle.get_our_node_id(), @@ -337,7 +339,7 @@ fn send_hop_payment(source: &ChanMan, middle: &ChanMan, middle_chan_id: u64, des cltv_expiry_delta: 200, }]], payment_params: None, - }, payment_hash, &Some(payment_secret)) { + }, payment_hash, &recipient_info) { check_payment_err(err); false } else { true } diff --git a/fuzz/src/full_stack.rs b/fuzz/src/full_stack.rs index 330124f8a89..eb1b298275b 100644 --- a/fuzz/src/full_stack.rs +++ b/fuzz/src/full_stack.rs @@ -498,7 +498,8 @@ pub fn do_test(data: &[u8], logger: &Arc) { let mut payment_secret = PaymentSecret([0; 32]); payment_secret.0[0..8].copy_from_slice(&be64_to_array(payments_sent)); payments_sent += 1; - match channelmanager.send_payment(&route, payment_hash, &Some(payment_secret)) { + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret), payment_metadata: None }; + match channelmanager.send_payment(&route, payment_hash, &recipient_info) { Ok(_) => {}, Err(_) => return, } diff --git a/lightning-invoice/src/de.rs b/lightning-invoice/src/de.rs index e9b639c1013..6e12eb942a6 100644 --- a/lightning-invoice/src/de.rs +++ b/lightning-invoice/src/de.rs @@ -459,6 +459,8 @@ impl FromBase32 for TaggedField { Ok(TaggedField::PrivateRoute(PrivateRoute::from_base32(field_data)?)), constants::TAG_PAYMENT_SECRET => Ok(TaggedField::PaymentSecret(PaymentSecret::from_base32(field_data)?)), + constants::TAG_PAYMENT_METADATA => + Ok(TaggedField::PaymentMetadata(Vec::::from_base32(field_data)?)), constants::TAG_FEATURES => Ok(TaggedField::Features(InvoiceFeatures::from_base32(field_data)?)), _ => { diff --git a/lightning-invoice/src/lib.rs b/lightning-invoice/src/lib.rs index 616ea99f0fe..8e999bb453e 100644 --- a/lightning-invoice/src/lib.rs +++ b/lightning-invoice/src/lib.rs @@ -205,10 +205,13 @@ pub const DEFAULT_MIN_FINAL_CLTV_EXPIRY: u64 = 18; /// * `D`: exactly one `Description` or `DescriptionHash` /// * `H`: exactly one `PaymentHash` /// * `T`: the timestamp is set +/// * `C`: the CLTV expiry is set +/// * `S`: the payment secret is set +/// * `M`: payment metadata is set /// /// (C-not exported) as we likely need to manually select one set of boolean type parameters. #[derive(Eq, PartialEq, Debug, Clone)] -pub struct InvoiceBuilder { +pub struct InvoiceBuilder { currency: Currency, amount: Option, si_prefix: Option, @@ -221,6 +224,7 @@ pub struct InvoiceBuilder, phantom_c: core::marker::PhantomData, phantom_s: core::marker::PhantomData, + phantom_m: core::marker::PhantomData, } /// Represents a syntactically and semantically correct lightning BOLT11 invoice. @@ -404,6 +408,7 @@ pub enum TaggedField { Fallback(Fallback), PrivateRoute(PrivateRoute), PaymentSecret(PaymentSecret), + PaymentMetadata(Vec), Features(InvoiceFeatures), } @@ -469,10 +474,11 @@ pub mod constants { pub const TAG_FALLBACK: u8 = 9; pub const TAG_PRIVATE_ROUTE: u8 = 3; pub const TAG_PAYMENT_SECRET: u8 = 16; + pub const TAG_PAYMENT_METADATA: u8 = 27; pub const TAG_FEATURES: u8 = 5; } -impl InvoiceBuilder { +impl InvoiceBuilder { /// Construct new, empty `InvoiceBuilder`. All necessary fields have to be filled first before /// `InvoiceBuilder::build(self)` becomes available. pub fn new(currrency: Currency) -> Self { @@ -489,14 +495,15 @@ impl InvoiceBuilder { phantom_t: core::marker::PhantomData, phantom_c: core::marker::PhantomData, phantom_s: core::marker::PhantomData, + phantom_m: core::marker::PhantomData, } } } -impl InvoiceBuilder { +impl InvoiceBuilder { /// Helper function to set the completeness flags. - fn set_flags(self) -> InvoiceBuilder { - InvoiceBuilder:: { + fn set_flags(self) -> InvoiceBuilder { + InvoiceBuilder:: { currency: self.currency, amount: self.amount, si_prefix: self.si_prefix, @@ -509,6 +516,7 @@ impl InvoiceBui phantom_t: core::marker::PhantomData, phantom_c: core::marker::PhantomData, phantom_s: core::marker::PhantomData, + phantom_m: core::marker::PhantomData, } } @@ -552,7 +560,7 @@ impl InvoiceBui } } -impl InvoiceBuilder { +impl InvoiceBuilder { /// Builds a `RawInvoice` if no `CreationError` occurred while construction any of the fields. pub fn build_raw(self) -> Result { @@ -585,9 +593,9 @@ impl InvoiceBuilder InvoiceBuilder { +impl InvoiceBuilder { /// Set the description. This function is only available if no description (hash) was set. - pub fn description(mut self, description: String) -> InvoiceBuilder { + pub fn description(mut self, description: String) -> InvoiceBuilder { match Description::new(description) { Ok(d) => self.tagged_fields.push(TaggedField::Description(d)), Err(e) => self.error = Some(e), @@ -596,24 +604,24 @@ impl InvoiceBuilder InvoiceBuilder { + pub fn description_hash(mut self, description_hash: sha256::Hash) -> InvoiceBuilder { self.tagged_fields.push(TaggedField::DescriptionHash(Sha256(description_hash))); self.set_flags() } } -impl InvoiceBuilder { +impl InvoiceBuilder { /// Set the payment hash. This function is only available if no payment hash was set. - pub fn payment_hash(mut self, hash: sha256::Hash) -> InvoiceBuilder { + pub fn payment_hash(mut self, hash: sha256::Hash) -> InvoiceBuilder { self.tagged_fields.push(TaggedField::PaymentHash(Sha256(hash))); self.set_flags() } } -impl InvoiceBuilder { +impl InvoiceBuilder { /// Sets the timestamp to a specific [`SystemTime`]. #[cfg(feature = "std")] - pub fn timestamp(mut self, time: SystemTime) -> InvoiceBuilder { + pub fn timestamp(mut self, time: SystemTime) -> InvoiceBuilder { match PositiveTimestamp::from_system_time(time) { Ok(t) => self.timestamp = Some(t), Err(e) => self.error = Some(e), @@ -623,7 +631,7 @@ impl InvoiceBuilder InvoiceBuilder { + pub fn duration_since_epoch(mut self, time: Duration) -> InvoiceBuilder { match PositiveTimestamp::from_duration_since_epoch(time) { Ok(t) => self.timestamp = Some(t), Err(e) => self.error = Some(e), @@ -634,34 +642,96 @@ impl InvoiceBuilder InvoiceBuilder { + pub fn current_timestamp(mut self) -> InvoiceBuilder { let now = PositiveTimestamp::from_system_time(SystemTime::now()); self.timestamp = Some(now.expect("for the foreseeable future this shouldn't happen")); self.set_flags() } } -impl InvoiceBuilder { +impl InvoiceBuilder { /// Sets `min_final_cltv_expiry`. - pub fn min_final_cltv_expiry(mut self, min_final_cltv_expiry: u64) -> InvoiceBuilder { + pub fn min_final_cltv_expiry(mut self, min_final_cltv_expiry: u64) -> InvoiceBuilder { self.tagged_fields.push(TaggedField::MinFinalCltvExpiry(MinFinalCltvExpiry(min_final_cltv_expiry))); self.set_flags() } } -impl InvoiceBuilder { +impl InvoiceBuilder { /// Sets the payment secret and relevant features. - pub fn payment_secret(mut self, payment_secret: PaymentSecret) -> InvoiceBuilder { - let mut features = InvoiceFeatures::empty(); - features.set_variable_length_onion_required(); - features.set_payment_secret_required(); + pub fn payment_secret(mut self, payment_secret: PaymentSecret) -> InvoiceBuilder { + let mut found_features = false; + self.tagged_fields = self.tagged_fields + .drain(..) + .map(|field| match field { + TaggedField::Features(mut f) => { + found_features = true; + f.set_variable_length_onion_required(); + f.set_payment_secret_required(); + TaggedField::Features(f) + }, + _ => field, + }) + .collect(); self.tagged_fields.push(TaggedField::PaymentSecret(payment_secret)); - self.tagged_fields.push(TaggedField::Features(features)); + if !found_features { + let mut features = InvoiceFeatures::empty(); + features.set_variable_length_onion_required(); + features.set_payment_secret_required(); + self.tagged_fields.push(TaggedField::Features(features)); + } + self.set_flags() + } +} + +impl InvoiceBuilder { + /// Sets the payment metadata. + /// + /// By default features are set to *optionally* allow the sender to include the payment metadata. + /// If you wish to require that the sender include the metadata (and fail to parse the invoice if + /// they don't support payment metadata fields), you need to call + /// [`InvoiceBuilder::require_payment_metadata`] after this. + pub fn payment_metadata(mut self, payment_metadata: Vec) -> InvoiceBuilder { + self.tagged_fields.push(TaggedField::PaymentMetadata(payment_metadata)); + let mut found_features = false; + self.tagged_fields = self.tagged_fields + .drain(..) + .map(|field| match field { + TaggedField::Features(mut f) => { + found_features = true; + f.set_payment_metadata_optional(); + TaggedField::Features(f) + }, + _ => field, + }) + .collect(); + if !found_features { + let mut features = InvoiceFeatures::empty(); + features.set_payment_metadata_optional(); + self.tagged_fields.push(TaggedField::Features(features)); + } self.set_flags() } } -impl InvoiceBuilder { +impl InvoiceBuilder { + /// Sets the payment secret and relevant features. + pub fn require_payment_metadata(mut self) -> InvoiceBuilder { + self.tagged_fields = self.tagged_fields + .drain(..) + .map(|field| match field { + TaggedField::Features(mut f) => { + f.set_payment_metadata_required(); + TaggedField::Features(f) + }, + _ => field, + }) + .collect(); + self + } +} + +impl InvoiceBuilder { /// Sets the `basic_mpp` feature as optional. pub fn basic_mpp(mut self) -> Self { for field in self.tagged_fields.iter_mut() { @@ -673,7 +743,7 @@ impl InvoiceBuilder { +impl InvoiceBuilder { /// Builds and signs an invoice using the supplied `sign_function`. This function MAY NOT fail /// and MUST produce a recoverable signature valid for the given hash and if applicable also for /// the included payee public key. @@ -926,6 +996,10 @@ impl RawInvoice { find_extract!(self.known_tagged_fields(), TaggedField::PaymentSecret(ref x), x) } + pub fn payment_metadata(&self) -> Option<&Vec> { + find_extract!(self.known_tagged_fields(), TaggedField::PaymentMetadata(ref x), x) + } + pub fn features(&self) -> Option<&InvoiceFeatures> { find_extract!(self.known_tagged_fields(), TaggedField::Features(ref x), x) } @@ -1188,6 +1262,11 @@ impl Invoice { self.signed_invoice.payment_secret().expect("was checked by constructor") } + /// Get the payment metadata blob if one was included in the invoice + pub fn payment_metadata(&self) -> Option<&Vec> { + self.signed_invoice.payment_metadata() + } + /// Get the invoice features if they were included in the invoice pub fn features(&self) -> Option<&InvoiceFeatures> { self.signed_invoice.features() @@ -1290,6 +1369,7 @@ impl TaggedField { TaggedField::Fallback(_) => constants::TAG_FALLBACK, TaggedField::PrivateRoute(_) => constants::TAG_PRIVATE_ROUTE, TaggedField::PaymentSecret(_) => constants::TAG_PAYMENT_SECRET, + TaggedField::PaymentMetadata(_) => constants::TAG_PAYMENT_METADATA, TaggedField::Features(_) => constants::TAG_FEATURES, }; @@ -1922,7 +2002,11 @@ mod test { ); assert_eq!(invoice.payment_hash(), &sha256::Hash::from_slice(&[21;32][..]).unwrap()); assert_eq!(invoice.payment_secret(), &PaymentSecret([42; 32])); - assert_eq!(invoice.features(), Some(&InvoiceFeatures::known())); + let mut features = InvoiceFeatures::empty(); + features.set_payment_secret_required(); + features.set_variable_length_onion_required(); + features.set_basic_mpp_optional(); + assert_eq!(invoice.features(), Some(&features)); let raw_invoice = builder.build_raw().unwrap(); assert_eq!(raw_invoice, *invoice.into_signed_raw().raw_invoice()) diff --git a/lightning-invoice/src/payment.rs b/lightning-invoice/src/payment.rs index 6b79a0123d9..170458e06b8 100644 --- a/lightning-invoice/src/payment.rs +++ b/lightning-invoice/src/payment.rs @@ -35,7 +35,7 @@ //! # #[cfg(feature = "no-std")] //! # extern crate core2; //! # -//! # use lightning::ln::{PaymentHash, PaymentPreimage, PaymentSecret}; +//! # use lightning::ln::{PaymentHash, PaymentPreimage, PaymentSecret, RecipientInfo}; //! # use lightning::ln::channelmanager::{ChannelDetails, PaymentId, PaymentSendFailure}; //! # use lightning::ln::msgs::LightningError; //! # use lightning::routing::scoring::Score; @@ -64,8 +64,7 @@ //! # impl Payer for FakePayer { //! # fn node_id(&self) -> PublicKey { unimplemented!() } //! # fn first_hops(&self) -> Vec { unimplemented!() } -//! # fn send_payment( -//! # &self, route: &Route, payment_hash: PaymentHash, payment_secret: &Option +//! # fn send_payment(&self, route: &Route, payment_hash: PaymentHash, recipient_info: &RecipientInfo //! # ) -> Result { unimplemented!() } //! # fn send_spontaneous_payment( //! # &self, route: &Route, payment_preimage: PaymentPreimage @@ -139,7 +138,7 @@ use bitcoin_hashes::Hash; use bitcoin_hashes::sha256::Hash as Sha256; use crate::prelude::*; -use lightning::ln::{PaymentHash, PaymentPreimage, PaymentSecret}; +use lightning::ln::{PaymentHash, PaymentPreimage, RecipientInfo}; use lightning::ln::channelmanager::{ChannelDetails, PaymentId, PaymentSendFailure}; use lightning::ln::msgs::LightningError; use lightning::routing::scoring::{LockableScore, Score}; @@ -187,7 +186,7 @@ pub trait Payer { /// Sends a payment over the Lightning Network using the given [`Route`]. fn send_payment( - &self, route: &Route, payment_hash: PaymentHash, payment_secret: &Option + &self, route: &Route, payment_hash: PaymentHash, recipient_info: &RecipientInfo ) -> Result; /// Sends a spontaneous payment over the Lightning Network using the given [`Route`]. @@ -309,7 +308,8 @@ where }; let send_payment = |route: &Route| { - self.payer.send_payment(route, payment_hash, &payment_secret) + let recipient_info = RecipientInfo { payment_secret, payment_metadata: invoice.payment_metadata().cloned() }; + self.payer.send_payment(route, payment_hash, &recipient_info) }; self.pay_internal(&route_params, payment_hash, send_payment) .map_err(|e| { self.payment_cache.lock().unwrap().remove(&payment_hash); e }) @@ -528,7 +528,7 @@ mod tests { use crate::{InvoiceBuilder, Currency}; use utils::create_invoice_from_channelmanager_and_duration_since_epoch; use bitcoin_hashes::sha256::Hash as Sha256; - use lightning::ln::PaymentPreimage; + use lightning::ln::{PaymentPreimage, PaymentSecret}; use lightning::ln::features::{ChannelFeatures, NodeFeatures, InitFeatures}; use lightning::ln::functional_test_utils::*; use lightning::ln::msgs::{ChannelMessageHandler, ErrorAction, LightningError}; @@ -1464,8 +1464,7 @@ mod tests { } fn send_payment( - &self, route: &Route, _payment_hash: PaymentHash, - _payment_secret: &Option + &self, route: &Route, _payment_hash: PaymentHash, _recipient_info: &RecipientInfo ) -> Result { self.check_value_msats(Amount::ForInvoice(route.get_total_amount())); self.check_attempts() diff --git a/lightning-invoice/src/ser.rs b/lightning-invoice/src/ser.rs index f921a5b0f69..24ec882f25a 100644 --- a/lightning-invoice/src/ser.rs +++ b/lightning-invoice/src/ser.rs @@ -446,6 +446,9 @@ impl ToBase32 for TaggedField { TaggedField::PaymentSecret(ref payment_secret) => { write_tagged_field(writer, constants::TAG_PAYMENT_SECRET, payment_secret) }, + TaggedField::PaymentMetadata(ref payment_metadata) => { + write_tagged_field(writer, constants::TAG_PAYMENT_METADATA, payment_metadata) + }, TaggedField::Features(ref features) => { write_tagged_field(writer, constants::TAG_FEATURES, features) }, diff --git a/lightning-invoice/src/utils.rs b/lightning-invoice/src/utils.rs index 9b3b41afbed..0070b359fc3 100644 --- a/lightning-invoice/src/utils.rs +++ b/lightning-invoice/src/utils.rs @@ -9,7 +9,7 @@ use bitcoin_hashes::{Hash, sha256}; use lightning::chain; use lightning::chain::chaininterface::{BroadcasterInterface, FeeEstimator}; use lightning::chain::keysinterface::{Recipient, KeysInterface, Sign}; -use lightning::ln::{PaymentHash, PaymentPreimage, PaymentSecret}; +use lightning::ln::{PaymentHash, PaymentPreimage, RecipientInfo}; use lightning::ln::channelmanager::{ChannelDetails, ChannelManager, PaymentId, PaymentSendFailure, MIN_FINAL_CLTV_EXPIRY}; #[cfg(feature = "std")] use lightning::ln::channelmanager::{PhantomRouteHints, MIN_CLTV_EXPIRY_DELTA}; @@ -487,9 +487,9 @@ where } fn send_payment( - &self, route: &Route, payment_hash: PaymentHash, payment_secret: &Option + &self, route: &Route, payment_hash: PaymentHash, recipient_info: &RecipientInfo ) -> Result { - self.send_payment(route, payment_hash, payment_secret) + self.send_payment(route, payment_hash, recipient_info) } fn send_spontaneous_payment( @@ -517,7 +517,7 @@ mod test { use bitcoin_hashes::Hash; use bitcoin_hashes::sha256::Hash as Sha256; use lightning::chain::keysinterface::PhantomKeysManager; - use lightning::ln::{PaymentPreimage, PaymentHash}; + use lightning::ln::{PaymentPreimage, PaymentHash, RecipientInfo}; use lightning::ln::channelmanager::{PhantomRouteHints, MIN_FINAL_CLTV_EXPIRY}; use lightning::ln::functional_test_utils::*; use lightning::ln::features::InitFeatures; @@ -578,7 +578,11 @@ mod test { let payment_event = { let mut payment_hash = PaymentHash([0; 32]); payment_hash.0.copy_from_slice(&invoice.payment_hash().as_ref()[0..32]); - nodes[0].node.send_payment(&route, payment_hash, &Some(invoice.payment_secret().clone())).unwrap(); + let recipient_info = RecipientInfo { + payment_secret: Some(invoice.payment_secret().clone()), + payment_metadata: None + }; + nodes[0].node.send_payment(&route, payment_hash, &recipient_info).unwrap(); let mut added_monitors = nodes[0].chain_monitor.added_monitors.lock().unwrap(); assert_eq!(added_monitors.len(), 1); added_monitors.clear(); @@ -853,7 +857,11 @@ mod test { let (payment_event, fwd_idx) = { let mut payment_hash = PaymentHash([0; 32]); payment_hash.0.copy_from_slice(&invoice.payment_hash().as_ref()[0..32]); - nodes[0].node.send_payment(&route, payment_hash, &Some(invoice.payment_secret().clone())).unwrap(); + let recipient_info = RecipientInfo { + payment_secret: Some(invoice.payment_secret().clone()), + payment_metadata: None + }; + nodes[0].node.send_payment(&route, payment_hash, &recipient_info).unwrap(); let mut added_monitors = nodes[0].chain_monitor.added_monitors.lock().unwrap(); assert_eq!(added_monitors.len(), 1); added_monitors.clear(); diff --git a/lightning-invoice/tests/ser_de.rs b/lightning-invoice/tests/ser_de.rs index 1d9c481513d..e2a373759f0 100644 --- a/lightning-invoice/tests/ser_de.rs +++ b/lightning-invoice/tests/ser_de.rs @@ -331,6 +331,56 @@ fn get_test_tuples() -> Vec<(String, SignedRawInvoice, bool, bool)> { true, // Different features than set in InvoiceBuilder true, // Some unknown fields ), + ( // Older version of the payment metadata test with a payment_pubkey set + "lnbc10m1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdp9wpshjmt9de6zqmt9w3skgct5vysxjmnnd9jx2mq8q8a04uqnp4q0n326hr8v9zprg8gsvezcch06gfaqqhde2aj730yg0durunfhv66sp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygs9q2gqqqqqqsgqy9gw6ymamd20jumvdgpfphkhp8fzhhdhycw36egcmla5vlrtrmhs9t7psfy3hkkdqzm9eq64fjg558znccds5nhsfmxveha5xe0dykgpspdha0".to_owned(), + InvoiceBuilder::new(Currency::Bitcoin) + .amount_milli_satoshis(1_000_000_000) + .duration_since_epoch(Duration::from_secs(1496314658)) + .payment_hash(sha256::Hash::from_hex( + "0001020304050607080900010203040506070809000102030405060708090102" + ).unwrap()) + .description("payment metadata inside".to_owned()) + .payment_metadata(hex::decode("01fafaf0").unwrap()) + .require_payment_metadata() + .payee_pub_key(PublicKey::from_slice(&hex::decode( + "03e7156ae33b0a208d0744199163177e909e80176e55d97a2f221ede0f934dd9ad" + ).unwrap()).unwrap()) + .payment_secret(PaymentSecret([0x11; 32])) + .build_raw() + .unwrap() + .sign(|_| { + RecoverableSignature::from_compact( + &hex::decode("2150ed137ddb54f9736c6a0290ded709d22bddb7261d1d6518dffb467c6b1eef02afc182491bdacd00b65c83554c914a1c53c61b0a4ef04eccccdfb4365ed259").unwrap(), + RecoveryId::from_i32(1).unwrap() + ) + }).unwrap(), + false, // Different features than set in InvoiceBuilder + true, // Some unknown fields + ), + ( + "lnbc10m1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdp9wpshjmt9de6zqmt9w3skgct5vysxjmnnd9jx2mq8q8a04uqsp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygs9q2gqqqqqqsgq7hf8he7ecf7n4ffphs6awl9t6676rrclv9ckg3d3ncn7fct63p6s365duk5wrk202cfy3aj5xnnp5gs3vrdvruverwwq7yzhkf5a3xqpd05wjc".to_owned(), + InvoiceBuilder::new(Currency::Bitcoin) + .amount_milli_satoshis(1_000_000_000) + .duration_since_epoch(Duration::from_secs(1496314658)) + .payment_hash(sha256::Hash::from_hex( + "0001020304050607080900010203040506070809000102030405060708090102" + ).unwrap()) + .description("payment metadata inside".to_owned()) + .payment_metadata(hex::decode("01fafaf0").unwrap()) + .require_payment_metadata() + .payment_secret(PaymentSecret([0x11; 32])) + .build_raw() + .unwrap() + .sign(|_| { + RecoverableSignature::from_compact( + &hex::decode("f5d27be7d9c27d3aa521bc35d77cabd6bda18f1f61716445b19e27e4e17a887508ea8de5a8e1d94f561248f65434e61a221160dac1f1991b9c0f1057b269d898").unwrap(), + RecoveryId::from_i32(1).unwrap() + ) + }).unwrap(), + false, // Different features than set in InvoiceBuilder + true, // Some unknown fields + ), + ] } diff --git a/lightning/src/chain/chainmonitor.rs b/lightning/src/chain/chainmonitor.rs index aae260e735b..a65145fbfcc 100644 --- a/lightning/src/chain/chainmonitor.rs +++ b/lightning/src/chain/chainmonitor.rs @@ -735,6 +735,7 @@ mod tests { use ln::features::InitFeatures; use ln::functional_test_utils::*; use ln::msgs::ChannelMessageHandler; + use ln::RecipientInfo; use util::errors::APIError; use util::events::{ClosureReason, MessageSendEvent, MessageSendEventsProvider}; use util::test_utils::{OnRegisterOutput, TxOutReference}; @@ -899,7 +900,11 @@ mod tests { // If the ChannelManager tries to update the channel, however, the ChainMonitor will pass // the update through to the ChannelMonitor which will refuse it (as the channel is closed). chanmon_cfgs[0].persister.set_update_ret(Ok(())); - unwrap_send_err!(nodes[0].node.send_payment(&route, second_payment_hash, &Some(second_payment_secret)), + let recipient_info = RecipientInfo { + payment_secret: Some(second_payment_secret), + payment_metadata: None, + }; + unwrap_send_err!(nodes[0].node.send_payment(&route, second_payment_hash, &recipient_info), true, APIError::ChannelUnavailable { ref err }, assert!(err.contains("ChannelMonitor storage failure"))); check_added_monitors!(nodes[0], 2); // After the failure we generate a close-channel monitor update diff --git a/lightning/src/chain/channelmonitor.rs b/lightning/src/chain/channelmonitor.rs index 738fff3837c..575d0bbeaa7 100644 --- a/lightning/src/chain/channelmonitor.rs +++ b/lightning/src/chain/channelmonitor.rs @@ -3345,7 +3345,7 @@ mod tests { use chain::package::{weight_offered_htlc, weight_received_htlc, weight_revoked_offered_htlc, weight_revoked_received_htlc, WEIGHT_REVOKED_OUTPUT}; use chain::transaction::OutPoint; use chain::keysinterface::InMemorySigner; - use ln::{PaymentPreimage, PaymentHash}; + use ln::{PaymentPreimage, PaymentHash, RecipientInfo}; use ln::chan_utils; use ln::chan_utils::{HTLCOutputInCommitment, ChannelPublicKeys, ChannelTransactionParameters, HolderCommitmentTransaction, CounterpartyChannelTransactionParameters}; use ln::channelmanager::PaymentSendFailure; @@ -3414,7 +3414,8 @@ mod tests { // If the ChannelManager tries to update the channel, however, the ChainMonitor will pass // the update through to the ChannelMonitor which will refuse it (as the channel is closed). let (route, payment_hash, _, payment_secret) = get_route_and_payment_hash!(nodes[1], nodes[0], 100_000); - unwrap_send_err!(nodes[1].node.send_payment(&route, payment_hash, &Some(payment_secret)), + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret), payment_metadata: None }; + unwrap_send_err!(nodes[1].node.send_payment(&route, payment_hash, &recipient_info), true, APIError::ChannelUnavailable { ref err }, assert!(err.contains("ChannelMonitor storage failure"))); check_added_monitors!(nodes[1], 2); // After the failure we generate a close-channel monitor update diff --git a/lightning/src/ln/chanmon_update_fail_tests.rs b/lightning/src/ln/chanmon_update_fail_tests.rs index 58fe30ba261..3380f186e19 100644 --- a/lightning/src/ln/chanmon_update_fail_tests.rs +++ b/lightning/src/ln/chanmon_update_fail_tests.rs @@ -19,6 +19,7 @@ use bitcoin::network::constants::Network; use chain::channelmonitor::{ANTI_REORG_DELAY, ChannelMonitor}; use chain::transaction::OutPoint; use chain::{ChannelMonitorUpdateErr, Listen, Watch}; +use ln::RecipientInfo; use ln::channelmanager::{ChannelManager, ChannelManagerReadArgs, RAACommitmentOrder, PaymentSendFailure}; use ln::channel::AnnouncementSigsState; use ln::features::InitFeatures; @@ -50,7 +51,8 @@ fn test_simple_monitor_permanent_update_fail() { let (route, payment_hash_1, _, payment_secret_1) = get_route_and_payment_hash!(&nodes[0], nodes[1], 1000000); chanmon_cfgs[0].persister.set_update_ret(Err(ChannelMonitorUpdateErr::PermanentFailure)); - unwrap_send_err!(nodes[0].node.send_payment(&route, payment_hash_1, &Some(payment_secret_1)), true, APIError::ChannelUnavailable {..}, {}); + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret_1), payment_metadata: None }; + unwrap_send_err!(nodes[0].node.send_payment(&route, payment_hash_1, &recipient_info), true, APIError::ChannelUnavailable {..}, {}); check_added_monitors!(nodes[0], 2); let events_1 = nodes[0].node.get_and_clear_pending_msg_events(); @@ -158,7 +160,8 @@ fn do_test_simple_monitor_temporary_update_fail(disconnect: bool) { chanmon_cfgs[0].persister.set_update_ret(Err(ChannelMonitorUpdateErr::TemporaryFailure)); { - unwrap_send_err!(nodes[0].node.send_payment(&route, payment_hash_1, &Some(payment_secret_1)), false, APIError::MonitorUpdateFailed, {}); + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret_1), payment_metadata: None }; + unwrap_send_err!(nodes[0].node.send_payment(&route, payment_hash_1, &recipient_info), false, APIError::MonitorUpdateFailed, {}); check_added_monitors!(nodes[0], 1); } @@ -209,7 +212,8 @@ fn do_test_simple_monitor_temporary_update_fail(disconnect: bool) { let (route, payment_hash_2, _, payment_secret_2) = get_route_and_payment_hash!(&nodes[0], nodes[1], 1000000); { chanmon_cfgs[0].persister.set_update_ret(Err(ChannelMonitorUpdateErr::TemporaryFailure)); - unwrap_send_err!(nodes[0].node.send_payment(&route, payment_hash_2, &Some(payment_secret_2)), false, APIError::MonitorUpdateFailed, {}); + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret_2), payment_metadata: None }; + unwrap_send_err!(nodes[0].node.send_payment(&route, payment_hash_2, &recipient_info), false, APIError::MonitorUpdateFailed, {}); check_added_monitors!(nodes[0], 1); } @@ -273,7 +277,8 @@ fn do_test_monitor_temporary_update_fail(disconnect_count: usize) { let (route, payment_hash_2, payment_preimage_2, payment_secret_2) = get_route_and_payment_hash!(nodes[0], nodes[1], 1000000); { chanmon_cfgs[0].persister.set_update_ret(Err(ChannelMonitorUpdateErr::TemporaryFailure)); - unwrap_send_err!(nodes[0].node.send_payment(&route, payment_hash_2, &Some(payment_secret_2)), false, APIError::MonitorUpdateFailed, {}); + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret_2), payment_metadata: None }; + unwrap_send_err!(nodes[0].node.send_payment(&route, payment_hash_2, &recipient_info), false, APIError::MonitorUpdateFailed, {}); check_added_monitors!(nodes[0], 1); } @@ -610,7 +615,8 @@ fn test_monitor_update_fail_cs() { let (route, our_payment_hash, payment_preimage, our_payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[1], 1000000); { - nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(our_payment_secret), payment_metadata: None }; + nodes[0].node.send_payment(&route, our_payment_hash, &recipient_info).unwrap(); check_added_monitors!(nodes[0], 1); } @@ -702,7 +708,8 @@ fn test_monitor_update_fail_no_rebroadcast() { let (route, our_payment_hash, payment_preimage_1, payment_secret_1) = get_route_and_payment_hash!(nodes[0], nodes[1], 1000000); { - nodes[0].node.send_payment(&route, our_payment_hash, &Some(payment_secret_1)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret_1), payment_metadata: None }; + nodes[0].node.send_payment(&route, our_payment_hash, &recipient_info).unwrap(); check_added_monitors!(nodes[0], 1); } @@ -750,14 +757,16 @@ fn test_monitor_update_raa_while_paused() { send_payment(&nodes[0], &[&nodes[1]], 5000000); let (route, our_payment_hash_1, payment_preimage_1, our_payment_secret_1) = get_route_and_payment_hash!(nodes[0], nodes[1], 1000000); { - nodes[0].node.send_payment(&route, our_payment_hash_1, &Some(our_payment_secret_1)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(our_payment_secret_1), payment_metadata: None }; + nodes[0].node.send_payment(&route, our_payment_hash_1, &recipient_info).unwrap(); check_added_monitors!(nodes[0], 1); } let send_event_1 = SendEvent::from_event(nodes[0].node.get_and_clear_pending_msg_events().remove(0)); let (route, our_payment_hash_2, payment_preimage_2, our_payment_secret_2) = get_route_and_payment_hash!(nodes[1], nodes[0], 1000000); { - nodes[1].node.send_payment(&route, our_payment_hash_2, &Some(our_payment_secret_2)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(our_payment_secret_2), payment_metadata: None }; + nodes[1].node.send_payment(&route, our_payment_hash_2, &recipient_info).unwrap(); check_added_monitors!(nodes[1], 1); } let send_event_2 = SendEvent::from_event(nodes[1].node.get_and_clear_pending_msg_events().remove(0)); @@ -846,7 +855,8 @@ fn do_test_monitor_update_fail_raa(test_ignore_second_cs: bool) { // holding cell. let (route, payment_hash_2, payment_preimage_2, payment_secret_2) = get_route_and_payment_hash!(nodes[0], nodes[2], 1000000); { - nodes[0].node.send_payment(&route, payment_hash_2, &Some(payment_secret_2)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret_2), payment_metadata: None }; + nodes[0].node.send_payment(&route, payment_hash_2, &recipient_info).unwrap(); check_added_monitors!(nodes[0], 1); } @@ -871,7 +881,8 @@ fn do_test_monitor_update_fail_raa(test_ignore_second_cs: bool) { // being paused waiting a monitor update. let (route, payment_hash_3, _, payment_secret_3) = get_route_and_payment_hash!(nodes[0], nodes[2], 1000000); { - nodes[0].node.send_payment(&route, payment_hash_3, &Some(payment_secret_3)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret_3), payment_metadata: None }; + nodes[0].node.send_payment(&route, payment_hash_3, &recipient_info).unwrap(); check_added_monitors!(nodes[0], 1); } @@ -890,7 +901,8 @@ fn do_test_monitor_update_fail_raa(test_ignore_second_cs: bool) { let (payment_preimage_4, payment_hash_4) = if test_ignore_second_cs { // Try to route another payment backwards from 2 to make sure 1 holds off on responding let (route, payment_hash_4, payment_preimage_4, payment_secret_4) = get_route_and_payment_hash!(nodes[2], nodes[0], 1000000); - nodes[2].node.send_payment(&route, payment_hash_4, &Some(payment_secret_4)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret_4), payment_metadata: None }; + nodes[2].node.send_payment(&route, payment_hash_4, &recipient_info).unwrap(); check_added_monitors!(nodes[2], 1); send_event = SendEvent::from_event(nodes[2].node.get_and_clear_pending_msg_events().remove(0)); @@ -1182,9 +1194,11 @@ fn raa_no_response_awaiting_raa_state() { // requires only an RAA response due to AwaitingRAA) we can deliver the RAA and require the CS // generation during RAA while in monitor-update-failed state. { - nodes[0].node.send_payment(&route, payment_hash_1, &Some(payment_secret_1)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret_1), payment_metadata: None }; + nodes[0].node.send_payment(&route, payment_hash_1, &recipient_info).unwrap(); check_added_monitors!(nodes[0], 1); - nodes[0].node.send_payment(&route, payment_hash_2, &Some(payment_secret_2)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret_2), payment_metadata: None }; + nodes[0].node.send_payment(&route, payment_hash_2, &recipient_info).unwrap(); check_added_monitors!(nodes[0], 0); } @@ -1234,7 +1248,8 @@ fn raa_no_response_awaiting_raa_state() { // chanmon_fail_consistency test required it to actually find the bug (by seeing out-of-sync // commitment transaction states) whereas here we can explicitly check for it. { - nodes[0].node.send_payment(&route, payment_hash_3, &Some(payment_secret_3)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret_3), payment_metadata: None }; + nodes[0].node.send_payment(&route, payment_hash_3, &recipient_info).unwrap(); check_added_monitors!(nodes[0], 0); assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty()); } @@ -1323,7 +1338,8 @@ fn claim_while_disconnected_monitor_update_fail() { // the monitor still failed let (route, payment_hash_2, payment_preimage_2, payment_secret_2) = get_route_and_payment_hash!(nodes[0], nodes[1], 1000000); { - nodes[0].node.send_payment(&route, payment_hash_2, &Some(payment_secret_2)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret_2), payment_metadata: None }; + nodes[0].node.send_payment(&route, payment_hash_2, &recipient_info).unwrap(); check_added_monitors!(nodes[0], 1); } @@ -1413,7 +1429,8 @@ fn monitor_failed_no_reestablish_response() { // on receipt). let (route, payment_hash_1, payment_preimage_1, payment_secret_1) = get_route_and_payment_hash!(nodes[0], nodes[1], 1000000); { - nodes[0].node.send_payment(&route, payment_hash_1, &Some(payment_secret_1)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret_1), payment_metadata: None }; + nodes[0].node.send_payment(&route, payment_hash_1, &recipient_info).unwrap(); check_added_monitors!(nodes[0], 1); } @@ -1486,7 +1503,8 @@ fn first_message_on_recv_ordering() { // can deliver it and fail the monitor update. let (route, payment_hash_1, payment_preimage_1, payment_secret_1) = get_route_and_payment_hash!(nodes[0], nodes[1], 1000000); { - nodes[0].node.send_payment(&route, payment_hash_1, &Some(payment_secret_1)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret_1), payment_metadata: None }; + nodes[0].node.send_payment(&route, payment_hash_1, &recipient_info).unwrap(); check_added_monitors!(nodes[0], 1); } @@ -1509,7 +1527,8 @@ fn first_message_on_recv_ordering() { // Route the second payment, generating an update_add_htlc/commitment_signed let (route, payment_hash_2, payment_preimage_2, payment_secret_2) = get_route_and_payment_hash!(nodes[0], nodes[1], 1000000); { - nodes[0].node.send_payment(&route, payment_hash_2, &Some(payment_secret_2)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret_2), payment_metadata: None }; + nodes[0].node.send_payment(&route, payment_hash_2, &recipient_info).unwrap(); check_added_monitors!(nodes[0], 1); } let mut events = nodes[0].node.get_and_clear_pending_msg_events(); @@ -1592,7 +1611,8 @@ fn test_monitor_update_fail_claim() { let (route, payment_hash_2, _, payment_secret_2) = get_route_and_payment_hash!(nodes[2], nodes[0], 1_000_000); { - nodes[2].node.send_payment(&route, payment_hash_2, &Some(payment_secret_2)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret_2), payment_metadata: None }; + nodes[2].node.send_payment(&route, payment_hash_2, &recipient_info).unwrap(); check_added_monitors!(nodes[2], 1); } @@ -1609,7 +1629,8 @@ fn test_monitor_update_fail_claim() { commitment_signed_dance!(nodes[1], nodes[2], payment_event.commitment_msg, false, true); let (_, payment_hash_3, payment_secret_3) = get_payment_preimage_hash!(nodes[0]); - nodes[2].node.send_payment(&route, payment_hash_3, &Some(payment_secret_3)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret_3), payment_metadata: None }; + nodes[2].node.send_payment(&route, payment_hash_3, &recipient_info).unwrap(); check_added_monitors!(nodes[2], 1); let mut events = nodes[2].node.get_and_clear_pending_msg_events(); @@ -1699,7 +1720,8 @@ fn test_monitor_update_on_pending_forwards() { let (route, payment_hash_2, payment_preimage_2, payment_secret_2) = get_route_and_payment_hash!(nodes[2], nodes[0], 1000000); { - nodes[2].node.send_payment(&route, payment_hash_2, &Some(payment_secret_2)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret_2), payment_metadata: None }; + nodes[2].node.send_payment(&route, payment_hash_2, &recipient_info).unwrap(); check_added_monitors!(nodes[2], 1); } @@ -1759,7 +1781,8 @@ fn monitor_update_claim_fail_no_response() { // Now start forwarding a second payment, skipping the last RAA so B is in AwaitingRAA let (route, payment_hash_2, payment_preimage_2, payment_secret_2) = get_route_and_payment_hash!(nodes[0], nodes[1], 1000000); { - nodes[0].node.send_payment(&route, payment_hash_2, &Some(payment_secret_2)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret_2), payment_metadata: None }; + nodes[0].node.send_payment(&route, payment_hash_2, &recipient_info).unwrap(); check_added_monitors!(nodes[0], 1); } @@ -1944,7 +1967,8 @@ fn test_path_paused_mpp() { // Now check that we get the right return value, indicating that the first path succeeded but // the second got a MonitorUpdateFailed err. This implies PaymentSendFailure::PartialFailure as // some paths succeeded, preventing retry. - if let Err(PaymentSendFailure::PartialFailure { results, ..}) = nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret)) { + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret), payment_metadata: None }; + if let Err(PaymentSendFailure::PartialFailure { results, ..}) = nodes[0].node.send_payment(&route, payment_hash, &recipient_info) { assert_eq!(results.len(), 2); if let Ok(()) = results[0] {} else { panic!(); } if let Err(APIError::MonitorUpdateFailed) = results[1] {} else { panic!(); } @@ -1989,7 +2013,8 @@ fn test_pending_update_fee_ack_on_reconnect() { send_payment(&nodes[0], &[&nodes[1]], 100_000_00); let (route, payment_hash, payment_preimage, payment_secret) = get_route_and_payment_hash!(&nodes[1], nodes[0], 1_000_000); - nodes[1].node.send_payment(&route, payment_hash, &Some(payment_secret)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret), payment_metadata: None }; + nodes[1].node.send_payment(&route, payment_hash, &recipient_info).unwrap(); check_added_monitors!(nodes[1], 1); let bs_initial_send_msgs = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id()); // bs_initial_send_msgs are not delivered until they are re-generated after reconnect @@ -2237,12 +2262,14 @@ fn do_channel_holding_cell_serialize(disconnect: bool, reload_a: bool) { // will not be freed from the holding cell. let (payment_preimage_0, _, _) = route_payment(&nodes[1], &[&nodes[0]], 100000); - nodes[0].node.send_payment(&route, payment_hash_1, &Some(payment_secret_1)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret_1), payment_metadata: None }; + nodes[0].node.send_payment(&route, payment_hash_1, &recipient_info).unwrap(); check_added_monitors!(nodes[0], 1); let send = SendEvent::from_node(&nodes[0]); assert_eq!(send.msgs.len(), 1); - nodes[0].node.send_payment(&route, payment_hash_2, &Some(payment_secret_2)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret_2), payment_metadata: None }; + nodes[0].node.send_payment(&route, payment_hash_2, &recipient_info).unwrap(); check_added_monitors!(nodes[0], 0); chanmon_cfgs[0].persister.set_update_ret(Err(ChannelMonitorUpdateErr::TemporaryFailure)); @@ -2432,7 +2459,8 @@ fn do_test_reconnect_dup_htlc_claims(htlc_status: HTLCStatusAtDupClaim, second_f // In order to get the HTLC claim into the holding cell at nodes[1], we need nodes[1] to be // awaiting a remote revoke_and_ack from nodes[0]. let (route, second_payment_hash, _, second_payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[1], 100_000); - nodes[0].node.send_payment(&route, second_payment_hash, &Some(second_payment_secret)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(second_payment_secret), payment_metadata: None }; + nodes[0].node.send_payment(&route, second_payment_hash, &recipient_info).unwrap(); check_added_monitors!(nodes[0], 1); let send_event = SendEvent::from_event(nodes[0].node.get_and_clear_pending_msg_events().remove(0)); diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs index 43032c51a3c..c4bb9866ac7 100644 --- a/lightning/src/ln/channel.rs +++ b/lightning/src/ln/channel.rs @@ -6566,6 +6566,7 @@ mod tests { first_hop_htlc_msat: 548, payment_id: PaymentId([42; 32]), payment_secret: None, + payment_metadata: None, payment_params: None, } }); diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index 2ce466c9ac6..e8a20ff9cf8 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -40,7 +40,7 @@ use chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, ChannelMonitor use chain::transaction::{OutPoint, TransactionData}; // Since this struct is returned in `list_channels` methods, expose it here in case users want to // construct one themselves. -use ln::{inbound_payment, PaymentHash, PaymentPreimage, PaymentSecret}; +use ln::{inbound_payment, PaymentHash, PaymentPreimage, PaymentSecret, RecipientInfo}; use ln::channel::{Channel, ChannelError, ChannelUpdateStatus, UpdateFulfillCommitFetch}; use ln::features::{ChannelTypeFeatures, InitFeatures, NodeFeatures}; use routing::router::{PaymentParameters, Route, RouteHop, RoutePath, RouteParameters}; @@ -212,6 +212,7 @@ pub(crate) enum HTLCSource { first_hop_htlc_msat: u64, payment_id: PaymentId, payment_secret: Option, + payment_metadata: Option>, payment_params: Option, }, } @@ -223,12 +224,13 @@ impl core::hash::Hash for HTLCSource { 0u8.hash(hasher); prev_hop_data.hash(hasher); }, - HTLCSource::OutboundRoute { path, session_priv, payment_id, payment_secret, first_hop_htlc_msat, payment_params } => { + HTLCSource::OutboundRoute { path, session_priv, payment_id, payment_secret, payment_metadata, first_hop_htlc_msat, payment_params } => { 1u8.hash(hasher); path.hash(hasher); session_priv[..].hash(hasher); payment_id.hash(hasher); payment_secret.hash(hasher); + payment_metadata.hash(hasher); first_hop_htlc_msat.hash(hasher); payment_params.hash(hasher); }, @@ -245,6 +247,7 @@ impl HTLCSource { first_hop_htlc_msat: 0, payment_id: PaymentId([2; 32]), payment_secret: None, + payment_metadata: None, payment_params: None, } } @@ -470,6 +473,7 @@ pub(crate) enum PendingOutboundPayment { session_privs: HashSet<[u8; 32]>, payment_hash: PaymentHash, payment_secret: Option, + payment_metadata: Option>, pending_amt_msat: u64, /// Used to track the fee paid. Only present if the payment was serialized on 0.0.103+. pending_fee_msat: Option, @@ -2331,7 +2335,7 @@ impl ChannelMana } // Only public for testing, this should otherwise never be called direcly - pub(crate) fn send_payment_along_path(&self, path: &Vec, payment_params: &Option, payment_hash: &PaymentHash, payment_secret: &Option, total_value: u64, cur_height: u32, payment_id: PaymentId, keysend_preimage: &Option) -> Result<(), APIError> { + pub(crate) fn send_payment_along_path(&self, path: &Vec, payment_params: &Option, payment_hash: &PaymentHash, payment_secret: &Option, payment_metadata: &Option>, total_value: u64, cur_height: u32, payment_id: PaymentId, keysend_preimage: &Option) -> Result<(), APIError> { log_trace!(self.logger, "Attempting to send payment for path with next hop {}", path.first().unwrap().short_channel_id); let prng_seed = self.keys_manager.get_secure_random_bytes(); let session_priv_bytes = self.keys_manager.get_secure_random_bytes(); @@ -2339,7 +2343,7 @@ impl ChannelMana let onion_keys = onion_utils::construct_onion_keys(&self.secp_ctx, &path, &session_priv) .map_err(|_| APIError::RouteError{err: "Pubkey along hop was maliciously selected"})?; - let (onion_payloads, htlc_msat, htlc_cltv) = onion_utils::build_onion_payloads(path, total_value, payment_secret, cur_height, keysend_preimage)?; + let (onion_payloads, htlc_msat, htlc_cltv) = onion_utils::build_onion_payloads(path, total_value, payment_secret, payment_metadata.clone(), cur_height, keysend_preimage)?; if onion_utils::route_size_insane(&onion_payloads) { return Err(APIError::RouteError{err: "Route size too large considering onion data"}); } @@ -2373,6 +2377,7 @@ impl ChannelMana pending_fee_msat: Some(0), payment_hash: *payment_hash, payment_secret: *payment_secret, + payment_metadata: payment_metadata.clone(), starting_block_height: self.best_block.read().unwrap().height(), total_msat: total_value, }); @@ -2396,6 +2401,7 @@ impl ChannelMana first_hop_htlc_msat: htlc_msat, payment_id, payment_secret: payment_secret.clone(), + payment_metadata: payment_metadata.clone(), payment_params: payment_params.clone(), }, onion_packet, &self.logger), channel_state, chan) @@ -2471,6 +2477,7 @@ impl ChannelMana /// irrevocably committed to on our end. In such a case, do NOT retry the payment with a /// different route unless you intend to pay twice! /// + /// Provide recipient_info to include payment_secret or payment_metadata, note that the /// payment_secret is unrelated to payment_hash (or PaymentPreimage) and exists to authenticate /// the sender to the recipient and prevent payment-probing (deanonymization) attacks. For /// newer nodes, it will be provided to you in the invoice. If you do not have one, the Route @@ -2479,11 +2486,11 @@ impl ChannelMana /// If a payment_secret *is* provided, we assume that the invoice had the payment_secret feature /// bit set (either as required or as available). If multiple paths are present in the Route, /// we assume the invoice had the basic_mpp feature set. - pub fn send_payment(&self, route: &Route, payment_hash: PaymentHash, payment_secret: &Option) -> Result { - self.send_payment_internal(route, payment_hash, payment_secret, None, None, None) + pub fn send_payment(&self, route: &Route, payment_hash: PaymentHash, recipient_info: &RecipientInfo) -> Result { + self.send_payment_internal(route, payment_hash, &recipient_info.payment_secret, &recipient_info.payment_metadata, None, None, None) } - fn send_payment_internal(&self, route: &Route, payment_hash: PaymentHash, payment_secret: &Option, keysend_preimage: Option, payment_id: Option, recv_value_msat: Option) -> Result { + fn send_payment_internal(&self, route: &Route, payment_hash: PaymentHash, payment_secret: &Option, payment_metadata: &Option>, keysend_preimage: Option, payment_id: Option, recv_value_msat: Option) -> Result { if route.paths.len() < 1 { return Err(PaymentSendFailure::ParameterError(APIError::RouteError{err: "There must be at least one path to send over"})); } @@ -2525,7 +2532,7 @@ impl ChannelMana let cur_height = self.best_block.read().unwrap().height() + 1; let mut results = Vec::new(); for path in route.paths.iter() { - results.push(self.send_payment_along_path(&path, &route.payment_params, &payment_hash, payment_secret, total_value, cur_height, payment_id, &keysend_preimage)); + results.push(self.send_payment_along_path(&path, &route.payment_params, &payment_hash, payment_secret, &payment_metadata, total_value, cur_height, payment_id, &keysend_preimage)); } let mut has_ok = false; let mut has_err = false; @@ -2588,12 +2595,12 @@ impl ChannelMana } } - let (total_msat, payment_hash, payment_secret) = { + let (total_msat, payment_hash, payment_secret, payment_metadata) = { let outbounds = self.pending_outbound_payments.lock().unwrap(); if let Some(payment) = outbounds.get(&payment_id) { match payment { PendingOutboundPayment::Retryable { - total_msat, payment_hash, payment_secret, pending_amt_msat, .. + total_msat, payment_hash, payment_secret, pending_amt_msat, payment_metadata, .. } => { let retry_amt_msat: u64 = route.paths.iter().map(|path| path.last().unwrap().fee_msat).sum(); if retry_amt_msat + *pending_amt_msat > *total_msat * (100 + RETRY_OVERFLOW_PERCENTAGE) / 100 { @@ -2601,7 +2608,7 @@ impl ChannelMana err: format!("retry_amt_msat of {} will put pending_amt_msat (currently: {}) more than 10% over total_payment_amt_msat of {}", retry_amt_msat, pending_amt_msat, total_msat).to_string() })) } - (*total_msat, *payment_hash, *payment_secret) + (*total_msat, *payment_hash, *payment_secret, payment_metadata.clone()) }, PendingOutboundPayment::Legacy { .. } => { return Err(PaymentSendFailure::ParameterError(APIError::APIMisuseError { @@ -2625,7 +2632,7 @@ impl ChannelMana })) } }; - return self.send_payment_internal(route, payment_hash, &payment_secret, None, Some(payment_id), Some(total_msat)).map(|_| ()) + return self.send_payment_internal(route, payment_hash, &payment_secret, &payment_metadata, None, Some(payment_id), Some(total_msat)).map(|_| ()) } /// Signals that no further retries for the given payment will occur. @@ -2679,7 +2686,7 @@ impl ChannelMana None => PaymentPreimage(self.keys_manager.get_secure_random_bytes()), }; let payment_hash = PaymentHash(Sha256::hash(&preimage.0).into_inner()); - match self.send_payment_internal(route, payment_hash, &None, Some(preimage), None, None) { + match self.send_payment_internal(route, payment_hash, &None, &None, Some(preimage), None, None) { Ok(payment_id) => Ok((payment_hash, payment_id)), Err(e) => Err(e) } @@ -3098,7 +3105,11 @@ impl ChannelMana prev_funding_outpoint } => { let (cltv_expiry, onion_payload, payment_data, phantom_shared_secret) = match routing { PendingHTLCRouting::Receive { payment_data, incoming_cltv_expiry, phantom_shared_secret } => { - let _legacy_hop_data = payment_data.clone(); + let _legacy_hop_data = msgs::FinalOnionHopData { + payment_secret: payment_data.payment_secret, + payment_metadata: None, // Object is only for serialization backwards compat + total_msat: payment_data.total_msat + }; (incoming_cltv_expiry, OnionPayload::Invoice { _legacy_hop_data }, Some(payment_data), phantom_shared_secret) }, PendingHTLCRouting::ReceiveKeysend { payment_preimage, incoming_cltv_expiry } => @@ -3177,6 +3188,7 @@ impl ChannelMana payment_hash, purpose: events::PaymentPurpose::InvoicePayment { payment_preimage: $payment_preimage, + payment_metadata: $payment_data.payment_metadata, payment_secret: $payment_data.payment_secret, }, amt: total_value, @@ -6147,6 +6159,7 @@ impl Readable for HTLCSource { let mut payment_id = None; let mut payment_secret = None; let mut payment_params = None; + let mut payment_metadata = None; read_tlv_fields!(reader, { (0, session_priv, required), (1, payment_id, option), @@ -6154,6 +6167,7 @@ impl Readable for HTLCSource { (3, payment_secret, option), (4, path, vec_type), (5, payment_params, option), + (7, payment_metadata, option), }); if payment_id.is_none() { // For backwards compat, if there was no payment_id written, use the session_priv bytes @@ -6167,6 +6181,7 @@ impl Readable for HTLCSource { payment_id: payment_id.unwrap(), payment_secret, payment_params, + payment_metadata, }) } 1 => Ok(HTLCSource::PreviousHopData(Readable::read(reader)?)), @@ -6178,7 +6193,7 @@ impl Readable for HTLCSource { impl Writeable for HTLCSource { fn write(&self, writer: &mut W) -> Result<(), ::io::Error> { match self { - HTLCSource::OutboundRoute { ref session_priv, ref first_hop_htlc_msat, ref path, payment_id, payment_secret, payment_params } => { + HTLCSource::OutboundRoute { ref session_priv, ref first_hop_htlc_msat, ref path, payment_id, payment_secret, ref payment_metadata, payment_params } => { 0u8.write(writer)?; let payment_id_opt = Some(payment_id); write_tlv_fields!(writer, { @@ -6188,6 +6203,7 @@ impl Writeable for HTLCSource { (3, payment_secret, option), (4, path, vec_type), (5, payment_params, option), + (7, payment_metadata, option), }); } HTLCSource::PreviousHopData(ref field) => { @@ -6242,6 +6258,7 @@ impl_writeable_tlv_based_enum_upgradable!(PendingOutboundPayment, (0, session_privs, required), (1, pending_fee_msat, option), (2, payment_hash, required), + (3, payment_metadata, option), (4, payment_secret, option), (6, total_msat, required), (8, pending_amt_msat, required), @@ -6704,7 +6721,7 @@ impl<'a, Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> for (_, monitor) in args.channel_monitors { if by_id.get(&monitor.get_funding_txo().0.to_channel_id()).is_none() { for (htlc_source, htlc) in monitor.get_pending_outbound_htlcs() { - if let HTLCSource::OutboundRoute { payment_id, session_priv, path, payment_secret, .. } = htlc_source { + if let HTLCSource::OutboundRoute { payment_id, session_priv, path, payment_secret, payment_metadata, .. } = htlc_source { if path.is_empty() { log_error!(args.logger, "Got an empty path for a pending payment"); return Err(DecodeError::InvalidValue); @@ -6724,6 +6741,7 @@ impl<'a, Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> session_privs: [session_priv_bytes].iter().map(|a| *a).collect(), payment_hash: htlc.payment_hash, payment_secret, + payment_metadata, pending_amt_msat: path_amt, pending_fee_msat: Some(path_fee), total_msat: path_amt, @@ -6844,7 +6862,7 @@ mod tests { use bitcoin::hashes::sha256::Hash as Sha256; use core::time::Duration; use core::sync::atomic::Ordering; - use ln::{PaymentPreimage, PaymentHash, PaymentSecret}; + use ln::{PaymentPreimage, PaymentHash, PaymentSecret, RecipientInfo}; use ln::channelmanager::{PaymentId, PaymentSendFailure}; use ln::channelmanager::inbound_payment; use ln::features::InitFeatures; @@ -6999,7 +7017,7 @@ mod tests { // Use the utility function send_payment_along_path to send the payment with MPP data which // indicates there are more HTLCs coming. let cur_height = CHAN_CONFIRM_DEPTH + 1; // route_payment calls send_payment, which adds 1 to the current height. So we do the same here to match. - nodes[0].node.send_payment_along_path(&route.paths[0], &route.payment_params, &our_payment_hash, &Some(payment_secret), 200_000, cur_height, payment_id, &None).unwrap(); + nodes[0].node.send_payment_along_path(&route.paths[0], &route.payment_params, &our_payment_hash, &Some(payment_secret), &None, 200_000, cur_height, payment_id, &None).unwrap(); check_added_monitors!(nodes[0], 1); let mut events = nodes[0].node.get_and_clear_pending_msg_events(); assert_eq!(events.len(), 1); @@ -7029,7 +7047,7 @@ mod tests { expect_payment_failed!(nodes[0], our_payment_hash, true); // Send the second half of the original MPP payment. - nodes[0].node.send_payment_along_path(&route.paths[0], &route.payment_params, &our_payment_hash, &Some(payment_secret), 200_000, cur_height, payment_id, &None).unwrap(); + nodes[0].node.send_payment_along_path(&route.paths[0], &route.payment_params, &our_payment_hash, &Some(payment_secret), &None, 200_000, cur_height, payment_id, &None).unwrap(); check_added_monitors!(nodes[0], 1); let mut events = nodes[0].node.get_and_clear_pending_msg_events(); assert_eq!(events.len(), 1); @@ -7166,7 +7184,8 @@ mod tests { // Next, attempt a regular payment and make sure it fails. let payment_secret = PaymentSecret([43; 32]); - nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret), payment_metadata: None }; + nodes[0].node.send_payment(&route, payment_hash, &recipient_info).unwrap(); check_added_monitors!(nodes[0], 1); let mut events = nodes[0].node.get_and_clear_pending_msg_events(); assert_eq!(events.len(), 1); @@ -7223,7 +7242,7 @@ mod tests { let test_preimage = PaymentPreimage([42; 32]); let mismatch_payment_hash = PaymentHash([43; 32]); - let _ = nodes[0].node.send_payment_internal(&route, mismatch_payment_hash, &None, Some(test_preimage), None, None).unwrap(); + let _ = nodes[0].node.send_payment_internal(&route, mismatch_payment_hash, &None, &None, Some(test_preimage), None, None).unwrap(); check_added_monitors!(nodes[0], 1); let updates = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id()); @@ -7268,7 +7287,7 @@ mod tests { let test_preimage = PaymentPreimage([42; 32]); let test_secret = PaymentSecret([43; 32]); let payment_hash = PaymentHash(Sha256::hash(&test_preimage.0).into_inner()); - let _ = nodes[0].node.send_payment_internal(&route, payment_hash, &Some(test_secret), Some(test_preimage), None, None).unwrap(); + let _ = nodes[0].node.send_payment_internal(&route, payment_hash, &Some(test_secret), &None, Some(test_preimage), None, None).unwrap(); check_added_monitors!(nodes[0], 1); let updates = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id()); @@ -7305,7 +7324,8 @@ mod tests { route.paths[1][0].short_channel_id = chan_2_id; route.paths[1][1].short_channel_id = chan_4_id; - match nodes[0].node.send_payment(&route, payment_hash, &None).unwrap_err() { + let recipient_info = RecipientInfo { payment_secret: None, payment_metadata: None }; + match nodes[0].node.send_payment(&route, payment_hash, &recipient_info).unwrap_err() { PaymentSendFailure::ParameterError(APIError::APIMisuseError { ref err }) => { assert!(regex::Regex::new(r"Payment secret is required for multi-path payments").unwrap().is_match(err)) }, _ => panic!("unexpected error") @@ -7323,6 +7343,7 @@ mod tests { let (_, payment_hash, payment_secret) = get_payment_preimage_hash!(&nodes[0]); let payment_data = msgs::FinalOnionHopData { payment_secret, + payment_metadata: None, total_msat: 100_000, }; @@ -7475,7 +7496,7 @@ pub mod bench { let payment_hash = PaymentHash(Sha256::hash(&payment_preimage.0[..]).into_inner()); let payment_secret = $node_b.create_inbound_payment_for_hash(payment_hash, None, 7200).unwrap(); - $node_a.send_payment(&route, payment_hash, &Some(payment_secret)).unwrap(); + $node_a.send_payment(&route, payment_hash, &Some(payment_secret), None).unwrap(); let payment_event = SendEvent::from_event($node_a.get_and_clear_pending_msg_events().pop().unwrap()); $node_b.handle_update_add_htlc(&$node_a.get_our_node_id(), &payment_event.msgs[0]); $node_b.handle_commitment_signed(&$node_a.get_our_node_id(), &payment_event.commitment_msg); diff --git a/lightning/src/ln/features.rs b/lightning/src/ln/features.rs index 2580874640e..dd6c329c2a2 100644 --- a/lightning/src/ln/features.rs +++ b/lightning/src/ln/features.rs @@ -192,7 +192,18 @@ mod sealed { VariableLengthOnion | PaymentSecret, // Byte 2 , + // Byte 3 + , + // Byte 4 + , + // Byte 5 + , + // Byte 6 + , ], + // Note that the optional feature bits set here are used to check if a bit is "known", but + // the `InvoiceBuilder` in lightning-invoice starts with `empty()` and does not set these + // bits unless the relevant data is included in the invoice. optional_features: [ // Byte 0 , @@ -200,6 +211,14 @@ mod sealed { , // Byte 2 BasicMPP, + // Byte 3 + , + // Byte 4 + , + // Byte 5 + , + // Byte 6 + PaymentMetadata, ], }); // This isn't a "real" feature context, and is only used in the channel_type field in an @@ -297,6 +316,7 @@ mod sealed { } flags[Self::BYTE_OFFSET] |= Self::REQUIRED_MASK; + flags[Self::BYTE_OFFSET] &= !Self::OPTIONAL_MASK; } /// Sets the feature's optional (odd) bit in the given flags. @@ -402,13 +422,15 @@ mod sealed { define_feature!(47, SCIDPrivacy, [InitContext, NodeContext, ChannelTypeContext], "Feature flags for only forwarding with SCID aliasing. Called `option_scid_alias` in the BOLTs", set_scid_privacy_optional, set_scid_privacy_required, supports_scid_privacy, requires_scid_privacy); - + define_feature!(49, PaymentMetadata, [InvoiceContext], + "Feature flags for payment metadata in invoices.", set_payment_metadata_optional, + set_payment_metadata_required, supports_payment_metadata, requires_payment_metadata); define_feature!(55, Keysend, [NodeContext], "Feature flags for keysend payments.", set_keysend_optional, set_keysend_required, supports_keysend, requires_keysend); #[cfg(test)] - define_feature!(123456789, UnknownFeature, [NodeContext, ChannelContext, InvoiceContext], + define_feature!(123456789, UnknownFeature, [NodeContext, ChannelContext, InitContext], "Feature flags for an unknown feature used in testing.", set_unknown_feature_optional, set_unknown_feature_required, supports_unknown_test_feature, requires_unknown_test_feature); } @@ -921,11 +943,11 @@ mod tests { #[test] fn convert_to_context_with_unknown_flags() { // Ensure the `from` context has fewer known feature bytes than the `to` context. - assert!(InvoiceFeatures::known().flags.len() < NodeFeatures::known().flags.len()); - let mut invoice_features = InvoiceFeatures::known(); - invoice_features.set_unknown_feature_optional(); - assert!(invoice_features.supports_unknown_bits()); - let node_features: NodeFeatures = invoice_features.to_context(); + assert!(InitFeatures::known().flags.len() < NodeFeatures::known().flags.len()); + let mut init_features = InitFeatures::known(); + init_features.set_unknown_feature_optional(); + assert!(init_features.supports_unknown_bits()); + let node_features: NodeFeatures = init_features.to_context(); assert!(!node_features.supports_unknown_bits()); } diff --git a/lightning/src/ln/functional_test_utils.rs b/lightning/src/ln/functional_test_utils.rs index b4807ea6886..a35b915d8a6 100644 --- a/lightning/src/ln/functional_test_utils.rs +++ b/lightning/src/ln/functional_test_utils.rs @@ -13,7 +13,7 @@ use chain::{BestBlock, Confirm, Listen, Watch, keysinterface::KeysInterface}; use chain::channelmonitor::ChannelMonitor; use chain::transaction::OutPoint; -use ln::{PaymentPreimage, PaymentHash, PaymentSecret}; +use ln::{PaymentPreimage, PaymentHash, PaymentSecret, RecipientInfo}; use ln::channelmanager::{ChainParameters, ChannelManager, ChannelManagerReadArgs, RAACommitmentOrder, PaymentSendFailure, PaymentId, MIN_CLTV_EXPIRY_DELTA}; use routing::network_graph::{NetGraphMsgHandler, NetworkGraph}; use routing::router::{PaymentParameters, Route, get_route}; @@ -1464,7 +1464,8 @@ macro_rules! expect_payment_failed_conditions { } pub fn send_along_route_with_secret<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, route: Route, expected_paths: &[&[&Node<'a, 'b, 'c>]], recv_value: u64, our_payment_hash: PaymentHash, our_payment_secret: PaymentSecret) -> PaymentId { - let payment_id = origin_node.node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(our_payment_secret), payment_metadata: None }; + let payment_id = origin_node.node.send_payment(&route, our_payment_hash, &recipient_info).unwrap(); check_added_monitors!(origin_node, expected_paths.len()); pass_along_route(origin_node, expected_paths, recv_value, our_payment_hash, our_payment_secret); payment_id @@ -1686,7 +1687,8 @@ pub fn route_over_limit<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_rou } let (_, our_payment_hash, our_payment_preimage) = get_payment_preimage_hash!(expected_route.last().unwrap()); - unwrap_send_err!(origin_node.node.send_payment(&route, our_payment_hash, &Some(our_payment_preimage)), true, APIError::ChannelUnavailable { ref err }, + let recipient_info = RecipientInfo { payment_secret: Some(our_payment_preimage), payment_metadata: None }; + unwrap_send_err!(origin_node.node.send_payment(&route, our_payment_hash, &recipient_info), true, APIError::ChannelUnavailable { ref err }, assert!(err.contains("Cannot send value that would put us over the max HTLC value in flight our peer will accept"))); } diff --git a/lightning/src/ln/functional_tests.rs b/lightning/src/ln/functional_tests.rs index aa68454063a..935e48dbf13 100644 --- a/lightning/src/ln/functional_tests.rs +++ b/lightning/src/ln/functional_tests.rs @@ -17,7 +17,7 @@ use chain::channelmonitor; use chain::channelmonitor::{ChannelMonitor, CLTV_CLAIM_BUFFER, LATENCY_GRACE_PERIOD_BLOCKS, ANTI_REORG_DELAY}; use chain::transaction::OutPoint; use chain::keysinterface::{BaseSign, KeysInterface}; -use ln::{PaymentPreimage, PaymentSecret, PaymentHash}; +use ln::{PaymentPreimage, PaymentSecret, PaymentHash, RecipientInfo}; use ln::channel::{commitment_tx_base_weight, COMMITMENT_TX_WEIGHT_PER_HTLC, CONCURRENT_INBOUND_HTLC_FEE_BUFFER, FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE, MIN_AFFORDABLE_HTLC_COUNT}; use ln::channelmanager::{ChannelManager, ChannelManagerReadArgs, PaymentId, RAACommitmentOrder, PaymentSendFailure, BREAKDOWN_TIMEOUT, MIN_CLTV_EXPIRY_DELTA, PAYMENT_EXPIRY_BLOCKS }; use ln::channel::{Channel, ChannelError}; @@ -246,7 +246,8 @@ fn test_async_inbound_update_fee() { // ...but before it's delivered, nodes[1] starts to send a payment back to nodes[0]... let (route, our_payment_hash, _, our_payment_secret) = get_route_and_payment_hash!(nodes[1], nodes[0], 40000); - nodes[1].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(our_payment_secret), payment_metadata: None }; + nodes[1].node.send_payment(&route, our_payment_hash, &recipient_info).unwrap(); check_added_monitors!(nodes[1], 1); let payment_event = { @@ -345,7 +346,8 @@ fn test_update_fee_unordered_raa() { // ...but before it's delivered, nodes[1] starts to send a payment back to nodes[0]... let (route, our_payment_hash, _, our_payment_secret) = get_route_and_payment_hash!(nodes[1], nodes[0], 40000); - nodes[1].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(our_payment_secret), payment_metadata: None }; + nodes[1].node.send_payment(&route, our_payment_hash, &recipient_info).unwrap(); check_added_monitors!(nodes[1], 1); let payment_event = { @@ -773,7 +775,8 @@ fn test_update_fee_with_fundee_update_add_htlc() { let (route, our_payment_hash, our_payment_preimage, our_payment_secret) = get_route_and_payment_hash!(nodes[1], nodes[0], 800000); // nothing happens since node[1] is in AwaitingRemoteRevoke - nodes[1].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(our_payment_secret), payment_metadata: None }; + nodes[1].node.send_payment(&route, our_payment_hash, &recipient_info).unwrap(); { let mut added_monitors = nodes[0].chain_monitor.added_monitors.lock().unwrap(); assert_eq!(added_monitors.len(), 0); @@ -1108,7 +1111,8 @@ fn holding_cell_htlc_counting() { let mut payments = Vec::new(); for _ in 0..::ln::channel::OUR_MAX_HTLCS { let (route, payment_hash, payment_preimage, payment_secret) = get_route_and_payment_hash!(nodes[1], nodes[2], 100000); - nodes[1].node.send_payment(&route, payment_hash, &Some(payment_secret)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret), payment_metadata: None }; + nodes[1].node.send_payment(&route, payment_hash, &recipient_info).unwrap(); payments.push((payment_preimage, payment_hash)); } check_added_monitors!(nodes[1], 1); @@ -1123,7 +1127,8 @@ fn holding_cell_htlc_counting() { // another HTLC. let (route, payment_hash_1, _, payment_secret_1) = get_route_and_payment_hash!(nodes[1], nodes[2], 100000); { - unwrap_send_err!(nodes[1].node.send_payment(&route, payment_hash_1, &Some(payment_secret_1)), true, APIError::ChannelUnavailable { ref err }, + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret_1), payment_metadata: None }; + unwrap_send_err!(nodes[1].node.send_payment(&route, payment_hash_1, &recipient_info), true, APIError::ChannelUnavailable { ref err }, assert!(regex::Regex::new(r"Cannot push more than their max accepted HTLCs \(\d+\)").unwrap().is_match(err))); assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty()); nodes[1].logger.assert_log_contains("lightning::ln::channelmanager".to_string(), "Cannot push more than their max accepted HTLCs".to_string(), 1); @@ -1132,7 +1137,8 @@ fn holding_cell_htlc_counting() { // This should also be true if we try to forward a payment. let (route, payment_hash_2, _, payment_secret_2) = get_route_and_payment_hash!(nodes[0], nodes[2], 100000); { - nodes[0].node.send_payment(&route, payment_hash_2, &Some(payment_secret_2)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret_2), payment_metadata: None }; + nodes[0].node.send_payment(&route, payment_hash_2, &recipient_info).unwrap(); check_added_monitors!(nodes[0], 1); } @@ -1338,7 +1344,8 @@ fn test_basic_channel_reserve() { let commit_tx_fee = 2 * commit_tx_fee_msat(get_feerate!(nodes[0], chan.2), 1 + 1, get_opt_anchors!(nodes[0], chan.2)); let max_can_send = 5000000 - channel_reserve - commit_tx_fee; let (route, our_payment_hash, _, our_payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[1], max_can_send + 1); - let err = nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).err().unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(our_payment_secret), payment_metadata: None }; + let err = nodes[0].node.send_payment(&route, our_payment_hash, &recipient_info).err().unwrap(); match err { PaymentSendFailure::AllFailedRetrySafe(ref fails) => { match &fails[0] { @@ -1371,7 +1378,7 @@ fn test_fee_spike_violation_fails_htlc() { let cur_height = nodes[1].node.best_block.read().unwrap().height() + 1; let onion_keys = onion_utils::construct_onion_keys(&secp_ctx, &route.paths[0], &session_priv).unwrap(); - let (onion_payloads, htlc_msat, htlc_cltv) = onion_utils::build_onion_payloads(&route.paths[0], 3460001, &Some(payment_secret), cur_height, &None).unwrap(); + let (onion_payloads, htlc_msat, htlc_cltv) = onion_utils::build_onion_payloads(&route.paths[0], 3460001, &Some(payment_secret), None, cur_height, &None).unwrap(); let onion_packet = onion_utils::construct_onion_packet(onion_payloads, onion_keys, [0; 32], &payment_hash); let msg = msgs::UpdateAddHTLC { channel_id: chan.2, @@ -1513,7 +1520,8 @@ fn test_chan_reserve_violation_outbound_htlc_inbound_chan() { // However one more HTLC should be significantly over the reserve amount and fail. let (route, our_payment_hash, _, our_payment_secret) = get_route_and_payment_hash!(nodes[1], nodes[0], 1_000_000); - unwrap_send_err!(nodes[1].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)), true, APIError::ChannelUnavailable { ref err }, + let recipient_info = RecipientInfo { payment_secret: Some(our_payment_secret), payment_metadata: None }; + unwrap_send_err!(nodes[1].node.send_payment(&route, our_payment_hash, &recipient_info), true, APIError::ChannelUnavailable { ref err }, assert_eq!(err, "Cannot send value that would put counterparty balance under holder-announced channel reserve value")); assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty()); nodes[1].logger.assert_log("lightning::ln::channelmanager".to_string(), "Cannot send value that would put counterparty balance under holder-announced channel reserve value".to_string(), 1); @@ -1548,7 +1556,7 @@ fn test_chan_reserve_violation_inbound_htlc_outbound_channel() { let session_priv = SecretKey::from_slice(&[42; 32]).unwrap(); let cur_height = nodes[1].node.best_block.read().unwrap().height() + 1; let onion_keys = onion_utils::construct_onion_keys(&secp_ctx, &route.paths[0], &session_priv).unwrap(); - let (onion_payloads, htlc_msat, htlc_cltv) = onion_utils::build_onion_payloads(&route.paths[0], 700_000, &Some(payment_secret), cur_height, &None).unwrap(); + let (onion_payloads, htlc_msat, htlc_cltv) = onion_utils::build_onion_payloads(&route.paths[0], 700_000, &Some(payment_secret), None, cur_height, &None).unwrap(); let onion_packet = onion_utils::construct_onion_packet(onion_payloads, onion_keys, [0; 32], &payment_hash); let msg = msgs::UpdateAddHTLC { channel_id: chan.2, @@ -1604,7 +1612,8 @@ fn test_chan_reserve_dust_inbound_htlcs_outbound_chan() { // One more than the dust amt should fail, however. let (route, our_payment_hash, _, our_payment_secret) = get_route_and_payment_hash!(nodes[1], nodes[0], dust_amt + 1); - unwrap_send_err!(nodes[1].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)), true, APIError::ChannelUnavailable { ref err }, + let recipient_info = RecipientInfo { payment_secret: Some(our_payment_secret), payment_metadata: None }; + unwrap_send_err!(nodes[1].node.send_payment(&route, our_payment_hash, &recipient_info), true, APIError::ChannelUnavailable { ref err }, assert_eq!(err, "Cannot send value that would put counterparty balance under holder-announced channel reserve value")); } @@ -1698,7 +1707,8 @@ fn test_chan_reserve_violation_inbound_htlc_inbound_chan() { // Add a pending HTLC. let (route_1, our_payment_hash_1, _, our_payment_secret_1) = get_route_and_payment_hash!(nodes[0], nodes[2], amt_msat_1); let payment_event_1 = { - nodes[0].node.send_payment(&route_1, our_payment_hash_1, &Some(our_payment_secret_1)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(our_payment_secret_1), payment_metadata: None }; + nodes[0].node.send_payment(&route_1, our_payment_hash_1, &recipient_info).unwrap(); check_added_monitors!(nodes[0], 1); let mut events = nodes[0].node.get_and_clear_pending_msg_events(); @@ -1718,7 +1728,7 @@ fn test_chan_reserve_violation_inbound_htlc_inbound_chan() { let session_priv = SecretKey::from_slice(&[42; 32]).unwrap(); let cur_height = nodes[0].node.best_block.read().unwrap().height() + 1; let onion_keys = onion_utils::construct_onion_keys(&secp_ctx, &route_2.paths[0], &session_priv).unwrap(); - let (onion_payloads, htlc_msat, htlc_cltv) = onion_utils::build_onion_payloads(&route_2.paths[0], recv_value_2, &None, cur_height, &None).unwrap(); + let (onion_payloads, htlc_msat, htlc_cltv) = onion_utils::build_onion_payloads(&route_2.paths[0], recv_value_2, &None, None, cur_height, &None).unwrap(); let onion_packet = onion_utils::construct_onion_packet(onion_payloads, onion_keys, [0; 32], &our_payment_hash_1); let msg = msgs::UpdateAddHTLC { channel_id: chan.2, @@ -1804,7 +1814,8 @@ fn test_channel_reserve_holding_cell_htlcs() { let (mut route, our_payment_hash, _, our_payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[2], recv_value_0); route.paths[0].last_mut().unwrap().fee_msat += 1; assert!(route.paths[0].iter().rev().skip(1).all(|h| h.fee_msat == feemsat)); - unwrap_send_err!(nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)), true, APIError::ChannelUnavailable { ref err }, + let recipient_info = RecipientInfo { payment_secret: Some(our_payment_secret), payment_metadata: None }; + unwrap_send_err!(nodes[0].node.send_payment(&route, our_payment_hash, &recipient_info), true, APIError::ChannelUnavailable { ref err }, assert!(regex::Regex::new(r"Cannot send value that would put us over the max HTLC value in flight our peer will accept \(\d+\)").unwrap().is_match(err))); assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty()); nodes[0].logger.assert_log_contains("lightning::ln::channelmanager".to_string(), "Cannot send value that would put us over the max HTLC value in flight our peer will accept".to_string(), 1); @@ -1855,7 +1866,8 @@ fn test_channel_reserve_holding_cell_htlcs() { let (route_1, our_payment_hash_1, our_payment_preimage_1, our_payment_secret_1) = get_route_and_payment_hash!(nodes[0], nodes[2], recv_value_1); let payment_event_1 = { - nodes[0].node.send_payment(&route_1, our_payment_hash_1, &Some(our_payment_secret_1)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(our_payment_secret_1), payment_metadata: None }; + nodes[0].node.send_payment(&route_1, our_payment_hash_1, &recipient_info).unwrap(); check_added_monitors!(nodes[0], 1); let mut events = nodes[0].node.get_and_clear_pending_msg_events(); @@ -1868,7 +1880,8 @@ fn test_channel_reserve_holding_cell_htlcs() { let recv_value_2 = stat01.value_to_self_msat - amt_msat_1 - stat01.channel_reserve_msat - total_fee_msat - commit_tx_fee_2_htlcs; { let (route, our_payment_hash, _, our_payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[2], recv_value_2 + 1); - unwrap_send_err!(nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)), true, APIError::ChannelUnavailable { ref err }, + let recipient_info = RecipientInfo { payment_secret: Some(our_payment_secret), payment_metadata: None }; + unwrap_send_err!(nodes[0].node.send_payment(&route, our_payment_hash, &recipient_info), true, APIError::ChannelUnavailable { ref err }, assert!(regex::Regex::new(r"Cannot send value that would put our balance under counterparty-announced channel reserve value \(\d+\)").unwrap().is_match(err))); assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty()); } @@ -1886,7 +1899,8 @@ fn test_channel_reserve_holding_cell_htlcs() { // now see if they go through on both sides let (route_21, our_payment_hash_21, our_payment_preimage_21, our_payment_secret_21) = get_route_and_payment_hash!(nodes[0], nodes[2], recv_value_21); // but this will stuck in the holding cell - nodes[0].node.send_payment(&route_21, our_payment_hash_21, &Some(our_payment_secret_21)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(our_payment_secret_21), payment_metadata: None }; + nodes[0].node.send_payment(&route_21, our_payment_hash_21, &recipient_info).unwrap(); check_added_monitors!(nodes[0], 0); let events = nodes[0].node.get_and_clear_pending_events(); assert_eq!(events.len(), 0); @@ -1894,7 +1908,8 @@ fn test_channel_reserve_holding_cell_htlcs() { // test with outbound holding cell amount > 0 { let (route, our_payment_hash, _, our_payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[2], recv_value_22+1); - unwrap_send_err!(nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)), true, APIError::ChannelUnavailable { ref err }, + let recipient_info = RecipientInfo { payment_secret: Some(our_payment_secret), payment_metadata: None }; + unwrap_send_err!(nodes[0].node.send_payment(&route, our_payment_hash, &recipient_info), true, APIError::ChannelUnavailable { ref err }, assert!(regex::Regex::new(r"Cannot send value that would put our balance under counterparty-announced channel reserve value \(\d+\)").unwrap().is_match(err))); assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty()); nodes[0].logger.assert_log_contains("lightning::ln::channelmanager".to_string(), "Cannot send value that would put our balance under counterparty-announced channel reserve value".to_string(), 2); @@ -1902,7 +1917,8 @@ fn test_channel_reserve_holding_cell_htlcs() { let (route_22, our_payment_hash_22, our_payment_preimage_22, our_payment_secret_22) = get_route_and_payment_hash!(nodes[0], nodes[2], recv_value_22); // this will also stuck in the holding cell - nodes[0].node.send_payment(&route_22, our_payment_hash_22, &Some(our_payment_secret_22)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(our_payment_secret_22), payment_metadata: None }; + nodes[0].node.send_payment(&route_22, our_payment_hash_22, &recipient_info).unwrap(); check_added_monitors!(nodes[0], 0); assert!(nodes[0].node.get_and_clear_pending_events().is_empty()); assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty()); @@ -2037,7 +2053,8 @@ fn channel_reserve_in_flight_removes() { // Start routing the third HTLC (this is just used to get everyone in the right state). let (route, payment_hash_3, payment_preimage_3, payment_secret_3) = get_route_and_payment_hash!(nodes[0], nodes[1], 100000); let send_1 = { - nodes[0].node.send_payment(&route, payment_hash_3, &Some(payment_secret_3)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret_3), payment_metadata: None }; + nodes[0].node.send_payment(&route, payment_hash_3, &recipient_info).unwrap(); check_added_monitors!(nodes[0], 1); let mut events = nodes[0].node.get_and_clear_pending_msg_events(); assert_eq!(events.len(), 1); @@ -2109,7 +2126,8 @@ fn channel_reserve_in_flight_removes() { // to A to ensure that A doesn't count the almost-removed HTLC in update_add processing. let (route, payment_hash_4, payment_preimage_4, payment_secret_4) = get_route_and_payment_hash!(nodes[1], nodes[0], 10000); let send_2 = { - nodes[1].node.send_payment(&route, payment_hash_4, &Some(payment_secret_4)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret_4), payment_metadata: None }; + nodes[1].node.send_payment(&route, payment_hash_4, &recipient_info).unwrap(); check_added_monitors!(nodes[1], 1); let mut events = nodes[1].node.get_and_clear_pending_msg_events(); assert_eq!(events.len(), 1); @@ -3132,7 +3150,8 @@ fn do_test_commitment_revoked_fail_backward_exhaustive(deliver_bs_raa: bool, use // Add a fourth HTLC, this one will get sequestered away in nodes[1]'s holding cell waiting // on nodes[2]'s RAA. let (route, fourth_payment_hash, _, fourth_payment_secret) = get_route_and_payment_hash!(nodes[1], nodes[2], 1000000); - nodes[1].node.send_payment(&route, fourth_payment_hash, &Some(fourth_payment_secret)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(fourth_payment_secret), payment_metadata: None }; + nodes[1].node.send_payment(&route, fourth_payment_hash, &recipient_info).unwrap(); assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty()); assert!(nodes[1].node.get_and_clear_pending_events().is_empty()); check_added_monitors!(nodes[1], 0); @@ -3289,7 +3308,8 @@ fn fail_backward_pending_htlc_upon_channel_failure() { // Alice -> Bob: Route a payment but without Bob sending revoke_and_ack. { let (route, payment_hash, _, payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[1], 50_000); - nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret), payment_metadata: None }; + nodes[0].node.send_payment(&route, payment_hash, &recipient_info).unwrap(); check_added_monitors!(nodes[0], 1); let payment_event = { @@ -3304,7 +3324,8 @@ fn fail_backward_pending_htlc_upon_channel_failure() { // Alice -> Bob: Route another payment but now Alice waits for Bob's earlier revoke_and_ack. let (route, failed_payment_hash, _, failed_payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[1], 50_000); { - nodes[0].node.send_payment(&route, failed_payment_hash, &Some(failed_payment_secret)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(failed_payment_secret), payment_metadata: None }; + nodes[0].node.send_payment(&route, failed_payment_hash, &recipient_info).unwrap(); check_added_monitors!(nodes[0], 0); assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty()); @@ -3317,7 +3338,7 @@ fn fail_backward_pending_htlc_upon_channel_failure() { let secp_ctx = Secp256k1::new(); let session_priv = SecretKey::from_slice(&[42; 32]).unwrap(); let current_height = nodes[1].node.best_block.read().unwrap().height() + 1; - let (onion_payloads, _amount_msat, cltv_expiry) = onion_utils::build_onion_payloads(&route.paths[0], 50_000, &Some(payment_secret), current_height, &None).unwrap(); + let (onion_payloads, _amount_msat, cltv_expiry) = onion_utils::build_onion_payloads(&route.paths[0], 50_000, &Some(payment_secret), None, current_height, &None).unwrap(); let onion_keys = onion_utils::construct_onion_keys(&secp_ctx, &route.paths[0], &session_priv).unwrap(); let onion_routing_packet = onion_utils::construct_onion_packet(onion_payloads, onion_keys, [0; 32], &payment_hash); @@ -3397,7 +3418,8 @@ fn test_force_close_fail_back() { let (route, our_payment_hash, our_payment_preimage, our_payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[2], 1000000); let mut payment_event = { - nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(our_payment_secret), payment_metadata: None }; + nodes[0].node.send_payment(&route, our_payment_hash, &recipient_info).unwrap(); check_added_monitors!(nodes[0], 1); let mut events = nodes[0].node.get_and_clear_pending_msg_events(); @@ -3613,7 +3635,8 @@ fn do_test_drop_messages_peer_disconnect(messages_delivered: u8, simulate_broken let (route, payment_hash_1, payment_preimage_1, payment_secret_1) = get_route_and_payment_hash!(nodes[0], nodes[1], 1000000); let payment_event = { - nodes[0].node.send_payment(&route, payment_hash_1, &Some(payment_secret_1)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret_1), payment_metadata: None }; + nodes[0].node.send_payment(&route, payment_hash_1, &recipient_info).unwrap(); check_added_monitors!(nodes[0], 1); let mut events = nodes[0].node.get_and_clear_pending_msg_events(); @@ -4056,7 +4079,8 @@ fn test_drop_messages_peer_disconnect_dual_htlc() { // Now try to send a second payment which will fail to send let (route, payment_hash_2, payment_preimage_2, payment_secret_2) = get_route_and_payment_hash!(nodes[0], nodes[1], 1000000); - nodes[0].node.send_payment(&route, payment_hash_2, &Some(payment_secret_2)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret_2), payment_metadata: None }; + nodes[0].node.send_payment(&route, payment_hash_2, &recipient_info).unwrap(); check_added_monitors!(nodes[0], 1); let events_1 = nodes[0].node.get_and_clear_pending_msg_events(); @@ -4207,7 +4231,7 @@ fn do_test_htlc_timeout(send_partial_mpp: bool) { // indicates there are more HTLCs coming. let cur_height = CHAN_CONFIRM_DEPTH + 1; // route_payment calls send_payment, which adds 1 to the current height. So we do the same here to match. let payment_id = PaymentId([42; 32]); - nodes[0].node.send_payment_along_path(&route.paths[0], &route.payment_params, &our_payment_hash, &Some(payment_secret), 200000, cur_height, payment_id, &None).unwrap(); + nodes[0].node.send_payment_along_path(&route.paths[0], &route.payment_params, &our_payment_hash, &Some(payment_secret), &None, 200000, cur_height, payment_id, &None).unwrap(); check_added_monitors!(nodes[0], 1); let mut events = nodes[0].node.get_and_clear_pending_msg_events(); assert_eq!(events.len(), 1); @@ -4272,7 +4296,8 @@ fn do_test_holding_cell_htlc_add_timeouts(forwarded_htlc: bool) { // Route a first payment to get the 1 -> 2 channel in awaiting_raa... let (route, first_payment_hash, _, first_payment_secret) = get_route_and_payment_hash!(nodes[1], nodes[2], 100000); { - nodes[1].node.send_payment(&route, first_payment_hash, &Some(first_payment_secret)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(first_payment_secret), payment_metadata: None }; + nodes[1].node.send_payment(&route, first_payment_hash, &recipient_info).unwrap(); } assert_eq!(nodes[1].node.get_and_clear_pending_msg_events().len(), 1); check_added_monitors!(nodes[1], 1); @@ -4280,7 +4305,8 @@ fn do_test_holding_cell_htlc_add_timeouts(forwarded_htlc: bool) { // Now attempt to route a second payment, which should be placed in the holding cell let sending_node = if forwarded_htlc { &nodes[0] } else { &nodes[1] }; let (route, second_payment_hash, _, second_payment_secret) = get_route_and_payment_hash!(sending_node, nodes[2], 100000); - sending_node.node.send_payment(&route, second_payment_hash, &Some(second_payment_secret)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(second_payment_secret), payment_metadata: None }; + sending_node.node.send_payment(&route, second_payment_hash, &recipient_info).unwrap(); if forwarded_htlc { check_added_monitors!(nodes[0], 1); let payment_event = SendEvent::from_event(nodes[0].node.get_and_clear_pending_msg_events().remove(0)); @@ -5905,7 +5931,8 @@ fn do_htlc_claim_current_remote_commitment_only(use_dust: bool) { let chan = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known()); let (route, payment_hash, _, payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[1], if use_dust { 50000 } else { 3000000 }); - nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret), payment_metadata: None }; + nodes[0].node.send_payment(&route, payment_hash, &recipient_info).unwrap(); check_added_monitors!(nodes[0], 1); let _as_update = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id()); @@ -6151,7 +6178,8 @@ fn test_fail_holding_cell_htlc_upon_free() { let (route, our_payment_hash, _, our_payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[1], max_can_send); // Send a payment which passes reserve checks but gets stuck in the holding cell. - let our_payment_id = nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(our_payment_secret), payment_metadata: None }; + let our_payment_id = nodes[0].node.send_payment(&route, our_payment_hash, &recipient_info).unwrap(); chan_stat = get_channel_value_stat!(nodes[0], chan.2); assert_eq!(chan_stat.holding_cell_outbound_amount_msat, max_can_send); @@ -6233,10 +6261,12 @@ fn test_free_and_fail_holding_cell_htlcs() { let (route_2, payment_hash_2, _, payment_secret_2) = get_route_and_payment_hash!(nodes[0], nodes[1], amt_2); // Send 2 payments which pass reserve checks but get stuck in the holding cell. - nodes[0].node.send_payment(&route_1, payment_hash_1, &Some(payment_secret_1)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret_1), payment_metadata: None }; + nodes[0].node.send_payment(&route_1, payment_hash_1, &recipient_info).unwrap(); chan_stat = get_channel_value_stat!(nodes[0], chan.2); assert_eq!(chan_stat.holding_cell_outbound_amount_msat, amt_1); - let payment_id_2 = nodes[0].node.send_payment(&route_2, payment_hash_2, &Some(payment_secret_2)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret_2), payment_metadata: None }; + let payment_id_2 = nodes[0].node.send_payment(&route_2, payment_hash_2, &recipient_info).unwrap(); chan_stat = get_channel_value_stat!(nodes[0], chan.2); assert_eq!(chan_stat.holding_cell_outbound_amount_msat, amt_1 + amt_2); @@ -6358,7 +6388,8 @@ fn test_fail_holding_cell_htlc_upon_free_multihop() { let max_can_send = 5000000 - channel_reserve - 2*commit_tx_fee_msat(feerate, 1 + 1, opt_anchors) - total_routing_fee_msat; let (route, our_payment_hash, _, our_payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[2], max_can_send); let payment_event = { - nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(our_payment_secret), payment_metadata: None }; + nodes[0].node.send_payment(&route, our_payment_hash, &recipient_info).unwrap(); check_added_monitors!(nodes[0], 1); let mut events = nodes[0].node.get_and_clear_pending_msg_events(); @@ -6460,7 +6491,8 @@ fn test_update_add_htlc_bolt2_sender_value_below_minimum_msat() { let (mut route, our_payment_hash, _, our_payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[1], 100000); route.paths[0][0].fee_msat = 100; - unwrap_send_err!(nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)), true, APIError::ChannelUnavailable { ref err }, + let recipient_info = RecipientInfo { payment_secret: Some(our_payment_secret), payment_metadata: None }; + unwrap_send_err!(nodes[0].node.send_payment(&route, our_payment_hash, &recipient_info), true, APIError::ChannelUnavailable { ref err }, assert!(regex::Regex::new(r"Cannot send less than their minimum HTLC value \(\d+\)").unwrap().is_match(err))); assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty()); nodes[0].logger.assert_log_contains("lightning::ln::channelmanager".to_string(), "Cannot send less than their minimum HTLC value".to_string(), 1); @@ -6477,7 +6509,8 @@ fn test_update_add_htlc_bolt2_sender_zero_value_msat() { let (mut route, our_payment_hash, _, our_payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[1], 100000); route.paths[0][0].fee_msat = 0; - unwrap_send_err!(nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)), true, APIError::ChannelUnavailable { ref err }, + let recipient_info = RecipientInfo { payment_secret: Some(our_payment_secret), payment_metadata: None }; + unwrap_send_err!(nodes[0].node.send_payment(&route, our_payment_hash, &recipient_info), true, APIError::ChannelUnavailable { ref err }, assert_eq!(err, "Cannot send 0-msat HTLC")); assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty()); @@ -6494,7 +6527,8 @@ fn test_update_add_htlc_bolt2_receiver_zero_value_msat() { let _chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 95000000, InitFeatures::known(), InitFeatures::known()); let (route, our_payment_hash, _, our_payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[1], 100000); - nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(our_payment_secret), payment_metadata: None }; + nodes[0].node.send_payment(&route, our_payment_hash, &recipient_info).unwrap(); check_added_monitors!(nodes[0], 1); let mut updates = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id()); updates.update_add_htlcs[0].amount_msat = 0; @@ -6520,7 +6554,8 @@ fn test_update_add_htlc_bolt2_sender_cltv_expiry_too_high() { .with_features(InvoiceFeatures::known()); let (mut route, our_payment_hash, _, our_payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[1], payment_params, 100000000, 0); route.paths[0].last_mut().unwrap().cltv_expiry_delta = 500000001; - unwrap_send_err!(nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)), true, APIError::RouteError { ref err }, + let recipient_info = RecipientInfo { payment_secret: Some(our_payment_secret), payment_metadata: None }; + unwrap_send_err!(nodes[0].node.send_payment(&route, our_payment_hash, &recipient_info), true, APIError::RouteError { ref err }, assert_eq!(err, &"Channel CLTV overflowed?")); } @@ -6539,7 +6574,8 @@ fn test_update_add_htlc_bolt2_sender_exceed_max_htlc_num_and_htlc_id_increment() for i in 0..max_accepted_htlcs { let (route, our_payment_hash, _, our_payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[1], 100000); let payment_event = { - nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(our_payment_secret), payment_metadata: None }; + nodes[0].node.send_payment(&route, our_payment_hash, &recipient_info).unwrap(); check_added_monitors!(nodes[0], 1); let mut events = nodes[0].node.get_and_clear_pending_msg_events(); @@ -6559,7 +6595,8 @@ fn test_update_add_htlc_bolt2_sender_exceed_max_htlc_num_and_htlc_id_increment() expect_payment_received!(nodes[1], our_payment_hash, our_payment_secret, 100000); } let (route, our_payment_hash, _, our_payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[1], 100000); - unwrap_send_err!(nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)), true, APIError::ChannelUnavailable { ref err }, + let recipient_info = RecipientInfo { payment_secret: Some(our_payment_secret), payment_metadata: None }; + unwrap_send_err!(nodes[0].node.send_payment(&route, our_payment_hash, &recipient_info), true, APIError::ChannelUnavailable { ref err }, assert!(regex::Regex::new(r"Cannot push more than their max accepted HTLCs \(\d+\)").unwrap().is_match(err))); assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty()); @@ -6583,7 +6620,8 @@ fn test_update_add_htlc_bolt2_sender_exceed_max_htlc_value_in_flight() { // Manually create a route over our max in flight (which our router normally automatically // limits us to. route.paths[0][0].fee_msat = max_in_flight + 1; - unwrap_send_err!(nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)), true, APIError::ChannelUnavailable { ref err }, + let recipient_info = RecipientInfo { payment_secret: Some(our_payment_secret), payment_metadata: None }; + unwrap_send_err!(nodes[0].node.send_payment(&route, our_payment_hash, &recipient_info), true, APIError::ChannelUnavailable { ref err }, assert!(regex::Regex::new(r"Cannot send value that would put us over the max HTLC value in flight our peer will accept \(\d+\)").unwrap().is_match(err))); assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty()); @@ -6609,7 +6647,8 @@ fn test_update_add_htlc_bolt2_receiver_check_amount_received_more_than_min() { } let (route, our_payment_hash, _, our_payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[1], htlc_minimum_msat); - nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(our_payment_secret), payment_metadata: None }; + nodes[0].node.send_payment(&route, our_payment_hash, &recipient_info).unwrap(); check_added_monitors!(nodes[0], 1); let mut updates = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id()); updates.update_add_htlcs[0].amount_msat = htlc_minimum_msat-1; @@ -6639,7 +6678,8 @@ fn test_update_add_htlc_bolt2_receiver_sender_can_afford_amount_sent() { let max_can_send = 5000000 - channel_reserve - commit_tx_fee_outbound; let (route, our_payment_hash, _, our_payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[1], max_can_send); - nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(our_payment_secret), payment_metadata: None }; + nodes[0].node.send_payment(&route, our_payment_hash, &recipient_info).unwrap(); check_added_monitors!(nodes[0], 1); let mut updates = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id()); @@ -6670,7 +6710,7 @@ fn test_update_add_htlc_bolt2_receiver_check_max_htlc_limit() { let session_priv = SecretKey::from_slice(&[42; 32]).unwrap(); let cur_height = nodes[0].node.best_block.read().unwrap().height() + 1; let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::signing_only(), &route.paths[0], &session_priv).unwrap(); - let (onion_payloads, _htlc_msat, htlc_cltv) = onion_utils::build_onion_payloads(&route.paths[0], 3999999, &Some(our_payment_secret), cur_height, &None).unwrap(); + let (onion_payloads, _htlc_msat, htlc_cltv) = onion_utils::build_onion_payloads(&route.paths[0], 3999999, &Some(our_payment_secret), None, cur_height, &None).unwrap(); let onion_packet = onion_utils::construct_onion_packet(onion_payloads, onion_keys, [0; 32], &our_payment_hash); let mut msg = msgs::UpdateAddHTLC { @@ -6706,7 +6746,8 @@ fn test_update_add_htlc_bolt2_receiver_check_max_in_flight_msat() { let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1000000, 1000000, InitFeatures::known(), InitFeatures::known()); let (route, our_payment_hash, _, our_payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[1], 1000000); - nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(our_payment_secret), payment_metadata: None }; + nodes[0].node.send_payment(&route, our_payment_hash, &recipient_info).unwrap(); check_added_monitors!(nodes[0], 1); let mut updates = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id()); updates.update_add_htlcs[0].amount_msat = get_channel_value_stat!(nodes[1], chan.2).counterparty_max_htlc_value_in_flight_msat + 1; @@ -6729,7 +6770,8 @@ fn test_update_add_htlc_bolt2_receiver_check_cltv_expiry() { create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 95000000, InitFeatures::known(), InitFeatures::known()); let (route, our_payment_hash, _, our_payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[1], 1000000); - nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(our_payment_secret), payment_metadata: None }; + nodes[0].node.send_payment(&route, our_payment_hash, &recipient_info).unwrap(); check_added_monitors!(nodes[0], 1); let mut updates = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id()); updates.update_add_htlcs[0].cltv_expiry = 500000000; @@ -6754,7 +6796,8 @@ fn test_update_add_htlc_bolt2_receiver_check_repeated_id_ignore() { create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known()); let (route, our_payment_hash, _, our_payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[1], 1000000); - nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(our_payment_secret), payment_metadata: None }; + nodes[0].node.send_payment(&route, our_payment_hash, &recipient_info).unwrap(); check_added_monitors!(nodes[0], 1); let updates = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id()); nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &updates.update_add_htlcs[0]); @@ -6799,7 +6842,8 @@ fn test_update_fulfill_htlc_bolt2_update_fulfill_htlc_before_commitment() { let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs); let chan = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known()); let (route, our_payment_hash, our_payment_preimage, our_payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[1], 1000000); - nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(our_payment_secret), payment_metadata: None }; + nodes[0].node.send_payment(&route, our_payment_hash, &recipient_info).unwrap(); check_added_monitors!(nodes[0], 1); let updates = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id()); @@ -6831,7 +6875,8 @@ fn test_update_fulfill_htlc_bolt2_update_fail_htlc_before_commitment() { let chan = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known()); let (route, our_payment_hash, _, our_payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[1], 1000000); - nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(our_payment_secret), payment_metadata: None }; + nodes[0].node.send_payment(&route, our_payment_hash, &recipient_info).unwrap(); check_added_monitors!(nodes[0], 1); let updates = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id()); nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &updates.update_add_htlcs[0]); @@ -6862,7 +6907,8 @@ fn test_update_fulfill_htlc_bolt2_update_fail_malformed_htlc_before_commitment() let chan = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known()); let (route, our_payment_hash, _, our_payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[1], 1000000); - nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(our_payment_secret), payment_metadata: None }; + nodes[0].node.send_payment(&route, our_payment_hash, &recipient_info).unwrap(); check_added_monitors!(nodes[0], 1); let updates = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id()); nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &updates.update_add_htlcs[0]); @@ -6977,7 +7023,8 @@ fn test_update_fulfill_htlc_bolt2_missing_badonion_bit_for_malformed_htlc_messag create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1000000, 1000000, InitFeatures::known(), InitFeatures::known()); let (route, our_payment_hash, _, our_payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[1], 1000000); - nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(our_payment_secret), payment_metadata: None }; + nodes[0].node.send_payment(&route, our_payment_hash, &recipient_info).unwrap(); check_added_monitors!(nodes[0], 1); let mut updates = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id()); @@ -7028,7 +7075,8 @@ fn test_update_fulfill_htlc_bolt2_after_malformed_htlc_message_must_forward_upda //First hop let mut payment_event = { - nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(our_payment_secret), payment_metadata: None }; + nodes[0].node.send_payment(&route, our_payment_hash, &recipient_info).unwrap(); check_added_monitors!(nodes[0], 1); let mut events = nodes[0].node.get_and_clear_pending_msg_events(); assert_eq!(events.len(), 1); @@ -7507,7 +7555,8 @@ fn test_check_htlc_underpaying() { let route = get_route(&nodes[0].node.get_our_node_id(), &payment_params, &nodes[0].network_graph.read_only(), None, 10_000, TEST_FINAL_CLTV, nodes[0].logger, &scorer, &random_seed_bytes).unwrap(); let (_, our_payment_hash, _) = get_payment_preimage_hash!(nodes[0]); let our_payment_secret = nodes[1].node.create_inbound_payment_for_hash(our_payment_hash, Some(100_000), 7200).unwrap(); - nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(our_payment_secret), payment_metadata: None }; + nodes[0].node.send_payment(&route, our_payment_hash, &recipient_info).unwrap(); check_added_monitors!(nodes[0], 1); let mut events = nodes[0].node.get_and_clear_pending_msg_events(); @@ -8132,7 +8181,8 @@ fn test_pending_claimed_htlc_no_balance_underflow() { route.payment_params = None; // This is all wrong, but unnecessary route.paths[0][0].pubkey = nodes[0].node.get_our_node_id(); let (_, payment_hash_2, payment_secret_2) = get_payment_preimage_hash!(nodes[0]); - nodes[1].node.send_payment(&route, payment_hash_2, &Some(payment_secret_2)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret_2), payment_metadata: None }; + nodes[1].node.send_payment(&route, payment_hash_2, &recipient_info).unwrap(); assert_eq!(nodes[1].node.list_channels()[0].balance_msat, 1_000_000); } @@ -8515,7 +8565,8 @@ fn test_preimage_storage() { { let (payment_hash, payment_secret) = nodes[1].node.create_inbound_payment(Some(100_000), 7200).unwrap(); let (route, _, _, _) = get_route_and_payment_hash!(nodes[0], nodes[1], 100_000); - nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret), payment_metadata: None }; + nodes[0].node.send_payment(&route, payment_hash, &recipient_info).unwrap(); check_added_monitors!(nodes[0], 1); let mut events = nodes[0].node.get_and_clear_pending_msg_events(); let mut payment_event = SendEvent::from_event(events.pop().unwrap()); @@ -8585,7 +8636,8 @@ fn test_secret_timeout() { { let (route, _, _, _) = get_route_and_payment_hash!(nodes[0], nodes[1], 100_000); - nodes[0].node.send_payment(&route, payment_hash, &Some(our_payment_secret)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(our_payment_secret), payment_metadata: None }; + nodes[0].node.send_payment(&route, payment_hash, &recipient_info).unwrap(); check_added_monitors!(nodes[0], 1); let mut events = nodes[0].node.get_and_clear_pending_msg_events(); let mut payment_event = SendEvent::from_event(events.pop().unwrap()); @@ -8597,10 +8649,11 @@ fn test_secret_timeout() { expect_pending_htlcs_forwardable!(nodes[1]); let events = nodes[1].node.get_and_clear_pending_events(); assert_eq!(events.len(), 1); - match events[0] { - Event::PaymentReceived { purpose: PaymentPurpose::InvoicePayment { payment_preimage, payment_secret }, .. } => { + match &events[0] { + Event::PaymentReceived { purpose: PaymentPurpose::InvoicePayment { payment_preimage, payment_secret, payment_metadata }, .. } => { assert!(payment_preimage.is_none()); - assert_eq!(payment_secret, our_payment_secret); + assert!(payment_metadata.is_none()); + assert_eq!(*payment_secret, our_payment_secret); // We don't actually have the payment preimage with which to claim this payment! }, _ => panic!("Unexpected event"), @@ -8655,17 +8708,20 @@ fn test_bad_secret_hash() { let expected_error_data = [0, 0, 0, 0, 0, 1, 0x86, 0xa0, 0, 0, 0, CHAN_CONFIRM_DEPTH as u8]; // Send a payment with the right payment hash but the wrong payment secret - nodes[0].node.send_payment(&route, our_payment_hash, &Some(random_payment_secret)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(random_payment_secret), payment_metadata: None }; + nodes[0].node.send_payment(&route, our_payment_hash, &recipient_info).unwrap(); handle_unknown_invalid_payment_data!(); expect_payment_failed!(nodes[0], our_payment_hash, true, expected_error_code, expected_error_data); // Send a payment with a random payment hash, but the right payment secret - nodes[0].node.send_payment(&route, random_payment_hash, &Some(our_payment_secret)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(our_payment_secret), payment_metadata: None }; + nodes[0].node.send_payment(&route, random_payment_hash, &recipient_info).unwrap(); handle_unknown_invalid_payment_data!(); expect_payment_failed!(nodes[0], random_payment_hash, true, expected_error_code, expected_error_data); // Send a payment with a random payment hash and random payment secret - nodes[0].node.send_payment(&route, random_payment_hash, &Some(random_payment_secret)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(random_payment_secret), payment_metadata: None }; + nodes[0].node.send_payment(&route, random_payment_hash, &recipient_info).unwrap(); handle_unknown_invalid_payment_data!(); expect_payment_failed!(nodes[0], random_payment_hash, true, expected_error_code, expected_error_data); } @@ -8805,7 +8861,8 @@ fn test_concurrent_monitor_claim() { // Route another payment to generate another update with still previous HTLC pending let (route, payment_hash, _, payment_secret) = get_route_and_payment_hash!(nodes[1], nodes[0], 3000000); { - nodes[1].node.send_payment(&route, payment_hash, &Some(payment_secret)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret), payment_metadata: None }; + nodes[1].node.send_payment(&route, payment_hash, &recipient_info).unwrap(); } check_added_monitors!(nodes[1], 1); @@ -9480,7 +9537,8 @@ fn test_forwardable_regen() { // First send a payment to nodes[1] let (route, payment_hash, payment_preimage, payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[1], 100_000); - nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret), payment_metadata: None }; + nodes[0].node.send_payment(&route, payment_hash, &recipient_info).unwrap(); check_added_monitors!(nodes[0], 1); let mut events = nodes[0].node.get_and_clear_pending_msg_events(); @@ -9493,7 +9551,8 @@ fn test_forwardable_regen() { // Next send a payment which is forwarded by nodes[1] let (route_2, payment_hash_2, payment_preimage_2, payment_secret_2) = get_route_and_payment_hash!(nodes[0], nodes[2], 200_000); - nodes[0].node.send_payment(&route_2, payment_hash_2, &Some(payment_secret_2)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret_2), payment_metadata: None }; + nodes[0].node.send_payment(&route_2, payment_hash_2, &recipient_info).unwrap(); check_added_monitors!(nodes[0], 1); let mut events = nodes[0].node.get_and_clear_pending_msg_events(); @@ -9591,7 +9650,8 @@ fn do_test_dup_htlc_second_rejected(test_for_second_fail_panic: bool) { let (our_payment_preimage, our_payment_hash, our_payment_secret) = get_payment_preimage_hash!(&nodes[1]); { - nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(our_payment_secret), payment_metadata: None }; + nodes[0].node.send_payment(&route, our_payment_hash, &recipient_info).unwrap(); check_added_monitors!(nodes[0], 1); let mut events = nodes[0].node.get_and_clear_pending_msg_events(); assert_eq!(events.len(), 1); @@ -9603,7 +9663,8 @@ fn do_test_dup_htlc_second_rejected(test_for_second_fail_panic: bool) { expect_payment_received!(nodes[1], our_payment_hash, our_payment_secret, 10_000); { - nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(our_payment_secret), payment_metadata: None }; + nodes[0].node.send_payment(&route, our_payment_hash, &recipient_info).unwrap(); check_added_monitors!(nodes[0], 1); let mut events = nodes[0].node.get_and_clear_pending_msg_events(); assert_eq!(events.len(), 1); @@ -9700,7 +9761,7 @@ fn test_inconsistent_mpp_params() { let cur_height = nodes[0].best_block_info().1; let payment_id = PaymentId([42; 32]); { - nodes[0].node.send_payment_along_path(&route.paths[0], &payment_params_opt, &our_payment_hash, &Some(our_payment_secret), 15_000_000, cur_height, payment_id, &None).unwrap(); + nodes[0].node.send_payment_along_path(&route.paths[0], &payment_params_opt, &our_payment_hash, &Some(our_payment_secret), &None, 15_000_000, cur_height, payment_id, &None).unwrap(); check_added_monitors!(nodes[0], 1); let mut events = nodes[0].node.get_and_clear_pending_msg_events(); @@ -9710,7 +9771,7 @@ fn test_inconsistent_mpp_params() { assert!(nodes[3].node.get_and_clear_pending_events().is_empty()); { - nodes[0].node.send_payment_along_path(&route.paths[1], &payment_params_opt, &our_payment_hash, &Some(our_payment_secret), 14_000_000, cur_height, payment_id, &None).unwrap(); + nodes[0].node.send_payment_along_path(&route.paths[1], &payment_params_opt, &our_payment_hash, &Some(our_payment_secret), &None, 14_000_000, cur_height, payment_id, &None).unwrap(); check_added_monitors!(nodes[0], 1); let mut events = nodes[0].node.get_and_clear_pending_msg_events(); @@ -9755,7 +9816,7 @@ fn test_inconsistent_mpp_params() { expect_payment_failed_conditions!(nodes[0], our_payment_hash, true, PaymentFailedConditions::new().mpp_parts_remain()); - nodes[0].node.send_payment_along_path(&route.paths[1], &payment_params_opt, &our_payment_hash, &Some(our_payment_secret), 15_000_000, cur_height, payment_id, &None).unwrap(); + nodes[0].node.send_payment_along_path(&route.paths[1], &payment_params_opt, &our_payment_hash, &Some(our_payment_secret), &None, 15_000_000, cur_height, payment_id, &None).unwrap(); check_added_monitors!(nodes[0], 1); let mut events = nodes[0].node.get_and_clear_pending_msg_events(); @@ -9918,7 +9979,8 @@ fn do_test_max_dust_htlc_exposure(dust_outbound_balance: bool, exposure_breach_e // Note, we need sent payment to be above outbound dust threshold on counterparty_tx of 2132 sats for i in 0..dust_outbound_htlc_on_holder_tx { let (route, payment_hash, _, payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[1], dust_outbound_htlc_on_holder_tx_msat); - if let Err(_) = nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret)) { panic!("Unexpected event at dust HTLC {}", i); } + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret), payment_metadata: None }; + if let Err(_) = nodes[0].node.send_payment(&route, payment_hash, &recipient_info) { panic!("Unexpected event at dust HTLC {}", i); } } } else { // Inbound dust threshold: 2324 sats (`dust_buffer_feerate` * HTLC_SUCCESS_TX_WEIGHT / 1000 + holder's `dust_limit_satoshis`) @@ -9934,11 +9996,12 @@ fn do_test_max_dust_htlc_exposure(dust_outbound_balance: bool, exposure_breach_e // Outbound dust balance: 5000 sats for i in 0..dust_htlc_on_counterparty_tx { let (route, payment_hash, _, payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[1], dust_htlc_on_counterparty_tx_msat); - if let Err(_) = nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret)) { panic!("Unexpected event at dust HTLC {}", i); } + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret), payment_metadata: None }; + if let Err(_) = nodes[0].node.send_payment(&route, payment_hash, &recipient_info) { panic!("unexpected event at dust htlc {}", i); } } } else { - // Inbound dust threshold: 2031 sats (`dust_buffer_feerate` * HTLC_TIMEOUT_TX_WEIGHT / 1000 + counteparty's `dust_limit_satoshis`) - // Inbound dust balance: 5000 sats + // inbound dust threshold: 2031 sats (`dust_buffer_feerate` * htlc_timeout_tx_weight / 1000 + counteparty's `dust_limit_satoshis`) + // inbound dust balance: 5000 sats for _ in 0..dust_htlc_on_counterparty_tx { route_payment(&nodes[1], &[&nodes[0]], dust_htlc_on_counterparty_tx_msat); } @@ -9953,13 +10016,16 @@ fn do_test_max_dust_htlc_exposure(dust_outbound_balance: bool, exposure_breach_e if on_holder_tx { let dust_outbound_overflow = dust_outbound_htlc_on_holder_tx_msat * (dust_outbound_htlc_on_holder_tx + 1); let dust_inbound_overflow = dust_inbound_htlc_on_holder_tx_msat * dust_inbound_htlc_on_holder_tx + dust_outbound_htlc_on_holder_tx_msat; - unwrap_send_err!(nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret)), true, APIError::ChannelUnavailable { ref err }, assert_eq!(err, &format!("Cannot send value that would put our exposure to dust HTLCs at {} over the limit {} on holder commitment tx", if dust_outbound_balance { dust_outbound_overflow } else { dust_inbound_overflow }, config.channel_options.max_dust_htlc_exposure_msat))); + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret), payment_metadata: None }; + unwrap_send_err!(nodes[0].node.send_payment(&route, payment_hash, &recipient_info), true, APIError::ChannelUnavailable { ref err }, assert_eq!(err, &format!("Cannot send value that would put our exposure to dust HTLCs at {} over the limit {} on holder commitment tx", if dust_outbound_balance { dust_outbound_overflow } else { dust_inbound_overflow }, config.channel_options.max_dust_htlc_exposure_msat))); } else { - unwrap_send_err!(nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret)), true, APIError::ChannelUnavailable { ref err }, assert_eq!(err, &format!("Cannot send value that would put our exposure to dust HTLCs at {} over the limit {} on counterparty commitment tx", dust_overflow, config.channel_options.max_dust_htlc_exposure_msat))); + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret), payment_metadata: None }; + unwrap_send_err!(nodes[0].node.send_payment(&route, payment_hash, &recipient_info), true, APIError::ChannelUnavailable { ref err }, assert_eq!(err, &format!("Cannot send value that would put our exposure to dust HTLCs at {} over the limit {} on counterparty commitment tx", dust_overflow, config.channel_options.max_dust_htlc_exposure_msat))); } } else if exposure_breach_event == ExposureEvent::AtHTLCReception { let (route, payment_hash, _, payment_secret) = get_route_and_payment_hash!(nodes[1], nodes[0], if on_holder_tx { dust_inbound_htlc_on_holder_tx_msat } else { dust_htlc_on_counterparty_tx_msat }); - nodes[1].node.send_payment(&route, payment_hash, &Some(payment_secret)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret), payment_metadata: None }; + nodes[1].node.send_payment(&route, payment_hash, &recipient_info).unwrap(); check_added_monitors!(nodes[1], 1); let mut events = nodes[1].node.get_and_clear_pending_msg_events(); assert_eq!(events.len(), 1); @@ -9977,7 +10043,8 @@ fn do_test_max_dust_htlc_exposure(dust_outbound_balance: bool, exposure_breach_e } } else if exposure_breach_event == ExposureEvent::AtUpdateFeeOutbound { let (route, payment_hash, _, payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[1], 2_500_000); - if let Err(_) = nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret)) { panic!("Unexpected event at update_fee-swallowed HTLC", ); } + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret), payment_metadata: None }; + if let Err(_) = nodes[0].node.send_payment(&route, payment_hash, &recipient_info) { panic!("Unexpected event at update_fee-swallowed HTLC", ); } { let mut feerate_lock = chanmon_cfgs[0].fee_estimator.sat_per_kw.lock().unwrap(); *feerate_lock = *feerate_lock * 10; diff --git a/lightning/src/ln/mod.rs b/lightning/src/ln/mod.rs index 1e5f49f07df..3e45337709f 100644 --- a/lightning/src/ln/mod.rs +++ b/lightning/src/ln/mod.rs @@ -86,6 +86,15 @@ pub struct PaymentPreimage(pub [u8;32]); /// (C-not exported) as we just use [u8; 32] directly #[derive(Hash, Copy, Clone, PartialEq, Eq, Debug)] pub struct PaymentSecret(pub [u8;32]); +/// Additional BOLT 11 data to attach to the payment, useful for applications where the recipient +/// doesn't keep any context for the payment. +#[derive(Clone, Debug, PartialEq)] +pub struct RecipientInfo { + /// Optional payment secret provided by the recipient as part of a BOLT 11 invoice. + pub payment_secret: Option, + /// Optional arbitrary data provided by the recipient as part of a BOLT 11 invoice. + pub payment_metadata: Option>, +} use prelude::*; use bitcoin::bech32; diff --git a/lightning/src/ln/monitor_tests.rs b/lightning/src/ln/monitor_tests.rs index 6fa0aab9d31..258fda71631 100644 --- a/lightning/src/ln/monitor_tests.rs +++ b/lightning/src/ln/monitor_tests.rs @@ -11,6 +11,7 @@ use chain::channelmonitor::{ANTI_REORG_DELAY, Balance}; use chain::transaction::OutPoint; +use ln::RecipientInfo; use ln::channel; use ln::channelmanager::BREAKDOWN_TIMEOUT; use ln::features::InitFeatures; @@ -51,7 +52,8 @@ fn chanmon_fail_from_stale_commitment() { let (update_a, _, chan_id_2, _) = create_announced_chan_between_nodes(&nodes, 1, 2, InitFeatures::known(), InitFeatures::known()); let (route, payment_hash, _, payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[2], 1_000_000); - nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret), payment_metadata: None }; + nodes[0].node.send_payment(&route, payment_hash, &recipient_info).unwrap(); check_added_monitors!(nodes[0], 1); let bs_txn = get_local_commitment_txn!(nodes[1], chan_id_2); @@ -560,7 +562,8 @@ fn test_balances_on_local_commitment_htlcs() { let (route, payment_hash, _, payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[1], 10_000_000); let htlc_cltv_timeout = nodes[0].best_block_info().1 + TEST_FINAL_CLTV + 1; // Note ChannelManager adds one to CLTV timeouts for safety - nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret), payment_metadata: None }; + nodes[0].node.send_payment(&route, payment_hash, &recipient_info).unwrap(); check_added_monitors!(nodes[0], 1); let updates = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id()); @@ -571,7 +574,8 @@ fn test_balances_on_local_commitment_htlcs() { expect_payment_received!(nodes[1], payment_hash, payment_secret, 10_000_000); let (route_2, payment_hash_2, payment_preimage_2, payment_secret_2) = get_route_and_payment_hash!(nodes[0], nodes[1], 20_000_000); - nodes[0].node.send_payment(&route_2, payment_hash_2, &Some(payment_secret_2)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret_2), payment_metadata: None }; + nodes[0].node.send_payment(&route_2, payment_hash_2, &recipient_info).unwrap(); check_added_monitors!(nodes[0], 1); let updates = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id()); diff --git a/lightning/src/ln/msgs.rs b/lightning/src/ln/msgs.rs index 281a2a8e977..60fb0180cc7 100644 --- a/lightning/src/ln/msgs.rs +++ b/lightning/src/ln/msgs.rs @@ -40,7 +40,7 @@ use io_extras::read_to_end; use util::events::MessageSendEventsProvider; use util::logger; -use util::ser::{Readable, Writeable, Writer, FixedLengthReader, HighZeroBytesDroppedVarInt}; +use util::ser::{Readable, Writeable, Writer, VecWriteWrapper, VecReadWrapper, FixedLengthReader, HighZeroBytesDroppedVarInt}; use ln::{PaymentPreimage, PaymentHash, PaymentSecret}; @@ -918,6 +918,7 @@ mod fuzzy_internal_msgs { #[derive(Clone)] pub(crate) struct FinalOnionHopData { pub(crate) payment_secret: PaymentSecret, + pub(crate) payment_metadata: Option>, /// The total value, in msat, of the payment as received by the ultimate recipient. /// Message serialization may panic if this value is more than 21 million Bitcoin. pub(crate) total_msat: u64, @@ -1301,6 +1302,11 @@ impl_writeable_msg!(UpdateAddHTLC, { onion_routing_packet }, {}); +// The serialization here is really funky - FinalOnionHopData somewhat serves as two different +// things. First, it is *the* object which is written with type 8 in the onion TLV. Second, it is +// the data which a node may expect to receive when we are the recipient of an invoice payment. +// Thus, its serialization doesn't match its in-memory layout - with the payment_metadata included +// in the struct, but serialized separately. impl Writeable for FinalOnionHopData { fn write(&self, w: &mut W) -> Result<(), io::Error> { self.payment_secret.0.write(w)?; @@ -1312,7 +1318,7 @@ impl Readable for FinalOnionHopData { fn read(r: &mut R) -> Result { let secret: [u8; 32] = Readable::read(r)?; let amt: HighZeroBytesDroppedVarInt = Readable::read(r)?; - Ok(Self { payment_secret: PaymentSecret(secret), total_msat: amt.0 }) + Ok(Self { payment_secret: PaymentSecret(secret), total_msat: amt.0, payment_metadata: None, }) } } @@ -1334,10 +1340,15 @@ impl Writeable for OnionHopData { }); }, OnionHopDataFormat::FinalNode { ref payment_data, ref keysend_preimage } => { + let payment_metadata = if let Some(data) = payment_data { + if let Some(ref metadata) = data.payment_metadata { Some(VecWriteWrapper(metadata)) + } else { None } + } else { None }; encode_varint_length_prefixed_tlv!(w, { (2, HighZeroBytesDroppedVarInt(self.amt_to_forward), required), (4, HighZeroBytesDroppedVarInt(self.outgoing_cltv_value), required), (8, payment_data, option), + (16, payment_metadata, option), (5482373484, keysend_preimage, option) }); }, @@ -1361,6 +1372,7 @@ impl Readable for OnionHopData { let mut cltv_value = HighZeroBytesDroppedVarInt(0u32); let mut short_id: Option = None; let mut payment_data: Option = None; + let mut payment_metadata: Option> = None; let mut keysend_preimage: Option = None; // The TLV type is chosen to be compatible with lnd and c-lightning. decode_tlv_stream!(&mut rd, { @@ -1368,19 +1380,22 @@ impl Readable for OnionHopData { (4, cltv_value, required), (6, short_id, option), (8, payment_data, option), + (16, payment_metadata, option), (5482373484, keysend_preimage, option) }); rd.eat_remaining().map_err(|_| DecodeError::ShortRead)?; let format = if let Some(short_channel_id) = short_id { if payment_data.is_some() { return Err(DecodeError::InvalidValue); } + if payment_metadata.is_some() { return Err(DecodeError::InvalidValue); } OnionHopDataFormat::NonFinalNode { short_channel_id, } } else { - if let &Some(ref data) = &payment_data { + if let Some(ref mut data) = &mut payment_data { if data.total_msat > MAX_VALUE_MSAT { return Err(DecodeError::InvalidValue); } + data.payment_metadata = payment_metadata.map(|v| v.0); } OnionHopDataFormat::FinalNode { payment_data, @@ -2587,6 +2602,7 @@ mod tests { format: OnionHopDataFormat::FinalNode { payment_data: Some(FinalOnionHopData { payment_secret: expected_payment_secret, + payment_metadata: None, total_msat: 0x1badca1f }), keysend_preimage: None, @@ -2601,6 +2617,7 @@ mod tests { if let OnionHopDataFormat::FinalNode { payment_data: Some(FinalOnionHopData { payment_secret, + payment_metadata: None, total_msat: 0x1badca1f }), keysend_preimage: None, diff --git a/lightning/src/ln/onion_route_tests.rs b/lightning/src/ln/onion_route_tests.rs index 9a07603fafe..fa02f55da7a 100644 --- a/lightning/src/ln/onion_route_tests.rs +++ b/lightning/src/ln/onion_route_tests.rs @@ -13,7 +13,7 @@ use chain::channelmonitor::{CLTV_CLAIM_BUFFER, LATENCY_GRACE_PERIOD_BLOCKS}; use chain::keysinterface::{KeysInterface, Recipient}; -use ln::{PaymentHash, PaymentSecret}; +use ln::{PaymentHash, PaymentSecret, RecipientInfo}; use ln::channelmanager::{HTLCForwardInfo, CLTV_FAR_FAR_AWAY, MIN_CLTV_EXPIRY_DELTA, PendingHTLCInfo, PendingHTLCRouting}; use ln::onion_utils; use routing::network_graph::{NetworkUpdate, RoutingFees, NodeId}; @@ -80,7 +80,8 @@ fn run_onion_failure_test_with_fail_intercept(_name: &str, test_case: } // 0 ~~> 2 send payment - nodes[0].node.send_payment(&route, payment_hash.clone(), &Some(*payment_secret)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(*payment_secret), payment_metadata: None }; + nodes[0].node.send_payment(&route, payment_hash.clone(), &recipient_info).unwrap(); check_added_monitors!(nodes[0], 1); let update_0 = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id()); // temper update_add (0 => 1) @@ -272,7 +273,8 @@ fn test_fee_failures() { // positive case let (route, payment_hash_success, payment_preimage_success, payment_secret_success) = get_route_and_payment_hash!(nodes[0], nodes[2], 40_000); - nodes[0].node.send_payment(&route, payment_hash_success, &Some(payment_secret_success)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret_success), payment_metadata: None }; + nodes[0].node.send_payment(&route, payment_hash_success, &recipient_info).unwrap(); check_added_monitors!(nodes[0], 1); pass_along_route(&nodes[0], &[&[&nodes[1], &nodes[2]]], 40_000, payment_hash_success, payment_secret_success); claim_payment(&nodes[0], &[&nodes[1], &nodes[2]], payment_preimage_success); @@ -293,7 +295,8 @@ fn test_fee_failures() { } let (payment_preimage_success, payment_hash_success, payment_secret_success) = get_payment_preimage_hash!(nodes[2]); - nodes[0].node.send_payment(&route, payment_hash_success, &Some(payment_secret_success)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret_success), payment_metadata: None }; + nodes[0].node.send_payment(&route, payment_hash_success, &recipient_info).unwrap(); check_added_monitors!(nodes[0], 1); pass_along_route(&nodes[0], &[&[&nodes[1], &nodes[2]]], 40_000, payment_hash_success, payment_secret_success); claim_payment(&nodes[0], &[&nodes[1], &nodes[2]], payment_preimage_success); @@ -334,7 +337,7 @@ fn test_onion_failure() { let session_priv = SecretKey::from_slice(&[3; 32]).unwrap(); let cur_height = nodes[0].best_block_info().1 + 1; let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route.paths[0], &session_priv).unwrap(); - let (mut onion_payloads, _htlc_msat, _htlc_cltv) = onion_utils::build_onion_payloads(&route.paths[0], 40000, &None, cur_height, &None).unwrap(); + let (mut onion_payloads, _htlc_msat, _htlc_cltv) = onion_utils::build_onion_payloads(&route.paths[0], 40000, &None, None, cur_height, &None).unwrap(); let mut new_payloads = Vec::new(); for payload in onion_payloads.drain(..) { new_payloads.push(BogusOnionHopData::new(payload)); @@ -351,7 +354,7 @@ fn test_onion_failure() { let session_priv = SecretKey::from_slice(&[3; 32]).unwrap(); let cur_height = nodes[0].best_block_info().1 + 1; let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route.paths[0], &session_priv).unwrap(); - let (mut onion_payloads, _htlc_msat, _htlc_cltv) = onion_utils::build_onion_payloads(&route.paths[0], 40000, &None, cur_height, &None).unwrap(); + let (mut onion_payloads, _htlc_msat, _htlc_cltv) = onion_utils::build_onion_payloads(&route.paths[0], 40000, &None, None, cur_height, &None).unwrap(); let mut new_payloads = Vec::new(); for payload in onion_payloads.drain(..) { new_payloads.push(BogusOnionHopData::new(payload)); @@ -578,7 +581,7 @@ fn test_onion_failure() { let height = nodes[2].best_block_info().1; route.paths[0][1].cltv_expiry_delta += CLTV_FAR_FAR_AWAY + route.paths[0][0].cltv_expiry_delta + 1; let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route.paths[0], &session_priv).unwrap(); - let (onion_payloads, _, htlc_cltv) = onion_utils::build_onion_payloads(&route.paths[0], 40000, &None, height, &None).unwrap(); + let (onion_payloads, _, htlc_cltv) = onion_utils::build_onion_payloads(&route.paths[0], 40000, &None, None, height, &None).unwrap(); let onion_packet = onion_utils::construct_onion_packet(onion_payloads, onion_keys, [0; 32], &payment_hash); msg.cltv_expiry = htlc_cltv; msg.onion_routing_packet = onion_packet; @@ -664,8 +667,8 @@ fn test_default_to_onion_payload_tlv_format() { assert!(unannounced_chan_hop.node_features.supports_variable_length_onion()); let cur_height = nodes[0].best_block_info().1 + 1; - let (announced_route_payloads, _htlc_msat, _htlc_cltv) = onion_utils::build_onion_payloads(&announced_route.paths[0], 40000, &None, cur_height, &None).unwrap(); - let (unannounced_route_paylods, _htlc_msat, _htlc_cltv) = onion_utils::build_onion_payloads(&unannounced_route.paths[0], 40000, &None, cur_height, &None).unwrap(); + let (announced_route_payloads, _htlc_msat, _htlc_cltv) = onion_utils::build_onion_payloads(&announced_route.paths[0], 40000, &None, None, cur_height, &None).unwrap(); + let (unannounced_route_paylods, _htlc_msat, _htlc_cltv) = onion_utils::build_onion_payloads(&unannounced_route.paths[0], 40000, &None, None, cur_height, &None).unwrap(); for onion_payloads in vec![announced_route_payloads, unannounced_route_paylods] { for onion_payload in onion_payloads.iter() { @@ -744,7 +747,7 @@ fn test_do_not_default_to_onion_payload_tlv_format_when_unsupported() { assert!(!hops[2].node_features.supports_variable_length_onion()); let cur_height = nodes[0].best_block_info().1 + 1; - let (onion_payloads, _htlc_msat, _htlc_cltv) = onion_utils::build_onion_payloads(&route.paths[0], 40000, &None, cur_height, &None).unwrap(); + let (onion_payloads, _htlc_msat, _htlc_cltv) = onion_utils::build_onion_payloads(&route.paths[0], 40000, &None, None, cur_height, &None).unwrap(); for onion_payload in onion_payloads.iter() { match onion_payload.format { @@ -813,7 +816,8 @@ fn test_phantom_onion_hmac_failure() { let (route, phantom_scid) = get_phantom_route!(nodes, recv_value_msat, channel); // Route the HTLC through to the destination. - nodes[0].node.send_payment(&route, payment_hash.clone(), &Some(payment_secret)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret), payment_metadata: None }; + nodes[0].node.send_payment(&route, payment_hash.clone(), &recipient_info).unwrap(); check_added_monitors!(nodes[0], 1); let update_0 = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id()); let mut update_add = update_0.update_add_htlcs[0].clone(); @@ -874,7 +878,8 @@ fn test_phantom_invalid_onion_payload() { // We'll use the session priv later when constructing an invalid onion packet. let session_priv = [3; 32]; *nodes[0].keys_manager.override_random_bytes.lock().unwrap() = Some(session_priv); - nodes[0].node.send_payment(&route, payment_hash.clone(), &Some(payment_secret)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret), payment_metadata: None }; + nodes[0].node.send_payment(&route, payment_hash.clone(), &recipient_info).unwrap(); check_added_monitors!(nodes[0], 1); let update_0 = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id()); let mut update_add = update_0.update_add_htlcs[0].clone(); @@ -896,7 +901,7 @@ fn test_phantom_invalid_onion_payload() { let height = nodes[0].best_block_info().1; let session_priv = SecretKey::from_slice(&session_priv).unwrap(); let mut onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route.paths[0], &session_priv).unwrap(); - let (mut onion_payloads, _, _) = onion_utils::build_onion_payloads(&route.paths[0], msgs::MAX_VALUE_MSAT + 1, &Some(payment_secret), height + 1, &None).unwrap(); + let (mut onion_payloads, _, _) = onion_utils::build_onion_payloads(&route.paths[0], msgs::MAX_VALUE_MSAT + 1, &Some(payment_secret), None, height + 1, &None).unwrap(); // We only want to construct the onion packet for the last hop, not the entire route, so // remove the first hop's payload and its keys. onion_keys.remove(0); @@ -945,7 +950,8 @@ fn test_phantom_final_incorrect_cltv_expiry() { let (route, phantom_scid) = get_phantom_route!(nodes, recv_value_msat, channel); // Route the HTLC through to the destination. - nodes[0].node.send_payment(&route, payment_hash.clone(), &Some(payment_secret)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret), payment_metadata: None }; + nodes[0].node.send_payment(&route, payment_hash.clone(), &recipient_info).unwrap(); check_added_monitors!(nodes[0], 1); let update_0 = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id()); let mut update_add = update_0.update_add_htlcs[0].clone(); @@ -1004,7 +1010,8 @@ fn test_phantom_failure_too_low_cltv() { route.paths[0][1].cltv_expiry_delta = 5; // Route the HTLC through to the destination. - nodes[0].node.send_payment(&route, payment_hash.clone(), &Some(payment_secret)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret), payment_metadata: None }; + nodes[0].node.send_payment(&route, payment_hash.clone(), &recipient_info).unwrap(); check_added_monitors!(nodes[0], 1); let update_0 = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id()); let mut update_add = update_0.update_add_htlcs[0].clone(); @@ -1047,7 +1054,8 @@ fn test_phantom_failure_too_low_recv_amt() { let (mut route, phantom_scid) = get_phantom_route!(nodes, bad_recv_amt_msat, channel); // Route the HTLC through to the destination. - nodes[0].node.send_payment(&route, payment_hash.clone(), &Some(payment_secret)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret), payment_metadata: None }; + nodes[0].node.send_payment(&route, payment_hash.clone(), &recipient_info).unwrap(); check_added_monitors!(nodes[0], 1); let update_0 = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id()); let mut update_add = update_0.update_add_htlcs[0].clone(); @@ -1099,7 +1107,8 @@ fn test_phantom_dust_exposure_failure() { let (mut route, _) = get_phantom_route!(nodes, max_dust_exposure + 1, channel); // Route the HTLC through to the destination. - nodes[0].node.send_payment(&route, payment_hash.clone(), &Some(payment_secret)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret), payment_metadata: None }; + nodes[0].node.send_payment(&route, payment_hash.clone(), &recipient_info).unwrap(); check_added_monitors!(nodes[0], 1); let update_0 = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id()); let mut update_add = update_0.update_add_htlcs[0].clone(); @@ -1142,7 +1151,8 @@ fn test_phantom_failure_reject_payment() { let (mut route, phantom_scid) = get_phantom_route!(nodes, recv_amt_msat, channel); // Route the HTLC through to the destination. - nodes[0].node.send_payment(&route, payment_hash.clone(), &Some(payment_secret)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret), payment_metadata: None }; + nodes[0].node.send_payment(&route, payment_hash.clone(), &recipient_info).unwrap(); check_added_monitors!(nodes[0], 1); let update_0 = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id()); let mut update_add = update_0.update_add_htlcs[0].clone(); diff --git a/lightning/src/ln/onion_utils.rs b/lightning/src/ln/onion_utils.rs index 9e4ae058f8d..30f48be3cdb 100644 --- a/lightning/src/ln/onion_utils.rs +++ b/lightning/src/ln/onion_utils.rs @@ -121,12 +121,23 @@ pub(super) fn construct_onion_keys(secp_ctx: &Secp256k1, total_msat: u64, payment_secret_option: &Option, starting_htlc_offset: u32, keysend_preimage: &Option) -> Result<(Vec, u64, u32), APIError> { +pub(super) fn build_onion_payloads(path: &Vec, total_msat: u64, payment_secret_option: &Option, payment_metadata: Option>, starting_htlc_offset: u32, keysend_preimage: &Option) -> Result<(Vec, u64, u32), APIError> { let mut cur_value_msat = 0u64; let mut cur_cltv = starting_htlc_offset; let mut last_short_channel_id = 0; let mut res: Vec = Vec::with_capacity(path.len()); + let mut last_hop_data = Some(msgs::OnionHopDataFormat::FinalNode { + payment_data: if let &Some(ref payment_secret) = payment_secret_option { + Some(msgs::FinalOnionHopData { + payment_secret: *payment_secret, + payment_metadata: payment_metadata, + total_msat, + }) + } else { None }, + keysend_preimage: *keysend_preimage, + }); + for (idx, hop) in path.iter().rev().enumerate() { // First hop gets special values so that it can check, on receipt, that everything is // exactly as it should be (and the next hop isn't trying to probe to find out if we're @@ -136,15 +147,7 @@ pub(super) fn build_onion_payloads(path: &Vec, total_msat: u64, paymen res.insert(0, msgs::OnionHopData { format: if hop.node_features.supports_variable_length_onion() { if idx == 0 { - msgs::OnionHopDataFormat::FinalNode { - payment_data: if let &Some(ref payment_secret) = payment_secret_option { - Some(msgs::FinalOnionHopData { - payment_secret: payment_secret.clone(), - total_msat, - }) - } else { None }, - keysend_preimage: *keysend_preimage, - } + last_hop_data.take().expect("Only called on the first iteration") } else { msgs::OnionHopDataFormat::NonFinalNode { short_channel_id: last_short_channel_id, diff --git a/lightning/src/ln/payment_tests.rs b/lightning/src/ln/payment_tests.rs index 46d5d22b49a..d5e06c2bbf2 100644 --- a/lightning/src/ln/payment_tests.rs +++ b/lightning/src/ln/payment_tests.rs @@ -15,6 +15,7 @@ use chain::{ChannelMonitorUpdateErr, Confirm, Listen, Watch}; use chain::channelmonitor::{ANTI_REORG_DELAY, ChannelMonitor, LATENCY_GRACE_PERIOD_BLOCKS}; use chain::transaction::OutPoint; use chain::keysinterface::KeysInterface; +use ln::RecipientInfo; use ln::channelmanager::{BREAKDOWN_TIMEOUT, ChannelManager, ChannelManagerReadArgs, MPP_TIMEOUT_TICKS, PaymentId, PaymentSendFailure}; use ln::features::{InitFeatures, InvoiceFeatures}; use ln::msgs; @@ -52,7 +53,8 @@ fn retry_single_path_payment() { send_payment(&nodes[1], &vec!(&nodes[2])[..], 2_000_000); // Make sure the payment fails on the first hop. - let payment_id = nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret), payment_metadata: None }; + let payment_id = nodes[0].node.send_payment(&route, payment_hash, &recipient_info).unwrap(); check_added_monitors!(nodes[0], 1); let mut events = nodes[0].node.get_and_clear_pending_msg_events(); assert_eq!(events.len(), 1); @@ -137,7 +139,8 @@ fn mpp_retry() { route.paths[1][1].short_channel_id = chan_4_id; // Initiate the MPP payment. - let payment_id = nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret), payment_metadata: None }; + let payment_id = nodes[0].node.send_payment(&route, payment_hash, &recipient_info).unwrap(); check_added_monitors!(nodes[0], 2); // one monitor per path let mut events = nodes[0].node.get_and_clear_pending_msg_events(); assert_eq!(events.len(), 2); @@ -221,7 +224,8 @@ fn do_mpp_receive_timeout(send_partial_mpp: bool) { route.paths[1][1].short_channel_id = chan_4_id; // Initiate the MPP payment. - let _ = nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret), payment_metadata: None }; + let _ = nodes[0].node.send_payment(&route, payment_hash, &recipient_info).unwrap(); check_added_monitors!(nodes[0], 2); // one monitor per path let mut events = nodes[0].node.get_and_clear_pending_msg_events(); assert_eq!(events.len(), 2); @@ -289,7 +293,8 @@ fn retry_expired_payment() { send_payment(&nodes[1], &vec!(&nodes[2])[..], 2_000_000); // Make sure the payment fails on the first hop. - let payment_id = nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret), payment_metadata: None }; + let payment_id = nodes[0].node.send_payment(&route, payment_hash, &recipient_info).unwrap(); check_added_monitors!(nodes[0], 1); let mut events = nodes[0].node.get_and_clear_pending_msg_events(); assert_eq!(events.len(), 1); @@ -340,7 +345,8 @@ fn no_pending_leak_on_initial_send_failure() { nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false); nodes[1].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false); - unwrap_send_err!(nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret)), + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret), payment_metadata: None }; + unwrap_send_err!(nodes[0].node.send_payment(&route, payment_hash, &recipient_info), true, APIError::ChannelUnavailable { ref err }, assert_eq!(err, "Peer for first hop currently disconnected/pending monitor update!")); @@ -377,7 +383,8 @@ fn do_retry_with_no_persist(confirm_before_reload: bool) { // out and retry. let (route, payment_hash, payment_preimage, payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[2], 1_000_000); let (payment_preimage_1, _, _, payment_id_1) = send_along_route(&nodes[0], route.clone(), &[&nodes[1], &nodes[2]], 1_000_000); - let payment_id = nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret), payment_metadata: None }; + let payment_id = nodes[0].node.send_payment(&route, payment_hash, &recipient_info).unwrap(); check_added_monitors!(nodes[0], 1); let mut events = nodes[0].node.get_and_clear_pending_msg_events(); @@ -810,7 +817,8 @@ fn get_ldk_payment_preimage() { &nodes[0].node.get_our_node_id(), &payment_params, &nodes[0].network_graph.read_only(), Some(&nodes[0].node.list_usable_channels().iter().collect::>()), amt_msat, TEST_FINAL_CLTV, nodes[0].logger, &scorer, &random_seed_bytes).unwrap(); - let _payment_id = nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret), payment_metadata: None }; + let _payment_id = nodes[0].node.send_payment(&route, payment_hash, &recipient_info).unwrap(); check_added_monitors!(nodes[0], 1); // Make sure to use `get_payment_preimage` diff --git a/lightning/src/ln/priv_short_conf_tests.rs b/lightning/src/ln/priv_short_conf_tests.rs index d7b940eb90e..2b707ab59e5 100644 --- a/lightning/src/ln/priv_short_conf_tests.rs +++ b/lightning/src/ln/priv_short_conf_tests.rs @@ -17,6 +17,7 @@ use chain::keysinterface::{Recipient, KeysInterface}; use ln::channelmanager::{ChannelManager, ChannelManagerReadArgs, MIN_CLTV_EXPIRY_DELTA}; use routing::network_graph::RoutingFees; use routing::router::{PaymentParameters, RouteHint, RouteHintHop}; +use ln::RecipientInfo; use ln::features::{InitFeatures, InvoiceFeatures}; use ln::msgs; use ln::msgs::{ChannelMessageHandler, RoutingMessageHandler, OptionalField, ChannelUpdate}; @@ -77,7 +78,8 @@ fn test_priv_forwarding_rejection() { .with_route_hints(last_hops); let (route, our_payment_hash, our_payment_preimage, our_payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[2], payment_params, 10_000, TEST_FINAL_CLTV); - nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(our_payment_secret), payment_metadata: None }; + nodes[0].node.send_payment(&route, our_payment_hash, &recipient_info).unwrap(); check_added_monitors!(nodes[0], 1); let payment_event = SendEvent::from_event(nodes[0].node.get_and_clear_pending_msg_events().remove(0)); nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &payment_event.msgs[0]); @@ -160,7 +162,8 @@ fn test_priv_forwarding_rejection() { get_event_msg!(nodes[1], MessageSendEvent::SendChannelUpdate, nodes[2].node.get_our_node_id()); get_event_msg!(nodes[2], MessageSendEvent::SendChannelUpdate, nodes[1].node.get_our_node_id()); - nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(our_payment_secret), payment_metadata: None }; + nodes[0].node.send_payment(&route, our_payment_hash, &recipient_info).unwrap(); check_added_monitors!(nodes[0], 1); pass_along_route(&nodes[0], &[&[&nodes[1], &nodes[2]]], 10_000, our_payment_hash, our_payment_secret); claim_payment(&nodes[0], &[&nodes[1], &nodes[2]], our_payment_preimage); @@ -278,7 +281,8 @@ fn test_routed_scid_alias() { .with_route_hints(hop_hints); let (route, payment_hash, payment_preimage, payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[2], payment_params, 100_000, 42); assert_eq!(route.paths[0][1].short_channel_id, last_hop[0].inbound_scid_alias.unwrap()); - nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret), payment_metadata: None }; + nodes[0].node.send_payment(&route, payment_hash, &recipient_info).unwrap(); check_added_monitors!(nodes[0], 1); pass_along_route(&nodes[0], &[&[&nodes[1], &nodes[2]]], 100_000, payment_hash, payment_secret); @@ -431,7 +435,8 @@ fn test_inbound_scid_privacy() { .with_route_hints(hop_hints.clone()); let (route, payment_hash, payment_preimage, payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[2], payment_params, 100_000, 42); assert_eq!(route.paths[0][1].short_channel_id, last_hop[0].inbound_scid_alias.unwrap()); - nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret), payment_metadata: None }; + nodes[0].node.send_payment(&route, payment_hash, &recipient_info).unwrap(); check_added_monitors!(nodes[0], 1); pass_along_route(&nodes[0], &[&[&nodes[1], &nodes[2]]], 100_000, payment_hash, payment_secret); @@ -446,7 +451,8 @@ fn test_inbound_scid_privacy() { .with_route_hints(hop_hints); let (route_2, payment_hash_2, _, payment_secret_2) = get_route_and_payment_hash!(nodes[0], nodes[2], payment_params_2, 100_000, 42); assert_eq!(route_2.paths[0][1].short_channel_id, last_hop[0].short_channel_id.unwrap()); - nodes[0].node.send_payment(&route_2, payment_hash_2, &Some(payment_secret_2)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret_2), payment_metadata: None }; + nodes[0].node.send_payment(&route_2, payment_hash_2, &recipient_info).unwrap(); check_added_monitors!(nodes[0], 1); let payment_event = SendEvent::from_node(&nodes[0]); @@ -501,7 +507,8 @@ fn test_scid_alias_returned() { route.paths[0][1].fee_msat = 10_000_000; // Overshoot the last channel's value // Route the HTLC through to the destination. - nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret), payment_metadata: None }; + nodes[0].node.send_payment(&route, payment_hash, &recipient_info).unwrap(); check_added_monitors!(nodes[0], 1); let as_updates = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id()); nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &as_updates.update_add_htlcs[0]); @@ -545,7 +552,8 @@ fn test_scid_alias_returned() { route.paths[0][0].fee_msat = 0; // But set fee paid to the middle hop to 0 // Route the HTLC through to the destination. - nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret), payment_metadata: None }; + nodes[0].node.send_payment(&route, payment_hash, &recipient_info).unwrap(); check_added_monitors!(nodes[0], 1); let as_updates = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id()); nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &as_updates.update_add_htlcs[0]); diff --git a/lightning/src/ln/shutdown_tests.rs b/lightning/src/ln/shutdown_tests.rs index 59004547b14..f5bda76a161 100644 --- a/lightning/src/ln/shutdown_tests.rs +++ b/lightning/src/ln/shutdown_tests.rs @@ -11,6 +11,7 @@ use chain::keysinterface::KeysInterface; use chain::transaction::OutPoint; +use ln::RecipientInfo; use ln::channelmanager::PaymentSendFailure; use routing::router::{PaymentParameters, get_route}; use ln::features::{InitFeatures, InvoiceFeatures}; @@ -98,8 +99,9 @@ fn updates_shutdown_wait() { let route_1 = get_route(&nodes[0].node.get_our_node_id(), &payment_params_1, &nodes[0].network_graph.read_only(), None, 100000, TEST_FINAL_CLTV, &logger, &scorer, &random_seed_bytes).unwrap(); let payment_params_2 = PaymentParameters::from_node_id(nodes[0].node.get_our_node_id()).with_features(InvoiceFeatures::known()); let route_2 = get_route(&nodes[1].node.get_our_node_id(), &payment_params_2, &nodes[1].network_graph.read_only(), None, 100000, TEST_FINAL_CLTV, &logger, &scorer, &random_seed_bytes).unwrap(); - unwrap_send_err!(nodes[0].node.send_payment(&route_1, payment_hash, &Some(payment_secret)), true, APIError::ChannelUnavailable {..}, {}); - unwrap_send_err!(nodes[1].node.send_payment(&route_2, payment_hash, &Some(payment_secret)), true, APIError::ChannelUnavailable {..}, {}); + let recipient_info = RecipientInfo { payment_secret: Some(payment_secret), payment_metadata: None }; + unwrap_send_err!(nodes[0].node.send_payment(&route_1, payment_hash, &recipient_info), true, APIError::ChannelUnavailable {..}, {}); + unwrap_send_err!(nodes[1].node.send_payment(&route_2, payment_hash, &recipient_info), true, APIError::ChannelUnavailable {..}, {}); assert!(nodes[2].node.claim_funds(payment_preimage)); check_added_monitors!(nodes[2], 1); @@ -157,7 +159,8 @@ fn htlc_fail_async_shutdown() { let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2, InitFeatures::known(), InitFeatures::known()); let (route, our_payment_hash, _, our_payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[2], 100000); - nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap(); + let recipient_info = RecipientInfo { payment_secret: Some(our_payment_secret), payment_metadata: None }; + nodes[0].node.send_payment(&route, our_payment_hash, &recipient_info).unwrap(); check_added_monitors!(nodes[0], 1); let updates = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id()); assert_eq!(updates.update_add_htlcs.len(), 1); diff --git a/lightning/src/routing/router.rs b/lightning/src/routing/router.rs index dc094b9b6e0..1efeaf8906e 100644 --- a/lightning/src/routing/router.rs +++ b/lightning/src/routing/router.rs @@ -4917,7 +4917,6 @@ mod tests { assert_eq!(route.paths[0][1].short_channel_id, 13); assert_eq!(route.paths[0][1].fee_msat, 90_000); assert_eq!(route.paths[0][1].cltv_expiry_delta, 42); - assert_eq!(route.paths[0][1].node_features.le_flags(), InvoiceFeatures::known().le_flags()); assert_eq!(route.paths[0][1].channel_features.le_flags(), &id_to_feature_flags(13)); } } diff --git a/lightning/src/util/events.rs b/lightning/src/util/events.rs index b67c2ec77b3..4d84e3c7b70 100644 --- a/lightning/src/util/events.rs +++ b/lightning/src/util/events.rs @@ -60,6 +60,9 @@ pub enum PaymentPurpose { /// [`ChannelManager::create_inbound_payment`]: crate::ln::channelmanager::ChannelManager::create_inbound_payment /// [`ChannelManager::create_inbound_payment_for_hash`]: crate::ln::channelmanager::ChannelManager::create_inbound_payment_for_hash payment_secret: PaymentSecret, + /// Additional metadata to attach to the payment. This supports applications where the recipient doesn't keep any context for the payment. + /// Note that the size of this field is limited by the maximum hop payload size. Long metadata fields reduce the maximum route length. + payment_metadata: Option>, }, /// Because this is a spontaneous payment, the payer generated their own preimage rather than us /// (the payee) providing a preimage. @@ -462,10 +465,12 @@ impl Writeable for Event { 1u8.write(writer)?; let mut payment_secret = None; let payment_preimage; + let mut payment_metadata = None; match &purpose { - PaymentPurpose::InvoicePayment { payment_preimage: preimage, payment_secret: secret } => { + PaymentPurpose::InvoicePayment { payment_preimage: preimage, payment_secret: secret, payment_metadata: metadata } => { payment_secret = Some(secret); payment_preimage = *preimage; + payment_metadata = metadata.as_ref(); }, PaymentPurpose::SpontaneousPayment(preimage) => { payment_preimage = Some(*preimage); @@ -473,6 +478,7 @@ impl Writeable for Event { } write_tlv_fields!(writer, { (0, payment_hash, required), + (1, payment_metadata, option), (2, payment_secret, option), (4, amt, required), (6, 0u64, required), // user_payment_id required for compatibility with 0.0.103 and earlier @@ -584,10 +590,12 @@ impl MaybeReadable for Event { let mut payment_hash = PaymentHash([0; 32]); let mut payment_preimage = None; let mut payment_secret = None; + let mut payment_metadata = None; let mut amt = 0; let mut _user_payment_id = None::; // For compatibility with 0.0.103 and earlier read_tlv_fields!(reader, { (0, payment_hash, required), + (1, payment_metadata, option), (2, payment_secret, option), (4, amt, required), (6, _user_payment_id, option), @@ -596,8 +604,10 @@ impl MaybeReadable for Event { let purpose = match payment_secret { Some(secret) => PaymentPurpose::InvoicePayment { payment_preimage, + payment_metadata, payment_secret: secret }, + None if payment_metadata.is_some() => return Err(msgs::DecodeError::InvalidValue), None if payment_preimage.is_some() => PaymentPurpose::SpontaneousPayment(payment_preimage.unwrap()), None => return Err(msgs::DecodeError::InvalidValue), };