Skip to content

Commit 43a9264

Browse files
committed
Add new ChannelId struct, unused
1 parent bbe20c3 commit 43a9264

File tree

2 files changed

+147
-0
lines changed

2 files changed

+147
-0
lines changed

lightning/src/ln/channel_id.rs

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
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+
use crate::ln::msgs::DecodeError;
11+
use crate::sign::EntropySource;
12+
use crate::util::ser::{Readable, Writeable, Writer};
13+
14+
use bitcoin::hashes::hex::ToHex;
15+
16+
use crate::io;
17+
use crate::prelude::*;
18+
use core::fmt;
19+
use core::ops::Deref;
20+
21+
22+
/// A unique 32-byte identifier for a channel.
23+
/// Depending on how the ID is generated, several varieties are distinguished (but all are stored as 32 bytes):
24+
/// - v1: generated based on funding tx outpoint (txid&index)
25+
/// - temporary: generated randomly
26+
/// (later planned v2: based on revocation point)
27+
/// The variety (context) is not stored, it is relevant only at creation.
28+
/// This is not exported to bindings users as we just use [u8; 32] directly
29+
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
30+
pub struct ChannelId {
31+
// The 32-byte data of the ID
32+
data: [u8; 32],
33+
}
34+
35+
impl ChannelId {
36+
/// Create v1 channel ID based on a funding TX ID and output index
37+
pub fn v1_from_funding_txid(txid: &[u8; 32], output_index: u16) -> Self {
38+
let mut res = [0; 32];
39+
res[..].copy_from_slice(&txid[..]);
40+
res[30] ^= ((output_index >> 8) & 0xff) as u8;
41+
res[31] ^= ((output_index >> 0) & 0xff) as u8;
42+
Self::from_bytes(res)
43+
}
44+
45+
/// Create a temporary channel ID randomly, based on an entropy source.
46+
pub fn temporary_from_entropy_source<ES: Deref>(entropy_source: &ES) -> Self
47+
where ES::Target: EntropySource {
48+
Self::from_bytes(entropy_source.get_secure_random_bytes())
49+
}
50+
51+
/// Generic constructor; create a new channel ID from the provided data.
52+
/// Use a more specific *from_* constructor when possible.
53+
/// This constructor is useful for tests, and internally, e.g. when the channel ID is being deserialized.
54+
pub fn from_bytes(data: [u8; 32]) -> Self {
55+
Self{data}
56+
}
57+
58+
/// Create a channel ID consisting of all-zeros data (placeholder).
59+
pub fn new_zero() -> Self {
60+
Self::from_bytes([0; 32])
61+
}
62+
63+
/// Accessor for the channel ID data
64+
pub fn bytes(&self) -> &[u8; 32] {
65+
&self.data
66+
}
67+
}
68+
69+
impl Writeable for ChannelId {
70+
fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
71+
self.data.write(w)
72+
}
73+
}
74+
75+
impl Readable for ChannelId {
76+
fn read<R: io::Read>(r: &mut R) -> Result<Self, DecodeError> {
77+
let buf: [u8; 32] = Readable::read(r)?;
78+
Ok(ChannelId::from_bytes(buf))
79+
}
80+
}
81+
82+
impl ToHex for ChannelId {
83+
fn to_hex(&self) -> String {
84+
self.data.to_hex()
85+
}
86+
}
87+
88+
impl fmt::Display for ChannelId {
89+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
90+
crate::util::logger::DebugBytes(&self.data).fmt(f)
91+
}
92+
}
93+
94+
#[cfg(test)]
95+
mod tests {
96+
use crate::ln::ChannelId;
97+
use crate::util::ser::{Readable, Writeable};
98+
use crate::util::test_utils;
99+
use bitcoin::hashes::hex::ToHex;
100+
use crate::prelude::*;
101+
use crate::io;
102+
103+
#[test]
104+
fn test_channel_id_new_from_data() {
105+
let data: [u8; 32] = [2; 32];
106+
let channel_id = ChannelId::from_bytes(data.clone());
107+
assert_eq!(*channel_id.bytes(), data);
108+
}
109+
110+
#[test]
111+
fn test_channel_id_v1_from_funding_txid() {
112+
let channel_id = ChannelId::v1_from_funding_txid(&[2; 32], 1);
113+
assert_eq!(channel_id.to_hex(), "0202020202020202020202020202020202020202020202020202020202020203");
114+
}
115+
116+
#[test]
117+
fn test_channel_id_equals() {
118+
let channel_id11 = ChannelId::v1_from_funding_txid(&[2; 32], 2);
119+
let channel_id12 = ChannelId::v1_from_funding_txid(&[2; 32], 2);
120+
let channel_id21 = ChannelId::v1_from_funding_txid(&[2; 32], 42);
121+
assert_eq!(channel_id11, channel_id12);
122+
assert_ne!(channel_id11, channel_id21);
123+
}
124+
125+
#[test]
126+
fn test_channel_id_write_read() {
127+
let data: [u8; 32] = [2; 32];
128+
let channel_id = ChannelId::from_bytes(data.clone());
129+
130+
let mut w = test_utils::TestVecWriter(Vec::new());
131+
channel_id.write(&mut w).unwrap();
132+
133+
let channel_id_2 = ChannelId::read(&mut io::Cursor::new(&w.0)).unwrap();
134+
assert_eq!(channel_id_2, channel_id);
135+
assert_eq!(channel_id_2.bytes(), &data);
136+
}
137+
138+
#[test]
139+
fn test_channel_id_display() {
140+
let channel_id = ChannelId::from_bytes([42; 32]);
141+
assert_eq!(format!("{}", &channel_id), "2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a");
142+
}
143+
}

lightning/src/ln/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#[macro_use]
1414
pub mod functional_test_utils;
1515

16+
pub mod channel_id;
1617
pub mod channelmanager;
1718
pub mod inbound_payment;
1819
pub mod msgs;
@@ -31,6 +32,9 @@ pub mod channel;
3132
#[cfg(not(fuzzing))]
3233
pub(crate) mod channel;
3334

35+
// Re-export ChannelId
36+
pub use self::channel_id::ChannelId;
37+
3438
pub(crate) mod onion_utils;
3539
mod outbound_payment;
3640
pub mod wire;

0 commit comments

Comments
 (0)