Skip to content

Commit 929f8cf

Browse files
authored
Merge pull request #3571 from TheBlueMatt/2024-12-0.1-bindings
Merge 0.1.1 into 0.1-bindings
2 parents 7e2c5ef + a5ef3fb commit 929f8cf

23 files changed

+850
-353
lines changed

CHANGELOG.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,39 @@
1+
# 0.1.1 - Jan 28, 2025 - "Onchain Matters"
2+
3+
## API Updates
4+
* A `ChannelManager::send_payment_with_route` was (re-)added, with semantics
5+
similar to `ChannelManager::send_payment` (rather than like the pre-0.1
6+
`send_payent_with_route`, #3534).
7+
* `RawBolt11Invoice::{to,from}_raw` were added (#3549).
8+
9+
## Bug Fixes
10+
* HTLCs which were forwarded where the inbound edge times out within the next
11+
three blocks will have the inbound HTLC failed backwards irrespective of the
12+
status of the outbound HTLC. This avoids the peer force-closing the channel
13+
(and claiming the inbound edge HTLC on-chain) even if we have not yet managed
14+
to claim the outbound edge on chain (#3556).
15+
* On restart, replay of `Event::SpendableOutput`s could have caused
16+
`OutputSweeper` to generate double-spending transactions, making it unable to
17+
claim any delayed claims. This was resolved by retaining old claims for more
18+
than four weeks after they are claimed on-chain to detect replays (#3559).
19+
* Fixed the additional feerate we will pay each time we RBF on-chain claims to
20+
match the Bitcoin Core policy (1 sat/vB) instead of 16 sats/vB (#3457).
21+
* Fixed a cased where a custom `Router` which returns an invalid `Route`,
22+
provided to `ChannelManager`, can result in an outbound payment remaining
23+
pending forever despite no HTLCs being pending (#3531).
24+
25+
## Security
26+
0.1.1 fixes a denial-of-service vulnerability allowing channel counterparties to
27+
cause force-closure of unrelated channels.
28+
* If a malicious channel counterparty force-closes a channel, broadcasting a
29+
revoked commitment transaction while the channel at closure time included
30+
multiple non-dust forwarded outbound HTLCs with identical payment hashes and
31+
amounts, failure to fail the HTLCs backwards could cause the channels on
32+
which we recieved the corresponding inbound HTLCs to be force-closed. Note
33+
that we'll receive, at a minimum, the malicious counterparty's reserve value
34+
when they broadcast the stale commitment (#3556). Thanks to Matt Morehouse for
35+
reporting this issue.
36+
137
# 0.1 - Jan 15, 2025 - "Human Readable Version Numbers"
238

339
The LDK 0.1 release represents an important milestone for the LDK project. While

fuzz/src/chanmon_consistency.rs

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ use lightning::ln::channel::FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE;
4848
use lightning::ln::channel_state::ChannelDetails;
4949
use lightning::ln::channelmanager::{
5050
ChainParameters, ChannelManager, ChannelManagerReadArgs, PaymentId, RecentPaymentDetails,
51+
RecipientOnionFields,
5152
};
5253
use lightning::ln::functional_test_utils::*;
5354
use lightning::ln::inbound_payment::ExpandedKey;
@@ -82,7 +83,6 @@ use bitcoin::secp256k1::{self, Message, PublicKey, Scalar, Secp256k1, SecretKey}
8283

8384
use lightning::io::Cursor;
8485
use std::cmp::{self, Ordering};
85-
use std::collections::VecDeque;
8686
use std::mem;
8787
use std::sync::atomic;
8888
use std::sync::{Arc, Mutex};
@@ -113,22 +113,14 @@ impl FeeEstimator for FuzzEstimator {
113113
}
114114
}
115115

116-
struct FuzzRouter {
117-
pub next_routes: Mutex<VecDeque<Route>>,
118-
}
116+
struct FuzzRouter {}
119117

120118
impl Router for FuzzRouter {
121119
fn find_route(
122120
&self, _payer: &PublicKey, _params: &RouteParameters,
123121
_first_hops: Option<&[&ChannelDetails]>, _inflight_htlcs: InFlightHtlcs,
124122
) -> Result<Route, msgs::LightningError> {
125-
if let Some(route) = self.next_routes.lock().unwrap().pop_front() {
126-
return Ok(route);
127-
}
128-
Err(msgs::LightningError {
129-
err: String::from("Not implemented"),
130-
action: msgs::ErrorAction::IgnoreError,
131-
})
123+
unreachable!()
132124
}
133125

134126
fn create_blinded_payment_paths<T: secp256k1::Signing + secp256k1::Verification>(
@@ -518,7 +510,7 @@ fn send_payment(
518510
PaymentParameters::from_node_id(source.get_our_node_id(), TEST_FINAL_CLTV),
519511
amt,
520512
);
521-
source.router.next_routes.lock().unwrap().push_back(Route {
513+
let route = Route {
522514
paths: vec![Path {
523515
hops: vec![RouteHop {
524516
pubkey: dest.get_our_node_id(),
@@ -532,11 +524,10 @@ fn send_payment(
532524
blinded_tail: None,
533525
}],
534526
route_params: Some(route_params.clone()),
535-
});
527+
};
536528
let onion = RecipientOnionFields::secret_only(payment_secret);
537529
let payment_id = PaymentId(payment_id);
538-
let res =
539-
source.send_payment(payment_hash, onion, payment_id, route_params, Retry::Attempts(0));
530+
let res = source.send_payment_with_route(route, payment_hash, onion, payment_id);
540531
match res {
541532
Err(err) => {
542533
panic!("Errored with {:?} on initial payment send", err);
@@ -592,7 +583,7 @@ fn send_hop_payment(
592583
PaymentParameters::from_node_id(source.get_our_node_id(), TEST_FINAL_CLTV),
593584
amt,
594585
);
595-
source.router.next_routes.lock().unwrap().push_back(Route {
586+
let route = Route {
596587
paths: vec![Path {
597588
hops: vec![
598589
RouteHop {
@@ -617,11 +608,10 @@ fn send_hop_payment(
617608
blinded_tail: None,
618609
}],
619610
route_params: Some(route_params.clone()),
620-
});
611+
};
621612
let onion = RecipientOnionFields::secret_only(payment_secret);
622613
let payment_id = PaymentId(payment_id);
623-
let res =
624-
source.send_payment(payment_hash, onion, payment_id, route_params, Retry::Attempts(0));
614+
let res = source.send_payment_with_route(route, payment_hash, onion, payment_id);
625615
match res {
626616
Err(err) => {
627617
panic!("Errored with {:?} on initial payment send", err);
@@ -640,7 +630,7 @@ fn send_hop_payment(
640630
pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out, anchors: bool) {
641631
let out = SearchingOutput::new(underlying_out);
642632
let broadcast = Arc::new(TestBroadcaster {});
643-
let router = FuzzRouter { next_routes: Mutex::new(VecDeque::new()) };
633+
let router = FuzzRouter {};
644634

645635
macro_rules! make_node {
646636
($node_id: expr, $fee_estimator: expr) => {{

lightning-background-processor/src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1092,7 +1092,7 @@ mod tests {
10921092
SCORER_PERSISTENCE_SECONDARY_NAMESPACE,
10931093
};
10941094
use lightning::util::ser::Writeable;
1095-
use lightning::util::sweep::{OutputSpendStatus, OutputSweeper};
1095+
use lightning::util::sweep::{OutputSpendStatus, OutputSweeper, PRUNE_DELAY_BLOCKS};
10961096
use lightning::util::test_utils;
10971097
use lightning::{get_event, get_event_msg};
10981098
use lightning_persister::fs_store::FilesystemStore;
@@ -2274,8 +2274,8 @@ mod tests {
22742274
}
22752275

22762276
// Check we stop tracking the spendable outputs when one of the txs reaches
2277-
// ANTI_REORG_DELAY confirmations.
2278-
confirm_transaction_depth(&mut nodes[0], &sweep_tx_0, ANTI_REORG_DELAY);
2277+
// PRUNE_DELAY_BLOCKS confirmations.
2278+
confirm_transaction_depth(&mut nodes[0], &sweep_tx_0, PRUNE_DELAY_BLOCKS);
22792279
assert_eq!(nodes[0].sweeper.tracked_spendable_outputs().len(), 0);
22802280

22812281
if !std::thread::panicking() {

lightning-invoice/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22
name = "lightning-invoice"
33
description = "Data structures to parse and serialize BOLT11 lightning invoices"
4-
version = "0.33.0"
4+
version = "0.33.1"
55
authors = ["Sebastian Geisler <[email protected]>"]
66
documentation = "https://docs.rs/lightning-invoice/"
77
license = "MIT OR Apache-2.0"

lightning-invoice/src/lib.rs

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ use core::iter::FilterMap;
4848
use core::num::ParseIntError;
4949
use core::ops::Deref;
5050
use core::slice::Iter;
51+
use core::str::FromStr;
5152
use core::time::Duration;
5253

5354
#[cfg(feature = "serde")]
@@ -78,8 +79,12 @@ use crate::prelude::*;
7879
/// Re-export serialization traits
7980
#[cfg(fuzzing)]
8081
pub use crate::de::FromBase32;
82+
#[cfg(not(fuzzing))]
83+
use crate::de::FromBase32;
8184
#[cfg(fuzzing)]
8285
pub use crate::ser::Base32Iterable;
86+
#[cfg(not(fuzzing))]
87+
use crate::ser::Base32Iterable;
8388

8489
/// Errors that indicate what is wrong with the invoice. They have some granularity for debug
8590
/// reasons, but should generally result in an "invalid BOLT11 invoice" message for the user.
@@ -1088,9 +1093,6 @@ impl RawBolt11Invoice {
10881093

10891094
/// Calculate the hash of the encoded `RawBolt11Invoice` which should be signed.
10901095
pub fn signable_hash(&self) -> [u8; 32] {
1091-
#[cfg(not(fuzzing))]
1092-
use crate::ser::Base32Iterable;
1093-
10941096
Self::hash_from_parts(self.hrp.to_string().as_bytes(), self.data.fe_iter())
10951097
}
10961098

@@ -1191,6 +1193,25 @@ impl RawBolt11Invoice {
11911193
pub fn currency(&self) -> Currency {
11921194
self.hrp.currency.clone()
11931195
}
1196+
1197+
/// Convert to HRP prefix and Fe32 encoded data part.
1198+
/// Can be used to transmit unsigned invoices for remote signing.
1199+
///
1200+
/// This is not exported to bindings users as we don't currently support Fe32s
1201+
pub fn to_raw(&self) -> (String, Vec<Fe32>) {
1202+
(self.hrp.to_string(), self.data.fe_iter().collect())
1203+
}
1204+
1205+
/// Convert from HRP prefix and Fe32 encoded data part.
1206+
/// Can be used to receive unsigned invoices for remote signing.
1207+
///
1208+
/// This is not exported to bindings users as we don't currently support Fe32s
1209+
pub fn from_raw(hrp: &str, data: &[Fe32]) -> Result<Self, Bolt11ParseError> {
1210+
let raw_hrp: RawHrp = RawHrp::from_str(hrp)?;
1211+
let data_part = RawDataPart::from_base32(data)?;
1212+
1213+
Ok(Self { hrp: raw_hrp, data: data_part })
1214+
}
11941215
}
11951216

11961217
impl PositiveTimestamp {

lightning/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "lightning"
3-
version = "0.1.0"
3+
version = "0.1.1"
44
authors = ["Matt Corallo"]
55
license = "MIT OR Apache-2.0"
66
repository = "https://github.com/lightningdevkit/rust-lightning/"

lightning/src/chain/chaininterface.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ pub trait FeeEstimator {
176176
}
177177

178178
/// Minimum relay fee as required by bitcoin network mempool policy.
179-
pub const MIN_RELAY_FEE_SAT_PER_1000_WEIGHT: u64 = 4000;
179+
pub const MIN_RELAY_FEE_SAT_PER_1000_WEIGHT: u64 = 253;
180180
/// Minimum feerate that takes a sane approach to bitcoind weight-to-vbytes rounding.
181181
/// See the following Core Lightning commit for an explanation:
182182
/// <https://github.com/ElementsProject/lightning/commit/2e687b9b352c9092b5e8bd4a688916ac50b44af0>

0 commit comments

Comments
 (0)