use util::ser::{Writeable, Writer, MaybeReadable, Readable, VecReadWrapper, VecWriteWrapper};
use bitcoin::blockdata::script::Script;
-
+use bitcoin::hashes::Hash;
+use bitcoin::hashes::sha256::Hash as Sha256;
use bitcoin::secp256k1::key::PublicKey;
use io;
/// payment is to pay an invoice or to send a spontaneous payment.
purpose: PaymentPurpose,
},
- /// Indicates an outbound payment we made succeeded (ie it made it all the way to its target
+ /// Indicates an outbound payment we made succeeded (i.e. it made it all the way to its target
/// and we got back the payment preimage for it).
+ ///
+ /// Note for MPP payments: in rare cases, this event may be preceded by a `PaymentFailed` event.
+ /// In this situation, you SHOULD treat this payment as having succeeded.
PaymentSent {
/// The preimage to the hash given to ChannelManager::send_payment.
/// Note that this serves as a payment receipt, if you wish to have such a thing, you must
/// store it somehow!
payment_preimage: PaymentPreimage,
+ /// The hash which was given to [`ChannelManager::send_payment`].
+ ///
+ /// [`ChannelManager::send_payment`]: crate::ln::channelmanager::ChannelManager::send_payment
+ payment_hash: PaymentHash,
},
/// Indicates an outbound payment we made failed. Probably some intermediary node dropped
/// something. You may wish to retry with a different route.
/// retry the payment via a different route.
rejected_by_dest: bool,
/// Any failure information conveyed via the Onion return packet by a node along the failed
- /// payment route. Should be applied to the [`NetworkGraph`] so that routing decisions can
- /// take into account the update.
+ /// payment route.
+ ///
+ /// Should be applied to the [`NetworkGraph`] so that routing decisions can take into
+ /// account the update. [`NetGraphMsgHandler`] is capable of doing this.
///
/// [`NetworkGraph`]: crate::routing::network_graph::NetworkGraph
+ /// [`NetGraphMsgHandler`]: crate::routing::network_graph::NetGraphMsgHandler
network_update: Option<NetworkUpdate>,
+ /// For both single-path and multi-path payments, this is set if all paths of the payment have
+ /// failed. This will be set to false if (1) this is an MPP payment and (2) other parts of the
+ /// larger MPP payment were still in flight when this event was generated.
+ all_paths_failed: bool,
#[cfg(test)]
error_code: Option<u16>,
#[cfg(test)]
(8, payment_preimage, option),
});
},
- &Event::PaymentSent { ref payment_preimage } => {
+ &Event::PaymentSent { ref payment_preimage, ref payment_hash} => {
2u8.write(writer)?;
write_tlv_fields!(writer, {
(0, payment_preimage, required),
+ (1, payment_hash, required),
});
},
- &Event::PaymentFailed { ref payment_hash, ref rejected_by_dest, ref network_update,
+ &Event::PaymentFailed { ref payment_hash, ref rejected_by_dest, ref network_update, ref all_paths_failed,
#[cfg(test)]
ref error_code,
#[cfg(test)]
(0, payment_hash, required),
(1, network_update, option),
(2, rejected_by_dest, required),
+ (3, all_paths_failed, required),
});
},
&Event::PendingHTLCsForwardable { time_forwardable: _ } => {
2u8 => {
let f = || {
let mut payment_preimage = PaymentPreimage([0; 32]);
+ let mut payment_hash = None;
read_tlv_fields!(reader, {
(0, payment_preimage, required),
+ (1, payment_hash, option),
});
+ if payment_hash.is_none() {
+ payment_hash = Some(PaymentHash(Sha256::hash(&payment_preimage.0[..]).into_inner()));
+ }
Ok(Some(Event::PaymentSent {
payment_preimage,
+ payment_hash: payment_hash.unwrap(),
}))
};
f()
let mut payment_hash = PaymentHash([0; 32]);
let mut rejected_by_dest = false;
let mut network_update = None;
+ let mut all_paths_failed = Some(true);
read_tlv_fields!(reader, {
(0, payment_hash, required),
(1, network_update, ignorable),
(2, rejected_by_dest, required),
+ (3, all_paths_failed, option),
});
Ok(Some(Event::PaymentFailed {
payment_hash,
rejected_by_dest,
network_update,
+ all_paths_failed: all_paths_failed.unwrap(),
#[cfg(test)]
error_code,
#[cfg(test)]