Skip to content

Commit 385819b

Browse files
committed
Add new ChannelId struct, unused
1 parent 3dffe54 commit 385819b

File tree

2 files changed

+148
-0
lines changed

2 files changed

+148
-0
lines changed

lightning/src/ln/channel_id.rs

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

lightning/src/ln/mod.rs

+4
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)