Merge pull request #3045 from TheBlueMatt/2024-03-fees-are-dust
[rust-lightning] / lightning / src / ln / types.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 //! Various wrapper types (most around 32-byte arrays) for use in lightning.
11
12 use crate::chain::transaction::OutPoint;
13 use crate::io;
14 use crate::ln::msgs::DecodeError;
15 use crate::sign::EntropySource;
16 use crate::util::ser::{Readable, Writeable, Writer};
17 use super::channel_keys::RevocationBasepoint;
18
19 #[allow(unused_imports)]
20 use crate::prelude::*;
21
22 use bitcoin::hashes::{
23         Hash as _,
24         HashEngine as _,
25         sha256::Hash as Sha256,
26 };
27 use core::fmt;
28 use core::ops::Deref;
29
30 /// A unique 32-byte identifier for a channel.
31 /// Depending on how the ID is generated, several varieties are distinguished
32 /// (but all are stored as 32 bytes):
33 ///   _v1_ and _temporary_.
34 /// A _v1_ channel ID is generated based on funding tx outpoint (txid & index).
35 /// A _temporary_ ID is generated randomly.
36 /// (Later revocation-point-based _v2_ is a possibility.)
37 /// The variety (context) is not stored, it is relevant only at creation.
38 ///
39 /// This is not exported to bindings users as we just use [u8; 32] directly.
40 #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
41 pub struct ChannelId(pub [u8; 32]);
42
43 impl ChannelId {
44         /// Create _v1_ channel ID based on a funding TX ID and output index
45         pub fn v1_from_funding_txid(txid: &[u8; 32], output_index: u16) -> Self {
46                 let mut res = [0; 32];
47                 res[..].copy_from_slice(&txid[..]);
48                 res[30] ^= ((output_index >> 8) & 0xff) as u8;
49                 res[31] ^= ((output_index >> 0) & 0xff) as u8;
50                 Self(res)
51         }
52
53         /// Create _v1_ channel ID from a funding tx outpoint
54         pub fn v1_from_funding_outpoint(outpoint: OutPoint) -> Self {
55                 Self::v1_from_funding_txid(outpoint.txid.as_byte_array(), outpoint.index)
56         }
57
58         /// Create a _temporary_ channel ID randomly, based on an entropy source.
59         pub fn temporary_from_entropy_source<ES: Deref>(entropy_source: &ES) -> Self
60         where ES::Target: EntropySource {
61                 Self(entropy_source.get_secure_random_bytes())
62         }
63
64         /// Generic constructor; create a new channel ID from the provided data.
65         /// Use a more specific `*_from_*` constructor when possible.
66         pub fn from_bytes(data: [u8; 32]) -> Self {
67                 Self(data)
68         }
69
70         /// Create a channel ID consisting of all-zeros data (e.g. when uninitialized or a placeholder).
71         pub fn new_zero() -> Self {
72                 Self([0; 32])
73         }
74
75         /// Check whether ID is consisting of all zeros (uninitialized)
76         pub fn is_zero(&self) -> bool {
77                 self.0[..] == [0; 32]
78         }
79
80         /// Create _v2_ channel ID by concatenating the holder revocation basepoint with the counterparty
81         /// revocation basepoint and hashing the result. The basepoints will be concatenated in increasing
82         /// sorted order.
83         pub fn v2_from_revocation_basepoints(
84                 ours: &RevocationBasepoint,
85                 theirs: &RevocationBasepoint,
86         ) -> Self {
87                 let ours = ours.0.serialize();
88                 let theirs = theirs.0.serialize();
89                 let (lesser, greater) = if ours < theirs {
90                         (ours, theirs)
91                 } else {
92                         (theirs, ours)
93                 };
94                 let mut engine = Sha256::engine();
95                 engine.input(&lesser[..]);
96                 engine.input(&greater[..]);
97                 Self(Sha256::from_engine(engine).to_byte_array())
98         }
99
100         /// Create temporary _v2_ channel ID by concatenating a zeroed out basepoint with the holder
101         /// revocation basepoint and hashing the result.
102         pub fn temporary_v2_from_revocation_basepoint(our_revocation_basepoint: &RevocationBasepoint) -> Self {
103                 Self(Sha256::hash(&[[0u8; 33], our_revocation_basepoint.0.serialize()].concat()).to_byte_array())
104         }
105 }
106
107 impl Writeable for ChannelId {
108         fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
109                 self.0.write(w)
110         }
111 }
112
113 impl Readable for ChannelId {
114         fn read<R: io::Read>(r: &mut R) -> Result<Self, DecodeError> {
115                 let buf: [u8; 32] = Readable::read(r)?;
116                 Ok(ChannelId(buf))
117         }
118 }
119
120 impl fmt::Display for ChannelId {
121         fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
122                 crate::util::logger::DebugBytes(&self.0).fmt(f)
123         }
124 }
125
126
127 /// The payment hash is the hash of the [`PaymentPreimage`] which is the value used to lock funds
128 /// in HTLCs while they transit the lightning network.
129 ///
130 /// This is not exported to bindings users as we just use [u8; 32] directly
131 #[derive(Hash, Copy, Clone, PartialEq, Eq, Debug, Ord, PartialOrd)]
132 pub struct PaymentHash(pub [u8; 32]);
133
134 impl core::fmt::Display for PaymentHash {
135         fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
136                 crate::util::logger::DebugBytes(&self.0).fmt(f)
137         }
138 }
139
140 /// The payment preimage is the "secret key" which is used to claim the funds of an HTLC on-chain
141 /// or in a lightning channel.
142 ///
143 /// This is not exported to bindings users as we just use [u8; 32] directly
144 #[derive(Hash, Copy, Clone, PartialEq, Eq, Debug, Ord, PartialOrd)]
145 pub struct PaymentPreimage(pub [u8; 32]);
146
147 impl core::fmt::Display for PaymentPreimage {
148         fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
149                 crate::util::logger::DebugBytes(&self.0).fmt(f)
150         }
151 }
152
153 /// Converts a `PaymentPreimage` into a `PaymentHash` by hashing the preimage with SHA256.
154 impl From<PaymentPreimage> for PaymentHash {
155         fn from(value: PaymentPreimage) -> Self {
156                 PaymentHash(Sha256::hash(&value.0).to_byte_array())
157         }
158 }
159
160 /// The payment secret is used to authenticate the sender of an HTLC to the recipient and tie
161 /// multi-part HTLCs together into a single payment.
162 ///
163 /// This is not exported to bindings users as we just use [u8; 32] directly
164 #[derive(Hash, Copy, Clone, PartialEq, Eq, Debug, Ord, PartialOrd)]
165 pub struct PaymentSecret(pub [u8; 32]);
166
167 use bitcoin::bech32;
168 use bitcoin::bech32::{Base32Len, FromBase32, ToBase32, WriteBase32, u5};
169
170 impl FromBase32 for PaymentSecret {
171         type Err = bech32::Error;
172
173         fn from_base32(field_data: &[u5]) -> Result<PaymentSecret, bech32::Error> {
174                 if field_data.len() != 52 {
175                         return Err(bech32::Error::InvalidLength)
176                 } else {
177                         let data_bytes = Vec::<u8>::from_base32(field_data)?;
178                         let mut payment_secret = [0; 32];
179                         payment_secret.copy_from_slice(&data_bytes);
180                         Ok(PaymentSecret(payment_secret))
181                 }
182         }
183 }
184
185 impl ToBase32 for PaymentSecret {
186         fn write_base32<W: WriteBase32>(&self, writer: &mut W) -> Result<(), <W as WriteBase32>::Err> {
187                 (&self.0[..]).write_base32(writer)
188         }
189 }
190
191 impl Base32Len for PaymentSecret {
192         fn base32_len(&self) -> usize {
193                 52
194         }
195 }
196
197 #[cfg(test)]
198 mod tests {
199         use bitcoin::hashes::{
200                 Hash as _,
201                 HashEngine as _,
202                 hex::FromHex as _,
203                 sha256::Hash as Sha256,
204         };
205         use bitcoin::secp256k1::PublicKey;
206         use hex::DisplayHex;
207
208         use super::ChannelId;
209         use crate::ln::channel_keys::RevocationBasepoint;
210         use crate::util::ser::{Readable, Writeable};
211         use crate::util::test_utils;
212         use crate::prelude::*;
213         use crate::io;
214
215         #[test]
216         fn test_channel_id_v1_from_funding_txid() {
217                 let channel_id = ChannelId::v1_from_funding_txid(&[2; 32], 1);
218                 assert_eq!(channel_id.0.as_hex().to_string(), "0202020202020202020202020202020202020202020202020202020202020203");
219         }
220
221         #[test]
222         fn test_channel_id_new_from_data() {
223                 let data: [u8; 32] = [2; 32];
224                 let channel_id = ChannelId::from_bytes(data.clone());
225                 assert_eq!(channel_id.0, data);
226         }
227
228         #[test]
229         fn test_channel_id_equals() {
230                 let channel_id11 = ChannelId::v1_from_funding_txid(&[2; 32], 2);
231                 let channel_id12 = ChannelId::v1_from_funding_txid(&[2; 32], 2);
232                 let channel_id21 = ChannelId::v1_from_funding_txid(&[2; 32], 42);
233                 assert_eq!(channel_id11, channel_id12);
234                 assert_ne!(channel_id11, channel_id21);
235         }
236
237         #[test]
238         fn test_channel_id_write_read() {
239                 let data: [u8; 32] = [2; 32];
240                 let channel_id = ChannelId::from_bytes(data.clone());
241
242                 let mut w = test_utils::TestVecWriter(Vec::new());
243                 channel_id.write(&mut w).unwrap();
244
245                 let channel_id_2 = ChannelId::read(&mut io::Cursor::new(&w.0)).unwrap();
246                 assert_eq!(channel_id_2, channel_id);
247                 assert_eq!(channel_id_2.0, data);
248         }
249
250         #[test]
251         fn test_channel_id_display() {
252                 let channel_id = ChannelId::v1_from_funding_txid(&[2; 32], 1);
253                 assert_eq!(format!("{}", &channel_id), "0202020202020202020202020202020202020202020202020202020202020203");
254         }
255
256         #[test]
257         fn test_channel_id_v2_from_basepoints() {
258                 // Ours greater than theirs
259                 let ours = RevocationBasepoint(PublicKey::from_slice(&<Vec<u8>>::from_hex("0324653eac434488002cc06bbfb7f10fe18991e35f9fe4302dbea6d2353dc0ab1c").unwrap()[..]).unwrap());
260                 let theirs = RevocationBasepoint(PublicKey::from_slice(&<Vec<u8>>::from_hex("02eec7245d6b7d2ccb30380bfbe2a3648cd7a942653f5aa340edcea1f283686619").unwrap()[..]).unwrap());
261
262                 let mut engine = Sha256::engine();
263                 engine.input(&theirs.0.serialize());
264                 engine.input(&ours.0.serialize());
265                 let expected_id = ChannelId(Sha256::from_engine(engine).to_byte_array());
266
267                 assert_eq!(ChannelId::v2_from_revocation_basepoints(&ours, &theirs), expected_id);
268
269                 // Theirs greater than ours
270                 let ours = RevocationBasepoint(PublicKey::from_slice(&<Vec<u8>>::from_hex("027f31ebc5462c1fdce1b737ecff52d37d75dea43ce11c74d25aa297165faa2007").unwrap()[..]).unwrap());
271                 let theirs = RevocationBasepoint(PublicKey::from_slice(&<Vec<u8>>::from_hex("02eec7245d6b7d2ccb30380bfbe2a3648cd7a942653f5aa340edcea1f283686619").unwrap()[..]).unwrap());
272
273                 let mut engine = Sha256::engine();
274                 engine.input(&ours.0.serialize());
275                 engine.input(&theirs.0.serialize());
276                 let expected_id = ChannelId(Sha256::from_engine(engine).to_byte_array());
277
278                 assert_eq!(ChannelId::v2_from_revocation_basepoints(&ours, &theirs), expected_id);
279         }
280 }