Skip to content

Commit 817c6bb

Browse files
committed
WIP: Adding tower messages
This involved LDK related work to use the macros in `teos-common::lightning_messages`. LDK fork used: https://github.com/meryacine/rust-lightning/tree/expose-tlv-macros The LDK fork above is implementing what's missing in this issue: lightningdevkit/rust-lightning#1539. which is expected to land in LDK v0.1
1 parent 2ab0b96 commit 817c6bb

File tree

3 files changed

+286
-2
lines changed

3 files changed

+286
-2
lines changed

teos-common/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,5 @@ rand = "0.8.4"
1515
chacha20poly1305 = "0.8.0"
1616

1717
# Bitcoin and Lightning
18-
bitcoin = "0.27"
19-
lightning = "0.0.105"
18+
bitcoin = "0.28.1"
19+
lightning = { git = "https://github.com/meryacine/rust-lightning", branch = "expose-tlv-macros" }

teos-common/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ pub mod appointment;
66
pub mod constants;
77
pub mod cryptography;
88
pub mod errors;
9+
pub mod lightning_messages;
910
pub mod receipts;
1011

1112
use std::fmt;

teos-common/src/lightning_messages.rs

Lines changed: 283 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,283 @@
1+
use bitcoin::secp256k1::PublicKey;
2+
use bitcoin::Txid;
3+
use lightning::ln::msgs::DecodeError;
4+
use lightning::ln::peer_handler::{CustomMessageHandler, PeerManager};
5+
use lightning::ln::wire::{CustomMessageReader, Type};
6+
use lightning::util::ser;
7+
8+
// To use (de)serialization macros.
9+
use lightning::*;
10+
11+
use crate::appointment::{Locator, LOCATOR_LEN};
12+
13+
/// A wrapper around a vector inside a lightning message.
14+
/// This wrapper mainly exists because we cannot implement LDK's (de)serialization traits
15+
/// for Vec (since neither the traits nor Vec are defined in our crate (the orphan rule)).
16+
pub struct LightningVec<T>(Vec<T>);
17+
18+
// Implement Deref for our wrapper so we can call Vec methods on it directly.
19+
impl<T> std::ops::Deref for LightningVec<T> {
20+
type Target = Vec<T>;
21+
22+
fn deref(&self) -> &Self::Target {
23+
&self.0
24+
}
25+
}
26+
27+
// fmt the inner Vec.
28+
impl<T: std::fmt::Debug> std::fmt::Debug for LightningVec<T> {
29+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
30+
self.0.fmt(f)
31+
}
32+
}
33+
34+
/// The register message sent by the user to subscribe for the watching service.
35+
#[derive(Debug)]
36+
pub struct Register {
37+
pub pubkey: PublicKey,
38+
pub appointment_slots: u32,
39+
pub subscription_period: u32,
40+
}
41+
42+
/// The subscription details message that is sent to the user after registering or toping up.
43+
/// This message is the response to the register message.
44+
#[derive(Debug)]
45+
pub struct SubscriptionDetails {
46+
pub appointment_max_size: u16,
47+
pub amount_msat: u32,
48+
// Optional TLV.
49+
pub signature: Option<String>,
50+
}
51+
52+
/// The add/update appointment message sent by the user.
53+
#[derive(Debug)]
54+
pub struct AddUpdateAppointment {
55+
pub locator: Locator,
56+
// NOTE: LDK will prefix varying size fields (e.g. vectors and strings) with their length.
57+
pub encrypted_blob: Vec<u8>,
58+
pub signature: String,
59+
// Optional TLV.
60+
pub to_self_delay: Option<u64>,
61+
}
62+
63+
/// The appointment accepted message that is sent after an accepted add/update appointment message.
64+
#[derive(Debug)]
65+
pub struct AppointmentAccepted {
66+
pub locator: Locator,
67+
pub start_block: u32,
68+
// Optional TLV.
69+
pub receipt_signature: Option<String>,
70+
}
71+
72+
/// The appointment rejected message that is sent if an add/update appointment message was rejected.
73+
#[derive(Debug)]
74+
pub struct AppointmentRejected {
75+
pub locator: Locator,
76+
pub rcode: u16,
77+
pub reason: String,
78+
}
79+
80+
/// The get appointment message sent by the user to retrieve a previously sent appointment from the tower.
81+
#[derive(Debug)]
82+
pub struct GetAppointment {
83+
pub locator: Locator,
84+
pub signature: String,
85+
}
86+
87+
/// The appointment found message sent by the tower after a get appointment message.
88+
#[derive(Debug)]
89+
pub struct AppointmentFound {
90+
pub locator: Locator,
91+
pub encrypted_blob: Vec<u8>,
92+
}
93+
94+
/// The tracker found message sent by the tower when the requested appointment has been acted upon.
95+
#[derive(Debug)]
96+
pub struct TrackerFound {
97+
pub dispute_txid: Txid,
98+
pub penalty_txid: Txid,
99+
pub penalty_rawtx: Vec<u8>,
100+
}
101+
102+
/// The appointment not found message sent by the tower in response to a get appointment message
103+
/// whose locator didn't match any known appointment.
104+
#[derive(Debug)]
105+
pub struct AppointmentNotFound {
106+
pub locator: Locator,
107+
}
108+
109+
/// The get subscription info message (a TEOS custom message, not a bolt13 one).
110+
#[derive(Debug)]
111+
pub struct GetSubscriptionInfo {
112+
pub signature: String,
113+
}
114+
115+
/// The user subscription info message sent by the tower in response to get subscription info message.
116+
#[derive(Debug)]
117+
pub struct UserSubscriptionInfo {
118+
pub available_slots: u32,
119+
pub subscription_expiry: u32,
120+
pub locators: LightningVec<Locator>,
121+
}
122+
123+
// Deserialization for a Locator inside a lightning message.
124+
impl ser::Readable for Locator {
125+
fn read<R: io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
126+
let mut buf = [0; LOCATOR_LEN];
127+
reader.read_exact(&mut buf)?;
128+
let locator =
129+
Self::deserialize(&buf).map_err(|_| DecodeError::Io(io::ErrorKind::InvalidData))?;
130+
Ok(locator)
131+
}
132+
}
133+
134+
// Serialization for a Locator inside a lighting message.
135+
impl ser::Writeable for Locator {
136+
fn write<W: ser::Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
137+
writer.write_all(&self.serialize())?;
138+
Ok(())
139+
}
140+
}
141+
142+
// Deserialization for a vector of Locators inside a lightning message.
143+
impl ser::Readable for LightningVec<Locator> {
144+
fn read<R: io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
145+
let len: u16 = ser::Readable::read(reader)?;
146+
let mut locators = Vec::with_capacity(len as usize);
147+
for _ in 0..len {
148+
locators.push(ser::Readable::read(reader)?);
149+
}
150+
Ok(Self(locators))
151+
}
152+
}
153+
154+
// Serialization for a vector of Locators inside a lighting message.
155+
impl ser::Writeable for LightningVec<Locator> {
156+
fn write<W: ser::Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
157+
(self.len() as u16).write(writer)?;
158+
for locator in self.iter() {
159+
locator.write(writer)?;
160+
}
161+
Ok(())
162+
}
163+
}
164+
165+
impl_writeable_msg!(Register, {
166+
pubkey,
167+
appointment_slots,
168+
subscription_period
169+
}, {});
170+
171+
impl_writeable_msg!(SubscriptionDetails, {
172+
appointment_max_size,
173+
amount_msat,
174+
}, {
175+
(1, signature, option),
176+
});
177+
178+
impl_writeable_msg!(AddUpdateAppointment, {
179+
locator,
180+
encrypted_blob,
181+
signature,
182+
}, {
183+
(1, to_self_delay, option),
184+
});
185+
186+
impl_writeable_msg!(AppointmentAccepted, {
187+
locator,
188+
start_block,
189+
}, {
190+
(1, receipt_signature, option),
191+
});
192+
193+
impl_writeable_msg!(AppointmentRejected, {
194+
locator,
195+
rcode,
196+
reason,
197+
}, {});
198+
199+
impl_writeable_msg!(GetAppointment, {
200+
locator,
201+
signature,
202+
}, {});
203+
204+
impl_writeable_msg!(AppointmentFound, {
205+
locator,
206+
encrypted_blob,
207+
}, {});
208+
209+
impl_writeable_msg!(TrackerFound, {
210+
dispute_txid,
211+
penalty_txid,
212+
penalty_rawtx,
213+
}, {});
214+
215+
impl_writeable_msg!(AppointmentNotFound, {
216+
locator,
217+
}, {});
218+
219+
impl_writeable_msg!(GetSubscriptionInfo, {
220+
signature,
221+
}, {});
222+
223+
impl_writeable_msg!(UserSubscriptionInfo, {
224+
available_slots,
225+
subscription_expiry,
226+
locators,
227+
}, {});
228+
229+
#[derive(Debug)]
230+
pub enum TowerMessage {
231+
// Register messages
232+
Register(Register),
233+
SubscriptionDetails(SubscriptionDetails),
234+
// Appointment submission messages
235+
AddUpdateAppointment(AddUpdateAppointment),
236+
AppointmentAccepted(AppointmentAccepted),
237+
AppointmentRejected(AppointmentRejected),
238+
// Appointment fetching messages
239+
GetAppointment(GetAppointment),
240+
AppointmentFound(AppointmentFound),
241+
TrackerFound(TrackerFound),
242+
AppointmentNotFound(AppointmentNotFound),
243+
// User subscription messages
244+
GetSubscriptionInfo(GetSubscriptionInfo),
245+
UserSubscriptionInfo(UserSubscriptionInfo),
246+
}
247+
248+
impl Type for TowerMessage {
249+
fn type_id(&self) -> u16 {
250+
match self {
251+
TowerMessage::Register(..) => 48848,
252+
TowerMessage::SubscriptionDetails(..) => 48850,
253+
TowerMessage::AddUpdateAppointment(..) => 48852,
254+
TowerMessage::AppointmentAccepted(..) => 48854,
255+
TowerMessage::AppointmentRejected(..) => 48856,
256+
TowerMessage::GetAppointment(..) => 48858,
257+
TowerMessage::AppointmentFound(..) => 48860,
258+
TowerMessage::TrackerFound(..) => 48862,
259+
TowerMessage::AppointmentNotFound(..) => 48864,
260+
// Let these messages get odd types since they are auxiliary messages.
261+
TowerMessage::GetSubscriptionInfo(..) => 48865,
262+
TowerMessage::UserSubscriptionInfo(..) => 48867,
263+
}
264+
}
265+
}
266+
267+
impl ser::Writeable for TowerMessage {
268+
fn write<W: ser::Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
269+
match self {
270+
TowerMessage::Register(msg) => msg.write(writer),
271+
TowerMessage::SubscriptionDetails(msg) => msg.write(writer),
272+
TowerMessage::AddUpdateAppointment(msg) => msg.write(writer),
273+
TowerMessage::AppointmentAccepted(msg) => msg.write(writer),
274+
TowerMessage::AppointmentRejected(msg) => msg.write(writer),
275+
TowerMessage::GetAppointment(msg) => msg.write(writer),
276+
TowerMessage::AppointmentFound(msg) => msg.write(writer),
277+
TowerMessage::TrackerFound(msg) => msg.write(writer),
278+
TowerMessage::AppointmentNotFound(msg) => msg.write(writer),
279+
TowerMessage::GetSubscriptionInfo(msg) => msg.write(writer),
280+
TowerMessage::UserSubscriptionInfo(msg) => msg.write(writer),
281+
}
282+
}
283+
}

0 commit comments

Comments
 (0)