diff --git a/fuzz/src/chanmon_consistency.rs b/fuzz/src/chanmon_consistency.rs index ef0ae1da820..8d684cd4cb0 100644 --- a/fuzz/src/chanmon_consistency.rs +++ b/fuzz/src/chanmon_consistency.rs @@ -310,7 +310,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, &Some(payment_secret), None) { check_payment_err(err); false } else { true } @@ -336,7 +336,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, &Some(payment_secret), None) { check_payment_err(err); false } else { true } diff --git a/fuzz/src/full_stack.rs b/fuzz/src/full_stack.rs index c5d091f2d21..20892f4cc56 100644 --- a/fuzz/src/full_stack.rs +++ b/fuzz/src/full_stack.rs @@ -463,7 +463,7 @@ pub fn do_test(data: &[u8], logger: &Arc) { sha.input(&payment_hash.0[..]); payment_hash.0 = Sha256::from_engine(sha).into_inner(); payments_sent += 1; - match channelmanager.send_payment(&route, payment_hash, &None) { + match channelmanager.send_payment(&route, payment_hash, &None, None) { Ok(_) => {}, Err(_) => return, } @@ -490,7 +490,7 @@ 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)) { + match channelmanager.send_payment(&route, payment_hash, &Some(payment_secret), None) { Ok(_) => {}, Err(_) => return, } diff --git a/lightning-invoice/src/de.rs b/lightning-invoice/src/de.rs index 9e96849a274..28b901d8384 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 c44db77575d..09b7f260148 100644 --- a/lightning-invoice/src/lib.rs +++ b/lightning-invoice/src/lib.rs @@ -163,10 +163,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, @@ -179,6 +182,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. @@ -362,6 +366,7 @@ pub enum TaggedField { Fallback(Fallback), PrivateRoute(PrivateRoute), PaymentSecret(PaymentSecret), + PaymentMetadata(Vec), Features(InvoiceFeatures), } @@ -427,10 +432,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 { @@ -447,14 +453,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, @@ -467,6 +474,7 @@ impl InvoiceBui phantom_t: core::marker::PhantomData, phantom_c: core::marker::PhantomData, phantom_s: core::marker::PhantomData, + phantom_m: core::marker::PhantomData, } } @@ -510,7 +518,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 { @@ -543,9 +551,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), @@ -554,24 +562,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), @@ -581,7 +589,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), @@ -592,34 +600,94 @@ 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 features = InvoiceFeatures::empty() - .set_variable_length_onion_required() - .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(f) => { + found_features = true; + TaggedField::Features(f + .set_variable_length_onion_required() + .set_payment_secret_required()) + }, + _ => field, + }) + .collect(); self.tagged_fields.push(TaggedField::PaymentSecret(payment_secret)); - self.tagged_fields.push(TaggedField::Features(features)); + if !found_features { + let features = InvoiceFeatures::empty() + .set_variable_length_onion_required() + .set_payment_secret_required(); + self.tagged_fields.push(TaggedField::Features(features)); + } self.set_flags() } } -impl InvoiceBuilder { +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(f) => { + found_features = true; + TaggedField::Features(f.set_payment_metadata_optional()) + }, + _ => field, + }) + .collect(); + if !found_features { + let features = InvoiceFeatures::empty() + .set_payment_metadata_optional(); + self.tagged_fields.push(TaggedField::Features(features)); + } + self.set_flags() + } +} + +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(f) => { + TaggedField::Features(f.set_payment_metadata_required()) + }, + _ => field, + }) + .collect(); + self + } +} + +impl InvoiceBuilder { /// Sets the `basic_mpp` feature as optional. pub fn basic_mpp(mut self) -> Self { self.tagged_fields = self.tagged_fields @@ -633,7 +701,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. @@ -886,6 +954,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) } @@ -1148,6 +1220,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() @@ -1250,6 +1327,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, }; @@ -1875,7 +1953,8 @@ 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())); + assert_eq!(invoice.features(), Some(&InvoiceFeatures::empty() + .set_payment_secret_required().set_variable_length_onion_required().set_basic_mpp_optional())); 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 f2486969e76..1d3ff7ae353 100644 --- a/lightning-invoice/src/payment.rs +++ b/lightning-invoice/src/payment.rs @@ -64,8 +64,8 @@ //! # 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, +//! # payment_secret: &Option, payment_metadata: Option> //! # ) -> Result { unimplemented!() } //! # fn send_spontaneous_payment( //! # &self, route: &Route, payment_preimage: PaymentPreimage @@ -186,8 +186,8 @@ pub trait Payer { fn first_hops(&self) -> Vec; /// Sends a payment over the Lightning Network using the given [`Route`]. - fn send_payment( - &self, route: &Route, payment_hash: PaymentHash, payment_secret: &Option + fn send_payment(&self, route: &Route, payment_hash: PaymentHash, + payment_secret: &Option, payment_metadata: Option> ) -> Result; /// Sends a spontaneous payment over the Lightning Network using the given [`Route`]. @@ -309,7 +309,7 @@ where }; let send_payment = |route: &Route| { - self.payer.send_payment(route, payment_hash, &payment_secret) + self.payer.send_payment(route, payment_hash, &payment_secret, invoice.payment_metadata().cloned()) }; self.pay_internal(&route_params, payment_hash, send_payment) .map_err(|e| { self.payment_cache.lock().unwrap().remove(&payment_hash); e }) @@ -1463,9 +1463,8 @@ mod tests { Vec::new() } - fn send_payment( - &self, route: &Route, _payment_hash: PaymentHash, - _payment_secret: &Option + fn send_payment(&self, route: &Route, _payment_hash: PaymentHash, + _payment_secret: &Option, _payment_metadata: Option> ) -> 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 390290768de..add94f51d19 100644 --- a/lightning-invoice/src/utils.rs +++ b/lightning-invoice/src/utils.rs @@ -164,10 +164,10 @@ where self.list_usable_channels() } - fn send_payment( - &self, route: &Route, payment_hash: PaymentHash, payment_secret: &Option + fn send_payment(&self, route: &Route, payment_hash: PaymentHash, + payment_secret: &Option, payment_metadata: Option> ) -> Result { - self.send_payment(route, payment_hash, payment_secret) + self.send_payment(route, payment_hash, payment_secret, payment_metadata) } fn send_spontaneous_payment( @@ -236,7 +236,7 @@ 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(); + nodes[0].node.send_payment(&route, payment_hash, &Some(invoice.payment_secret().clone()), None).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 1eaeb313785..8dc18d151a6 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) + .timestamp(UNIX_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) + .timestamp(UNIX_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 05f88329176..d8456a55bbb 100644 --- a/lightning/src/chain/chainmonitor.rs +++ b/lightning/src/chain/chainmonitor.rs @@ -901,7 +901,7 @@ 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)), + unwrap_send_err!(nodes[0].node.send_payment(&route, second_payment_hash, &Some(second_payment_secret), None), 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 8786f47db0d..746fac6510c 100644 --- a/lightning/src/chain/channelmonitor.rs +++ b/lightning/src/chain/channelmonitor.rs @@ -3378,7 +3378,7 @@ 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)), + unwrap_send_err!(nodes[1].node.send_payment(&route, payment_hash, &Some(payment_secret), None), 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 236b1e498f4..3d4ad76b63b 100644 --- a/lightning/src/ln/chanmon_update_fail_tests.rs +++ b/lightning/src/ln/chanmon_update_fail_tests.rs @@ -49,7 +49,7 @@ 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 {..}, {}); + unwrap_send_err!(nodes[0].node.send_payment(&route, payment_hash_1, &Some(payment_secret_1), None), true, APIError::ChannelUnavailable {..}, {}); check_added_monitors!(nodes[0], 2); let events_1 = nodes[0].node.get_and_clear_pending_msg_events(); @@ -157,7 +157,7 @@ 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, {}); + unwrap_send_err!(nodes[0].node.send_payment(&route, payment_hash_1, &Some(payment_secret_1), None), false, APIError::MonitorUpdateFailed, {}); check_added_monitors!(nodes[0], 1); } @@ -208,7 +208,7 @@ 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, {}); + unwrap_send_err!(nodes[0].node.send_payment(&route, payment_hash_2, &Some(payment_secret_2), None), false, APIError::MonitorUpdateFailed, {}); check_added_monitors!(nodes[0], 1); } @@ -272,7 +272,7 @@ 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, {}); + unwrap_send_err!(nodes[0].node.send_payment(&route, payment_hash_2, &Some(payment_secret_2), None), false, APIError::MonitorUpdateFailed, {}); check_added_monitors!(nodes[0], 1); } @@ -609,7 +609,7 @@ 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(); + nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret), None).unwrap(); check_added_monitors!(nodes[0], 1); } @@ -701,7 +701,7 @@ 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(); + nodes[0].node.send_payment(&route, our_payment_hash, &Some(payment_secret_1), None).unwrap(); check_added_monitors!(nodes[0], 1); } @@ -749,14 +749,14 @@ 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(); + nodes[0].node.send_payment(&route, our_payment_hash_1, &Some(our_payment_secret_1), None).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(); + nodes[1].node.send_payment(&route, our_payment_hash_2, &Some(our_payment_secret_2), None).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)); @@ -845,7 +845,7 @@ 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(); + nodes[0].node.send_payment(&route, payment_hash_2, &Some(payment_secret_2), None).unwrap(); check_added_monitors!(nodes[0], 1); } @@ -870,7 +870,7 @@ 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(); + nodes[0].node.send_payment(&route, payment_hash_3, &Some(payment_secret_3), None).unwrap(); check_added_monitors!(nodes[0], 1); } @@ -889,7 +889,7 @@ 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(); + nodes[2].node.send_payment(&route, payment_hash_4, &Some(payment_secret_4), None).unwrap(); check_added_monitors!(nodes[2], 1); send_event = SendEvent::from_event(nodes[2].node.get_and_clear_pending_msg_events().remove(0)); @@ -1181,9 +1181,9 @@ 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(); + nodes[0].node.send_payment(&route, payment_hash_1, &Some(payment_secret_1), None).unwrap(); check_added_monitors!(nodes[0], 1); - nodes[0].node.send_payment(&route, payment_hash_2, &Some(payment_secret_2)).unwrap(); + nodes[0].node.send_payment(&route, payment_hash_2, &Some(payment_secret_2), None).unwrap(); check_added_monitors!(nodes[0], 0); } @@ -1233,7 +1233,7 @@ 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(); + nodes[0].node.send_payment(&route, payment_hash_3, &Some(payment_secret_3), None).unwrap(); check_added_monitors!(nodes[0], 0); assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty()); } @@ -1322,7 +1322,7 @@ 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(); + nodes[0].node.send_payment(&route, payment_hash_2, &Some(payment_secret_2), None).unwrap(); check_added_monitors!(nodes[0], 1); } @@ -1407,7 +1407,7 @@ 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(); + nodes[0].node.send_payment(&route, payment_hash_1, &Some(payment_secret_1), None).unwrap(); check_added_monitors!(nodes[0], 1); } @@ -1480,7 +1480,7 @@ 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(); + nodes[0].node.send_payment(&route, payment_hash_1, &Some(payment_secret_1), None).unwrap(); check_added_monitors!(nodes[0], 1); } @@ -1503,7 +1503,7 @@ 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(); + nodes[0].node.send_payment(&route, payment_hash_2, &Some(payment_secret_2), None).unwrap(); check_added_monitors!(nodes[0], 1); } let mut events = nodes[0].node.get_and_clear_pending_msg_events(); @@ -1586,7 +1586,7 @@ 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(); + nodes[2].node.send_payment(&route, payment_hash_2, &Some(payment_secret_2), None).unwrap(); check_added_monitors!(nodes[2], 1); } @@ -1603,7 +1603,7 @@ 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(); + nodes[2].node.send_payment(&route, payment_hash_3, &Some(payment_secret_3), None).unwrap(); check_added_monitors!(nodes[2], 1); let mut events = nodes[2].node.get_and_clear_pending_msg_events(); @@ -1693,7 +1693,7 @@ 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(); + nodes[2].node.send_payment(&route, payment_hash_2, &Some(payment_secret_2), None).unwrap(); check_added_monitors!(nodes[2], 1); } @@ -1753,7 +1753,7 @@ 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(); + nodes[0].node.send_payment(&route, payment_hash_2, &Some(payment_secret_2), None).unwrap(); check_added_monitors!(nodes[0], 1); } @@ -1923,7 +1923,7 @@ 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)) { + if let Err(PaymentSendFailure::PartialFailure { results, ..}) = nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret), None) { assert_eq!(results.len(), 2); if let Ok(()) = results[0] {} else { panic!(); } if let Err(APIError::MonitorUpdateFailed) = results[1] {} else { panic!(); } @@ -1968,7 +1968,7 @@ 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(); + nodes[1].node.send_payment(&route, payment_hash, &Some(payment_secret), None).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 @@ -2172,12 +2172,12 @@ 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(); + nodes[0].node.send_payment(&route, payment_hash_1, &Some(payment_secret_1), None).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(); + nodes[0].node.send_payment(&route, payment_hash_2, &Some(payment_secret_2), None).unwrap(); check_added_monitors!(nodes[0], 0); chanmon_cfgs[0].persister.set_update_ret(Err(ChannelMonitorUpdateErr::TemporaryFailure)); @@ -2367,7 +2367,7 @@ 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(); + nodes[0].node.send_payment(&route, second_payment_hash, &Some(second_payment_secret), None).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 cc015a681bc..02d6d83efca 100644 --- a/lightning/src/ln/channel.rs +++ b/lightning/src/ln/channel.rs @@ -6080,6 +6080,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 0ca9dbd465b..1f119db9aa7 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -236,7 +236,7 @@ mod inbound_payment { /// [`KeysInterface::get_inbound_payment_key_material`]: crate::chain::keysinterface::KeysInterface::get_inbound_payment_key_material /// [`create_inbound_payment`]: crate::ln::channelmanager::ChannelManager::create_inbound_payment /// [`create_inbound_payment_for_hash`]: crate::ln::channelmanager::ChannelManager::create_inbound_payment_for_hash - pub(super) fn verify(payment_hash: PaymentHash, payment_data: msgs::FinalOnionHopData, highest_seen_timestamp: u64, keys: &ExpandedKey, logger: &L) -> Result, ()> + pub(super) fn verify(payment_hash: PaymentHash, payment_data: &msgs::FinalOnionHopData, highest_seen_timestamp: u64, keys: &ExpandedKey, logger: &L) -> Result, ()> where L::Target: Logger { let (iv_bytes, metadata_bytes) = decrypt_metadata(payment_data.payment_secret, keys); @@ -449,7 +449,11 @@ enum OnionPayload { /// Contains a total_msat (which may differ from value if this is a Multi-Path Payment) and a /// payment_secret which prevents path-probing attacks and can associate different HTLCs which /// are part of the same payment. - Invoice(msgs::FinalOnionHopData), + Invoice { + /// This is only here for backwards-compatibility in serialization, in the future it can be + /// removed, breaking clients running 0.0.104 and earlier. + _legacy_hop_data: msgs::FinalOnionHopData, + }, /// Contains the payer-provided preimage. Spontaneous(PaymentPreimage), } @@ -459,6 +463,7 @@ struct ClaimableHTLC { cltv_expiry: u32, value: u64, onion_payload: OnionPayload, + total_msat: u64, } /// A payment identifier used to uniquely identify a payment to LDK. @@ -491,6 +496,7 @@ pub(crate) enum HTLCSource { first_hop_htlc_msat: u64, payment_id: PaymentId, payment_secret: Option, + payment_metadata: Option>, payment_params: Option, }, } @@ -502,12 +508,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); }, @@ -523,6 +530,7 @@ impl HTLCSource { first_hop_htlc_msat: 0, payment_id: PaymentId([2; 32]), payment_secret: None, + payment_metadata: None, payment_params: None, } } @@ -734,6 +742,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, @@ -2428,7 +2437,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(); @@ -2436,7 +2445,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"}); } @@ -2470,6 +2479,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, }); @@ -2493,6 +2503,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) @@ -2576,11 +2587,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, payment_secret: &Option, payment_metadata: Option>) -> Result { + self.send_payment_internal(route, payment_hash, payment_secret, 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"})); } @@ -2622,7 +2633,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; @@ -2685,12 +2696,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 { @@ -2698,7 +2709,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 { @@ -2722,7 +2733,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. @@ -2776,7 +2787,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) } @@ -3172,11 +3183,17 @@ impl ChannelMana HTLCForwardInfo::AddHTLC { prev_short_channel_id, prev_htlc_id, forward_info: PendingHTLCInfo { routing, incoming_shared_secret, payment_hash, amt_to_forward, .. }, prev_funding_outpoint } => { - let (cltv_expiry, onion_payload) = match routing { - PendingHTLCRouting::Receive { payment_data, incoming_cltv_expiry } => - (incoming_cltv_expiry, OnionPayload::Invoice(payment_data)), + let (cltv_expiry, onion_payload, payment_data) = match routing { + PendingHTLCRouting::Receive { payment_data, incoming_cltv_expiry } => { + 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)) + }, PendingHTLCRouting::ReceiveKeysend { payment_preimage, incoming_cltv_expiry } => - (incoming_cltv_expiry, OnionPayload::Spontaneous(payment_preimage)), + (incoming_cltv_expiry, OnionPayload::Spontaneous(payment_preimage), None), _ => { panic!("short_channel_id == 0 should imply any pending_forward entries are of type Receive"); } @@ -3189,6 +3206,7 @@ impl ChannelMana incoming_packet_shared_secret: incoming_shared_secret, }, value: amt_to_forward, + total_msat: if let Some(data) = &payment_data { data.total_msat } else { amt_to_forward }, cltv_expiry, onion_payload, }; @@ -3211,8 +3229,7 @@ impl ChannelMana } macro_rules! check_total_value { - ($payment_data_total_msat: expr, $payment_secret: expr, $payment_preimage: expr) => {{ - let mut total_value = 0; + ($payment_data: expr, $payment_preimage: expr) => {{ let mut payment_received_generated = false; let htlcs = channel_state.claimable_htlcs.entry(payment_hash) .or_insert(Vec::new()); @@ -3223,14 +3240,14 @@ impl ChannelMana continue } } - htlcs.push(claimable_htlc); + let mut total_value = claimable_htlc.value; for htlc in htlcs.iter() { total_value += htlc.value; match &htlc.onion_payload { - OnionPayload::Invoice(htlc_payment_data) => { - if htlc_payment_data.total_msat != $payment_data_total_msat { + OnionPayload::Invoice { .. } => { + if htlc.total_msat != claimable_htlc.total_msat { log_trace!(self.logger, "Failing HTLCs with payment_hash {} as the HTLCs had inconsistent total values (eg {} and {})", - log_bytes!(payment_hash.0), $payment_data_total_msat, htlc_payment_data.total_msat); + log_bytes!(payment_hash.0), claimable_htlc.total_msat, htlc.total_msat); total_value = msgs::MAX_VALUE_MSAT; } if total_value >= msgs::MAX_VALUE_MSAT { break; } @@ -3238,18 +3255,19 @@ impl ChannelMana _ => unreachable!(), } } - if total_value >= msgs::MAX_VALUE_MSAT || total_value > $payment_data_total_msat { + if total_value >= msgs::MAX_VALUE_MSAT || total_value > claimable_htlc.total_msat { log_trace!(self.logger, "Failing HTLCs with payment_hash {} as the total value {} ran over expected value {} (or HTLCs were inconsistent)", - log_bytes!(payment_hash.0), total_value, $payment_data_total_msat); + log_bytes!(payment_hash.0), total_value, claimable_htlc.total_msat); for htlc in htlcs.iter() { fail_htlc!(htlc); } - } else if total_value == $payment_data_total_msat { + } else if total_value == claimable_htlc.total_msat { new_events.push(events::Event::PaymentReceived { payment_hash, purpose: events::PaymentPurpose::InvoicePayment { payment_preimage: $payment_preimage, - payment_secret: $payment_secret, + payment_metadata: $payment_data.payment_metadata, + payment_secret: $payment_data.payment_secret, }, amt: total_value, }); @@ -3259,6 +3277,7 @@ impl ChannelMana // payment value yet, wait until we receive more // MPP parts. } + htlcs.push(claimable_htlc); payment_received_generated }} } @@ -3273,17 +3292,16 @@ impl ChannelMana match payment_secrets.entry(payment_hash) { hash_map::Entry::Vacant(_) => { match claimable_htlc.onion_payload { - OnionPayload::Invoice(ref payment_data) => { - let payment_preimage = match inbound_payment::verify(payment_hash, payment_data.clone(), self.highest_seen_timestamp.load(Ordering::Acquire) as u64, &self.inbound_payment_key, &self.logger) { + OnionPayload::Invoice { .. } => { + let payment_data = payment_data.unwrap(); + let payment_preimage = match inbound_payment::verify(payment_hash, &payment_data, self.highest_seen_timestamp.load(Ordering::Acquire) as u64, &self.inbound_payment_key, &self.logger) { Ok(payment_preimage) => payment_preimage, Err(()) => { fail_htlc!(claimable_htlc); continue } }; - let payment_data_total_msat = payment_data.total_msat; - let payment_secret = payment_data.payment_secret.clone(); - check_total_value!(payment_data_total_msat, payment_secret, payment_preimage); + check_total_value!(payment_data, payment_preimage); }, OnionPayload::Spontaneous(preimage) => { match channel_state.claimable_htlcs.entry(payment_hash) { @@ -3304,14 +3322,12 @@ impl ChannelMana } }, hash_map::Entry::Occupied(inbound_payment) => { - let payment_data = - if let OnionPayload::Invoice(ref data) = claimable_htlc.onion_payload { - data.clone() - } else { - log_trace!(self.logger, "Failing new keysend HTLC with payment_hash {} because we already have an inbound payment with the same payment hash", log_bytes!(payment_hash.0)); - fail_htlc!(claimable_htlc); - continue - }; + if payment_data.is_none() { + log_trace!(self.logger, "Failing new keysend HTLC with payment_hash {} because we already have an inbound payment with the same payment hash", log_bytes!(payment_hash.0)); + fail_htlc!(claimable_htlc); + continue + }; + let payment_data = payment_data.unwrap(); if inbound_payment.get().payment_secret != payment_data.payment_secret { log_trace!(self.logger, "Failing new HTLC with payment_hash {} as it didn't match our expected payment secret.", log_bytes!(payment_hash.0)); fail_htlc!(claimable_htlc); @@ -3320,7 +3336,7 @@ impl ChannelMana log_bytes!(payment_hash.0), payment_data.total_msat, inbound_payment.get().min_value_msat.unwrap()); fail_htlc!(claimable_htlc); } else { - let payment_received_generated = check_total_value!(payment_data.total_msat, payment_data.payment_secret, inbound_payment.get().payment_preimage); + let payment_received_generated = check_total_value!(payment_data, inbound_payment.get().payment_preimage); if payment_received_generated { inbound_payment.remove_entry(); } @@ -5920,20 +5936,21 @@ impl_writeable_tlv_based!(HTLCPreviousHopData, { impl Writeable for ClaimableHTLC { fn write(&self, writer: &mut W) -> Result<(), io::Error> { let payment_data = match &self.onion_payload { - OnionPayload::Invoice(data) => Some(data.clone()), + OnionPayload::Invoice { _legacy_hop_data } => Some(_legacy_hop_data), _ => None, }; let keysend_preimage = match self.onion_payload { - OnionPayload::Invoice(_) => None, + OnionPayload::Invoice { .. } => None, OnionPayload::Spontaneous(preimage) => Some(preimage.clone()), }; - write_tlv_fields! - (writer, - { - (0, self.prev_hop, required), (2, self.value, required), - (4, payment_data, option), (6, self.cltv_expiry, required), - (8, keysend_preimage, option), - }); + write_tlv_fields!(writer, { + (0, self.prev_hop, required), + (1, self.total_msat, required), + (2, self.value, required), + (4, payment_data, option), + (6, self.cltv_expiry, required), + (8, keysend_preimage, option), + }); Ok(()) } } @@ -5944,31 +5961,40 @@ impl Readable for ClaimableHTLC { let mut value = 0; let mut payment_data: Option = None; let mut cltv_expiry = 0; + let mut total_msat = None; let mut keysend_preimage: Option = None; - read_tlv_fields! - (reader, - { - (0, prev_hop, required), (2, value, required), - (4, payment_data, option), (6, cltv_expiry, required), - (8, keysend_preimage, option) - }); + read_tlv_fields!(reader, { + (0, prev_hop, required), + (1, total_msat, option), + (2, value, required), + (4, payment_data, option), + (6, cltv_expiry, required), + (8, keysend_preimage, option) + }); let onion_payload = match keysend_preimage { Some(p) => { if payment_data.is_some() { return Err(DecodeError::InvalidValue) } + if total_msat.is_none() { + total_msat = Some(value); + } OnionPayload::Spontaneous(p) }, None => { if payment_data.is_none() { return Err(DecodeError::InvalidValue) } - OnionPayload::Invoice(payment_data.unwrap()) + if total_msat.is_none() { + total_msat = Some(payment_data.as_ref().unwrap().total_msat); + } + OnionPayload::Invoice { _legacy_hop_data: payment_data.unwrap() } }, }; Ok(Self { prev_hop: prev_hop.0.unwrap(), value, + total_msat: total_msat.unwrap(), onion_payload, cltv_expiry, }) @@ -5986,6 +6012,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), @@ -5993,6 +6020,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 @@ -6006,6 +6034,7 @@ impl Readable for HTLCSource { payment_id: payment_id.unwrap(), payment_secret, payment_params, + payment_metadata, }) } 1 => Ok(HTLCSource::PreviousHopData(Readable::read(reader)?)), @@ -6017,7 +6046,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, { @@ -6027,6 +6056,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) => { @@ -6081,6 +6111,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), @@ -6537,7 +6568,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); @@ -6557,6 +6588,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, @@ -6798,7 +6830,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); @@ -6828,7 +6860,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); @@ -6964,7 +6996,7 @@ 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(); + nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret), 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); @@ -7020,7 +7052,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()); @@ -7064,7 +7096,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()); @@ -7101,7 +7133,7 @@ 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() { + match nodes[0].node.send_payment(&route, payment_hash, &None, None).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") @@ -7119,6 +7151,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, }; @@ -7126,7 +7159,7 @@ mod tests { // payment verification fails as expected. let mut bad_payment_hash = payment_hash.clone(); bad_payment_hash.0[0] += 1; - match inbound_payment::verify(bad_payment_hash, payment_data.clone(), nodes[0].node.highest_seen_timestamp.load(Ordering::Acquire) as u64, &nodes[0].node.inbound_payment_key, &nodes[0].logger) { + match inbound_payment::verify(bad_payment_hash, &payment_data, nodes[0].node.highest_seen_timestamp.load(Ordering::Acquire) as u64, &nodes[0].node.inbound_payment_key, &nodes[0].logger) { Ok(_) => panic!("Unexpected ok"), Err(()) => { nodes[0].logger.assert_log_contains("lightning::ln::channelmanager::inbound_payment".to_string(), "Failing HTLC with user-generated payment_hash".to_string(), 1); @@ -7134,7 +7167,7 @@ mod tests { } // Check that using the original payment hash succeeds. - assert!(inbound_payment::verify(payment_hash, payment_data, nodes[0].node.highest_seen_timestamp.load(Ordering::Acquire) as u64, &nodes[0].node.inbound_payment_key, &nodes[0].logger).is_ok()); + assert!(inbound_payment::verify(payment_hash, &payment_data, nodes[0].node.highest_seen_timestamp.load(Ordering::Acquire) as u64, &nodes[0].node.inbound_payment_key, &nodes[0].logger).is_ok()); } } @@ -7269,7 +7302,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 0ccce88e9f5..e4018ad4131 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 @@ -289,6 +308,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. @@ -390,12 +410,15 @@ mod sealed { define_feature!(45, ChannelType, [InitContext, NodeContext], "Feature flags for `option_channel_type`.", set_channel_type_optional, set_channel_type_required, supports_channel_type, requires_channel_type); + 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); } @@ -885,10 +908,10 @@ 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 invoice_features = InvoiceFeatures::known().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 init_features = InitFeatures::known().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 5ec16f90fc9..ca93be6ac46 100644 --- a/lightning/src/ln/functional_test_utils.rs +++ b/lightning/src/ln/functional_test_utils.rs @@ -1347,7 +1347,7 @@ 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 payment_id = origin_node.node.send_payment(&route, our_payment_hash, &Some(our_payment_secret), None).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 @@ -1562,7 +1562,7 @@ 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 }, + unwrap_send_err!(origin_node.node.send_payment(&route, our_payment_hash, &Some(our_payment_preimage), None), 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 b896e0dbe8f..359a7f8b043 100644 --- a/lightning/src/ln/functional_tests.rs +++ b/lightning/src/ln/functional_tests.rs @@ -225,7 +225,7 @@ 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(); + nodes[1].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret), None).unwrap(); check_added_monitors!(nodes[1], 1); let payment_event = { @@ -324,7 +324,7 @@ 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(); + nodes[1].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret), None).unwrap(); check_added_monitors!(nodes[1], 1); let payment_event = { @@ -790,7 +790,7 @@ 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(); + nodes[1].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret), None).unwrap(); { let mut added_monitors = nodes[0].chain_monitor.added_monitors.lock().unwrap(); assert_eq!(added_monitors.len(), 0); @@ -1125,7 +1125,7 @@ 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(); + nodes[1].node.send_payment(&route, payment_hash, &Some(payment_secret), None).unwrap(); payments.push((payment_preimage, payment_hash)); } check_added_monitors!(nodes[1], 1); @@ -1140,7 +1140,7 @@ 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 }, + unwrap_send_err!(nodes[1].node.send_payment(&route, payment_hash_1, &Some(payment_secret_1), None), 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); @@ -1149,7 +1149,7 @@ 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(); + nodes[0].node.send_payment(&route, payment_hash_2, &Some(payment_secret_2), None).unwrap(); check_added_monitors!(nodes[0], 1); } @@ -1355,7 +1355,7 @@ 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 err = nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret), None).err().unwrap(); match err { PaymentSendFailure::AllFailedRetrySafe(ref fails) => { match &fails[0] { @@ -1388,7 +1388,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, @@ -1530,7 +1530,7 @@ 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 }, + unwrap_send_err!(nodes[1].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret), None), 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); @@ -1565,7 +1565,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, @@ -1621,7 +1621,7 @@ 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 }, + unwrap_send_err!(nodes[1].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret), None), true, APIError::ChannelUnavailable { ref err }, assert_eq!(err, "Cannot send value that would put counterparty balance under holder-announced channel reserve value")); } @@ -1715,7 +1715,7 @@ 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(); + nodes[0].node.send_payment(&route_1, our_payment_hash_1, &Some(our_payment_secret_1), None).unwrap(); check_added_monitors!(nodes[0], 1); let mut events = nodes[0].node.get_and_clear_pending_msg_events(); @@ -1735,7 +1735,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, @@ -1821,7 +1821,7 @@ 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 }, + unwrap_send_err!(nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret), None), 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); @@ -1872,7 +1872,7 @@ 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(); + nodes[0].node.send_payment(&route_1, our_payment_hash_1, &Some(our_payment_secret_1), None).unwrap(); check_added_monitors!(nodes[0], 1); let mut events = nodes[0].node.get_and_clear_pending_msg_events(); @@ -1885,7 +1885,7 @@ 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 }, + unwrap_send_err!(nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret), None), 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()); } @@ -1903,7 +1903,7 @@ 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(); + nodes[0].node.send_payment(&route_21, our_payment_hash_21, &Some(our_payment_secret_21), None).unwrap(); check_added_monitors!(nodes[0], 0); let events = nodes[0].node.get_and_clear_pending_events(); assert_eq!(events.len(), 0); @@ -1911,7 +1911,7 @@ 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 }, + unwrap_send_err!(nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret), None), 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); @@ -1919,7 +1919,7 @@ 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(); + nodes[0].node.send_payment(&route_22, our_payment_hash_22, &Some(our_payment_secret_22), None).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()); @@ -2054,7 +2054,7 @@ 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(); + nodes[0].node.send_payment(&route, payment_hash_3, &Some(payment_secret_3), 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); @@ -2126,7 +2126,7 @@ 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(); + nodes[1].node.send_payment(&route, payment_hash_4, &Some(payment_secret_4), None).unwrap(); check_added_monitors!(nodes[1], 1); let mut events = nodes[1].node.get_and_clear_pending_msg_events(); assert_eq!(events.len(), 1); @@ -3136,7 +3136,7 @@ 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(); + nodes[1].node.send_payment(&route, fourth_payment_hash, &Some(fourth_payment_secret), None).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); @@ -3293,7 +3293,7 @@ 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(); + nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret), None).unwrap(); check_added_monitors!(nodes[0], 1); let payment_event = { @@ -3308,7 +3308,7 @@ 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(); + nodes[0].node.send_payment(&route, failed_payment_hash, &Some(failed_payment_secret), None).unwrap(); check_added_monitors!(nodes[0], 0); assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty()); @@ -3321,7 +3321,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); @@ -3401,7 +3401,7 @@ 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(); + nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret), None).unwrap(); check_added_monitors!(nodes[0], 1); let mut events = nodes[0].node.get_and_clear_pending_msg_events(); @@ -3576,7 +3576,7 @@ 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(); + nodes[0].node.send_payment(&route, payment_hash_1, &Some(payment_secret_1), None).unwrap(); check_added_monitors!(nodes[0], 1); let mut events = nodes[0].node.get_and_clear_pending_msg_events(); @@ -3948,7 +3948,7 @@ 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(); + nodes[0].node.send_payment(&route, payment_hash_2, &Some(payment_secret_2), None).unwrap(); check_added_monitors!(nodes[0], 1); let events_1 = nodes[0].node.get_and_clear_pending_msg_events(); @@ -4099,7 +4099,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); @@ -4164,7 +4164,7 @@ 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(); + nodes[1].node.send_payment(&route, first_payment_hash, &Some(first_payment_secret), None).unwrap(); } assert_eq!(nodes[1].node.get_and_clear_pending_msg_events().len(), 1); check_added_monitors!(nodes[1], 1); @@ -4172,7 +4172,7 @@ 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(); + sending_node.node.send_payment(&route, second_payment_hash, &Some(second_payment_secret), None).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)); @@ -5794,7 +5794,7 @@ 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(); + nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret), None).unwrap(); check_added_monitors!(nodes[0], 1); let _as_update = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id()); @@ -6038,7 +6038,7 @@ 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 our_payment_id = nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret), None).unwrap(); chan_stat = get_channel_value_stat!(nodes[0], chan.2); assert_eq!(chan_stat.holding_cell_outbound_amount_msat, max_can_send); @@ -6120,10 +6120,10 @@ 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(); + nodes[0].node.send_payment(&route_1, payment_hash_1, &Some(payment_secret_1), None).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 payment_id_2 = nodes[0].node.send_payment(&route_2, payment_hash_2, &Some(payment_secret_2), None).unwrap(); chan_stat = get_channel_value_stat!(nodes[0], chan.2); assert_eq!(chan_stat.holding_cell_outbound_amount_msat, amt_1 + amt_2); @@ -6245,7 +6245,7 @@ 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(); + nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret), None).unwrap(); check_added_monitors!(nodes[0], 1); let mut events = nodes[0].node.get_and_clear_pending_msg_events(); @@ -6347,7 +6347,7 @@ 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 }, + unwrap_send_err!(nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret), None), 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); @@ -6364,7 +6364,7 @@ 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 }, + unwrap_send_err!(nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret), None), 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()); @@ -6381,7 +6381,7 @@ 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(); + nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret), None).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; @@ -6404,7 +6404,7 @@ fn test_update_add_htlc_bolt2_sender_cltv_expiry_too_high() { let _chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1000000, 0, InitFeatures::known(), InitFeatures::known()); let (route, our_payment_hash, _, our_payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[1], vec![], 100000000, 500000001); - unwrap_send_err!(nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)), true, APIError::RouteError { ref err }, + unwrap_send_err!(nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret), None), true, APIError::RouteError { ref err }, assert_eq!(err, &"Channel CLTV overflowed?")); } @@ -6423,7 +6423,7 @@ 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(); + nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret), None).unwrap(); check_added_monitors!(nodes[0], 1); let mut events = nodes[0].node.get_and_clear_pending_msg_events(); @@ -6443,7 +6443,7 @@ 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 }, + unwrap_send_err!(nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret), None), 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()); @@ -6467,7 +6467,7 @@ 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 }, + unwrap_send_err!(nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret), None), 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()); @@ -6493,7 +6493,7 @@ 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(); + nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret), None).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; @@ -6523,7 +6523,7 @@ 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(); + nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret), None).unwrap(); check_added_monitors!(nodes[0], 1); let mut updates = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id()); @@ -6554,7 +6554,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 { @@ -6590,7 +6590,7 @@ 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(); + nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret), None).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; @@ -6613,7 +6613,7 @@ 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(); + nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret), None).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; @@ -6638,7 +6638,7 @@ 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(); + nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret), None).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]); @@ -6683,7 +6683,7 @@ 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(); + nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret), None).unwrap(); check_added_monitors!(nodes[0], 1); let updates = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id()); @@ -6715,7 +6715,7 @@ 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(); + nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret), None).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]); @@ -6746,7 +6746,7 @@ 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(); + nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret), None).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]); @@ -6861,7 +6861,7 @@ 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(); + nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret), None).unwrap(); check_added_monitors!(nodes[0], 1); let mut updates = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id()); @@ -6912,7 +6912,7 @@ 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(); + nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret), 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); @@ -7355,7 +7355,7 @@ fn test_check_htlc_underpaying() { let route = get_route(&nodes[0].node.get_our_node_id(), &payment_params, nodes[0].network_graph, None, 10_000, TEST_FINAL_CLTV, nodes[0].logger, &scorer).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(); + nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret), None).unwrap(); check_added_monitors!(nodes[0], 1); let mut events = nodes[0].node.get_and_clear_pending_msg_events(); @@ -7546,7 +7546,7 @@ fn test_priv_forwarding_rejection() { let last_hops = vec![route_hint]; let (route, our_payment_hash, our_payment_preimage, our_payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[2], last_hops, 10_000, TEST_FINAL_CLTV); - nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap(); + nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret), None).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]); @@ -7629,7 +7629,7 @@ 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(); + nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret), None).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); @@ -8213,7 +8213,7 @@ 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(); + nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret), None).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()); @@ -8283,7 +8283,7 @@ 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(); + nodes[0].node.send_payment(&route, payment_hash, &Some(our_payment_secret), None).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()); @@ -8295,10 +8295,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"), @@ -8353,17 +8354,17 @@ 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(); + nodes[0].node.send_payment(&route, our_payment_hash, &Some(random_payment_secret), None).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(); + nodes[0].node.send_payment(&route, random_payment_hash, &Some(our_payment_secret), None).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(); + nodes[0].node.send_payment(&route, random_payment_hash, &Some(random_payment_secret), None).unwrap(); handle_unknown_invalid_payment_data!(); expect_payment_failed!(nodes[0], random_payment_hash, true, expected_error_code, expected_error_data); } @@ -8503,7 +8504,7 @@ 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(); + nodes[1].node.send_payment(&route, payment_hash, &Some(payment_secret), None).unwrap(); } check_added_monitors!(nodes[1], 1); @@ -9178,7 +9179,7 @@ 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(); + nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret), None).unwrap(); check_added_monitors!(nodes[0], 1); let mut events = nodes[0].node.get_and_clear_pending_msg_events(); @@ -9191,7 +9192,7 @@ 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(); + nodes[0].node.send_payment(&route_2, payment_hash_2, &Some(payment_secret_2), None).unwrap(); check_added_monitors!(nodes[0], 1); let mut events = nodes[0].node.get_and_clear_pending_msg_events(); @@ -9425,7 +9426,7 @@ 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); } + if let Err(_) = nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret), None) { 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`) @@ -9441,7 +9442,7 @@ 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); } + if let Err(_) = nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret), None) { 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`) @@ -9460,13 +9461,13 @@ 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))); + unwrap_send_err!(nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret), None), 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))); + unwrap_send_err!(nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret), None), 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(); + nodes[1].node.send_payment(&route, payment_hash, &Some(payment_secret), None).unwrap(); check_added_monitors!(nodes[1], 1); let mut events = nodes[1].node.get_and_clear_pending_msg_events(); assert_eq!(events.len(), 1); @@ -9484,7 +9485,7 @@ 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", ); } + if let Err(_) = nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret), None) { 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/monitor_tests.rs b/lightning/src/ln/monitor_tests.rs index 2b582fe877b..d7cb32952bc 100644 --- a/lightning/src/ln/monitor_tests.rs +++ b/lightning/src/ln/monitor_tests.rs @@ -51,7 +51,7 @@ 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(); + nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret), None).unwrap(); check_added_monitors!(nodes[0], 1); let bs_txn = get_local_commitment_txn!(nodes[1], chan_id_2); diff --git a/lightning/src/ln/msgs.rs b/lightning/src/ln/msgs.rs index 9007f3f2ea7..190532202a4 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}; @@ -904,6 +904,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, @@ -1274,6 +1275,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)?; @@ -1285,7 +1291,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, }) } } @@ -1314,10 +1320,15 @@ impl Writeable for OnionHopData { if let Some(final_data) = payment_data { if final_data.total_msat > MAX_VALUE_MSAT { panic!("We should never be sending infinite/overflow onion payments"); } } + 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) }); }, @@ -1341,6 +1352,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, { @@ -1348,19 +1360,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, @@ -2551,6 +2566,7 @@ mod tests { format: OnionHopDataFormat::FinalNode { payment_data: Some(FinalOnionHopData { payment_secret: expected_payment_secret, + payment_metadata: None, total_msat: 0x1badca1f }), keysend_preimage: None, @@ -2565,6 +2581,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 4feae104d75..721cf4594dc 100644 --- a/lightning/src/ln/onion_route_tests.rs +++ b/lightning/src/ln/onion_route_tests.rs @@ -76,7 +76,7 @@ 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(); + nodes[0].node.send_payment(&route, payment_hash.clone(), &Some(*payment_secret), None).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) @@ -268,7 +268,7 @@ 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(); + nodes[0].node.send_payment(&route, payment_hash_success, &Some(payment_secret_success), None).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); @@ -289,7 +289,7 @@ 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(); + nodes[0].node.send_payment(&route, payment_hash_success, &Some(payment_secret_success), None).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); @@ -330,7 +330,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)); @@ -347,7 +347,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)); @@ -558,7 +558,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; diff --git a/lightning/src/ln/onion_utils.rs b/lightning/src/ln/onion_utils.rs index ec668045eb0..1349e14f4cb 100644 --- a/lightning/src/ln/onion_utils.rs +++ b/lightning/src/ln/onion_utils.rs @@ -120,12 +120,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 @@ -135,15 +146,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 a86676422ed..6e7dc134c9e 100644 --- a/lightning/src/ln/payment_tests.rs +++ b/lightning/src/ln/payment_tests.rs @@ -50,7 +50,7 @@ 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 payment_id = nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret), 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); @@ -135,7 +135,7 @@ 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 payment_id = nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret), None).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); @@ -215,7 +215,7 @@ 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 payment_id = nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret), 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); @@ -266,7 +266,7 @@ 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)), + unwrap_send_err!(nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret), None), true, APIError::ChannelUnavailable { ref err }, assert_eq!(err, "Peer for first hop currently disconnected/pending monitor update!")); @@ -303,7 +303,7 @@ 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 payment_id = nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret), None).unwrap(); check_added_monitors!(nodes[0], 1); let mut events = nodes[0].node.get_and_clear_pending_msg_events(); @@ -728,7 +728,7 @@ fn get_ldk_payment_preimage() { &nodes[0].node.get_our_node_id(), &payment_params, &nodes[0].network_graph, Some(&nodes[0].node.list_usable_channels().iter().collect::>()), amt_msat, TEST_FINAL_CLTV, nodes[0].logger, &scorer).unwrap(); - let _payment_id = nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret)).unwrap(); + let _payment_id = nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret), None).unwrap(); check_added_monitors!(nodes[0], 1); // Make sure to use `get_payment_preimage` diff --git a/lightning/src/ln/shutdown_tests.rs b/lightning/src/ln/shutdown_tests.rs index 7cfca4b86fb..7ef4272ebd1 100644 --- a/lightning/src/ln/shutdown_tests.rs +++ b/lightning/src/ln/shutdown_tests.rs @@ -95,8 +95,8 @@ fn updates_shutdown_wait() { let route_1 = get_route(&nodes[0].node.get_our_node_id(), &payment_params_1, nodes[0].network_graph, None, 100000, TEST_FINAL_CLTV, &logger, &scorer).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, None, 100000, TEST_FINAL_CLTV, &logger, &scorer).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 {..}, {}); + unwrap_send_err!(nodes[0].node.send_payment(&route_1, payment_hash, &Some(payment_secret), None), true, APIError::ChannelUnavailable {..}, {}); + unwrap_send_err!(nodes[1].node.send_payment(&route_2, payment_hash, &Some(payment_secret), None), true, APIError::ChannelUnavailable {..}, {}); assert!(nodes[2].node.claim_funds(payment_preimage)); check_added_monitors!(nodes[2], 1); @@ -154,7 +154,7 @@ 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(); + nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret), None).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 cf2afbbbadb..a50e29cae05 100644 --- a/lightning/src/routing/router.rs +++ b/lightning/src/routing/router.rs @@ -4599,7 +4599,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 a4a733c8e50..e2c86253100 100644 --- a/lightning/src/util/events.rs +++ b/lightning/src/util/events.rs @@ -60,6 +60,8 @@ 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, + ///XXX + payment_metadata: Option>, }, /// Because this is a spontaneous payment, the payer generated their own preimage rather than us /// (the payee) providing a preimage. @@ -417,10 +419,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); @@ -428,6 +432,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 @@ -533,10 +538,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), @@ -545,8 +552,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), };