Skip to content

Commit ccf89d0

Browse files
authored
Merge pull request #1 from lightningdevkit/main
sync to the remote
2 parents e0fbff2 + 9e0cfc5 commit ccf89d0

32 files changed

+1549
-381
lines changed

CLAUDE.md

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Development Rules
6+
7+
- Always ensure tests pass before committing.
8+
- Run `cargo fmt --all` after every code change
9+
- Never add new dependencies unless explicitly requested
10+
- Please always disclose the use of any AI tools in commit messages and PR descriptions
11+
- When adding new `.rs` files, please ensure to always add the licensing header as found in all other files.
12+
13+
## Architecture Overview
14+
15+
LDK-Node is a self-custodial Lightning Network node library built on top of **LDK** (Lightning Development Kit) for Lightning functionality and **BDK** (Bitcoin Development Kit) for on-chain wallet operations. It provides a simple, ready-to-go interface for building Lightning applications with language bindings for Swift, Kotlin, and Python via UniFFI.
16+
17+
### Core Components
18+
19+
| Component | Location | Responsibility |
20+
|-----------|----------|----------------|
21+
| `Node` | `src/lib.rs` | Central abstraction containing all subsystems; entry point for API |
22+
| `Builder` | `src/builder.rs` | Fluent configuration interface for constructing `Node` instances |
23+
| `Wallet` | `src/wallet/` | BDK-based on-chain wallet with SQLite persistence |
24+
| `ChainSource` | `src/chain/` | Chain data abstraction (Esplora, Electrum, Bitcoin Core) |
25+
| `EventHandler` | `src/event.rs` | Translates LDK events to user-facing `Node` events |
26+
| `PaymentStore` | `src/payment/store.rs` | Persistent payment tracking with status and metadata |
27+
28+
### Module Organization
29+
30+
| Module | Purpose |
31+
|--------|---------|
32+
| `payment/` | Payment processing (BOLT11, BOLT12, on-chain, spontaneous, unified) |
33+
| `wallet/` | On-chain wallet abstraction, serialization, persistence |
34+
| `chain/` | Chain data sources, wallet syncing, transaction broadcasting |
35+
| `io/` | Persistence layer (`SQLiteStore`, `VssStore`, KV-store utilities) |
36+
| `liquidity.rs` | Liquidity provider integration (LSPS1/LSPS2) |
37+
| `connection.rs` | Peer connection management and reconnection logic |
38+
| `gossip.rs` | Gossip data source management (RGS, P2P) |
39+
| `graph.rs` | Network graph querying and channel/node information |
40+
| `types.rs` | Type aliases for LDK components (`ChannelManager`, `PeerManager`, etc.) |
41+
| `ffi/` | UniFFI bindings for cross-language support |
42+
43+
### Key Design Patterns
44+
45+
- **Arc-based Shared Ownership**: Extensive use of `Arc` for thread-safe shared components enabling background task spawning
46+
- **Event-Driven Architecture**: Events flow from LDK → `EventHandler``EventQueue` → User application
47+
- **Trait-based Abstraction**: `KVStore`/`KVStoreSync` for storage, `ChainSource` for chain backends, `StorableObject` for persistence
48+
- **Builder Pattern**: Fluent configuration with sensible defaults and validation during build phase
49+
- **Background Tasks**: Multiple categories (wallet sync, gossip updates, peer reconnection, fee updates, event processing)
50+
51+
### Lifecycle
52+
53+
**Startup (`node.start()`)**: Acquires lock → starts chain source → updates fee rates → spawns background sync tasks → sets up gossip/listeners/peer reconnection → starts event processor → marks running
54+
55+
**Shutdown (`node.stop()`)**: Acquires lock → signals stop → aborts cancellable tasks → waits for background tasks → disconnects peers → persists final state
56+
57+
### Type Aliases (from `types.rs`)
58+
59+
Key LDK type aliases used throughout the codebase:
60+
- `ChannelManager` - LDK channel management
61+
- `ChainMonitor` - LDK chain monitoring
62+
- `PeerManager` - LDK peer connections
63+
- `OnionMessenger` - LDK onion messaging
64+
- `Router` - LDK pathfinding (`DefaultRouter`)
65+
- `Scorer` - Combined probabilistic + external scoring
66+
- `Graph` - `NetworkGraph`
67+
- `Sweeper` - `OutputSweeper`

Cargo.toml

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -39,22 +39,22 @@ default = []
3939
#lightning-liquidity = { version = "0.2.0", features = ["std"] }
4040
#lightning-macros = { version = "0.2.0" }
4141

42-
lightning = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "e9ce486a425933041b319ac72512227353310dc5", features = ["std"] }
43-
lightning-types = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "e9ce486a425933041b319ac72512227353310dc5" }
44-
lightning-invoice = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "e9ce486a425933041b319ac72512227353310dc5", features = ["std"] }
45-
lightning-net-tokio = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "e9ce486a425933041b319ac72512227353310dc5" }
46-
lightning-persister = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "e9ce486a425933041b319ac72512227353310dc5", features = ["tokio"] }
47-
lightning-background-processor = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "e9ce486a425933041b319ac72512227353310dc5" }
48-
lightning-rapid-gossip-sync = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "e9ce486a425933041b319ac72512227353310dc5" }
49-
lightning-block-sync = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "e9ce486a425933041b319ac72512227353310dc5", features = ["rest-client", "rpc-client", "tokio"] }
50-
lightning-transaction-sync = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "e9ce486a425933041b319ac72512227353310dc5", features = ["esplora-async-https", "time", "electrum-rustls-ring"] }
51-
lightning-liquidity = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "e9ce486a425933041b319ac72512227353310dc5", features = ["std"] }
52-
lightning-macros = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "e9ce486a425933041b319ac72512227353310dc5" }
42+
lightning = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "b6c17c593a5d7bacb18fe3b9f69074a0596ae8f0", features = ["std"] }
43+
lightning-types = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "b6c17c593a5d7bacb18fe3b9f69074a0596ae8f0" }
44+
lightning-invoice = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "b6c17c593a5d7bacb18fe3b9f69074a0596ae8f0", features = ["std"] }
45+
lightning-net-tokio = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "b6c17c593a5d7bacb18fe3b9f69074a0596ae8f0" }
46+
lightning-persister = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "b6c17c593a5d7bacb18fe3b9f69074a0596ae8f0", features = ["tokio"] }
47+
lightning-background-processor = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "b6c17c593a5d7bacb18fe3b9f69074a0596ae8f0" }
48+
lightning-rapid-gossip-sync = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "b6c17c593a5d7bacb18fe3b9f69074a0596ae8f0" }
49+
lightning-block-sync = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "b6c17c593a5d7bacb18fe3b9f69074a0596ae8f0", features = ["rest-client", "rpc-client", "tokio"] }
50+
lightning-transaction-sync = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "b6c17c593a5d7bacb18fe3b9f69074a0596ae8f0", features = ["esplora-async-https", "time", "electrum-rustls-ring"] }
51+
lightning-liquidity = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "b6c17c593a5d7bacb18fe3b9f69074a0596ae8f0", features = ["std"] }
52+
lightning-macros = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "b6c17c593a5d7bacb18fe3b9f69074a0596ae8f0" }
5353

5454
bdk_chain = { version = "0.23.0", default-features = false, features = ["std"] }
5555
bdk_esplora = { version = "0.22.0", default-features = false, features = ["async-https-rustls", "tokio"]}
5656
bdk_electrum = { version = "0.23.0", default-features = false, features = ["use-rustls-ring"]}
57-
bdk_wallet = { version = "2.2.0", default-features = false, features = ["std", "keys-bip39"]}
57+
bdk_wallet = { version = "2.3.0", default-features = false, features = ["std", "keys-bip39"]}
5858

5959
bitreq = { version = "0.3", default-features = false, features = ["async-https"] }
6060
rustls = { version = "0.23", default-features = false }
@@ -75,16 +75,16 @@ serde = { version = "1.0.210", default-features = false, features = ["std", "der
7575
serde_json = { version = "1.0.128", default-features = false, features = ["std"] }
7676
log = { version = "0.4.22", default-features = false, features = ["std"]}
7777

78-
vss-client = { package = "vss-client-ng", version = "0.4" }
78+
vss-client = { package = "vss-client-ng", version = "0.5" }
7979
prost = { version = "0.11.6", default-features = false}
8080
#bitcoin-payment-instructions = { version = "0.6" }
81-
bitcoin-payment-instructions = { git = "https://github.com/tnull/bitcoin-payment-instructions", rev = "6796e87525d6c564e1332354a808730e2ba2ebf8" }
81+
bitcoin-payment-instructions = { git = "https://github.com/tnull/bitcoin-payment-instructions", rev = "ea50a9d2a8da524b69a2af43233706666cf2ffa5" }
8282

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

8686
[dev-dependencies]
87-
lightning = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "e9ce486a425933041b319ac72512227353310dc5", features = ["std", "_test_utils"] }
87+
lightning = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "b6c17c593a5d7bacb18fe3b9f69074a0596ae8f0", features = ["std", "_test_utils"] }
8888
proptest = "1.0.0"
8989
regex = "1.5.6"
9090
criterion = { version = "0.7.0", features = ["async_tokio"] }

benches/payments.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use bitcoin::hex::DisplayHex;
88
use bitcoin::Amount;
99
use common::{
1010
expect_channel_ready_event, generate_blocks_and_wait, premine_and_distribute_funds,
11-
setup_bitcoind_and_electrsd, setup_two_nodes_with_store, TestChainSource,
11+
random_chain_source, setup_bitcoind_and_electrsd, setup_two_nodes_with_store,
1212
};
1313
use criterion::{criterion_group, criterion_main, Criterion};
1414
use ldk_node::{Event, Node};
@@ -119,7 +119,7 @@ async fn send_payments(node_a: Arc<Node>, node_b: Arc<Node>) -> std::time::Durat
119119
fn payment_benchmark(c: &mut Criterion) {
120120
// Set up two nodes. Because this is slow, we reuse the same nodes for each sample.
121121
let (bitcoind, electrsd) = setup_bitcoind_and_electrsd();
122-
let chain_source = TestChainSource::Esplora(&electrsd);
122+
let chain_source = random_chain_source(&bitcoind, &electrsd);
123123

124124
let (node_a, node_b) = setup_two_nodes_with_store(
125125
&chain_source,

bindings/ldk_node.udl

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,22 @@ dictionary BackgroundSyncConfig {
2626
u64 fee_rate_cache_update_interval_secs;
2727
};
2828

29+
dictionary SyncTimeoutsConfig {
30+
u64 onchain_wallet_sync_timeout_secs;
31+
u64 lightning_wallet_sync_timeout_secs;
32+
u64 fee_rate_cache_update_timeout_secs;
33+
u64 tx_broadcast_timeout_secs;
34+
u8 per_request_timeout_secs;
35+
};
36+
2937
dictionary EsploraSyncConfig {
3038
BackgroundSyncConfig? background_sync_config;
39+
SyncTimeoutsConfig timeouts_config;
3140
};
3241

3342
dictionary ElectrumSyncConfig {
3443
BackgroundSyncConfig? background_sync_config;
44+
SyncTimeoutsConfig timeouts_config;
3545
};
3646

3747
dictionary LSPS2ServiceConfig {
@@ -119,6 +129,7 @@ interface Builder {
119129
void set_node_alias(string node_alias);
120130
[Throws=BuildError]
121131
void set_async_payments_role(AsyncPaymentsRole? role);
132+
void set_wallet_recovery_mode();
122133
[Throws=BuildError]
123134
Node build(NodeEntropy node_entropy);
124135
[Throws=BuildError]
@@ -266,6 +277,8 @@ interface OnchainPayment {
266277
Txid send_to_address([ByRef]Address address, u64 amount_sats, FeeRate? fee_rate);
267278
[Throws=NodeError]
268279
Txid send_all_to_address([ByRef]Address address, boolean retain_reserve, FeeRate? fee_rate);
280+
[Throws=NodeError]
281+
Txid bump_fee_rbf(PaymentId payment_id, FeeRate? fee_rate);
269282
};
270283

271284
interface FeeRate {

src/builder.rs

Lines changed: 74 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ use lightning::routing::scoring::{
3232
ProbabilisticScoringFeeParameters,
3333
};
3434
use lightning::sign::{EntropySource, NodeSigner};
35+
use lightning::util::config::HTLCInterceptionFlags;
3536
use lightning::util::persist::{
3637
KVStore, CHANNEL_MANAGER_PERSISTENCE_KEY, CHANNEL_MANAGER_PERSISTENCE_PRIMARY_NAMESPACE,
3738
CHANNEL_MANAGER_PERSISTENCE_SECONDARY_NAMESPACE,
@@ -55,12 +56,14 @@ use crate::gossip::GossipSource;
5556
use crate::io::sqlite_store::SqliteStore;
5657
use crate::io::utils::{
5758
read_event_queue, read_external_pathfinding_scores_from_cache, read_network_graph,
58-
read_node_metrics, read_output_sweeper, read_payments, read_peer_info, read_scorer,
59-
write_node_metrics,
59+
read_node_metrics, read_output_sweeper, read_payments, read_peer_info, read_pending_payments,
60+
read_scorer, write_node_metrics,
6061
};
6162
use crate::io::vss_store::VssStoreBuilder;
6263
use crate::io::{
6364
self, PAYMENT_INFO_PERSISTENCE_PRIMARY_NAMESPACE, PAYMENT_INFO_PERSISTENCE_SECONDARY_NAMESPACE,
65+
PENDING_PAYMENT_INFO_PERSISTENCE_PRIMARY_NAMESPACE,
66+
PENDING_PAYMENT_INFO_PERSISTENCE_SECONDARY_NAMESPACE,
6467
};
6568
use crate::liquidity::{
6669
LSPS1ClientConfig, LSPS2ClientConfig, LSPS2ServiceConfig, LiquiditySourceBuilder,
@@ -73,8 +76,8 @@ use crate::runtime::{Runtime, RuntimeSpawner};
7376
use crate::tx_broadcaster::TransactionBroadcaster;
7477
use crate::types::{
7578
AsyncPersister, ChainMonitor, ChannelManager, DynStore, DynStoreWrapper, GossipSync, Graph,
76-
KeysManager, MessageRouter, OnionMessenger, PaymentStore, PeerManager, Persister,
77-
SyncAndAsyncKVStore,
79+
KeysManager, MessageRouter, OnionMessenger, PaymentStore, PeerManager, PendingPaymentStore,
80+
Persister, SyncAndAsyncKVStore,
7881
};
7982
use crate::wallet::persist::KVStoreWalletPersister;
8083
use crate::wallet::Wallet;
@@ -241,6 +244,7 @@ pub struct NodeBuilder {
241244
async_payments_role: Option<AsyncPaymentsRole>,
242245
runtime_handle: Option<tokio::runtime::Handle>,
243246
pathfinding_scores_sync_config: Option<PathfindingScoresSyncConfig>,
247+
recovery_mode: bool,
244248
}
245249

246250
impl NodeBuilder {
@@ -258,6 +262,7 @@ impl NodeBuilder {
258262
let log_writer_config = None;
259263
let runtime_handle = None;
260264
let pathfinding_scores_sync_config = None;
265+
let recovery_mode = false;
261266
Self {
262267
config,
263268
chain_data_source_config,
@@ -267,6 +272,7 @@ impl NodeBuilder {
267272
runtime_handle,
268273
async_payments_role: None,
269274
pathfinding_scores_sync_config,
275+
recovery_mode,
270276
}
271277
}
272278

@@ -541,6 +547,16 @@ impl NodeBuilder {
541547
Ok(self)
542548
}
543549

550+
/// Configures the [`Node`] to resync chain data from genesis on first startup, recovering any
551+
/// historical wallet funds.
552+
///
553+
/// This should only be set on first startup when importing an older wallet from a previously
554+
/// used [`NodeEntropy`].
555+
pub fn set_wallet_recovery_mode(&mut self) -> &mut Self {
556+
self.recovery_mode = true;
557+
self
558+
}
559+
544560
/// Builds a [`Node`] instance with a [`SqliteStore`] backend and according to the options
545561
/// previously configured.
546562
pub fn build(&self, node_entropy: NodeEntropy) -> Result<Node, BuildError> {
@@ -676,6 +692,7 @@ impl NodeBuilder {
676692
self.liquidity_source_config.as_ref(),
677693
self.pathfinding_scores_sync_config.as_ref(),
678694
self.async_payments_role,
695+
self.recovery_mode,
679696
seed_bytes,
680697
runtime,
681698
logger,
@@ -916,6 +933,15 @@ impl ArcedNodeBuilder {
916933
self.inner.write().unwrap().set_async_payments_role(role).map(|_| ())
917934
}
918935

936+
/// Configures the [`Node`] to resync chain data from genesis on first startup, recovering any
937+
/// historical wallet funds.
938+
///
939+
/// This should only be set on first startup when importing an older wallet from a previously
940+
/// used [`NodeEntropy`].
941+
pub fn set_wallet_recovery_mode(&self) {
942+
self.inner.write().unwrap().set_wallet_recovery_mode();
943+
}
944+
919945
/// Builds a [`Node`] instance with a [`SqliteStore`] backend and according to the options
920946
/// previously configured.
921947
pub fn build(&self, node_entropy: Arc<NodeEntropy>) -> Result<Arc<Node>, BuildError> {
@@ -1030,8 +1056,8 @@ fn build_with_store_internal(
10301056
gossip_source_config: Option<&GossipSourceConfig>,
10311057
liquidity_source_config: Option<&LiquiditySourceConfig>,
10321058
pathfinding_scores_sync_config: Option<&PathfindingScoresSyncConfig>,
1033-
async_payments_role: Option<AsyncPaymentsRole>, seed_bytes: [u8; 64], runtime: Arc<Runtime>,
1034-
logger: Arc<Logger>, kv_store: Arc<DynStore>,
1059+
async_payments_role: Option<AsyncPaymentsRole>, recovery_mode: bool, seed_bytes: [u8; 64],
1060+
runtime: Arc<Runtime>, logger: Arc<Logger>, kv_store: Arc<DynStore>,
10351061
) -> Result<Node, BuildError> {
10361062
optionally_install_rustls_cryptoprovider();
10371063

@@ -1057,12 +1083,14 @@ fn build_with_store_internal(
10571083

10581084
let kv_store_ref = Arc::clone(&kv_store);
10591085
let logger_ref = Arc::clone(&logger);
1060-
let (payment_store_res, node_metris_res) = runtime.block_on(async move {
1061-
tokio::join!(
1062-
read_payments(&*kv_store_ref, Arc::clone(&logger_ref)),
1063-
read_node_metrics(&*kv_store_ref, Arc::clone(&logger_ref)),
1064-
)
1065-
});
1086+
let (payment_store_res, node_metris_res, pending_payment_store_res) =
1087+
runtime.block_on(async move {
1088+
tokio::join!(
1089+
read_payments(&*kv_store_ref, Arc::clone(&logger_ref)),
1090+
read_node_metrics(&*kv_store_ref, Arc::clone(&logger_ref)),
1091+
read_pending_payments(&*kv_store_ref, Arc::clone(&logger_ref))
1092+
)
1093+
});
10661094

10671095
// Initialize the status fields.
10681096
let node_metrics = match node_metris_res {
@@ -1225,32 +1253,52 @@ fn build_with_store_internal(
12251253
BuildError::WalletSetupFailed
12261254
})?;
12271255

1228-
if let Some(best_block) = chain_tip_opt {
1229-
// Insert the first checkpoint if we have it, to avoid resyncing from genesis.
1230-
// TODO: Use a proper wallet birthday once BDK supports it.
1231-
let mut latest_checkpoint = wallet.latest_checkpoint();
1232-
let block_id =
1233-
bdk_chain::BlockId { height: best_block.height, hash: best_block.block_hash };
1234-
latest_checkpoint = latest_checkpoint.insert(block_id);
1235-
let update =
1236-
bdk_wallet::Update { chain: Some(latest_checkpoint), ..Default::default() };
1237-
wallet.apply_update(update).map_err(|e| {
1238-
log_error!(logger, "Failed to apply checkpoint during wallet setup: {}", e);
1239-
BuildError::WalletSetupFailed
1240-
})?;
1256+
if !recovery_mode {
1257+
if let Some(best_block) = chain_tip_opt {
1258+
// Insert the first checkpoint if we have it, to avoid resyncing from genesis.
1259+
// TODO: Use a proper wallet birthday once BDK supports it.
1260+
let mut latest_checkpoint = wallet.latest_checkpoint();
1261+
let block_id = bdk_chain::BlockId {
1262+
height: best_block.height,
1263+
hash: best_block.block_hash,
1264+
};
1265+
latest_checkpoint = latest_checkpoint.insert(block_id);
1266+
let update =
1267+
bdk_wallet::Update { chain: Some(latest_checkpoint), ..Default::default() };
1268+
wallet.apply_update(update).map_err(|e| {
1269+
log_error!(logger, "Failed to apply checkpoint during wallet setup: {}", e);
1270+
BuildError::WalletSetupFailed
1271+
})?;
1272+
}
12411273
}
12421274
wallet
12431275
},
12441276
};
12451277

1278+
let pending_payment_store = match pending_payment_store_res {
1279+
Ok(pending_payments) => Arc::new(PendingPaymentStore::new(
1280+
pending_payments,
1281+
PENDING_PAYMENT_INFO_PERSISTENCE_PRIMARY_NAMESPACE.to_string(),
1282+
PENDING_PAYMENT_INFO_PERSISTENCE_SECONDARY_NAMESPACE.to_string(),
1283+
Arc::clone(&kv_store),
1284+
Arc::clone(&logger),
1285+
)),
1286+
Err(e) => {
1287+
log_error!(logger, "Failed to read pending payment data from store: {}", e);
1288+
return Err(BuildError::ReadFailed);
1289+
},
1290+
};
1291+
12461292
let wallet = Arc::new(Wallet::new(
12471293
bdk_wallet,
12481294
wallet_persister,
12491295
Arc::clone(&tx_broadcaster),
12501296
Arc::clone(&fee_estimator),
1297+
Arc::clone(&chain_source),
12511298
Arc::clone(&payment_store),
12521299
Arc::clone(&config),
12531300
Arc::clone(&logger),
1301+
Arc::clone(&pending_payment_store),
12541302
));
12551303

12561304
// Initialize the KeysManager
@@ -1415,7 +1463,7 @@ fn build_with_store_internal(
14151463
if liquidity_source_config.and_then(|lsc| lsc.lsps2_service.as_ref()).is_some() {
14161464
// If we act as an LSPS2 service, we need to be able to intercept HTLCs and forward the
14171465
// information to the service handler.
1418-
user_config.accept_intercept_htlcs = true;
1466+
user_config.htlc_interception_flags = HTLCInterceptionFlags::ToInterceptSCIDs.into();
14191467

14201468
// If we act as an LSPS2 service, we allow forwarding to unannounced channels.
14211469
user_config.accept_forwards_to_priv_channels = true;

0 commit comments

Comments
 (0)