Skip to content

Commit 48b76b4

Browse files
authored
Merge pull request #1008 from tnull/2026-07-bump-ldk-to-0.3-beta
Bump LDK to 0.3.0-beta1
2 parents af46a83 + dce81a1 commit 48b76b4

5 files changed

Lines changed: 98 additions & 39 deletions

File tree

Cargo.toml

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -41,18 +41,18 @@ postgres = ["dep:tokio-postgres", "dep:native-tls", "dep:postgres-native-tls"]
4141
#lightning-macros = { version = "0.2.0" }
4242
#lightning-dns-resolver = { version = "0.3.0" }
4343

44-
lightning = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "506cb91f2e0fb87906188b79777bcf42595d3623", features = ["std"] }
45-
lightning-types = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "506cb91f2e0fb87906188b79777bcf42595d3623" }
46-
lightning-invoice = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "506cb91f2e0fb87906188b79777bcf42595d3623", features = ["std"] }
47-
lightning-net-tokio = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "506cb91f2e0fb87906188b79777bcf42595d3623" }
48-
lightning-persister = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "506cb91f2e0fb87906188b79777bcf42595d3623", features = ["tokio"] }
49-
lightning-background-processor = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "506cb91f2e0fb87906188b79777bcf42595d3623" }
50-
lightning-rapid-gossip-sync = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "506cb91f2e0fb87906188b79777bcf42595d3623" }
51-
lightning-block-sync = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "506cb91f2e0fb87906188b79777bcf42595d3623", features = ["rest-client", "rpc-client", "tokio"] }
52-
lightning-transaction-sync = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "506cb91f2e0fb87906188b79777bcf42595d3623", features = ["esplora-async-https", "time", "electrum-rustls-ring"] }
53-
lightning-liquidity = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "506cb91f2e0fb87906188b79777bcf42595d3623", features = ["std"] }
54-
lightning-macros = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "506cb91f2e0fb87906188b79777bcf42595d3623" }
55-
lightning-dns-resolver = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "506cb91f2e0fb87906188b79777bcf42595d3623" }
44+
lightning = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "9174965af9437196c527a9aa0df36bbcf050c8bb", features = ["std"] }
45+
lightning-types = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "9174965af9437196c527a9aa0df36bbcf050c8bb" }
46+
lightning-invoice = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "9174965af9437196c527a9aa0df36bbcf050c8bb", features = ["std"] }
47+
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"] }
49+
lightning-background-processor = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "9174965af9437196c527a9aa0df36bbcf050c8bb" }
50+
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"] }
53+
lightning-liquidity = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "9174965af9437196c527a9aa0df36bbcf050c8bb", features = ["std"] }
54+
lightning-macros = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "9174965af9437196c527a9aa0df36bbcf050c8bb" }
55+
lightning-dns-resolver = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "9174965af9437196c527a9aa0df36bbcf050c8bb" }
5656

5757
bdk_chain = { version = "0.23.3", default-features = false, features = ["std"] }
5858
bdk_esplora = { version = "0.22.2", default-features = false, features = ["async-https-rustls", "tokio"]}
@@ -71,6 +71,7 @@ getrandom = { version = "0.3", default-features = false }
7171
chrono = { version = "0.4", default-features = false, features = ["clock"] }
7272
tokio = { version = "1.39", default-features = false, features = [ "rt-multi-thread", "time", "sync", "macros", "net" ] }
7373
esplora-client = { version = "0.12", default-features = false, features = ["tokio", "async-https-rustls"] }
74+
ldk-esplora-client = { package = "esplora-client", version = "0.13", default-features = false, features = ["tokio", "async-https-rustls"] }
7475
electrum-client = { version = "0.25", default-features = false, features = ["proxy", "use-rustls-ring"] }
7576
libc = "0.2"
7677
uniffi = { version = "0.29.5", features = ["build"], optional = true }
@@ -85,14 +86,14 @@ postgres-native-tls = { version = "0.5", default-features = false, features = ["
8586
vss-client = { package = "vss-client-ng", version = "0.6" }
8687
prost = { version = "0.11.6", default-features = false}
8788
#bitcoin-payment-instructions = { version = "0.6" }
88-
bitcoin-payment-instructions = { git = "https://github.com/tnull/bitcoin-payment-instructions", rev = "0e430be98c09540624a68a68022ee0551e86d1be" }
89+
bitcoin-payment-instructions = { git = "https://github.com/tnull/bitcoin-payment-instructions", rev = "1d6ffaa8962391ddc84aeef98bd7439e55ccae9d" }
8990

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

9394
[dev-dependencies]
94-
lightning = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "506cb91f2e0fb87906188b79777bcf42595d3623", features = ["std", "_test_utils"] }
95-
lightning-persister = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "506cb91f2e0fb87906188b79777bcf42595d3623", features = ["tokio"] }
95+
lightning = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "9174965af9437196c527a9aa0df36bbcf050c8bb", features = ["std", "_test_utils"] }
96+
lightning-persister = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "9174965af9437196c527a9aa0df36bbcf050c8bb", features = ["tokio"] }
9697
rand = { version = "0.9.2", default-features = false, features = ["std", "thread_rng", "os_rng"] }
9798
proptest = "1.0.0"
9899
regex = "1.5.6"

src/chain/esplora.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,16 +56,24 @@ impl EsploraChainSource {
5656
let mut client_builder = esplora_client::Builder::new(&server_url);
5757
client_builder =
5858
client_builder.timeout(sync_config.timeouts_config.per_request_timeout_secs as u64);
59+
let mut ldk_client_builder = ldk_esplora_client::Builder::new(&server_url);
60+
ldk_client_builder = ldk_client_builder.timeout(Duration::from_secs(
61+
sync_config.timeouts_config.per_request_timeout_secs as u64,
62+
));
5963

6064
for (header_name, header_value) in &headers {
6165
client_builder = client_builder.header(header_name, header_value);
66+
ldk_client_builder = ldk_client_builder.header(header_name, header_value);
6267
}
6368

6469
let esplora_client = client_builder.build_async().map_err(|e| {
6570
log_error!(logger, "Failed to build Esplora client: {}", e);
6671
})?;
72+
let ldk_esplora_client = ldk_client_builder.build_async().map_err(|e| {
73+
log_error!(logger, "Failed to build LDK Esplora client: {}", e);
74+
})?;
6775
let tx_sync =
68-
Arc::new(EsploraSyncClient::from_client(esplora_client.clone(), Arc::clone(&logger)));
76+
Arc::new(EsploraSyncClient::from_client(ldk_esplora_client, Arc::clone(&logger)));
6977

7078
let onchain_wallet_sync_status = Mutex::new(WalletSyncStatus::Completed);
7179
let lightning_wallet_sync_status = Mutex::new(WalletSyncStatus::Completed);

src/event.rs

Lines changed: 68 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -196,9 +196,7 @@ pub enum Event {
196196
/// transaction.
197197
claim_from_onchain_tx: bool,
198198
/// The final amount forwarded, in milli-satoshis, after the fee is deducted.
199-
///
200-
/// The caveat described above the `total_fee_earned_msat` field applies here as well.
201-
outbound_amount_forwarded_msat: Option<u64>,
199+
outbound_amount_forwarded_msat: u64,
202200
},
203201
/// A payment for a previously-registered payment hash has been received.
204202
///
@@ -271,8 +269,10 @@ pub enum Event {
271269
/// This will be `None` for events serialized by LDK Node v0.2.1 and prior.
272270
reason: Option<ClosureReason>,
273271
},
274-
/// A channel splice has been negotiated and the funding transaction is pending
275-
/// confirmation on-chain.
272+
/// A channel splice with local inputs or outputs has been negotiated and the funding
273+
/// transaction is pending confirmation on-chain.
274+
///
275+
/// This event is not emitted when only the counterparty contributes to a splice.
276276
SpliceNegotiated {
277277
/// The `channel_id` of the channel.
278278
channel_id: ChannelId,
@@ -283,7 +283,9 @@ pub enum Event {
283283
/// The outpoint of the channel's splice funding transaction.
284284
new_funding_txo: OutPoint,
285285
},
286-
/// A channel splice negotiation round has failed.
286+
/// A channel splice negotiation round with local inputs or outputs has failed.
287+
///
288+
/// This event is not emitted when only the counterparty contributes to a splice.
287289
SpliceNegotiationFailed {
288290
/// The `channel_id` of the channel.
289291
channel_id: ChannelId,
@@ -350,7 +352,7 @@ impl_writeable_tlv_based_enum!(Event,
350352
(8, total_fee_earned_msat, option),
351353
(10, skimmed_fee_msat, option),
352354
(12, claim_from_onchain_tx, required),
353-
(14, outbound_amount_forwarded_msat, option),
355+
(14, outbound_amount_forwarded_msat, (default_value, 0)),
354356
(15, prev_htlcs, (default_value_vec, vec![HTLCLocator {
355357
channel_id: legacy_prev_channel_id.ok_or(lightning::ln::msgs::DecodeError::InvalidValue)?,
356358
user_channel_id: legacy_prev_user_channel_id.map(UserChannelId),
@@ -1500,7 +1502,7 @@ where
15001502
from_prev_str,
15011503
next_htlcs.len(),
15021504
to_next_str,
1503-
outbound_amount_forwarded_msat.unwrap_or(0),
1505+
outbound_amount_forwarded_msat,
15041506
fee_earned,
15051507
);
15061508
} else {
@@ -1511,7 +1513,7 @@ where
15111513
from_prev_str,
15121514
next_htlcs.len(),
15131515
to_next_str,
1514-
outbound_amount_forwarded_msat.unwrap_or(0),
1516+
outbound_amount_forwarded_msat,
15151517
fee_earned,
15161518
);
15171519
}
@@ -2120,6 +2122,14 @@ mod tests {
21202122
counterparty_node_id: Option<PublicKey>,
21212123
reason: Option<ClosureReason>,
21222124
},
2125+
PaymentForwarded {
2126+
prev_htlcs: Vec<HTLCLocator>,
2127+
next_htlcs: Vec<HTLCLocator>,
2128+
total_fee_earned_msat: Option<u64>,
2129+
skimmed_fee_msat: Option<u64>,
2130+
claim_from_onchain_tx: bool,
2131+
outbound_amount_forwarded_msat: Option<u64>,
2132+
},
21232133
}
21242134

21252135
impl_writeable_tlv_based_enum!(LegacyEvent,
@@ -2129,6 +2139,14 @@ mod tests {
21292139
(2, user_channel_id, required),
21302140
(3, reason, upgradable_option),
21312141
},
2142+
(7, PaymentForwarded) => {
2143+
(8, total_fee_earned_msat, option),
2144+
(10, skimmed_fee_msat, option),
2145+
(12, claim_from_onchain_tx, required),
2146+
(14, outbound_amount_forwarded_msat, option),
2147+
(15, prev_htlcs, (default_value_vec, Vec::new())),
2148+
(17, next_htlcs, (default_value_vec, Vec::new())),
2149+
},
21322150
);
21332151

21342152
fn encode_legacy_event_queue(event: LegacyEvent) -> Vec<u8> {
@@ -2190,6 +2208,47 @@ mod tests {
21902208
assert!(res.is_err());
21912209
}
21922210

2211+
#[test]
2212+
fn event_queue_defaults_legacy_missing_forwarded_amount() {
2213+
let store: Arc<DynStore> = Arc::new(DynStoreWrapper(InMemoryStore::new()));
2214+
let logger = Arc::new(TestLogger::new());
2215+
let prev_htlcs = vec![HTLCLocator {
2216+
channel_id: ChannelId([1; 32]),
2217+
user_channel_id: None,
2218+
node_id: None,
2219+
}];
2220+
let next_htlcs = vec![HTLCLocator {
2221+
channel_id: ChannelId([2; 32]),
2222+
user_channel_id: None,
2223+
node_id: None,
2224+
}];
2225+
let legacy_event = LegacyEvent::PaymentForwarded {
2226+
prev_htlcs: prev_htlcs.clone(),
2227+
next_htlcs: next_htlcs.clone(),
2228+
total_fee_earned_msat: None,
2229+
skimmed_fee_msat: None,
2230+
claim_from_onchain_tx: true,
2231+
outbound_amount_forwarded_msat: None,
2232+
};
2233+
let expected_event = LegacyEvent::PaymentForwarded {
2234+
prev_htlcs,
2235+
next_htlcs,
2236+
total_fee_earned_msat: None,
2237+
skimmed_fee_msat: None,
2238+
claim_from_onchain_tx: true,
2239+
outbound_amount_forwarded_msat: Some(0),
2240+
};
2241+
let persisted_bytes = encode_legacy_event_queue(legacy_event);
2242+
2243+
let event_queue =
2244+
EventQueue::read(&mut &persisted_bytes[..], (Arc::clone(&store), logger)).unwrap();
2245+
assert_eq!(
2246+
event_queue.next_event().unwrap().encode(),
2247+
expected_event.encode(),
2248+
"legacy forwarded amount should normalize to zero"
2249+
);
2250+
}
2251+
21932252
#[tokio::test]
21942253
async fn event_queue_concurrency() {
21952254
let store: Arc<DynStore> = Arc::new(DynStoreWrapper(InMemoryStore::new()));

tests/common/mod.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1063,7 +1063,6 @@ pub async fn splice_in_with_all(
10631063
node_a.splice_in_with_all(user_channel_id, node_b.node_id()).unwrap();
10641064

10651065
let splice_txo = expect_splice_negotiated_event!(node_a, node_b.node_id());
1066-
expect_splice_negotiated_event!(node_b, node_a.node_id());
10671066
wait_for_tx(&electrsd.client, splice_txo.txid).await;
10681067
}
10691068

@@ -1537,7 +1536,6 @@ pub(crate) async fn do_channel_full_cycle<E: ElectrumApi>(
15371536
assert!(splice_out_sat > 500_000);
15381537
node_b.splice_out(&user_channel_id_b, node_a.node_id(), &addr_a, splice_out_sat).unwrap();
15391538

1540-
expect_splice_negotiated_event!(node_a, node_b.node_id());
15411539
expect_splice_negotiated_event!(node_b, node_a.node_id());
15421540

15431541
generate_blocks_and_wait(&bitcoind, electrsd, 6).await;
@@ -1560,7 +1558,6 @@ pub(crate) async fn do_channel_full_cycle<E: ElectrumApi>(
15601558
node_a.splice_in(&user_channel_id_a, node_b.node_id(), splice_in_sat).unwrap();
15611559

15621560
expect_splice_negotiated_event!(node_a, node_b.node_id());
1563-
expect_splice_negotiated_event!(node_b, node_a.node_id());
15641561

15651562
generate_blocks_and_wait(&bitcoind, electrsd, 6).await;
15661563
node_a.sync_wallets().unwrap();

tests/integration_tests_rust.rs

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1754,8 +1754,7 @@ async fn splice_channel() {
17541754
// Splice-in funds for Node B so that it has outbound liquidity to make a payment
17551755
node_b.splice_in(&user_channel_id_b, node_a.node_id(), 4_000_000).unwrap();
17561756

1757-
let txo = expect_splice_negotiated_event!(node_a, node_b.node_id());
1758-
expect_splice_negotiated_event!(node_b, node_a.node_id());
1757+
let txo = expect_splice_negotiated_event!(node_b, node_a.node_id());
17591758

17601759
// Node B contributed to this splice, so wait for its funding broadcast to be classified before
17611760
// syncing — otherwise a sync racing the broadcaster's queue records a generic on-chain payment.
@@ -1815,7 +1814,6 @@ async fn splice_channel() {
18151814
node_a.splice_out(&user_channel_id_a, node_b.node_id(), &address, amount_msat / 1000).unwrap();
18161815

18171816
let txo = expect_splice_negotiated_event!(node_a, node_b.node_id());
1818-
expect_splice_negotiated_event!(node_b, node_a.node_id());
18191817

18201818
// Node A contributed to this splice, so wait for its funding broadcast to be classified before
18211819
// syncing — otherwise a sync racing the broadcaster's queue records a generic on-chain payment.
@@ -1928,8 +1926,7 @@ async fn run_rbf_splice_channel_test(confirm_original: bool) {
19281926
// Initiate a splice-in to create a pending splice
19291927
node_b.splice_in(&user_channel_id_b, node_a.node_id(), 1_000_000).unwrap();
19301928

1931-
let original_txo = expect_splice_negotiated_event!(node_a, node_b.node_id());
1932-
expect_splice_negotiated_event!(node_b, node_a.node_id());
1929+
let original_txo = expect_splice_negotiated_event!(node_b, node_a.node_id());
19331930

19341931
// Sync so the original splice candidate is recorded as a canonical wallet transaction before
19351932
// the RBF below replaces it. The post-RBF sync then observes the original candidate being
@@ -1966,8 +1963,7 @@ async fn run_rbf_splice_channel_test(confirm_original: bool) {
19661963
// bump_channel_funding_fee should succeed when there's a pending splice
19671964
node_b.bump_channel_funding_fee(&user_channel_id_b, node_a.node_id()).unwrap();
19681965

1969-
let rbf_txo = expect_splice_negotiated_event!(node_a, node_b.node_id());
1970-
expect_splice_negotiated_event!(node_b, node_a.node_id());
1966+
let rbf_txo = expect_splice_negotiated_event!(node_b, node_a.node_id());
19711967

19721968
assert_ne!(original_txo, rbf_txo, "RBF should produce a different funding txo");
19731969

@@ -2172,8 +2168,7 @@ async fn splice_payment_reorged_to_unconfirmed() {
21722168

21732169
// node_b splices in, recording a funding payment it contributed to.
21742170
node_b.splice_in(&user_channel_id_b, node_a.node_id(), 1_000_000).unwrap();
2175-
let splice_txo = expect_splice_negotiated_event!(node_a, node_b.node_id());
2176-
expect_splice_negotiated_event!(node_b, node_a.node_id());
2171+
let splice_txo = expect_splice_negotiated_event!(node_b, node_a.node_id());
21772172
wait_for_tx(&electrsd.client, splice_txo.txid).await;
21782173
// Ensure node_b classified the splice before syncing so the test exercises a funding payment's
21792174
// reorg rather than a generic on-chain payment's.
@@ -2250,8 +2245,7 @@ async fn splice_in_rbf_joins_counterparty_splice() {
22502245
// node_b (which didn't fund the channel open, so holds the on-chain balance) initiates a
22512246
// splice-in; node_a does not contribute to this first candidate.
22522247
node_b.splice_in(&user_channel_id_b, node_a.node_id(), 1_000_000).unwrap();
2253-
let counterparty_txo = expect_splice_negotiated_event!(node_a, node_b.node_id());
2254-
expect_splice_negotiated_event!(node_b, node_a.node_id());
2248+
let counterparty_txo = expect_splice_negotiated_event!(node_b, node_a.node_id());
22552249
wait_for_tx(&electrsd.client, counterparty_txo.txid).await;
22562250
node_a.sync_wallets().unwrap();
22572251
node_b.sync_wallets().unwrap();

0 commit comments

Comments
 (0)