1use crate::chain::transaction::OutPoint;
13use crate::io;
14use crate::ln::msgs::DecodeError;
15use crate::sign::EntropySource;
16use crate::util::ser::{Readable, Writeable, Writer};
17use super::channel_keys::RevocationBasepoint;
18
19#[allow(unused_imports)]
20use crate::prelude::*;
21
22use bitcoin::hashes::{
23 Hash as _,
24 HashEngine as _,
25 sha256::Hash as Sha256,
26};
27use bitcoin::hex::display::impl_fmt_traits;
28use core::borrow::Borrow;
29use core::ops::Deref;
30
31#[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)]
40pub struct ChannelId(pub [u8; 32]);
41
42impl ChannelId {
43 pub fn v1_from_funding_txid(txid: &[u8; 32], output_index: u16) -> Self {
45 let mut res = [0; 32];
46 res[..].copy_from_slice(&txid[..]);
47 res[30] ^= ((output_index >> 8) & 0xff) as u8;
48 res[31] ^= ((output_index >> 0) & 0xff) as u8;
49 Self(res)
50 }
51
52 pub fn v1_from_funding_outpoint(outpoint: OutPoint) -> Self {
54 Self::v1_from_funding_txid(outpoint.txid.as_byte_array(), outpoint.index)
55 }
56
57 pub fn temporary_from_entropy_source<ES: Deref>(entropy_source: &ES) -> Self
59 where ES::Target: EntropySource {
60 Self(entropy_source.get_secure_random_bytes())
61 }
62
63 pub fn from_bytes(data: [u8; 32]) -> Self {
66 Self(data)
67 }
68
69 pub fn new_zero() -> Self {
71 Self([0; 32])
72 }
73
74 pub fn is_zero(&self) -> bool {
76 self.0[..] == [0; 32]
77 }
78
79 pub fn v2_from_revocation_basepoints(
83 ours: &RevocationBasepoint,
84 theirs: &RevocationBasepoint,
85 ) -> Self {
86 let ours = ours.0.serialize();
87 let theirs = theirs.0.serialize();
88 let (lesser, greater) = if ours < theirs {
89 (ours, theirs)
90 } else {
91 (theirs, ours)
92 };
93 let mut engine = Sha256::engine();
94 engine.input(&lesser[..]);
95 engine.input(&greater[..]);
96 Self(Sha256::from_engine(engine).to_byte_array())
97 }
98
99 pub fn temporary_v2_from_revocation_basepoint(our_revocation_basepoint: &RevocationBasepoint) -> Self {
102 Self(Sha256::hash(&[[0u8; 33], our_revocation_basepoint.0.serialize()].concat()).to_byte_array())
103 }
104}
105
106impl Writeable for ChannelId {
107 fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
108 self.0.write(w)
109 }
110}
111
112impl Readable for ChannelId {
113 fn read<R: io::Read>(r: &mut R) -> Result<Self, DecodeError> {
114 let buf: [u8; 32] = Readable::read(r)?;
115 Ok(ChannelId(buf))
116 }
117}
118
119impl Borrow<[u8]> for ChannelId {
120 fn borrow(&self) -> &[u8] {
121 &self.0[..]
122 }
123}
124
125impl_fmt_traits! {
126 impl fmt_traits for ChannelId {
127 const LENGTH: usize = 32;
128 }
129}
130
131#[cfg(test)]
132mod tests {
133 use bitcoin::hashes::{
134 Hash as _,
135 HashEngine as _,
136 hex::FromHex as _,
137 sha256::Hash as Sha256,
138 };
139 use bitcoin::secp256k1::PublicKey;
140 use bitcoin::hex::DisplayHex;
141
142 use super::ChannelId;
143 use crate::ln::channel_keys::RevocationBasepoint;
144 use crate::util::ser::{Readable, Writeable};
145 use crate::util::test_utils;
146 use crate::prelude::*;
147 use crate::io;
148
149 #[test]
150 fn test_channel_id_v1_from_funding_txid() {
151 let channel_id = ChannelId::v1_from_funding_txid(&[2; 32], 1);
152 assert_eq!(channel_id.0.as_hex().to_string(), "0202020202020202020202020202020202020202020202020202020202020203");
153 }
154
155 #[test]
156 fn test_channel_id_new_from_data() {
157 let data: [u8; 32] = [2; 32];
158 let channel_id = ChannelId::from_bytes(data.clone());
159 assert_eq!(channel_id.0, data);
160 }
161
162 #[test]
163 fn test_channel_id_equals() {
164 let channel_id11 = ChannelId::v1_from_funding_txid(&[2; 32], 2);
165 let channel_id12 = ChannelId::v1_from_funding_txid(&[2; 32], 2);
166 let channel_id21 = ChannelId::v1_from_funding_txid(&[2; 32], 42);
167 assert_eq!(channel_id11, channel_id12);
168 assert_ne!(channel_id11, channel_id21);
169 }
170
171 #[test]
172 fn test_channel_id_write_read() {
173 let data: [u8; 32] = [2; 32];
174 let channel_id = ChannelId::from_bytes(data.clone());
175
176 let mut w = test_utils::TestVecWriter(Vec::new());
177 channel_id.write(&mut w).unwrap();
178
179 let channel_id_2 = ChannelId::read(&mut io::Cursor::new(&w.0)).unwrap();
180 assert_eq!(channel_id_2, channel_id);
181 assert_eq!(channel_id_2.0, data);
182 }
183
184 #[test]
185 fn test_channel_id_display() {
186 let channel_id = ChannelId::v1_from_funding_txid(&[2; 32], 1);
187 assert_eq!(format!("{}", &channel_id), "0202020202020202020202020202020202020202020202020202020202020203");
188 }
189
190 #[test]
191 fn test_channel_id_v2_from_basepoints() {
192 let ours = RevocationBasepoint(PublicKey::from_slice(&<Vec<u8>>::from_hex("0324653eac434488002cc06bbfb7f10fe18991e35f9fe4302dbea6d2353dc0ab1c").unwrap()[..]).unwrap());
194 let theirs = RevocationBasepoint(PublicKey::from_slice(&<Vec<u8>>::from_hex("02eec7245d6b7d2ccb30380bfbe2a3648cd7a942653f5aa340edcea1f283686619").unwrap()[..]).unwrap());
195
196 let mut engine = Sha256::engine();
197 engine.input(&theirs.0.serialize());
198 engine.input(&ours.0.serialize());
199 let expected_id = ChannelId(Sha256::from_engine(engine).to_byte_array());
200
201 assert_eq!(ChannelId::v2_from_revocation_basepoints(&ours, &theirs), expected_id);
202
203 let ours = RevocationBasepoint(PublicKey::from_slice(&<Vec<u8>>::from_hex("027f31ebc5462c1fdce1b737ecff52d37d75dea43ce11c74d25aa297165faa2007").unwrap()[..]).unwrap());
205 let theirs = RevocationBasepoint(PublicKey::from_slice(&<Vec<u8>>::from_hex("02eec7245d6b7d2ccb30380bfbe2a3648cd7a942653f5aa340edcea1f283686619").unwrap()[..]).unwrap());
206
207 let mut engine = Sha256::engine();
208 engine.input(&ours.0.serialize());
209 engine.input(&theirs.0.serialize());
210 let expected_id = ChannelId(Sha256::from_engine(engine).to_byte_array());
211
212 assert_eq!(ChannelId::v2_from_revocation_basepoints(&ours, &theirs), expected_id);
213 }
214}