aa6779fb33d29d6f742d5b2fb5fdfe2ba742333f
[rust-lightning] / lightning / src / onion_message / async_payments.rs
1 // This file is Copyright its original authors, visible in version control
2 // history.
3 //
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
8 // licenses.
9
10 //! Message handling for async payments.
11
12 use crate::io;
13 use crate::ln::msgs::DecodeError;
14 use crate::onion_message::packet::OnionMessageContents;
15 use crate::util::ser::{Readable, ReadableArgs, Writeable, Writer};
16
17 // TLV record types for the `onionmsg_tlv` TLV stream as defined in BOLT 4.
18 const HELD_HTLC_AVAILABLE_TLV_TYPE: u64 = 72;
19 const RELEASE_HELD_HTLC_TLV_TYPE: u64 = 74;
20
21 /// Possible async payment messages sent and received via an [`OnionMessage`].
22 ///
23 /// [`OnionMessage`]: crate::ln::msgs::OnionMessage
24 #[derive(Clone, Debug)]
25 pub enum AsyncPaymentsMessage {
26         /// An HTLC is being held upstream for the often-offline recipient, to be released via
27         /// [`ReleaseHeldHtlc`].
28         HeldHtlcAvailable(HeldHtlcAvailable),
29
30         /// Releases the HTLC corresponding to an inbound [`HeldHtlcAvailable`] message.
31         ReleaseHeldHtlc(ReleaseHeldHtlc),
32 }
33
34 /// An HTLC destined for the recipient of this message is being held upstream. The reply path
35 /// accompanying this onion message should be used to send a [`ReleaseHeldHtlc`] response, which
36 /// will cause the upstream HTLC to be released.
37 #[derive(Clone, Debug)]
38 pub struct HeldHtlcAvailable {
39         /// The secret that will be used by the recipient of this message to release the held HTLC.
40         pub payment_release_secret: [u8; 32],
41 }
42
43 /// Releases the HTLC corresponding to an inbound [`HeldHtlcAvailable`] message.
44 #[derive(Clone, Debug)]
45 pub struct ReleaseHeldHtlc {
46         /// Used to release the HTLC held upstream if it matches the corresponding
47         /// [`HeldHtlcAvailable::payment_release_secret`].
48         pub payment_release_secret: [u8; 32],
49 }
50
51 impl OnionMessageContents for ReleaseHeldHtlc {
52         fn tlv_type(&self) -> u64 {
53                 RELEASE_HELD_HTLC_TLV_TYPE
54         }
55         fn msg_type(&self) -> &'static str {
56                 "Release Held HTLC"
57         }
58 }
59
60 impl_writeable_tlv_based!(HeldHtlcAvailable, {
61         (0, payment_release_secret, required),
62 });
63
64 impl_writeable_tlv_based!(ReleaseHeldHtlc, {
65         (0, payment_release_secret, required),
66 });
67
68 impl AsyncPaymentsMessage {
69         /// Returns whether `tlv_type` corresponds to a TLV record for async payment messages.
70         pub fn is_known_type(tlv_type: u64) -> bool {
71                 match tlv_type {
72                         HELD_HTLC_AVAILABLE_TLV_TYPE | RELEASE_HELD_HTLC_TLV_TYPE => true,
73                         _ => false,
74                 }
75         }
76 }
77
78 impl OnionMessageContents for AsyncPaymentsMessage {
79         fn tlv_type(&self) -> u64 {
80                 match self {
81                         Self::HeldHtlcAvailable(_) => HELD_HTLC_AVAILABLE_TLV_TYPE,
82                         Self::ReleaseHeldHtlc(msg) => msg.tlv_type(),
83                 }
84         }
85         fn msg_type(&self) -> &'static str {
86                 match &self {
87                         Self::HeldHtlcAvailable(_) => "Held HTLC Available",
88                         Self::ReleaseHeldHtlc(msg) => msg.msg_type(),
89                 }
90         }
91 }
92
93 impl Writeable for AsyncPaymentsMessage {
94         fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
95                 match self {
96                         Self::HeldHtlcAvailable(message) => message.write(w),
97                         Self::ReleaseHeldHtlc(message) => message.write(w),
98                 }
99         }
100 }
101
102 impl ReadableArgs<u64> for AsyncPaymentsMessage {
103         fn read<R: io::Read>(r: &mut R, tlv_type: u64) -> Result<Self, DecodeError> {
104                 match tlv_type {
105                         HELD_HTLC_AVAILABLE_TLV_TYPE => Ok(Self::HeldHtlcAvailable(Readable::read(r)?)),
106                         RELEASE_HELD_HTLC_TLV_TYPE => Ok(Self::ReleaseHeldHtlc(Readable::read(r)?)),
107                         _ => Err(DecodeError::InvalidValue),
108                 }
109         }
110 }