Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rename most lightning-liquidity types for bindings compatibility #3583

Merged
2 changes: 2 additions & 0 deletions ci/ci-tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -132,3 +132,5 @@ RUSTFLAGS="--cfg=taproot" cargo test --verbose --color always -p lightning
RUSTFLAGS="--cfg=splicing" cargo test --verbose --color always -p lightning
[ "$CI_MINIMIZE_DISK_USAGE" != "" ] && cargo clean
RUSTFLAGS="--cfg=async_payments" cargo test --verbose --color always -p lightning
[ "$CI_MINIMIZE_DISK_USAGE" != "" ] && cargo clean
RUSTFLAGS="--cfg=lsps1_service" cargo test --verbose --color always -p lightning-liquidity
15 changes: 7 additions & 8 deletions lightning-liquidity/README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
# lightning-liquidity

The goal of this crate is to provide types and primitives to integrate a spec-compliant LSP with an LDK-based node. To this end, this crate provides client-side as well as service-side logic to implement the [LSP specifications].
The goal of this crate is to provide types and primitives to integrate a spec-compliant LSP with an LDK-based node. To this end, this crate provides client-side as well as service-side logic to implement the LSPS specifications.

**Note**: Service-side support is currently considered "beta", i.e., not fully
ready for production use.

Currently the following specifications are supported:
- [LSPS0] defines the transport protocol with the LSP over which the other protocols communicate.
- [LSPS1] allows to order Lightning channels from an LSP. This is useful when the client needs
- [bLIP-50 / LSPS0] defines the transport protocol with the LSP over which the other protocols communicate.
- [bLIP-51 / LSPS1] allows to order Lightning channels from an LSP. This is useful when the client needs
inbound Lightning liquidity for which they are willing and able to pay in bitcoin.
- [LSPS2] allows to generate a special invoice for which, when paid, an LSP
- [bLIP-52 / LSPS2] allows to generate a special invoice for which, when paid, an LSP
will open a "just-in-time" channel. This is useful for the initial
on-boarding of clients as the channel opening fees are deducted from the
incoming payment, i.e., no funds are required client-side to initiate this
Expand All @@ -19,7 +19,6 @@ To get started, you'll want to setup a `LiquidityManager` and configure it to be

`LiquidityManager` uses an eventing system to notify the user about important updates to the protocol flow. To this end, you will need to handle events emitted via one of the event handling methods provided by `LiquidityManager`, e.g., `LiquidityManager::next_event`.

[LSP specifications]: https://github.com/BitcoinAndLightningLayerSpecs/lsp
[LSPS0]: https://github.com/BitcoinAndLightningLayerSpecs/lsp/tree/main/LSPS0
[LSPS1]: https://github.com/BitcoinAndLightningLayerSpecs/lsp/tree/main/LSPS1
[LSPS2]: https://github.com/BitcoinAndLightningLayerSpecs/lsp/tree/main/LSPS2
[bLIP-50 / LSPS0]: https://github.com/lightning/blips/blob/master/blip-0050.md
[bLIP-51 / LSPS1]: https://github.com/lightning/blips/blob/master/blip-0051.md
[bLIP-52 / LSPS2]: https://github.com/lightning/blips/blob/master/blip-0052.md
57 changes: 45 additions & 12 deletions lightning-liquidity/src/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ use core::task::{Poll, Waker};
pub const MAX_EVENT_QUEUE_SIZE: usize = 1000;

pub(crate) struct EventQueue {
queue: Arc<Mutex<VecDeque<Event>>>,
queue: Arc<Mutex<VecDeque<LiquidityEvent>>>,
waker: Arc<Mutex<Option<Waker>>>,
#[cfg(feature = "std")]
condvar: crate::sync::Condvar,
Expand All @@ -47,11 +47,11 @@ impl EventQueue {
Self { queue, waker }
}

pub fn enqueue(&self, event: Event) {
pub fn enqueue<E: Into<LiquidityEvent>>(&self, event: E) {
{
let mut queue = self.queue.lock().unwrap();
if queue.len() < MAX_EVENT_QUEUE_SIZE {
queue.push_back(event);
queue.push_back(event.into());
} else {
return;
}
Expand All @@ -64,19 +64,21 @@ impl EventQueue {
self.condvar.notify_one();
}

pub fn next_event(&self) -> Option<Event> {
pub fn next_event(&self) -> Option<LiquidityEvent> {
self.queue.lock().unwrap().pop_front()
}

pub async fn next_event_async(&self) -> Event {
pub async fn next_event_async(&self) -> LiquidityEvent {
EventFuture { event_queue: Arc::clone(&self.queue), waker: Arc::clone(&self.waker) }.await
}

#[cfg(feature = "std")]
pub fn wait_next_event(&self) -> Event {
pub fn wait_next_event(&self) -> LiquidityEvent {
let mut queue = self
.condvar
.wait_while(self.queue.lock().unwrap(), |queue: &mut VecDeque<Event>| queue.is_empty())
.wait_while(self.queue.lock().unwrap(), |queue: &mut VecDeque<LiquidityEvent>| {
queue.is_empty()
})
.unwrap();

let event = queue.pop_front().expect("non-empty queue");
Expand All @@ -95,14 +97,14 @@ impl EventQueue {
event
}

pub fn get_and_clear_pending_events(&self) -> Vec<Event> {
pub fn get_and_clear_pending_events(&self) -> Vec<LiquidityEvent> {
self.queue.lock().unwrap().split_off(0).into()
}
}

/// An event which you should probably take some action in response to.
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Event {
pub enum LiquidityEvent {
/// An LSPS0 client event.
LSPS0Client(lsps0::event::LSPS0ClientEvent),
/// An LSPS1 (Channel Request) client event.
Expand All @@ -116,13 +118,44 @@ pub enum Event {
LSPS2Service(lsps2::event::LSPS2ServiceEvent),
}

impl From<lsps0::event::LSPS0ClientEvent> for LiquidityEvent {
fn from(event: lsps0::event::LSPS0ClientEvent) -> Self {
Self::LSPS0Client(event)
}
}

impl From<lsps1::event::LSPS1ClientEvent> for LiquidityEvent {
fn from(event: lsps1::event::LSPS1ClientEvent) -> Self {
Self::LSPS1Client(event)
}
}

#[cfg(lsps1_service)]
impl From<lsps1::event::LSPS1ServiceEvent> for LiquidityEvent {
fn from(event: lsps1::event::LSPS1ServiceEvent) -> Self {
Self::LSPS1Service(event)
}
}

impl From<lsps2::event::LSPS2ClientEvent> for LiquidityEvent {
fn from(event: lsps2::event::LSPS2ClientEvent) -> Self {
Self::LSPS2Client(event)
}
}

impl From<lsps2::event::LSPS2ServiceEvent> for LiquidityEvent {
fn from(event: lsps2::event::LSPS2ServiceEvent) -> Self {
Self::LSPS2Service(event)
}
}

struct EventFuture {
event_queue: Arc<Mutex<VecDeque<Event>>>,
event_queue: Arc<Mutex<VecDeque<LiquidityEvent>>>,
waker: Arc<Mutex<Option<Waker>>>,
}

impl Future for EventFuture {
type Output = Event;
type Output = LiquidityEvent;

fn poll(
self: core::pin::Pin<&mut Self>, cx: &mut core::task::Context<'_>,
Expand Down Expand Up @@ -154,7 +187,7 @@ mod tests {
let secp_ctx = Secp256k1::new();
let counterparty_node_id =
PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
let expected_event = Event::LSPS0Client(LSPS0ClientEvent::ListProtocolsResponse {
let expected_event = LiquidityEvent::LSPS0Client(LSPS0ClientEvent::ListProtocolsResponse {
counterparty_node_id,
protocols: Vec::new(),
});
Expand Down
23 changes: 12 additions & 11 deletions lightning-liquidity/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,21 @@
// licenses.
#![crate_name = "lightning_liquidity"]

//! The goal of this crate is to provide types and primitives to integrate a spec-compliant LSP with an LDK-based node. To this end, this crate provides client-side as well as service-side logic to implement the [LSP specifications].
//! The goal of this crate is to provide types and primitives to integrate a spec-compliant LSP
//! with an LDK-based node. To this end, this crate provides client-side as well as service-side
//! logic to implement the LSPS specifications.
//!
//! **Note**: Service-side support is currently considered "beta", i.e., not fully ready for
//! production use.
//!
//! Currently the following specifications are supported:
//! - [LSPS0] defines the transport protocol with the LSP over which the other protocols communicate.
//! - [LSPS1] allows to order Lightning channels from an LSP. This is useful when the client needs
//! - [bLIP-50 / LSPS0] defines the transport protocol with the LSP over which the other protocols communicate.
//! - [bLIP-51 / LSPS1] defines a protocol for ordering Lightning channels from an LSP. This is useful when the client needs
//! inbound Lightning liquidity for which they are willing and able to pay in bitcoin.
//! - [LSPS2] allows to generate a special invoice for which, when paid, an LSP will open a
//! "just-in-time" channel. This is useful for the initial on-boarding of clients as the channel
//! opening fees are deducted from the incoming payment, i.e., no funds are required client-side to
//! initiate this flow.
//! - [bLIP-52 / LSPS2] defines a protocol for generating a special invoice for which, when paid,
//! an LSP will open a "just-in-time" channel. This is useful for the initial on-boarding of
//! clients as the channel opening fees are deducted from the incoming payment, i.e., no funds are
//! required client-side to initiate this flow.
//!
//! To get started, you'll want to setup a [`LiquidityManager`] and configure it to be the
//! [`CustomMessageHandler`] of your LDK node. You can then for example call
Expand All @@ -32,10 +34,9 @@
//! protocol flow. To this end, you will need to handle events emitted via one of the event
//! handling methods provided by [`LiquidityManager`], e.g., [`LiquidityManager::next_event`].
//!
//! [LSP specifications]: https://github.com/BitcoinAndLightningLayerSpecs/lsp
//! [LSPS0]: https://github.com/BitcoinAndLightningLayerSpecs/lsp/tree/main/LSPS0
//! [LSPS1]: https://github.com/BitcoinAndLightningLayerSpecs/lsp/tree/main/LSPS1
//! [LSPS2]: https://github.com/BitcoinAndLightningLayerSpecs/lsp/tree/main/LSPS2
//! [bLIP-50 / LSPS0]: https://github.com/lightning/blips/blob/master/blip-0050.md
//! [bLIP-51 / LSPS1]: https://github.com/lightning/blips/blob/master/blip-0051.md
//! [bLIP-52 / LSPS2]: https://github.com/lightning/blips/blob/master/blip-0052.md
//! [`CustomMessageHandler`]: lightning::ln::peer_handler::CustomMessageHandler
//! [`LiquidityManager::next_event`]: crate::LiquidityManager::next_event
#![deny(missing_docs)]
Expand Down
61 changes: 30 additions & 31 deletions lightning-liquidity/src/lsps0/client.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
//! Contains the main LSPS0 client-side object, [`LSPS0ClientHandler`].
//! Contains the main bLIP-50 / LSPS0 client-side object, [`LSPS0ClientHandler`].
//!
//! Please refer to the [LSPS0
//! specifcation](https://github.com/BitcoinAndLightningLayerSpecs/lsp/tree/main/LSPS0) for more
//! Please refer to the [bLIP-50 / LSPS0
//! specifcation](https://github.com/lightning/blips/blob/master/blip-0050.md) for more
//! information.

use crate::events::{Event, EventQueue};
use crate::events::EventQueue;
use crate::lsps0::event::LSPS0ClientEvent;
use crate::lsps0::msgs::{
LSPS0Message, LSPS0Request, LSPS0Response, ListProtocolsRequest, ListProtocolsResponse,
LSPS0ListProtocolsRequest, LSPS0ListProtocolsResponse, LSPS0Message, LSPS0Request,
LSPS0Response,
};
use crate::lsps0::ser::{ProtocolMessageHandler, ResponseError};
use crate::lsps0::ser::{LSPSProtocolMessageHandler, LSPSResponseError};
use crate::message_queue::MessageQueue;
use crate::sync::Arc;
use crate::utils;
Expand All @@ -22,7 +23,7 @@ use bitcoin::secp256k1::PublicKey;

use core::ops::Deref;

/// A message handler capable of sending and handling LSPS0 messages.
/// A message handler capable of sending and handling bLIP-50 / LSPS0 messages.
pub struct LSPS0ClientHandler<ES: Deref>
where
ES::Target: EntropySource,
Expand All @@ -43,15 +44,15 @@ where
Self { entropy_source, pending_messages, pending_events }
}

/// Calls LSPS0's `list_protocols`.
/// Calls bLIP-50 / LSPS0's `list_protocols`.
///
/// Please refer to the [LSPS0
/// specifcation](https://github.com/BitcoinAndLightningLayerSpecs/lsp/tree/main/LSPS0#lsps-specification-support-query)
/// Please refer to the [bLIP-50 / LSPS0
/// specifcation](https://github.com/lightning/blips/blob/master/blip-0050.md#lsps-specification-support-query)
/// for more information.
pub fn list_protocols(&self, counterparty_node_id: &PublicKey) {
let msg = LSPS0Message::Request(
utils::generate_request_id(&self.entropy_source),
LSPS0Request::ListProtocols(ListProtocolsRequest {}),
LSPS0Request::ListProtocols(LSPS0ListProtocolsRequest {}),
);

self.pending_messages.enqueue(counterparty_node_id, msg.into());
Expand All @@ -61,29 +62,27 @@ where
&self, response: LSPS0Response, counterparty_node_id: &PublicKey,
) -> Result<(), LightningError> {
match response {
LSPS0Response::ListProtocols(ListProtocolsResponse { protocols }) => {
self.pending_events.enqueue(Event::LSPS0Client(
LSPS0ClientEvent::ListProtocolsResponse {
counterparty_node_id: *counterparty_node_id,
protocols,
},
));
LSPS0Response::ListProtocols(LSPS0ListProtocolsResponse { protocols }) => {
self.pending_events.enqueue(LSPS0ClientEvent::ListProtocolsResponse {
counterparty_node_id: *counterparty_node_id,
protocols,
});
Ok(())
},
LSPS0Response::ListProtocolsError(ResponseError { code, message, data, .. }) => {
Err(LightningError {
err: format!(
"ListProtocols error received. code = {}, message = {}, data = {:?}",
code, message, data
),
action: ErrorAction::IgnoreAndLog(Level::Info),
})
},
LSPS0Response::ListProtocolsError(LSPSResponseError {
code, message, data, ..
}) => Err(LightningError {
err: format!(
"ListProtocols error received. code = {}, message = {}, data = {:?}",
code, message, data
),
action: ErrorAction::IgnoreAndLog(Level::Info),
}),
}
}
}

impl<ES: Deref> ProtocolMessageHandler for LSPS0ClientHandler<ES>
impl<ES: Deref> LSPSProtocolMessageHandler for LSPS0ClientHandler<ES>
where
ES::Target: EntropySource,
{
Expand Down Expand Up @@ -114,7 +113,7 @@ mod tests {
use alloc::string::ToString;
use alloc::sync::Arc;

use crate::lsps0::ser::{LSPSMessage, RequestId};
use crate::lsps0::ser::{LSPSMessage, LSPSRequestId};
use crate::tests::utils::{self, TestEntropy};

use super::*;
Expand Down Expand Up @@ -147,8 +146,8 @@ mod tests {
assert_eq!(
*message,
LSPSMessage::LSPS0(LSPS0Message::Request(
RequestId("00000000000000000000000000000000".to_string()),
LSPS0Request::ListProtocols(ListProtocolsRequest {})
LSPSRequestId("00000000000000000000000000000000".to_string()),
LSPS0Request::ListProtocols(LSPS0ListProtocolsRequest {})
))
);
}
Expand Down
4 changes: 2 additions & 2 deletions lightning-liquidity/src/lsps0/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@
// You may not use this file except in accordance with one or both of these
// licenses.

//! Contains LSPS0 event types
//! Contains bLIP-50 / LSPS0 event types.

use crate::prelude::Vec;
use bitcoin::secp256k1::PublicKey;

/// An event which an LSPS0 client may want to take some action in response to.
/// An event which an bLIP-50 / LSPS0 client may want to take some action in response to.
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum LSPS0ClientEvent {
/// Information from the LSP about the protocols they support.
Expand Down
2 changes: 1 addition & 1 deletion lightning-liquidity/src/lsps0/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
// You may not use this file except in accordance with one or both of these
// licenses.

//! Types and primitives that implement the LSPS0: Transport Layer specification.
//! Types and primitives that implement the bLIP-50 / LSPS0: Transport Layer specification.

pub mod client;
pub mod event;
Expand Down
Loading
Loading