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

LSPS1: Update message format and get client working #140

Draft
wants to merge 11 commits into
base: main
Choose a base branch
from
4 changes: 0 additions & 4 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,6 @@ jobs:
run: |
cargo doc --release
cargo doc --no-default-features --features no-std
RUSTFLAGS="--cfg lsps1" RUSTDOCFLAGS="--cfg lsps1" cargo doc --release
RUSTFLAGS="--cfg lsps1" RUSTDOCFLAGS="--cfg lsps1" cargo doc --no-default-features --features no-std
- name: Build on Rust ${{ matrix.toolchain }}
run: cargo build --verbose --color always
- name: Check formatting
Expand All @@ -49,8 +47,6 @@ jobs:
- name: Test on Rust ${{ matrix.toolchain }}
run: |
cargo test
RUSTFLAGS="--cfg lsps1" cargo test
- name: Test on Rust ${{ matrix.toolchain }} with no-std support
run: |
cargo test --no-default-features --features no-std
RUSTFLAGS="--cfg lsps1" cargo test --no-default-features --features no-std
15 changes: 15 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ no-std = ["hashbrown", "lightning/no-std", "lightning-invoice/no-std", "bitcoin/
[dependencies]
lightning = { version = "0.0.123", default-features = false, features = ["max_level_trace"] }
lightning-invoice = { version = "0.31.0", default-features = false, features = ["serde"] }

#lightning = { path = "../rust-lightning/lightning", default-features = false, features = ["max_level_trace"] }
#lightning-invoice = { path = "../rust-lightning/lightning-invoice", default-features = false, features = ["serde"] }

bitcoin = { version = "0.30.2", default-features = false, features = ["serde"] }
hashbrown = { version = "0.8", optional = true }
core2 = { version = "0.3.0", optional = true, default-features = false }
Expand All @@ -33,5 +37,16 @@ serde_json = "1.0"
lightning = { version = "0.0.123", default-features = false, features = ["max_level_trace", "_test_utils"] }
lightning-persister = { version = "0.0.123", default-features = false }
lightning-background-processor = { version = "0.0.123", default-features = false, features = ["std"] }

# lightning = { path = "../rust-lightning/lightning", default-features = false, features = ["max_level_trace", "_test_utils"] }
# lightning-persister = { path = "../rust-lightning/lightning-persister", default-features = false }
# lightning-background-processor = { path = "../rust-lightning/lightning-background-processor", default-features = false, features = ["std"] }
proptest = "1.0.0"
tokio = { version = "1.35", default-features = false, features = [ "rt-multi-thread", "time", "sync", "macros" ] }

[lints.rust.unexpected_cfgs]
level = "forbid"
# When adding a new cfg attribute, ensure that it is added to this list.
check-cfg = [
"cfg(lsps1_service)",
]
4 changes: 1 addition & 3 deletions src/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
//! [`LiquidityManager::get_and_clear_pending_events`]: crate::LiquidityManager::get_and_clear_pending_events

use crate::lsps0;
#[cfg(lsps1)]
use crate::lsps1;
use crate::lsps2;
use crate::prelude::{Vec, VecDeque};
Expand Down Expand Up @@ -98,10 +97,9 @@ pub enum Event {
/// An LSPS0 client event.
LSPS0Client(lsps0::event::LSPS0ClientEvent),
/// An LSPS1 (Channel Request) client event.
#[cfg(lsps1)]
LSPS1Client(lsps1::event::LSPS1ClientEvent),
/// An LSPS1 (Channel Request) server event.
#[cfg(lsps1)]
#[cfg(lsps1_service)]
LSPS1Service(lsps1::event::LSPS1ServiceEvent),
/// An LSPS2 (JIT Channel) client event.
LSPS2Client(lsps2::event::LSPS2ClientEvent),
Expand Down
3 changes: 0 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,6 @@ mod prelude {

pub mod events;
pub mod lsps0;
#[cfg(lsps1)]
// TODO: disallow warnings once the implementation is finished
#[allow(warnings)]
pub mod lsps1;
pub mod lsps2;
mod manager;
Expand Down
1 change: 0 additions & 1 deletion src/lsps0/msgs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ impl TryFrom<LSPSMessage> for LSPS0Message {
match message {
LSPSMessage::Invalid(_) => Err(()),
LSPSMessage::LSPS0(message) => Ok(message),
#[cfg(lsps1)]
LSPSMessage::LSPS1(_) => Err(()),
LSPSMessage::LSPS2(_) => Err(()),
}
Expand Down
79 changes: 57 additions & 22 deletions src/lsps0/ser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ use crate::lsps0::msgs::{
LSPS0_LISTPROTOCOLS_METHOD_NAME,
};

#[cfg(lsps1)]
use crate::lsps1::msgs::{
LSPS1Message, LSPS1Request, LSPS1Response, LSPS1_CREATE_ORDER_METHOD_NAME,
LSPS1_GET_INFO_METHOD_NAME, LSPS1_GET_ORDER_METHOD_NAME,
Expand Down Expand Up @@ -47,11 +46,8 @@ pub(crate) const _LSPS0_CLIENT_REJECTED_ERROR_CODE: i32 = 001;
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub(crate) enum LSPSMethod {
LSPS0ListProtocols,
#[cfg(lsps1)]
LSPS1GetInfo,
#[cfg(lsps1)]
LSPS1GetOrder,
#[cfg(lsps1)]
LSPS1CreateOrder,
LSPS2GetInfo,
LSPS2Buy,
Expand All @@ -62,11 +58,8 @@ impl FromStr for LSPSMethod {
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
LSPS0_LISTPROTOCOLS_METHOD_NAME => Ok(Self::LSPS0ListProtocols),
#[cfg(lsps1)]
LSPS1_GET_INFO_METHOD_NAME => Ok(Self::LSPS1GetInfo),
#[cfg(lsps1)]
LSPS1_CREATE_ORDER_METHOD_NAME => Ok(Self::LSPS1CreateOrder),
#[cfg(lsps1)]
LSPS1_GET_ORDER_METHOD_NAME => Ok(Self::LSPS1GetOrder),
LSPS2_GET_INFO_METHOD_NAME => Ok(Self::LSPS2GetInfo),
LSPS2_BUY_METHOD_NAME => Ok(Self::LSPS2Buy),
Expand All @@ -79,11 +72,8 @@ impl Display for LSPSMethod {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let s = match self {
Self::LSPS0ListProtocols => LSPS0_LISTPROTOCOLS_METHOD_NAME,
#[cfg(lsps1)]
Self::LSPS1GetInfo => LSPS1_GET_INFO_METHOD_NAME,
#[cfg(lsps1)]
Self::LSPS1CreateOrder => LSPS1_CREATE_ORDER_METHOD_NAME,
#[cfg(lsps1)]
Self::LSPS1GetOrder => LSPS1_GET_ORDER_METHOD_NAME,
Self::LSPS2GetInfo => LSPS2_GET_INFO_METHOD_NAME,
Self::LSPS2Buy => LSPS2_BUY_METHOD_NAME,
Expand All @@ -100,7 +90,6 @@ impl From<&LSPS0Request> for LSPSMethod {
}
}

#[cfg(lsps1)]
impl From<&LSPS1Request> for LSPSMethod {
fn from(value: &LSPS1Request) -> Self {
match value {
Expand Down Expand Up @@ -216,7 +205,6 @@ pub enum LSPSMessage {
/// An LSPS0 message.
LSPS0(LSPS0Message),
/// An LSPS1 message.
#[cfg(lsps1)]
LSPS1(LSPS1Message),
/// An LSPS2 message.
LSPS2(LSPS2Message),
Expand All @@ -241,7 +229,6 @@ impl LSPSMessage {
LSPSMessage::LSPS0(LSPS0Message::Request(request_id, request)) => {
Some((RequestId(request_id.0.clone()), request.into()))
},
#[cfg(lsps1)]
LSPSMessage::LSPS1(LSPS1Message::Request(request_id, request)) => {
Some((RequestId(request_id.0.clone()), request.into()))
},
Expand Down Expand Up @@ -287,7 +274,6 @@ impl Serialize for LSPSMessage {
},
}
},
#[cfg(lsps1)]
LSPSMessage::LSPS1(LSPS1Message::Request(request_id, request)) => {
jsonrpc_object.serialize_field(JSONRPC_ID_FIELD_KEY, &request_id.0)?;
jsonrpc_object
Expand All @@ -305,7 +291,6 @@ impl Serialize for LSPSMessage {
},
}
},
#[cfg(lsps1)]
LSPSMessage::LSPS1(LSPS1Message::Response(request_id, response)) => {
jsonrpc_object.serialize_field(JSONRPC_ID_FIELD_KEY, &request_id.0)?;

Expand Down Expand Up @@ -442,7 +427,6 @@ impl<'de, 'a> Visitor<'de> for LSPSMessageVisitor<'a> {
id,
LSPS0Request::ListProtocols(ListProtocolsRequest {}),
))),
#[cfg(lsps1)]
LSPSMethod::LSPS1GetInfo => {
let request = serde_json::from_value(params.unwrap_or(json!({})))
.map_err(de::Error::custom)?;
Expand All @@ -451,7 +435,6 @@ impl<'de, 'a> Visitor<'de> for LSPSMessageVisitor<'a> {
LSPS1Request::GetInfo(request),
)))
},
#[cfg(lsps1)]
LSPSMethod::LSPS1CreateOrder => {
let request = serde_json::from_value(params.unwrap_or(json!({})))
.map_err(de::Error::custom)?;
Expand All @@ -460,7 +443,6 @@ impl<'de, 'a> Visitor<'de> for LSPSMessageVisitor<'a> {
LSPS1Request::CreateOrder(request),
)))
},
#[cfg(lsps1)]
LSPSMethod::LSPS1GetOrder => {
let request = serde_json::from_value(params.unwrap_or(json!({})))
.map_err(de::Error::custom)?;
Expand Down Expand Up @@ -502,7 +484,6 @@ impl<'de, 'a> Visitor<'de> for LSPSMessageVisitor<'a> {
Err(de::Error::custom("Received invalid JSON-RPC object: one of method, result, or error required"))
}
},
#[cfg(lsps1)]
LSPSMethod::LSPS1GetInfo => {
if let Some(error) = error {
Ok(LSPSMessage::LSPS1(LSPS1Message::Response(
Expand All @@ -520,7 +501,6 @@ impl<'de, 'a> Visitor<'de> for LSPSMessageVisitor<'a> {
Err(de::Error::custom("Received invalid JSON-RPC object: one of method, result, or error required"))
}
},
#[cfg(lsps1)]
LSPSMethod::LSPS1CreateOrder => {
if let Some(error) = error {
Ok(LSPSMessage::LSPS1(LSPS1Message::Response(
Expand All @@ -538,7 +518,6 @@ impl<'de, 'a> Visitor<'de> for LSPSMessageVisitor<'a> {
Err(de::Error::custom("Received invalid JSON-RPC object: one of method, result, or error required"))
}
},
#[cfg(lsps1)]
LSPSMethod::LSPS1GetOrder => {
if let Some(error) = error {
Ok(LSPSMessage::LSPS1(LSPS1Message::Response(
Expand Down Expand Up @@ -654,7 +633,63 @@ pub(crate) mod string_amount_option {
}
}

#[cfg(lsps1)]
pub(crate) mod unchecked_address {
use crate::prelude::{String, ToString};
use bitcoin::Address;
use core::str::FromStr;
use serde::de::Unexpected;
use serde::{Deserialize, Deserializer, Serializer};

pub(crate) fn serialize<S>(x: &Address, s: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
s.serialize_str(&x.to_string())
}

pub(crate) fn deserialize<'de, D>(deserializer: D) -> Result<Address, D::Error>
where
D: Deserializer<'de>,
{
let buf = String::deserialize(deserializer)?;

let parsed_addr = Address::from_str(&buf).map_err(|_| {
serde::de::Error::invalid_value(Unexpected::Str(&buf), &"invalid address string")
})?;
Ok(parsed_addr.assume_checked())
}
}

pub(crate) mod unchecked_address_option {
use crate::prelude::{String, ToString};
use bitcoin::Address;
use core::str::FromStr;
use serde::de::Unexpected;
use serde::{Deserialize, Deserializer, Serialize, Serializer};

pub(crate) fn serialize<S>(x: &Option<Address>, s: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let v = x.as_ref().map(|v| v.to_string());
Option::<String>::serialize(&v, s)
}

pub(crate) fn deserialize<'de, D>(deserializer: D) -> Result<Option<bitcoin::Address>, D::Error>
where
D: Deserializer<'de>,
{
if let Some(buf) = Option::<String>::deserialize(deserializer)? {
let val = Address::from_str(&buf).map_err(|_| {
serde::de::Error::invalid_value(Unexpected::Str(&buf), &"invalid address string")
})?;
Ok(Some(val.assume_checked()))
} else {
Ok(None)
}
}
}

pub(crate) mod u32_fee_rate {
use bitcoin::FeeRate;
use serde::{Deserialize, Deserializer, Serializer};
Expand Down
Loading
Loading