1 // This file is Copyright its original authors, visible in version control
4 // This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
5 // or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
7 // You may not use this file except in accordance with one or both of these
10 //! Message handling for async payments.
13 use crate::ln::msgs::DecodeError;
14 use crate::onion_message::messenger::PendingOnionMessage;
15 use crate::onion_message::messenger::{Responder, ResponseInstruction};
16 use crate::onion_message::packet::OnionMessageContents;
17 use crate::prelude::*;
18 use crate::util::ser::{Readable, ReadableArgs, Writeable, Writer};
20 // TLV record types for the `onionmsg_tlv` TLV stream as defined in BOLT 4.
21 const HELD_HTLC_AVAILABLE_TLV_TYPE: u64 = 72;
22 const RELEASE_HELD_HTLC_TLV_TYPE: u64 = 74;
24 /// A handler for an [`OnionMessage`] containing an async payments message as its payload.
26 /// [`OnionMessage`]: crate::ln::msgs::OnionMessage
27 pub trait AsyncPaymentsMessageHandler {
28 /// Handle a [`HeldHtlcAvailable`] message. A [`ReleaseHeldHtlc`] should be returned to release
30 fn held_htlc_available(
31 &self, message: HeldHtlcAvailable, responder: Option<Responder>,
32 ) -> ResponseInstruction<ReleaseHeldHtlc>;
34 /// Handle a [`ReleaseHeldHtlc`] message. If authentication of the message succeeds, an HTLC
35 /// should be released to the corresponding payee.
36 fn release_held_htlc(&self, message: ReleaseHeldHtlc);
38 /// Release any [`AsyncPaymentsMessage`]s that need to be sent.
40 /// Typically, this is used for messages initiating an async payment flow rather than in response
41 /// to another message.
42 #[cfg(not(c_bindings))]
43 fn release_pending_messages(&self) -> Vec<PendingOnionMessage<AsyncPaymentsMessage>> {
47 /// Release any [`AsyncPaymentsMessage`]s that need to be sent.
49 /// Typically, this is used for messages initiating a payment flow rather than in response to
52 fn release_pending_messages(
56 crate::onion_message::messenger::Destination,
57 Option<crate::blinded_path::BlindedPath>,
63 /// Possible async payment messages sent and received via an [`OnionMessage`].
65 /// [`OnionMessage`]: crate::ln::msgs::OnionMessage
66 #[derive(Clone, Debug)]
67 pub enum AsyncPaymentsMessage {
68 /// An HTLC is being held upstream for the often-offline recipient, to be released via
69 /// [`ReleaseHeldHtlc`].
70 HeldHtlcAvailable(HeldHtlcAvailable),
72 /// Releases the HTLC corresponding to an inbound [`HeldHtlcAvailable`] message.
73 ReleaseHeldHtlc(ReleaseHeldHtlc),
76 /// An HTLC destined for the recipient of this message is being held upstream. The reply path
77 /// accompanying this onion message should be used to send a [`ReleaseHeldHtlc`] response, which
78 /// will cause the upstream HTLC to be released.
79 #[derive(Clone, Debug)]
80 pub struct HeldHtlcAvailable {
81 /// The secret that will be used by the recipient of this message to release the held HTLC.
82 pub payment_release_secret: [u8; 32],
85 /// Releases the HTLC corresponding to an inbound [`HeldHtlcAvailable`] message.
86 #[derive(Clone, Debug)]
87 pub struct ReleaseHeldHtlc {
88 /// Used to release the HTLC held upstream if it matches the corresponding
89 /// [`HeldHtlcAvailable::payment_release_secret`].
90 pub payment_release_secret: [u8; 32],
93 impl OnionMessageContents for ReleaseHeldHtlc {
94 fn tlv_type(&self) -> u64 {
95 RELEASE_HELD_HTLC_TLV_TYPE
97 fn msg_type(&self) -> &'static str {
102 impl_writeable_tlv_based!(HeldHtlcAvailable, {
103 (0, payment_release_secret, required),
106 impl_writeable_tlv_based!(ReleaseHeldHtlc, {
107 (0, payment_release_secret, required),
110 impl AsyncPaymentsMessage {
111 /// Returns whether `tlv_type` corresponds to a TLV record for async payment messages.
112 pub fn is_known_type(tlv_type: u64) -> bool {
114 HELD_HTLC_AVAILABLE_TLV_TYPE | RELEASE_HELD_HTLC_TLV_TYPE => true,
120 impl OnionMessageContents for AsyncPaymentsMessage {
121 fn tlv_type(&self) -> u64 {
123 Self::HeldHtlcAvailable(_) => HELD_HTLC_AVAILABLE_TLV_TYPE,
124 Self::ReleaseHeldHtlc(msg) => msg.tlv_type(),
127 fn msg_type(&self) -> &'static str {
129 Self::HeldHtlcAvailable(_) => "Held HTLC Available",
130 Self::ReleaseHeldHtlc(msg) => msg.msg_type(),
135 impl Writeable for AsyncPaymentsMessage {
136 fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
138 Self::HeldHtlcAvailable(message) => message.write(w),
139 Self::ReleaseHeldHtlc(message) => message.write(w),
144 impl ReadableArgs<u64> for AsyncPaymentsMessage {
145 fn read<R: io::Read>(r: &mut R, tlv_type: u64) -> Result<Self, DecodeError> {
147 HELD_HTLC_AVAILABLE_TLV_TYPE => Ok(Self::HeldHtlcAvailable(Readable::read(r)?)),
148 RELEASE_HELD_HTLC_TLV_TYPE => Ok(Self::ReleaseHeldHtlc(Readable::read(r)?)),
149 _ => Err(DecodeError::InvalidValue),