Skip to content

Commit 4d0293a

Browse files
authored
Merge pull request #56 from lightningdevkit/update-deps
2 parents dd74385 + 3582c5e commit 4d0293a

17 files changed

Lines changed: 370 additions & 118 deletions

File tree

.github/workflows/tests.yml

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,36 +7,28 @@ on:
77
branches: [ main, master ]
88
workflow_dispatch:
99

10+
concurrency:
11+
group: ${{ github.workflow }}-${{ github.ref }}
12+
cancel-in-progress: true
13+
1014
jobs:
1115
rust_tests:
1216
name: Rust Checks
1317
runs-on: self-hosted
14-
timeout-minutes: 60
18+
timeout-minutes: 120
1519
steps:
1620
- uses: actions/checkout@v4
17-
- uses: actions-rs/toolchain@v1
21+
- uses: dtolnay/rust-toolchain@stable
1822
with:
19-
toolchain: stable
2023
components: clippy, rustfmt
21-
override: true
22-
profile: minimal
2324

2425
- name: Install Protoc
2526
uses: arduino/setup-protoc@v3
2627
with:
2728
version: "30.2"
2829
repo-token: ${{ secrets.GITHUB_TOKEN }}
2930

30-
- uses: actions/cache@v3
31-
with:
32-
path: |
33-
~/.cargo/registry
34-
~/.cargo/git
35-
target
36-
key: cargo-${{ runner.os }}-rust-tests-${{ hashFiles('**/Cargo.toml') }}
37-
restore-keys: |
38-
cargo-${{ runner.os }}-rust-tests-
39-
cargo-${{ runner.os }}-
31+
- uses: Swatinem/rust-cache@v2.7.8
4032

4133
- name: Check formatting
4234
run: cargo fmt --check

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 = { version = "0.6.0" }
20-
lightning = { version = "0.2.0" }
21-
lightning-invoice = { version = "0.34.0" }
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" }
2222

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

graduated-rebalancer/src/lib.rs

Lines changed: 18 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
1010
use bitcoin_payment_instructions::amount::Amount;
1111
use bitcoin_payment_instructions::PaymentMethod;
12-
use lightning::bitcoin::hashes::Hash;
1312
use lightning::bitcoin::hex::DisplayHex;
1413
use lightning::bitcoin::OutPoint;
1514
use lightning::util::logger::Logger;
@@ -278,7 +277,7 @@ where
278277
self.logger,
279278
"Attempting to pay invoice {inv} to rebalance for {transfer_amt:?}",
280279
);
281-
let expected_hash = *inv.payment_hash();
280+
let expected_hash = inv.payment_hash();
282281
match self.trusted.pay(PaymentMethod::LightningBolt11(inv), transfer_amt).await {
283282
Ok(rebalance_id) => {
284283
log_debug!(
@@ -295,29 +294,23 @@ where
295294
})
296295
.await;
297296

298-
let ln_payment = match self
299-
.ln_wallet
300-
.await_payment_receipt(expected_hash.to_byte_array())
301-
.await
302-
{
303-
Some(receipt) => receipt,
304-
None => {
305-
log_error!(self.logger, "Failed to receive rebalance payment!");
306-
return;
307-
},
308-
};
309-
310-
let trusted_payment = match self
311-
.trusted
312-
.await_payment_success(expected_hash.to_byte_array())
313-
.await
314-
{
315-
Some(success) => success,
316-
None => {
317-
log_error!(self.logger, "Failed to send rebalance payment!");
318-
return;
319-
},
320-
};
297+
let ln_payment =
298+
match self.ln_wallet.await_payment_receipt(expected_hash.0).await {
299+
Some(receipt) => receipt,
300+
None => {
301+
log_error!(self.logger, "Failed to receive rebalance payment!");
302+
return;
303+
},
304+
};
305+
306+
let trusted_payment =
307+
match self.trusted.await_payment_success(expected_hash.0).await {
308+
Some(success) => success,
309+
None => {
310+
log_error!(self.logger, "Failed to send rebalance payment!");
311+
return;
312+
},
313+
};
321314

322315
log_info!(
323316
self.logger,

orange-sdk/Cargo.toml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ edition = "2024"
55
authors = ["benthecarman <benthecarman@live.com>"]
66
documentation = "https://docs.rs/orange-sdk/"
77
license = "MIT OR Apache-2.0"
8-
keywords = [ "lightning", "bitcoin", "spark", "cashu" ]
8+
keywords = ["lightning", "bitcoin", "spark", "cashu"]
99
readme = "../README.md"
1010

1111
[lib]
@@ -23,24 +23,24 @@ _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 = { version = "0.7.0" }
26+
ldk-node = { git = "https://github.com/lightningdevkit/ldk-node", rev = "109978de1f57fc3b3f23f241f238b97d9deaa56a" }
2727
lightning-macros = "0.2.0"
2828
bitcoin-payment-instructions = { workspace = true, features = ["http"] }
2929
chrono = { version = "0.4", default-features = false }
3030
rand = { version = "0.8.5", optional = true }
31-
breez-sdk-spark = { git = "https://github.com/breez/spark-sdk.git", rev = "1000f276d2f16592b5f6eb8fce29228f34ff88bf", default-features = false, optional = true }
31+
breez-sdk-spark = { git = "https://github.com/breez/spark-sdk.git", rev = "0d8db793618a4f9eaf8098d759baefe58ea2da49", default-features = false, optional = true }
3232
tokio = { version = "1.0", default-features = false, features = ["rt-multi-thread", "sync", "macros"] }
3333
uuid = { version = "1.0", default-features = false, optional = true }
34-
cdk = { version = "0.15.1", default-features = false, features = ["wallet"], optional = true }
34+
cdk = { version = "0.16.0", default-features = false, features = ["wallet"], optional = true }
3535
serde_json = { version = "1.0", optional = true }
3636
async-trait = "0.1"
3737
log = "0.4.28"
3838

3939
corepc-node = { version = "0.10.1", features = ["29_0", "download"], optional = true }
4040
electrsd = { version = "0.36.1", default-features = false, features = ["esplora_a33e97e1", "corepc-node_29_0"], optional = true }
41-
cdk-ldk-node = { version = "0.15.1", optional = true }
42-
cdk-sqlite = { version = "0.15.1", optional = true }
43-
cdk-axum = { version = "0.15.1", optional = true }
41+
cdk-ldk-node = { version = "0.16.0", optional = true }
42+
cdk-sqlite = { version = "0.16.0", optional = true }
43+
cdk-axum = { version = "0.16.0", optional = true }
4444
axum = { version = "0.8.1", optional = true }
4545

4646
uniffi = { version = "0.29", default-features = false, features = ["cli"], optional = true }

orange-sdk/src/dyn_store.rs

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
//! Object-safe wrapper around ldk-node's `KVStore` + `KVStoreSync` traits.
2+
//!
3+
//! `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.
8+
//!
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`.
14+
15+
use std::future::Future;
16+
use std::pin::Pin;
17+
use std::sync::Arc;
18+
19+
use ldk_node::lightning::io;
20+
use ldk_node::lightning::util::persist::{KVStore, KVStoreSync};
21+
22+
/// Object-safe view of a `KVStore + KVStoreSync` backend. Async methods return boxed
23+
/// futures so the trait can be used through `dyn`.
24+
pub(crate) trait DynStore: Send + Sync + 'static {
25+
fn read_async(
26+
&self, primary_namespace: &str, secondary_namespace: &str, key: &str,
27+
) -> Pin<Box<dyn Future<Output = Result<Vec<u8>, io::Error>> + Send + 'static>>;
28+
29+
fn write_async(
30+
&self, primary_namespace: &str, secondary_namespace: &str, key: &str, buf: Vec<u8>,
31+
) -> Pin<Box<dyn Future<Output = Result<(), io::Error>> + Send + 'static>>;
32+
33+
fn remove_async(
34+
&self, primary_namespace: &str, secondary_namespace: &str, key: &str, lazy: bool,
35+
) -> Pin<Box<dyn Future<Output = Result<(), io::Error>> + Send + 'static>>;
36+
37+
fn list_async(
38+
&self, primary_namespace: &str, secondary_namespace: &str,
39+
) -> 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>;
56+
}
57+
58+
impl<T> DynStore for T
59+
where
60+
T: KVStore + KVStoreSync + Send + Sync + 'static,
61+
{
62+
fn read_async(
63+
&self, p: &str, s: &str, k: &str,
64+
) -> Pin<Box<dyn Future<Output = Result<Vec<u8>, io::Error>> + Send + 'static>> {
65+
Box::pin(<T as KVStore>::read(self, p, s, k))
66+
}
67+
68+
fn write_async(
69+
&self, p: &str, s: &str, k: &str, buf: Vec<u8>,
70+
) -> Pin<Box<dyn Future<Output = Result<(), io::Error>> + Send + 'static>> {
71+
Box::pin(<T as KVStore>::write(self, p, s, k, buf))
72+
}
73+
74+
fn remove_async(
75+
&self, p: &str, s: &str, k: &str, lazy: bool,
76+
) -> Pin<Box<dyn Future<Output = Result<(), io::Error>> + Send + 'static>> {
77+
Box::pin(<T as KVStore>::remove(self, p, s, k, lazy))
78+
}
79+
80+
fn list_async(
81+
&self, p: &str, s: &str,
82+
) -> Pin<Box<dyn Future<Output = Result<Vec<String>, io::Error>> + Send + 'static>> {
83+
Box::pin(<T as KVStore>::list(self, p, s))
84+
}
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+
}
101+
}
102+
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.
112+
impl KVStore for dyn DynStore {
113+
fn read(
114+
&self, p: &str, s: &str, k: &str,
115+
) -> impl Future<Output = Result<Vec<u8>, io::Error>> + Send + 'static {
116+
self.read_async(p, s, k)
117+
}
118+
fn write(
119+
&self, p: &str, s: &str, k: &str, buf: Vec<u8>,
120+
) -> impl Future<Output = Result<(), io::Error>> + Send + 'static {
121+
self.write_async(p, s, k, buf)
122+
}
123+
fn remove(
124+
&self, p: &str, s: &str, k: &str, lazy: bool,
125+
) -> impl Future<Output = Result<(), io::Error>> + Send + 'static {
126+
self.remove_async(p, s, k, lazy)
127+
}
128+
fn list(
129+
&self, p: &str, s: &str,
130+
) -> impl Future<Output = Result<Vec<String>, io::Error>> + Send + 'static {
131+
self.list_async(p, s)
132+
}
133+
}
134+
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+
150+
/// 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`.
153+
#[derive(Clone)]
154+
pub(crate) struct LdkNodeStore(pub(crate) Arc<dyn DynStore>);
155+
156+
impl KVStore for LdkNodeStore {
157+
fn read(
158+
&self, p: &str, s: &str, k: &str,
159+
) -> impl Future<Output = Result<Vec<u8>, io::Error>> + Send + 'static {
160+
self.0.read_async(p, s, k)
161+
}
162+
fn write(
163+
&self, p: &str, s: &str, k: &str, buf: Vec<u8>,
164+
) -> impl Future<Output = Result<(), io::Error>> + Send + 'static {
165+
self.0.write_async(p, s, k, buf)
166+
}
167+
fn remove(
168+
&self, p: &str, s: &str, k: &str, lazy: bool,
169+
) -> impl Future<Output = Result<(), io::Error>> + Send + 'static {
170+
self.0.remove_async(p, s, k, lazy)
171+
}
172+
fn list(
173+
&self, p: &str, s: &str,
174+
) -> impl Future<Output = Result<Vec<String>, io::Error>> + Send + 'static {
175+
self.0.list_async(p, s)
176+
}
177+
}
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 & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use crate::logging::Logger;
22
use crate::store::{self, PaymentId};
33

4+
use crate::dyn_store::DynStore;
45
use ldk_node::bitcoin::secp256k1::PublicKey;
56
use ldk_node::bitcoin::{OutPoint, Txid};
67
use ldk_node::lightning::events::{ClosureReason, PaymentFailureReason};
@@ -11,7 +12,7 @@ use ldk_node::lightning::util::ser::{Writeable, Writer};
1112
use ldk_node::lightning::{impl_writeable_tlv_based_enum, log_debug, log_error, log_warn};
1213
use ldk_node::lightning_types::payment::{PaymentHash, PaymentPreimage};
1314
use ldk_node::payment::{ConfirmationStatus, PaymentKind};
14-
use ldk_node::{CustomTlvRecord, DynStore, UserChannelId};
15+
use ldk_node::{CustomTlvRecord, UserChannelId};
1516

1617
use std::collections::VecDeque;
1718
use std::sync::Arc;
@@ -207,12 +208,12 @@ impl_writeable_tlv_based_enum!(Event,
207208
pub struct EventQueue {
208209
queue: Arc<Mutex<VecDeque<Event>>>,
209210
waker: Arc<Mutex<Option<Waker>>>,
210-
kv_store: Arc<DynStore>,
211+
kv_store: Arc<dyn DynStore>,
211212
logger: Arc<Logger>,
212213
}
213214

214215
impl EventQueue {
215-
pub(crate) fn new(kv_store: Arc<DynStore>, logger: Arc<Logger>) -> Self {
216+
pub(crate) fn new(kv_store: Arc<dyn DynStore>, logger: Arc<Logger>) -> Self {
216217
let queue = Arc::new(Mutex::new(VecDeque::new()));
217218
let waker = Arc::new(Mutex::new(None));
218219
Self { queue, waker, kv_store, logger }
@@ -335,6 +336,7 @@ impl LdkEventHandler {
335336
payment_hash,
336337
payment_preimage,
337338
fee_paid_msat,
339+
bolt12_invoice: _,
338340
} => {
339341
let preimage = payment_preimage.unwrap(); // safe
340342
let payment_id = PaymentId::SelfCustodial(payment_id.unwrap().0); // safe

0 commit comments

Comments
 (0)