Skip to content

Commit 77f9564

Browse files
authored
Merge pull request #1061 from tnull/2026-08-rust-features
Introduce Rust features
2 parents ef92510 + 1c1063b commit 77f9564

34 files changed

Lines changed: 1024 additions & 610 deletions

.github/workflows/hrn-integration.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,4 @@ jobs:
4343
- name: Run HRN Integration Tests
4444
run: |
4545
RUSTFLAGS="--cfg no_download --cfg hrn_tests $RUSTFLAGS" cargo test --test integration_tests_hrn
46-
RUSTFLAGS="--cfg no_download --cfg hrn_tests $RUSTFLAGS" cargo test --test integration_tests_hrn --features uniffi
46+
RUSTFLAGS="--cfg no_download --cfg hrn_tests $RUSTFLAGS" cargo test --test integration_tests_hrn --no-default-features --features uniffi-default

.github/workflows/kotlin.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ jobs:
1212
runs-on: ubuntu-latest
1313

1414
env:
15+
LDK_NODE_EXTRA_FEATURES: chain-bitcoind
1516
LDK_NODE_JVM_DIR: bindings/kotlin/ldk-node-jvm
1617
LDK_NODE_ANDROID_DIR: bindings/kotlin/ldk-node-android
1718

.github/workflows/postgres-integration.yml

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,13 @@ jobs:
3232
- name: Install Rust stable toolchain
3333
run: |
3434
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile=minimal --default-toolchain stable
35+
- name: Check all features
36+
run: cargo check --all-features --tests --verbose --color always
37+
- name: Check sparse feature sets
38+
run: |
39+
cargo check --no-default-features --features uniffi,chain-bitcoind,storage-postgres --verbose --color always
40+
cargo test --lib --no-run --no-default-features --features chain-electrum,storage-postgres --verbose --color always
41+
cargo check --test integration_tests_postgres --no-default-features --features chain-electrum,storage-postgres --verbose --color always
3542
- name: Enable caching for bitcoind
3643
id: cache-bitcoind
3744
uses: actions/cache@v4
@@ -58,9 +65,9 @@ jobs:
5865
- name: Run PostgreSQL store tests
5966
env:
6067
TEST_POSTGRES_URL: "host=localhost user=postgres password=postgres"
61-
run: cargo test --features postgres io::postgres_store
68+
run: cargo test --features storage-postgres io::postgres_store
6269
- name: Run PostgreSQL integration tests
6370
env:
6471
TEST_POSTGRES_URL: "host=localhost user=postgres password=postgres"
6572
run: |
66-
RUSTFLAGS="--cfg no_download --cfg cycle_tests" cargo test --features postgres --test integration_tests_postgres
73+
RUSTFLAGS="--cfg no_download --cfg cycle_tests" cargo test --features storage-postgres --test integration_tests_postgres

.github/workflows/python.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ jobs:
1313

1414
env:
1515
CARGO_TARGET_DIR: /tmp/cargo-target-ldk-node-python-ci
16+
LDK_NODE_EXTRA_FEATURES: chain-bitcoind
1617
LDK_NODE_PYTHON_DIR: bindings/python
1718

1819
steps:

.github/workflows/rust.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,20 +76,20 @@ jobs:
7676
run: cargo build --verbose --color always
7777
- name: Build with UniFFI support on Rust ${{ matrix.toolchain }}
7878
if: matrix.build-uniffi
79-
run: cargo build --features uniffi --verbose --color always
79+
run: cargo build --no-default-features --features uniffi-default --verbose --color always
8080
- name: Check release build on Rust ${{ matrix.toolchain }}
8181
run: cargo check --release --verbose --color always
8282
- name: Check release build with UniFFI support on Rust ${{ matrix.toolchain }}
8383
if: matrix.build-uniffi
84-
run: cargo check --release --features uniffi --verbose --color always
84+
run: cargo check --release --no-default-features --features uniffi-default --verbose --color always
8585
- name: Test on Rust ${{ matrix.toolchain }}
8686
if: "matrix.platform != 'windows-latest'"
8787
run: |
8888
RUSTFLAGS="--cfg no_download --cfg cycle_tests --cfg tokio_unstable" cargo test
8989
- name: Test with UniFFI support on Rust ${{ matrix.toolchain }}
9090
if: "matrix.platform != 'windows-latest' && matrix.build-uniffi"
9191
run: |
92-
RUSTFLAGS="--cfg no_download --cfg cycle_tests" cargo test --features uniffi
92+
RUSTFLAGS="--cfg no_download --cfg cycle_tests" cargo test --no-default-features --features uniffi-default
9393
9494
linting:
9595
name: Linting
@@ -106,7 +106,7 @@ jobs:
106106
- name: Ban `unwrap` in library code
107107
run: |
108108
cargo clippy --lib --verbose --color always -- -A warnings -D clippy::unwrap_used -A clippy::tabs_in_doc_comments
109-
cargo clippy --lib --features uniffi --verbose --color always -- -A warnings -D clippy::unwrap_used -A clippy::tabs_in_doc_comments
109+
cargo clippy --lib --no-default-features --features uniffi-default --verbose --color always -- -A warnings -D clippy::unwrap_used -A clippy::tabs_in_doc_comments
110110
111111
doc:
112112
name: Documentation

.github/workflows/swift.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ jobs:
1111
timeout-minutes: 120
1212
runs-on: macos-latest
1313

14+
env:
15+
LDK_NODE_EXTRA_FEATURES: chain-bitcoind
16+
1417
steps:
1518
- name: Checkout repository
1619
uses: actions/checkout@v6

Cargo.toml

Lines changed: 61 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ readme = "README.md"
1212
keywords = ["bitcoin", "lightning", "ldk", "bdk"]
1313
categories = ["cryptography::cryptocurrencies"]
1414

15+
[package.metadata.docs.rs]
16+
features = ["storage-postgres-vendored-tls"]
17+
rustdoc-args = ["--cfg", "docsrs"]
18+
1519
[lib]
1620
crate-type = ["lib", "staticlib", "cdylib"]
1721
name = "ldk_node"
@@ -24,8 +28,49 @@ codegen-units = 1 # Reduce number of codegen units to increase optimizations.
2428
panic = 'abort' # Abort on panic
2529

2630
[features]
27-
default = []
28-
postgres = ["dep:tokio-postgres", "dep:native-tls", "dep:postgres-native-tls"]
31+
default = [
32+
"chain-esplora",
33+
"chain-electrum",
34+
"chain-bitcoind",
35+
"storage-sqlite",
36+
"storage-filesystem",
37+
"storage-vss",
38+
"unified-payments",
39+
]
40+
chain-esplora = [
41+
"dep:bdk_esplora",
42+
"dep:esplora-client",
43+
"dep:ldk-esplora-client",
44+
"dep:lightning-transaction-sync",
45+
"lightning-transaction-sync/esplora-async-https",
46+
"lightning-transaction-sync/time",
47+
]
48+
chain-electrum = [
49+
"dep:bdk_electrum",
50+
"dep:electrum-client",
51+
"dep:lightning-transaction-sync",
52+
"lightning-transaction-sync/electrum-rustls-ring",
53+
]
54+
chain-bitcoind = ["dep:lightning-block-sync"]
55+
storage-sqlite = ["dep:rusqlite"]
56+
storage-filesystem = ["dep:lightning-persister"]
57+
storage-vss = ["dep:vss-client", "dep:prost"]
58+
storage-postgres = ["dep:tokio-postgres", "dep:native-tls", "dep:postgres-native-tls"]
59+
storage-postgres-vendored-tls = ["storage-postgres", "native-tls/vendored"]
60+
unified-payments = [
61+
"dep:bip21",
62+
"dep:bitcoin-payment-instructions",
63+
"dep:lightning-dns-resolver",
64+
]
65+
uniffi = ["dep:uniffi"]
66+
uniffi-default = [
67+
"uniffi",
68+
"chain-esplora",
69+
"chain-electrum",
70+
"storage-sqlite",
71+
"storage-vss",
72+
"unified-payments",
73+
]
2974

3075
[dependencies]
3176
#lightning = { version = "0.2.0", features = ["std"] }
@@ -45,35 +90,35 @@ lightning = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "
4590
lightning-types = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "9174965af9437196c527a9aa0df36bbcf050c8bb" }
4691
lightning-invoice = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "9174965af9437196c527a9aa0df36bbcf050c8bb", features = ["std"] }
4792
lightning-net-tokio = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "9174965af9437196c527a9aa0df36bbcf050c8bb" }
48-
lightning-persister = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "9174965af9437196c527a9aa0df36bbcf050c8bb", features = ["tokio"] }
93+
lightning-persister = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "9174965af9437196c527a9aa0df36bbcf050c8bb", features = ["tokio"], optional = true }
4994
lightning-background-processor = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "9174965af9437196c527a9aa0df36bbcf050c8bb" }
5095
lightning-rapid-gossip-sync = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "9174965af9437196c527a9aa0df36bbcf050c8bb" }
51-
lightning-block-sync = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "9174965af9437196c527a9aa0df36bbcf050c8bb", features = ["rest-client", "rpc-client", "tokio"] }
52-
lightning-transaction-sync = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "9174965af9437196c527a9aa0df36bbcf050c8bb", features = ["esplora-async-https", "time", "electrum-rustls-ring"] }
96+
lightning-block-sync = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "9174965af9437196c527a9aa0df36bbcf050c8bb", features = ["rest-client", "rpc-client", "tokio"], optional = true }
97+
lightning-transaction-sync = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "9174965af9437196c527a9aa0df36bbcf050c8bb", optional = true }
5398
lightning-liquidity = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "9174965af9437196c527a9aa0df36bbcf050c8bb", features = ["std"] }
5499
lightning-macros = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "9174965af9437196c527a9aa0df36bbcf050c8bb" }
55-
lightning-dns-resolver = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "9174965af9437196c527a9aa0df36bbcf050c8bb" }
100+
lightning-dns-resolver = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "9174965af9437196c527a9aa0df36bbcf050c8bb", optional = true }
56101

57102
bdk_chain = { version = "0.23.3", default-features = false, features = ["std"] }
58-
bdk_esplora = { version = "0.22.2", default-features = false, features = ["async-https-rustls", "tokio"]}
59-
bdk_electrum = { version = "0.24.0", default-features = false, features = ["use-rustls-ring"]}
103+
bdk_esplora = { version = "0.22.2", default-features = false, features = ["async-https-rustls", "tokio"], optional = true }
104+
bdk_electrum = { version = "0.24.0", default-features = false, features = ["use-rustls-ring"], optional = true }
60105
bdk_wallet = { version = "3.1.0", default-features = false, features = ["std", "keys-bip39"]}
61106

62107
bitreq = { version = "0.3", default-features = false, features = ["async-https", "json-using-serde"] }
63108
rustls = { version = "0.23", default-features = false }
64-
rusqlite = { version = "0.31.0", features = ["bundled"] }
109+
rusqlite = { version = "0.31.0", features = ["bundled"], optional = true }
65110
bitcoin = "0.32.7"
66111
bip39 = { version = "2.0.0", features = ["rand"] }
67-
bip21 = { version = "0.5", features = ["std"], default-features = false }
112+
bip21 = { version = "0.5", features = ["std"], default-features = false, optional = true }
68113

69114
base64 = { version = "0.22.1", default-features = false, features = ["std"] }
70115
getrandom = { version = "0.3", default-features = false }
71116
chrono = { version = "0.4", default-features = false, features = ["clock"] }
72117
tokio = { version = "1.39", default-features = false, features = [ "rt-multi-thread", "time", "sync", "macros", "net" ] }
73118
tokio-util = { version = "0.7.10", default-features = false, features = ["rt"] }
74-
esplora-client = { version = "0.12", default-features = false, features = ["tokio", "async-https-rustls"] }
75-
ldk-esplora-client = { package = "esplora-client", version = "0.13", default-features = false, features = ["tokio", "async-https-rustls"] }
76-
electrum-client = { version = "0.25", default-features = false, features = ["proxy", "use-rustls-ring"] }
119+
esplora-client = { version = "0.12", default-features = false, features = ["tokio", "async-https-rustls"], optional = true }
120+
ldk-esplora-client = { package = "esplora-client", version = "0.13", default-features = false, features = ["tokio", "async-https-rustls"], optional = true }
121+
electrum-client = { version = "0.25", default-features = false, features = ["proxy", "use-rustls-ring"], optional = true }
77122
libc = "0.2"
78123
uniffi = { version = "0.29.5", features = ["build"], optional = true }
79124
serde = { version = "1.0.210", default-features = false, features = ["std", "derive"] }
@@ -84,10 +129,10 @@ async-trait = { version = "0.1", default-features = false }
84129
tokio-postgres = { version = "0.7", default-features = false, features = ["runtime"], optional = true }
85130
native-tls = { version = "0.2", default-features = false, optional = true }
86131
postgres-native-tls = { version = "0.5", default-features = false, features = ["runtime"], optional = true }
87-
vss-client = { package = "vss-client-ng", version = "0.6" }
88-
prost = { version = "0.11.6", default-features = false}
132+
vss-client = { package = "vss-client-ng", version = "0.6", optional = true }
133+
prost = { version = "0.11.6", default-features = false, optional = true}
89134
#bitcoin-payment-instructions = { version = "0.6" }
90-
bitcoin-payment-instructions = { git = "https://github.com/tnull/bitcoin-payment-instructions", rev = "1d6ffaa8962391ddc84aeef98bd7439e55ccae9d" }
135+
bitcoin-payment-instructions = { git = "https://github.com/tnull/bitcoin-payment-instructions", rev = "1d6ffaa8962391ddc84aeef98bd7439e55ccae9d", optional = true }
91136

92137
[target.'cfg(windows)'.dependencies]
93138
winapi = { version = "0.3", features = ["winbase"] }

README.md

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,65 @@ LDK Node currently comes with a decidedly opinionated set of design choices:
6464

6565
- On-chain data is handled by the integrated [BDK][bdk] wallet.
6666
- Chain data may currently be sourced from the Bitcoin Core RPC interface, or from an [Electrum][electrum] or [Esplora][esplora] server.
67-
- Wallet and channel state may be persisted to an [SQLite][sqlite] or [PostgreSQL][postgresql] database, to file system, or to a custom back-end to be implemented by the user.
67+
- Wallet and channel state may be persisted to an [SQLite][sqlite] or [PostgreSQL][postgresql] database, to the filesystem, to a VSS server, or to a custom back-end to be implemented by the user.
6868
- Gossip data may be sourced via Lightning's peer-to-peer network or the [Rapid Gossip Sync](https://docs.rs/lightning-rapid-gossip-sync/*/lightning_rapid_gossip_sync/) protocol.
6969
- Entropy for the Lightning and on-chain wallets may be sourced from raw bytes or a [BIP39](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki) mnemonic. In addition, LDK Node offers the means to generate and persist the entropy bytes to disk.
7070

71+
### Cargo Features
72+
73+
LDK Node's optional dependencies are grouped by the functionality they provide:
74+
75+
| Feature | Functionality |
76+
| --- | --- |
77+
| `chain-esplora` | Esplora chain source |
78+
| `chain-electrum` | Electrum chain source |
79+
| `chain-bitcoind` | Bitcoin Core RPC and REST chain source |
80+
| `storage-sqlite` | SQLite storage |
81+
| `storage-filesystem` | Filesystem storage |
82+
| `storage-vss` | Versioned Storage Service storage |
83+
| `storage-postgres` | PostgreSQL storage |
84+
| `storage-postgres-vendored-tls` | PostgreSQL storage with vendored OpenSSL |
85+
| `unified-payments` | BIP 21 and human-readable-name payment support |
86+
| `uniffi` | UniFFI language bindings |
87+
| `uniffi-default` | The standard language-binding feature set |
88+
89+
The `default` feature set preserves the native Rust API's previous behavior. It enables all three
90+
chain sources, SQLite, filesystem and VSS storage, and unified payments. PostgreSQL and UniFFI
91+
remain opt-in. Every build must enable at least one chain source feature.
92+
93+
On Linux, `storage-postgres` uses the system OpenSSL installation and requires the OpenSSL
94+
development headers and `pkg-config`. Enable `storage-postgres-vendored-tls` instead to build
95+
OpenSSL from source. Vendored builds require a C compiler, `make`, and Perl.
96+
97+
Disable the default features to select only the functionality and dependencies an application
98+
needs. For example:
99+
100+
```shell
101+
cargo build --no-default-features --features chain-esplora,storage-sqlite
102+
```
103+
104+
`uniffi-default` enables UniFFI, Esplora, Electrum, SQLite, VSS, and unified payments. It excludes
105+
Bitcoin Core, filesystem storage, and PostgreSQL. Binding users can add any of those features:
106+
107+
```shell
108+
cargo build --no-default-features --features uniffi-default,chain-bitcoind
109+
```
110+
111+
Use `uniffi` directly instead of `uniffi-default` to assemble a fully custom binding build. For
112+
example, a Bitcoin Core and PostgreSQL-only binding build uses:
113+
114+
```shell
115+
cargo build --no-default-features --features uniffi,chain-bitcoind,storage-postgres
116+
```
117+
118+
The binding generation scripts use `uniffi-default`. Set `LDK_NODE_EXTRA_FEATURES` to add features
119+
to their builds:
120+
121+
```shell
122+
LDK_NODE_EXTRA_FEATURES=chain-bitcoind,storage-postgres \
123+
./scripts/uniffi_bindgen_generate_python.sh
124+
```
125+
71126
## Compatibility
72127

73128
LDK Node does not provide a stable public API until v1.0. Persisted node state is backwards compatible: newer releases are guaranteed to load state written by older releases. Downgrades are not supported, so state written by a newer release may not load with an older release.

bindings/ldk_node.udl

Lines changed: 0 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -44,47 +44,6 @@ interface ProbingConfigBuilder {
4444
};
4545

4646
interface Builder {
47-
constructor();
48-
[Name=from_config]
49-
constructor(Config config);
50-
void set_chain_source_esplora(string server_url, EsploraSyncConfig? config);
51-
void set_chain_source_electrum(string server_url, ElectrumSyncConfig? config);
52-
void set_chain_source_bitcoind_rpc(string rpc_host, u16 rpc_port, string rpc_user, string rpc_password, u32? wallet_rescan_from_height);
53-
void set_chain_source_bitcoind_rest(string rest_host, u16 rest_port, string rpc_host, u16 rpc_port, string rpc_user, string rpc_password, u32? wallet_rescan_from_height);
54-
void set_gossip_source_p2p();
55-
void set_gossip_source_rgs(string rgs_server_url);
56-
void set_pathfinding_scores_source(string url);
57-
void add_liquidity_source(PublicKey node_id, SocketAddress address, string? token, boolean trust_peer_0conf);
58-
void set_storage_dir_path(string storage_dir_path);
59-
void set_filesystem_logger(string? log_file_path, LogLevel? max_log_level);
60-
void set_log_facade_logger();
61-
void set_custom_logger(LogWriter log_writer);
62-
void set_network(Network network);
63-
[Throws=BuildError]
64-
void set_listening_addresses(sequence<SocketAddress> listening_addresses);
65-
[Throws=BuildError]
66-
void set_announcement_addresses(sequence<SocketAddress> announcement_addresses);
67-
[Throws=BuildError]
68-
void set_tor_config(TorConfig tor_config);
69-
[Throws=BuildError]
70-
void set_node_alias(string node_alias);
71-
[Throws=BuildError]
72-
void set_async_payments_role(AsyncPaymentsRole? role);
73-
void set_probing_config(ProbingConfig config);
74-
[Throws=BuildError]
75-
Node build(NodeEntropy node_entropy);
76-
[Throws=BuildError]
77-
Node build_with_postgres_store(NodeEntropy node_entropy, string connection_string, string? db_name, string? kv_table_name, string? certificate_pem);
78-
[Throws=BuildError]
79-
Node build_with_fs_store(NodeEntropy node_entropy);
80-
[Throws=BuildError]
81-
Node build_with_vss_store(NodeEntropy node_entropy, string vss_url, string store_id, record<string, string> fixed_headers);
82-
[Throws=BuildError]
83-
Node build_with_vss_store_and_lnurl_auth(NodeEntropy node_entropy, string vss_url, string store_id, string lnurl_auth_server_url, record<string, string> fixed_headers);
84-
[Throws=BuildError]
85-
Node build_with_vss_store_and_fixed_headers(NodeEntropy node_entropy, string vss_url, string store_id, record<string, string> fixed_headers);
86-
[Throws=BuildError]
87-
Node build_with_vss_store_and_header_provider(NodeEntropy node_entropy, string vss_url, string store_id, VssHeaderProvider header_provider);
8847
};
8948

9049
interface Node {
@@ -108,7 +67,6 @@ interface Node {
10867
Bolt12Payment bolt12_payment();
10968
SpontaneousPayment spontaneous_payment();
11069
OnchainPayment onchain_payment();
111-
UnifiedPayment unified_payment();
11270
Liquidity liquidity();
11371
[Throws=NodeError]
11472
void lnurl_auth(string lnurl);
@@ -179,8 +137,6 @@ interface FeeRate {
179137
u64 to_sat_per_vb_ceil();
180138
};
181139

182-
typedef interface UnifiedPayment;
183-
184140
typedef interface Liquidity;
185141

186142
[Error]

0 commit comments

Comments
 (0)