Skip to content

Commit be9d64f

Browse files
authored
Merge pull request #80 from lightningdevkit/update-ldk-node
Update ldk-node and align lightning deps
2 parents 73c9554 + 284ce8e commit be9d64f

10 files changed

Lines changed: 53 additions & 130 deletions

File tree

Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@ codegen-units = 1 # Reduce number of codegen units to increase optimizations.
1616
panic = 'abort' # Abort on panic
1717

1818
[workspace.dependencies]
19-
bitcoin-payment-instructions = { git = "https://github.com/jkczyz/bitcoin-payment-instructions", rev = "679dac50cc0d81ec4d31da94b93d467e5308f16a" }
20-
lightning = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "369a2cf9c8ef810deea0cd2b4cf6ed0691b78144" }
21-
lightning-invoice = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "369a2cf9c8ef810deea0cd2b4cf6ed0691b78144" }
19+
bitcoin-payment-instructions = { git = "https://github.com/tnull/bitcoin-payment-instructions", rev = "ff09ce9401afa448549a8f101172700bcd14d7bb" }
20+
lightning = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "3dfcc4cca1866c5e5d4d4eaf3b82e09584e2ce5c" }
21+
lightning-invoice = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "3dfcc4cca1866c5e5d4d4eaf3b82e09584e2ce5c" }
2222

2323
[profile.release]
2424
panic = "abort"

orange-sdk/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ _cashu-tests = ["_test-utils", "cdk-ldk-node", "cdk/mint", "cdk-sqlite", "cdk-ax
2323
[dependencies]
2424
graduated-rebalancer = { path = "../graduated-rebalancer", version = "0.1.0" }
2525

26-
ldk-node = { git = "https://github.com/lightningdevkit/ldk-node", rev = "109978de1f57fc3b3f23f241f238b97d9deaa56a" }
26+
ldk-node = { git = "https://github.com/lightningdevkit/ldk-node", rev = "8a5426044bdcae6369d7a847697c6143676e2df5" }
2727
lightning-macros = "0.2.0"
2828
bitcoin-payment-instructions = { workspace = true, features = ["http"] }
2929
chrono = { version = "0.4", default-features = false }

orange-sdk/src/dyn_store.rs

Lines changed: 16 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,22 @@
1-
//! Object-safe wrapper around ldk-node's `KVStore` + `KVStoreSync` traits.
1+
//! Object-safe wrapper around ldk-node's async `KVStore` trait.
22
//!
33
//! `lightning`'s `KVStore` returns `impl Future` from its methods, which makes the trait not
4-
//! object-safe — orange-sdk can't share a backend across components as `Arc<dyn KVStore>`. The
5-
//! supertrait `SyncAndAsyncKVStore` that ldk-node exposes inherits the same problem, and even
6-
//! if it didn't, no `Deref` blanket impl exists for `KVStoreSync`, so `Arc<...>` doesn't satisfy
7-
//! it on its own.
4+
//! object-safe — orange-sdk can't share a backend across components as `Arc<dyn KVStore>`.
85
//!
9-
//! This module defines `DynStore`, an object-safe trait covering both sync and async kv
10-
//! methods (async ones return boxed futures), with a blanket impl over any concrete type that
11-
//! implements `KVStore + KVStoreSync`. The whole crate stores backends as
12-
//! `Arc<dyn DynStore>`; conversion to a value ldk-node accepts happens at the call site
13-
//! through a thin newtype that delegates both traits back to `DynStore`.
6+
//! This module defines `DynStore`, an object-safe trait covering the kv methods (returning
7+
//! boxed futures), with a blanket impl over any concrete type that implements `KVStore`. The
8+
//! whole crate stores backends as `Arc<dyn DynStore>`; conversion to a value ldk-node accepts
9+
//! happens at the call site through a thin newtype that delegates back to `DynStore`.
1410
1511
use std::future::Future;
1612
use std::pin::Pin;
1713
use std::sync::Arc;
1814

1915
use ldk_node::lightning::io;
20-
use ldk_node::lightning::util::persist::{KVStore, KVStoreSync};
16+
use ldk_node::lightning::util::persist::KVStore;
2117

22-
/// Object-safe view of a `KVStore + KVStoreSync` backend. Async methods return boxed
23-
/// futures so the trait can be used through `dyn`.
18+
/// Object-safe view of a `KVStore` backend. Async methods return boxed futures so the trait
19+
/// can be used through `dyn`.
2420
pub(crate) trait DynStore: Send + Sync + 'static {
2521
fn read_async(
2622
&self, primary_namespace: &str, secondary_namespace: &str, key: &str,
@@ -37,27 +33,11 @@ pub(crate) trait DynStore: Send + Sync + 'static {
3733
fn list_async(
3834
&self, primary_namespace: &str, secondary_namespace: &str,
3935
) -> Pin<Box<dyn Future<Output = Result<Vec<String>, io::Error>> + Send + 'static>>;
40-
41-
fn read_sync(
42-
&self, primary_namespace: &str, secondary_namespace: &str, key: &str,
43-
) -> Result<Vec<u8>, io::Error>;
44-
45-
fn write_sync(
46-
&self, primary_namespace: &str, secondary_namespace: &str, key: &str, buf: Vec<u8>,
47-
) -> Result<(), io::Error>;
48-
49-
fn remove_sync(
50-
&self, primary_namespace: &str, secondary_namespace: &str, key: &str, lazy: bool,
51-
) -> Result<(), io::Error>;
52-
53-
fn list_sync(
54-
&self, primary_namespace: &str, secondary_namespace: &str,
55-
) -> Result<Vec<String>, io::Error>;
5636
}
5737

5838
impl<T> DynStore for T
5939
where
60-
T: KVStore + KVStoreSync + Send + Sync + 'static,
40+
T: KVStore + Send + Sync + 'static,
6141
{
6242
fn read_async(
6343
&self, p: &str, s: &str, k: &str,
@@ -82,33 +62,12 @@ where
8262
) -> Pin<Box<dyn Future<Output = Result<Vec<String>, io::Error>> + Send + 'static>> {
8363
Box::pin(<T as KVStore>::list(self, p, s))
8464
}
85-
86-
fn read_sync(&self, p: &str, s: &str, k: &str) -> Result<Vec<u8>, io::Error> {
87-
<T as KVStoreSync>::read(self, p, s, k)
88-
}
89-
90-
fn write_sync(&self, p: &str, s: &str, k: &str, buf: Vec<u8>) -> Result<(), io::Error> {
91-
<T as KVStoreSync>::write(self, p, s, k, buf)
92-
}
93-
94-
fn remove_sync(&self, p: &str, s: &str, k: &str, lazy: bool) -> Result<(), io::Error> {
95-
<T as KVStoreSync>::remove(self, p, s, k, lazy)
96-
}
97-
98-
fn list_sync(&self, p: &str, s: &str) -> Result<Vec<String>, io::Error> {
99-
<T as KVStoreSync>::list(self, p, s)
100-
}
10165
}
10266

103-
// Make `Arc<dyn DynStore>` itself implement `KVStore` + `KVStoreSync` so the same handle
104-
// orange-sdk shares internally can be handed to ldk-node's `build_with_store`. We give it
105-
// `KVStore::read` etc. by forwarding to the boxed-future variants on the trait, and the
106-
// sync trait by forwarding to the sync variants.
107-
//
108-
// Note: we impl on `dyn DynStore` (which is local), not `Arc` directly — that gives us
109-
// `&dyn DynStore: KVStore + KVStoreSync` and, via lightning's `Deref` blanket impl for
110-
// `KVStore`, `Arc<dyn DynStore>: KVStore`. For `KVStoreSync` (no `Deref` blanket exists)
111-
// callers wrap the `Arc` in `LdkNodeStore` below before handing it to ldk-node.
67+
// Make `dyn DynStore` itself implement `KVStore` so the same handle orange-sdk shares
68+
// internally can be handed to ldk-node's `build_with_store`. We forward to the boxed-future
69+
// variants on the trait. Via lightning's `Deref` blanket impl for `KVStore`, this gives us
70+
// `Arc<dyn DynStore>: KVStore` too.
11271
impl KVStore for dyn DynStore {
11372
fn read(
11473
&self, p: &str, s: &str, k: &str,
@@ -132,24 +91,9 @@ impl KVStore for dyn DynStore {
13291
}
13392
}
13493

135-
impl KVStoreSync for dyn DynStore {
136-
fn read(&self, p: &str, s: &str, k: &str) -> Result<Vec<u8>, io::Error> {
137-
self.read_sync(p, s, k)
138-
}
139-
fn write(&self, p: &str, s: &str, k: &str, buf: Vec<u8>) -> Result<(), io::Error> {
140-
self.write_sync(p, s, k, buf)
141-
}
142-
fn remove(&self, p: &str, s: &str, k: &str, lazy: bool) -> Result<(), io::Error> {
143-
self.remove_sync(p, s, k, lazy)
144-
}
145-
fn list(&self, p: &str, s: &str) -> Result<Vec<String>, io::Error> {
146-
self.list_sync(p, s)
147-
}
148-
}
149-
15094
/// Cloneable handle wrapping `Arc<dyn DynStore>` that satisfies ldk-node's
151-
/// `SyncAndAsyncKVStore + Send + Sync + 'static` bound on `build_with_store`. Both trait
152-
/// impls just forward to the underlying `dyn DynStore`.
95+
/// `KVStore + Send + Sync + 'static` bound on `build_with_store`. The trait impl just
96+
/// forwards to the underlying `dyn DynStore`.
15397
#[derive(Clone)]
15498
pub(crate) struct LdkNodeStore(pub(crate) Arc<dyn DynStore>);
15599

@@ -175,18 +119,3 @@ impl KVStore for LdkNodeStore {
175119
self.0.list_async(p, s)
176120
}
177121
}
178-
179-
impl KVStoreSync for LdkNodeStore {
180-
fn read(&self, p: &str, s: &str, k: &str) -> Result<Vec<u8>, io::Error> {
181-
self.0.read_sync(p, s, k)
182-
}
183-
fn write(&self, p: &str, s: &str, k: &str, buf: Vec<u8>) -> Result<(), io::Error> {
184-
self.0.write_sync(p, s, k, buf)
185-
}
186-
fn remove(&self, p: &str, s: &str, k: &str, lazy: bool) -> Result<(), io::Error> {
187-
self.0.remove_sync(p, s, k, lazy)
188-
}
189-
fn list(&self, p: &str, s: &str) -> Result<Vec<String>, io::Error> {
190-
self.0.list_sync(p, s)
191-
}
192-
}

orange-sdk/src/event.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -383,7 +383,7 @@ impl LdkEventHandler {
383383
} => {
384384
let payment_id = payment_id.expect("this is safe");
385385
let lsp_fee_msats = self.ldk_node.payment(&payment_id).and_then(|p| {
386-
if let PaymentKind::Bolt11Jit { counterparty_skimmed_fee_msat, .. } = p.kind {
386+
if let PaymentKind::Bolt11 { counterparty_skimmed_fee_msat, .. } = p.kind {
387387
counterparty_skimmed_fee_msat
388388
} else {
389389
None
@@ -466,13 +466,13 @@ impl LdkEventHandler {
466466
return;
467467
}
468468
},
469-
ldk_node::Event::SplicePending {
469+
ldk_node::Event::SpliceNegotiated {
470470
channel_id,
471471
user_channel_id,
472472
counterparty_node_id,
473473
new_funding_txo,
474474
} => {
475-
log_debug!(self.logger, "Received SplicePending event {event:?}");
475+
log_debug!(self.logger, "Received SpliceNegotiated event {event:?}");
476476
// Reserve the metadata slot before delivering so any task waking on the
477477
// inbox (the rebalancer's `OnChainRebalanceInitiated` for splice-in,
478478
// `pay_lightning` for splice-out) sees an entry to upsert.
@@ -493,8 +493,8 @@ impl LdkEventHandler {
493493
return;
494494
}
495495
},
496-
ldk_node::Event::SpliceFailed { .. } => {
497-
log_warn!(self.logger, "Received SpliceFailed event: {event:?}");
496+
ldk_node::Event::SpliceNegotiationFailed { .. } => {
497+
log_warn!(self.logger, "Received SpliceNegotiationFailed event: {event:?}");
498498
},
499499
}
500500

orange-sdk/src/ffi/ldk_node.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ impl ChannelDetails {
6969

7070
/// The node ID of the counterparty.
7171
pub fn counterparty_node_id(&self) -> String {
72-
self.0.counterparty_node_id.to_string()
72+
self.0.counterparty.node_id.to_string()
7373
}
7474

7575
/// The funding transaction output.

orange-sdk/src/lib.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -903,8 +903,9 @@ impl Wallet {
903903
for payment in lightning_payments {
904904
use ldk_node::payment::PaymentDirection;
905905
let lightning_receive_fee = match payment.kind {
906-
PaymentKind::Bolt11Jit { counterparty_skimmed_fee_msat, .. } => {
907-
let msats = counterparty_skimmed_fee_msat.unwrap_or(0);
906+
// A skimmed fee is only ever set on an inbound JIT-channel receive; outbound and
907+
// regular inbound Bolt11 payments leave it `None`.
908+
PaymentKind::Bolt11 { counterparty_skimmed_fee_msat: Some(msats), .. } => {
908909
debug_assert_eq!(payment.direction, PaymentDirection::Inbound);
909910
Some(Amount::from_milli_sats(msats).expect("Must be valid"))
910911
},
@@ -1111,10 +1112,14 @@ impl Wallet {
11111112
let res = self.inner.ln_wallet.get_bolt11_invoice(amount).await;
11121113
match res {
11131114
Ok(inv) => inv,
1114-
Err(NodeError::ConnectionFailed) => {
1115+
Err(
1116+
NodeError::ConnectionFailed
1117+
| NodeError::LiquidityRequestFailed
1118+
| NodeError::LiquiditySourceUnavailable,
1119+
) => {
11151120
log_warn!(
11161121
self.inner.logger,
1117-
"Failed to connect to LSP when getting BOLT 11 invoice, falling back to trusted wallet"
1122+
"Failed to source inbound liquidity from LSP when getting BOLT 11 invoice, falling back to trusted wallet"
11181123
);
11191124
from_trusted = true;
11201125
self.inner.trusted.get_bolt11_invoice(amount).await?

orange-sdk/src/lightning_wallet.rs

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ impl LightningWallet {
102102
}
103103

104104
let (lsp_socket_addr, lsp_node_id, lsp_token) = config.lsp;
105-
builder.set_liquidity_source_lsps2(lsp_node_id, lsp_socket_addr.clone(), lsp_token);
105+
builder.add_liquidity_source(lsp_node_id, lsp_socket_addr.clone(), lsp_token, true);
106106
match config.chain_source {
107107
ChainSource::Esplora { url, username, password } => {
108108
let sync_config = if config.network == Network::Regtest {
@@ -329,7 +329,7 @@ impl LightningWallet {
329329
// find existing channel to splice out of
330330
let channels = self.inner.ldk_node.list_channels();
331331
let channel =
332-
channels.iter().find(|c| c.counterparty_node_id == self.inner.lsp_node_id);
332+
channels.iter().find(|c| c.counterparty.node_id == self.inner.lsp_node_id);
333333

334334
match channel {
335335
None => {
@@ -339,7 +339,7 @@ impl LightningWallet {
339339
Some(chan) => {
340340
self.inner.ldk_node.splice_out(
341341
&chan.user_channel_id,
342-
chan.counterparty_node_id,
342+
chan.counterparty.node_id,
343343
address,
344344
amount_sats,
345345
)?;
@@ -376,13 +376,13 @@ impl LightningWallet {
376376
pub(crate) async fn splice_all_into_channel(&self) -> Result<UserChannelId, NodeError> {
377377
// find existing channel to splice into
378378
let channels = self.inner.ldk_node.list_channels();
379-
let channel = channels.iter().find(|c| c.counterparty_node_id == self.inner.lsp_node_id);
379+
let channel = channels.iter().find(|c| c.counterparty.node_id == self.inner.lsp_node_id);
380380

381381
match channel {
382382
Some(chan) => {
383383
self.inner
384384
.ldk_node
385-
.splice_in_with_all(&chan.user_channel_id, chan.counterparty_node_id)?;
385+
.splice_in_with_all(&chan.user_channel_id, chan.counterparty.node_id)?;
386386
Ok(chan.user_channel_id)
387387
},
388388
None => {
@@ -409,11 +409,11 @@ impl LightningWallet {
409409
if chan.is_usable {
410410
self.inner
411411
.ldk_node
412-
.close_channel(&chan.user_channel_id, chan.counterparty_node_id)?;
412+
.close_channel(&chan.user_channel_id, chan.counterparty.node_id)?;
413413
} else {
414414
self.inner.ldk_node.force_close_channel(
415415
&chan.user_channel_id,
416-
chan.counterparty_node_id,
416+
chan.counterparty.node_id,
417417
None,
418418
)?;
419419
}
@@ -464,11 +464,7 @@ impl graduated_rebalancer::LightningWallet for LightningWallet {
464464
loop {
465465
if let Some(payment) = self.inner.ldk_node.payment(&id) {
466466
let counterparty_skimmed_fee_msat = match payment.kind {
467-
PaymentKind::Bolt11 { hash, .. } => {
468-
debug_assert!(hash.0 == payment_hash, "Payment Hash mismatch");
469-
None
470-
},
471-
PaymentKind::Bolt11Jit { hash, counterparty_skimmed_fee_msat, .. } => {
467+
PaymentKind::Bolt11 { hash, counterparty_skimmed_fee_msat, .. } => {
472468
debug_assert!(hash.0 == payment_hash, "Payment Hash mismatch");
473469
counterparty_skimmed_fee_msat
474470
},
@@ -492,7 +488,7 @@ impl graduated_rebalancer::LightningWallet for LightningWallet {
492488

493489
fn has_channel_with_lsp(&self) -> bool {
494490
let channels = self.inner.ldk_node.list_channels();
495-
channels.iter().any(|c| c.counterparty_node_id == self.inner.lsp_node_id)
491+
channels.iter().any(|c| c.counterparty.node_id == self.inner.lsp_node_id)
496492
}
497493

498494
fn open_channel_with_lsp(
@@ -550,10 +546,7 @@ impl From<PaymentStatus> for TxStatus {
550546
impl From<&PaymentDetails> for PaymentType {
551547
fn from(d: &PaymentDetails) -> PaymentType {
552548
match (&d.kind, d.direction == PaymentDirection::Outbound) {
553-
(
554-
PaymentKind::Bolt11 { preimage, .. } | PaymentKind::Bolt11Jit { preimage, .. },
555-
true,
556-
) => {
549+
(PaymentKind::Bolt11 { preimage, .. }, true) => {
557550
if d.status == PaymentStatus::Succeeded {
558551
debug_assert!(preimage.is_some());
559552
}

orange-sdk/src/trusted_wallet/dummy.rs

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -210,8 +210,8 @@ impl DummyTrustedWallet {
210210
Event::ChannelPending { .. } => {},
211211
Event::ChannelReady { .. } => {},
212212
Event::ChannelClosed { .. } => {},
213-
Event::SplicePending { .. } => {},
214-
Event::SpliceFailed { .. } => {},
213+
Event::SpliceNegotiated { .. } => {},
214+
Event::SpliceNegotiationFailed { .. } => {},
215215
}
216216
println!("dummy: {event:?}");
217217
if let Err(e) = events_ref.event_handled() {
@@ -294,7 +294,7 @@ impl DummyTrustedWallet {
294294
lsp_clone
295295
.list_channels()
296296
.iter()
297-
.any(|c| c.counterparty_node_id == ldk_node_id && c.is_usable)
297+
.any(|c| c.counterparty.node_id == ldk_node_id && c.is_usable)
298298
},
299299
)
300300
.await;
@@ -312,7 +312,7 @@ impl DummyTrustedWallet {
312312
move || lsp_clone.list_channels(),
313313
)
314314
.await;
315-
if !lsp_channels.iter().any(|c| c.counterparty_node_id == ldk_node_id && c.is_usable) {
315+
if !lsp_channels.iter().any(|c| c.counterparty.node_id == ldk_node_id && c.is_usable) {
316316
panic!(
317317
"No usable LSP-side channel found for dummy node {ldk_node_id}: {lsp_channels:?}"
318318
);
@@ -462,11 +462,7 @@ impl TrustedWalletInterface for DummyTrustedWallet {
462462
loop {
463463
if let Some(payment) = self.ldk_node.payment(&id) {
464464
let counterparty_skimmed_fee_msat = match payment.kind {
465-
PaymentKind::Bolt11 { hash, .. } => {
466-
debug_assert!(hash.0 == payment_hash, "Payment Hash mismatch");
467-
None
468-
},
469-
PaymentKind::Bolt11Jit { hash, counterparty_skimmed_fee_msat, .. } => {
465+
PaymentKind::Bolt11 { hash, counterparty_skimmed_fee_msat, .. } => {
470466
debug_assert!(hash.0 == payment_hash, "Payment Hash mismatch");
471467
counterparty_skimmed_fee_msat
472468
},

orange-sdk/tests/integration_tests.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1221,11 +1221,11 @@ async fn test_force_close_handling() {
12211221
let channel = lsp
12221222
.list_channels()
12231223
.into_iter()
1224-
.find(|c| c.counterparty_node_id == wallet.node_id())
1224+
.find(|c| c.counterparty.node_id == wallet.node_id())
12251225
.unwrap();
12261226

12271227
// force close the channel
1228-
lsp.force_close_channel(&channel.user_channel_id, channel.counterparty_node_id, None)
1228+
lsp.force_close_channel(&channel.user_channel_id, channel.counterparty.node_id, None)
12291229
.unwrap();
12301230

12311231
// wait for the channel to be closed

0 commit comments

Comments
 (0)