Skip to content
This repository was archived by the owner on Jan 6, 2025. It is now read-only.

Commit 089bb91

Browse files
committed
Make crate no-std compatible
Copying the pattern from the `lightning` crate, we re-export `alloc`/`hashbrown` or `std` depending on whether the `std` feature is set. We also copy some `sync` types from the `lightning` crate that are `no-std` compatible. Moreover, we check no-std compatibility in CI and, since we already touched most of them, reorder and cleanup the `use` statements in all modules.
1 parent e00d917 commit 089bb91

17 files changed

+369
-174
lines changed

.github/workflows/build.yml

+12-4
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,21 @@ jobs:
3232
- name: Cargo check
3333
run: cargo check --release
3434
- name: Check documentation
35-
run: cargo doc --release
35+
run: |
36+
cargo doc --release
37+
RUSTFLAGS="--cfg lsps1" cargo doc --release
38+
cargo doc --no-default-features --features no-std
39+
RUSTFLAGS="--cfg lsps1" cargo doc --no-default-features --features no-std
3640
- name: Build on Rust ${{ matrix.toolchain }}
3741
run: cargo build --verbose --color always
3842
- name: Check formatting
3943
if: matrix.check-fmt
4044
run: rustup component add rustfmt && cargo fmt --all -- --check
4145
- name: Test on Rust ${{ matrix.toolchain }}
42-
run: cargo test
43-
- name: Test on Rust ${{ matrix.toolchain }} with LSPS1 support
44-
run: RUSTFLAGS="--cfg lsps1" cargo test
46+
run: |
47+
cargo test
48+
RUSTFLAGS="--cfg lsps1" cargo test
49+
- name: Test on Rust ${{ matrix.toolchain }} with no-std support
50+
run: |
51+
cargo test --no-default-features --features no-std
52+
RUSTFLAGS="--cfg lsps1" cargo test --no-default-features --features no-std

Cargo.toml

+10-4
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,18 @@ description = "Types and primitives to integrate a spec-compliant LSP with an LD
77

88
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
99

10+
[features]
11+
default = ["std"]
12+
std = ["lightning/std", "bitcoin/std"]
13+
no-std = ["hashbrown", "lightning/no-std", "bitcoin/no-std", "core2/alloc"]
14+
1015
[dependencies]
11-
lightning = { version = "0.0.118", default-features = false, features = ["max_level_trace", "std"] }
16+
lightning = { version = "0.0.118", default-features = false, features = ["max_level_trace"] }
1217
lightning-invoice = "0.26.0"
18+
bitcoin = { version = "0.29.0", default-features = false }
19+
hashbrown = { version = "0.8", optional = true }
20+
core2 = { version = "0.3.0", optional = true, default-features = false }
1321

14-
bitcoin = "0.29.0"
15-
16-
chrono = { version = "0.4", default-features = false, features = ["std", "serde"] }
22+
chrono = { version = "0.4", default-features = false, features = ["serde", "alloc"] }
1723
serde = { version = "1.0", default-features = false, features = ["derive", "alloc"] }
1824
serde_json = "1.0"

src/events.rs

+21-4
Original file line numberDiff line numberDiff line change
@@ -18,25 +18,42 @@
1818
#[cfg(lsps1)]
1919
use crate::lsps1;
2020
use crate::lsps2;
21-
use std::collections::VecDeque;
22-
use std::sync::{Condvar, Mutex};
21+
use crate::prelude::{Vec, VecDeque};
22+
use crate::sync::Mutex;
2323

24-
#[derive(Default)]
2524
pub(crate) struct EventQueue {
2625
queue: Mutex<VecDeque<Event>>,
27-
condvar: Condvar,
26+
#[cfg(feature = "std")]
27+
condvar: std::sync::Condvar,
2828
}
2929

3030
impl EventQueue {
31+
pub fn new() -> Self {
32+
let queue = Mutex::new(VecDeque::new());
33+
#[cfg(feature = "std")]
34+
{
35+
let condvar = std::sync::Condvar::new();
36+
Self { queue, condvar }
37+
}
38+
#[cfg(not(feature = "std"))]
39+
Self { queue }
40+
}
41+
3142
pub fn enqueue(&self, event: Event) {
3243
{
3344
let mut queue = self.queue.lock().unwrap();
3445
queue.push_back(event);
3546
}
3647

48+
#[cfg(feature = "std")]
3749
self.condvar.notify_one();
3850
}
3951

52+
pub fn next_event(&self) -> Option<Event> {
53+
self.queue.lock().unwrap().pop_front()
54+
}
55+
56+
#[cfg(feature = "std")]
4057
pub fn wait_next_event(&self) -> Event {
4158
let mut queue =
4259
self.condvar.wait_while(self.queue.lock().unwrap(), |queue| queue.is_empty()).unwrap();

src/lib.rs

+21
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,33 @@
1717
#![allow(ellipsis_inclusive_range_patterns)]
1818
#![allow(clippy::drop_non_drop)]
1919
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
20+
#![cfg_attr(not(feature = "std"), no_std)]
21+
#[cfg(not(any(feature = "std", feature = "no-std")))]
22+
compile_error!("at least one of the `std` or `no-std` features must be enabled");
23+
24+
#[macro_use]
25+
extern crate alloc;
26+
27+
mod prelude {
28+
#[cfg(feature = "hashbrown")]
29+
extern crate hashbrown;
30+
31+
#[cfg(feature = "hashbrown")]
32+
pub use self::hashbrown::{hash_map, HashMap, HashSet};
33+
pub use alloc::{boxed::Box, collections::VecDeque, string::String, vec, vec::Vec};
34+
#[cfg(not(feature = "hashbrown"))]
35+
pub use std::collections::{hash_map, HashMap, HashSet};
36+
37+
pub use alloc::borrow::ToOwned;
38+
pub use alloc::string::ToString;
39+
}
2040

2141
pub mod events;
2242
mod lsps0;
2343
#[cfg(lsps1)]
2444
mod lsps1;
2545
pub mod lsps2;
46+
mod sync;
2647
mod utils;
2748

2849
pub use lsps0::message_handler::{JITChannelsConfig, LiquidityManager, LiquidityProviderConfig};

src/lsps0/message_handler.rs

+14-8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
#![allow(missing_docs)]
2-
31
#[cfg(lsps1)]
42
use {
53
crate::lsps1::channel_manager::CRManager,
@@ -12,6 +10,8 @@ use crate::lsps0::msgs::{LSPSMessage, RawLSPSMessage, LSPS_MESSAGE_TYPE_ID};
1210
use crate::lsps0::protocol::LSPS0MessageHandler;
1311
use crate::lsps2::channel_manager::JITChannelManager;
1412
use crate::lsps2::msgs::{OpeningFeeParams, RawOpeningFeeParams};
13+
use crate::prelude::{HashMap, String, ToString, Vec};
14+
use crate::sync::{Arc, Mutex, RwLock};
1515

1616
use lightning::chain::{self, BestBlock, Confirm, Filter, Listen};
1717
use lightning::ln::channelmanager::{AChannelManager, ChainParameters, InterceptId};
@@ -32,10 +32,8 @@ use bitcoin::BlockHash;
3232
#[cfg(lsps1)]
3333
use chrono::Utc;
3434

35-
use std::collections::HashMap;
36-
use std::convert::TryFrom;
37-
use std::ops::Deref;
38-
use std::sync::{Arc, Mutex, RwLock};
35+
use core::convert::TryFrom;
36+
use core::ops::Deref;
3937

4038
const LSPS_FEATURE_BIT: usize = 729;
4139

@@ -146,7 +144,7 @@ where
146144
) -> Self
147145
where {
148146
let pending_messages = Arc::new(Mutex::new(vec![]));
149-
let pending_events = Arc::new(EventQueue::default());
147+
let pending_events = Arc::new(EventQueue::new());
150148

151149
let lsps0_message_handler = LSPS0MessageHandler::new(
152150
entropy_source.clone().clone(),
@@ -197,13 +195,21 @@ where {
197195
}
198196
}
199197

200-
/// Blocks until next event is ready and returns it.
198+
/// Blocks the current thread until next event is ready and returns it.
201199
///
202200
/// Typically you would spawn a thread or task that calls this in a loop.
201+
#[cfg(feature = "std")]
203202
pub fn wait_next_event(&self) -> Event {
204203
self.pending_events.wait_next_event()
205204
}
206205

206+
/// Returns `Some` if an event is ready.
207+
///
208+
/// Typically you would spawn a thread or task that calls this in a loop.
209+
pub fn next_event(&self) -> Option<Event> {
210+
self.pending_events.next_event()
211+
}
212+
207213
/// Returns and clears all events without blocking.
208214
///
209215
/// Typically you would spawn a thread or task that calls this in a loop.

src/lsps0/msgs.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,19 @@ use crate::lsps2::msgs::{
77
LSPS2Message, LSPS2Request, LSPS2Response, LSPS2_BUY_METHOD_NAME, LSPS2_GET_INFO_METHOD_NAME,
88
LSPS2_GET_VERSIONS_METHOD_NAME,
99
};
10+
use crate::prelude::{HashMap, String, ToString, Vec};
11+
1012
use lightning::impl_writeable_msg;
1113
use lightning::ln::wire;
14+
1215
use serde::de;
1316
use serde::de::{MapAccess, Visitor};
1417
use serde::ser::SerializeStruct;
1518
use serde::{Deserialize, Deserializer, Serialize};
1619
use serde_json::json;
17-
use std::collections::HashMap;
18-
use std::convert::TryFrom;
19-
use std::fmt;
20+
21+
use core::convert::TryFrom;
22+
use core::fmt;
2023

2124
const LSPS_MESSAGE_SERIALIZED_STRUCT_NAME: &str = "LSPSMessage";
2225
const JSONRPC_FIELD_KEY: &str = "jsonrpc";

src/lsps0/protocol.rs

+12-8
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
1-
use bitcoin::secp256k1::PublicKey;
2-
use lightning::ln::msgs::{ErrorAction, LightningError};
3-
use lightning::sign::EntropySource;
4-
use lightning::util::logger::Level;
5-
use std::ops::Deref;
6-
use std::sync::{Arc, Mutex};
7-
81
use crate::lsps0::message_handler::ProtocolMessageHandler;
92
use crate::lsps0::msgs::{
103
LSPS0Message, LSPS0Request, LSPS0Response, LSPSMessage, ListProtocolsRequest,
114
ListProtocolsResponse, RequestId, ResponseError,
125
};
6+
use crate::prelude::Vec;
7+
use crate::sync::{Arc, Mutex};
138
use crate::utils;
149

10+
use lightning::ln::msgs::{ErrorAction, LightningError};
11+
use lightning::sign::EntropySource;
12+
use lightning::util::logger::Level;
13+
14+
use bitcoin::secp256k1::PublicKey;
15+
16+
use core::ops::Deref;
17+
1518
pub struct LSPS0MessageHandler<ES: Deref>
1619
where
1720
ES::Target: EntropySource,
@@ -104,7 +107,8 @@ where
104107
#[cfg(test)]
105108
mod tests {
106109

107-
use std::sync::Arc;
110+
use alloc::string::ToString;
111+
use alloc::sync::Arc;
108112

109113
use super::*;
110114

0 commit comments

Comments
 (0)