Skip to content

Commit 7a992ba

Browse files
committed
Add new ChannelId type; unused
1 parent 3dffe54 commit 7a992ba

File tree

2 files changed

+145
-0
lines changed

2 files changed

+145
-0
lines changed

lightning/src/ln/channel_id.rs

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

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)