What changed, and why it matters
This commit raises the Minimum Supported Rust Version (MSRV) from 1.63.0 to 1.75.0 for the rust-lightning project. It updates CI configuration, documentation, linting rules, and dependency pinning scripts. It also replaces older Rust idioms with newer, cleaner equivalents (such as using div_ceil and is_some_and methods) that require the newer compiler version. There is no security fix or vulnerability being patched here.
No security action required. Downstream users building from source should ensure their Rust toolchain is at least 1.75.0. Distributors and package maintainers should update build requirements accordingly.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The commit bumps the MSRV to Rust 1.75.0 across all crates, unifying the previously split MSRV (1.63.0 for most crates, 1.75.0 for lightning-transaction-sync). Changes include CI matrix updates, removal of dependency version pins needed only for older compilers, removal of clippy allow annotations tied to pre-1.75 MSRV, and source-code refactoring to use stabilized APIs like usize::div_ceil, Option::is_some_and, and io::Error::other. These are semantic-preserving cleanups enabled by the newer compiler.
Changed components
CI/build configurationCONTRIBUTING.mdlinting scriptsdependency pinning scriptslightning-invoicelightning-liquiditylightning-persisterlightning-typeslightning core craterustfmt configurationInspect captured patch +55 / −90
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index cbc50ba..b643058 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -31,10 +31,10 @@ jobs:
fail-fast: false
matrix:
platform: [ self-hosted, windows-latest, macos-latest ]
- toolchain: [ stable, beta, 1.63.0 ] # 1.63.0 is the MSRV for all crates but `lightning-transaction-sync`.
+ toolchain: [ stable, beta, 1.75.0 ] # 1.75.0 is the MSRV for all crates
exclude:
- platform: windows-latest
- toolchain: 1.63.0
+ toolchain: 1.75.0
- platform: windows-latest
toolchain: beta
- platform: macos-latest
@@ -60,7 +60,7 @@ jobs:
shellcheck ci/*.sh -aP ci
shellcheck contrib/*.sh -aP contrib
- name: Set RUSTFLAGS to deny warnings
- if: "matrix.toolchain == '1.63.0'"
+ if: "matrix.toolchain == '1.75.0'"
run: echo "RUSTFLAGS=-D warnings" >> "$GITHUB_ENV"
- name: Run CI script
shell: bash # Default on Winblows is powershell
@@ -71,7 +71,7 @@ jobs:
fail-fast: false
matrix:
platform: [ ubuntu-latest, macos-latest ]
- toolchain: [ stable, beta, 1.75.0 ] # 1.75.0 is the MSRV for `lightning-transaction-sync`.
+ toolchain: [ stable, beta, 1.75.0 ]
runs-on: ${{ matrix.platform }}
steps:
- name: Checkout source code
@@ -254,17 +254,13 @@ jobs:
fuzz:
runs-on: self-hosted
env:
- TOOLCHAIN: 1.63
+ TOOLCHAIN: 1.75
steps:
- name: Checkout source code
uses: actions/checkout@v4
- name: Install Rust ${{ env.TOOLCHAIN }} toolchain
run: |
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile=minimal --default-toolchain ${{ env.TOOLCHAIN }}
- - name: Pin the regex dependency
- run: |
- cd fuzz && cargo update -p regex --precise "1.9.6" --verbose
- cd write-seeds && cargo update -p regex --precise "1.9.6" --verbose
- name: Sanity check fuzz targets on Rust ${{ env.TOOLCHAIN }}
run: |
cd fuzz
@@ -293,7 +289,7 @@ jobs:
rustfmt:
runs-on: ubuntu-latest
env:
- TOOLCHAIN: 1.63.0
+ TOOLCHAIN: 1.75.0
steps:
- name: Checkout source code
uses: actions/checkout@v4
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index b0fcae8..1bc431a 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -88,7 +88,7 @@ be covered by functional tests.
When refactoring, structure your PR to make it easy to review and don't
hesitate to split it into multiple small, focused PRs.
-The Minimum Supported Rust Version (MSRV) currently is 1.63.0 (enforced by
+The Minimum Supported Rust Version (MSRV) currently is 1.75.0 (enforced by
our GitHub Actions). We support reading serialized LDK objects written by any
version of LDK 0.0.99 and above. We support LDK versions 0.0.113 and above
reading serialized LDK objects written by modern LDK. Any expected issues with
@@ -124,7 +124,7 @@ display fine at any tab-length display setting. We use `rustfmt` to establish
uniform coding standards throughout the codebase. Please run
```bash
-cargo +1.63.0 fmt
+cargo +1.75.0 fmt
```
before committing and pushing any changes, as compliance will also be checked
diff --git a/ci/check-lint.sh b/ci/check-lint.sh
index bd4df3b..39c1069 100755
--- a/ci/check-lint.sh
+++ b/ci/check-lint.sh
@@ -47,7 +47,6 @@ CLIPPY() {
-A clippy::len_without_is_empty \
-A clippy::len_zero \
-A clippy::let_and_return \
- -A clippy::manual_div_ceil `# to be removed once we hit MSRV 1.73.0` \
-A clippy::manual_filter \
-A clippy::manual_map \
-A clippy::manual_memcpy \
@@ -106,9 +105,7 @@ CLIPPY() {
-A clippy::unnecessary_unwrap \
-A clippy::unused_unit \
-A clippy::useless_conversion \
- -A clippy::unnecessary_map_or `# to be removed once we hit MSRV 1.70` \
-A clippy::manual_repeat_n `# to be removed once we hit MSRV 1.86` \
- -A clippy::io_other_error `# to be removed once we hit MSRV 1.74` \
-A clippy::manual_is_multiple_of `# to be removed once we hit MSRV 1.87` \
-A clippy::uninlined-format-args
}
diff --git a/ci/ci-tests.sh b/ci/ci-tests.sh
index 41faed6..c423921 100755
--- a/ci/ci-tests.sh
+++ b/ci/ci-tests.sh
@@ -2,40 +2,20 @@
#shellcheck disable=SC2002,SC2207
set -eox pipefail
-RUSTC_MINOR_VERSION=$(rustc --version | awk '{ split($2,a,"."); print a[2] }')
+# Currently unused as we don't have to pin anything for MSRV:
+#RUSTC_MINOR_VERSION=$(rustc --version | awk '{ split($2,a,"."); print a[2] }')
# Some crates require pinning to meet our MSRV even for our downstream users,
# which we do here.
# Further crates which appear only as dev-dependencies are pinned further down.
function PIN_RELEASE_DEPS {
- # Starting with version 1.39.0, the `tokio` crate has an MSRV of rustc 1.70.0
- [ "$RUSTC_MINOR_VERSION" -lt 70 ] && cargo update -p tokio --precise "1.38.1" --verbose
-
return 0 # Don't fail the script if our rustc is higher than the last check
}
PIN_RELEASE_DEPS # pin the release dependencies in our main workspace
-# Starting with version 1.10.0, the `regex` crate has an MSRV of rustc 1.65.0.
-[ "$RUSTC_MINOR_VERSION" -lt 65 ] && cargo update -p regex --precise "1.9.6" --verbose
-
-# The addr2line v0.21 crate (a dependency of `backtrace` starting with 0.3.69) relies on rustc 1.65
-[ "$RUSTC_MINOR_VERSION" -lt 65 ] && cargo update -p backtrace --precise "0.3.68" --verbose
-
-# The once_cell v1.21.0 crate (a dependency of `proptest`) relies on rustc 1.70
-[ "$RUSTC_MINOR_VERSION" -lt 70 ] && cargo update -p once_cell --precise "1.20.3" --verbose
-
-# proptest 1.3.0 requires rustc 1.64.0
-[ "$RUSTC_MINOR_VERSION" -lt 64 ] && cargo update -p proptest --precise "1.2.0" --verbose
-
-# parking_lot 0.12.4 requires rustc 1.64.0
-[ "$RUSTC_MINOR_VERSION" -lt 64 ] && cargo update -p parking_lot --precise "0.12.3" --verbose
-
-# parking_lot_core 0.9.11 requires rustc 1.64.0
-[ "$RUSTC_MINOR_VERSION" -lt 64 ] && cargo update -p parking_lot_core --precise "0.9.10" --verbose
-
-# lock_api 0.4.13 requires rustc 1.64.0
-[ "$RUSTC_MINOR_VERSION" -lt 64 ] && cargo update -p lock_api --precise "0.4.12" --verbose
+# The backtrace v0.3.75 crate relies on rustc 1.82
+[ "$RUSTC_MINOR_VERSION" -lt 82 ] && cargo update -p backtrace --precise "0.3.74" --verbose
export RUST_BACKTRACE=1
@@ -49,7 +29,6 @@ cargo test --verbose --color always
echo -e "\n\nTesting upgrade from prior versions of LDK"
pushd lightning-tests
-[ "$RUSTC_MINOR_VERSION" -lt 65 ] && cargo update -p regex --precise "1.9.6" --verbose
cargo test
popd
diff --git a/lightning-invoice/src/de.rs b/lightning-invoice/src/de.rs
index a4e3cf7..0747015 100644
--- a/lightning-invoice/src/de.rs
+++ b/lightning-invoice/src/de.rs
@@ -102,7 +102,7 @@ impl FromBase32 for Bolt11InvoiceFeatures {
// Carry bits, 0, 1, 2, 3, or 4 bits
let mut carry_bits = 0;
let mut carry = 0u8;
- let expected_raw_length = (field_data.len() * 5 + 7) / 8;
+ let expected_raw_length = (field_data.len() * 5).div_ceil(8);
let mut output = Vec::<u8>::with_capacity(expected_raw_length);
// Iterate over input in reverse
diff --git a/lightning-invoice/src/ser.rs b/lightning-invoice/src/ser.rs
index 6da172c..5c93fa8 100644
--- a/lightning-invoice/src/ser.rs
+++ b/lightning-invoice/src/ser.rs
@@ -237,7 +237,7 @@ fn encode_int_be_base32(int: u64) -> impl ExactSizeIterator<Item = Fe32> {
/// The length of the output of `encode_int_be_base32`.
fn encoded_int_be_base32_size(int: u64) -> usize {
let bit_len = 64 - int.leading_zeros() as usize; // cast ok as value is in 0..=64.
- (bit_len + 4) / 5
+ bit_len.div_ceil(5)
}
impl Base32Iterable for RawDataPart {
diff --git a/lightning-liquidity/src/lsps2/service.rs b/lightning-liquidity/src/lsps2/service.rs
index 7d7d75b..c715d40 100644
--- a/lightning-liquidity/src/lsps2/service.rs
+++ b/lightning-liquidity/src/lsps2/service.rs
@@ -781,7 +781,7 @@ where
/// Returns whether the peer has any active LSPS2 requests.
pub(crate) fn has_active_requests(&self, counterparty_node_id: &PublicKey) -> bool {
let outer_state_lock = self.per_peer_state.read().unwrap();
- outer_state_lock.get(counterparty_node_id).map_or(false, |inner| {
+ outer_state_lock.get(counterparty_node_id).is_some_and(|inner| {
let peer_state = inner.lock().unwrap();
!peer_state.outbound_channels_by_intercept_scid.is_empty()
})
diff --git a/lightning-liquidity/src/lsps5/service.rs b/lightning-liquidity/src/lsps5/service.rs
index 1111c68..f7f5e06 100644
--- a/lightning-liquidity/src/lsps5/service.rs
+++ b/lightning-liquidity/src/lsps5/service.rs
@@ -596,7 +596,7 @@ where
// (other than lsps5.webhook_registered) close in time.
if notification.method != WebhookNotificationMethod::LSPS5WebhookRegistered {
let rate_limit_applies = peer_state.webhooks().iter().any(|(_, webhook)| {
- webhook.last_notification_sent.as_ref().map_or(false, |last_sent| {
+ webhook.last_notification_sent.as_ref().is_some_and(|last_sent| {
now.duration_since(&last_sent) < NOTIFICATION_COOLDOWN_TIME
})
});
diff --git a/lightning-liquidity/src/manager.rs b/lightning-liquidity/src/manager.rs
index 5d95d32..f0143fc 100644
--- a/lightning-liquidity/src/manager.rs
+++ b/lightning-liquidity/src/manager.rs
@@ -770,12 +770,12 @@ where
let lsps2_has_active_requests = self
.lsps2_service_handler
.as_ref()
- .map_or(false, |h| h.has_active_requests(sender_node_id));
+ .is_some_and(|h| h.has_active_requests(sender_node_id));
#[cfg(lsps1_service)]
let lsps1_has_active_requests = self
.lsps1_service_handler
.as_ref()
- .map_or(false, |h| h.has_active_requests(sender_node_id));
+ .is_some_and(|h| h.has_active_requests(sender_node_id));
#[cfg(not(lsps1_service))]
let lsps1_has_active_requests = false;
@@ -918,7 +918,7 @@ where
fn provided_node_features(&self) -> NodeFeatures {
let mut features = NodeFeatures::empty();
- let advertise_service = self.service_config.as_ref().map_or(false, |c| c.advertise_service);
+ let advertise_service = self.service_config.as_ref().is_some_and(|c| c.advertise_service);
if advertise_service {
features
@@ -932,7 +932,7 @@ where
fn provided_init_features(&self, _their_node_id: PublicKey) -> InitFeatures {
let mut features = InitFeatures::empty();
- let advertise_service = self.service_config.as_ref().map_or(false, |c| c.advertise_service);
+ let advertise_service = self.service_config.as_ref().is_some_and(|c| c.advertise_service);
if advertise_service {
features
.set_optional_custom_bit(LSPS_FEATURE_BIT)
diff --git a/lightning-persister/src/utils.rs b/lightning-persister/src/utils.rs
index 74fa0d0..e8e7be5 100644
--- a/lightning-persister/src/utils.rs
+++ b/lightning-persister/src/utils.rs
@@ -26,7 +26,7 @@ pub(crate) fn check_namespace_key_validity(
PrintableString(secondary_namespace),
PrintableString(key)
);
- return Err(std::io::Error::new(std::io::ErrorKind::Other, msg));
+ return Err(std::io::Error::other(msg));
}
if primary_namespace.is_empty() && !secondary_namespace.is_empty() {
@@ -37,7 +37,7 @@ pub(crate) fn check_namespace_key_validity(
let msg = format!(
"Failed to {} {}/{}/{}: primary namespace may not be empty if a non-empty secondary namespace is given.", operation,
PrintableString(primary_namespace), PrintableString(secondary_namespace), PrintableString(key));
- return Err(std::io::Error::new(std::io::ErrorKind::Other, msg));
+ return Err(std::io::Error::other(msg));
}
if !is_valid_kvstore_str(primary_namespace)
@@ -50,7 +50,7 @@ pub(crate) fn check_namespace_key_validity(
let msg = format!("Failed to {} {}/{}/{}: primary namespace, secondary namespace, and key must be valid.",
operation,
PrintableString(primary_namespace), PrintableString(secondary_namespace), PrintableString(key));
- return Err(std::io::Error::new(std::io::ErrorKind::Other, msg));
+ return Err(std::io::Error::other(msg));
}
} else {
if primary_namespace.is_empty() && !secondary_namespace.is_empty() {
@@ -60,7 +60,7 @@ pub(crate) fn check_namespace_key_validity(
let msg = format!(
"Failed to {} {}/{}: primary namespace may not be empty if a non-empty secondary namespace is given.",
operation, PrintableString(primary_namespace), PrintableString(secondary_namespace));
- return Err(std::io::Error::new(std::io::ErrorKind::Other, msg));
+ return Err(std::io::Error::other(msg));
}
if !is_valid_kvstore_str(primary_namespace) || !is_valid_kvstore_str(secondary_namespace) {
debug_assert!(
@@ -76,7 +76,7 @@ pub(crate) fn check_namespace_key_validity(
PrintableString(primary_namespace),
PrintableString(secondary_namespace)
);
- return Err(std::io::Error::new(std::io::ErrorKind::Other, msg));
+ return Err(std::io::Error::other(msg));
}
}
diff --git a/lightning-types/src/features.rs b/lightning-types/src/features.rs
index 54f1d9e..05a504a 100644
--- a/lightning-types/src/features.rs
+++ b/lightning-types/src/features.rs
@@ -698,7 +698,7 @@ mod sealed {
);
// By default, allocate enough bytes to cover up to Splice. Update this as new features are
// added which we expect to appear commonly across contexts.
- pub(super) const MIN_FEATURES_ALLOCATION_BYTES: usize = (63 + 7) / 8;
+ pub(super) const MIN_FEATURES_ALLOCATION_BYTES: usize = 63_usize.div_ceil(8);
define_feature!(
141, // The BOLTs PR uses feature bit 40/41, so add +100 for the experimental bit
AnchorZeroFeeCommitmentsStaging,
diff --git a/lightning/src/blinded_path/utils.rs b/lightning/src/blinded_path/utils.rs
index 5fc359a..8894f37 100644
--- a/lightning/src/blinded_path/utils.rs
+++ b/lightning/src/blinded_path/utils.rs
@@ -256,8 +256,7 @@ impl<T: Writeable> Writeable for BlindedPathWithPadding<T> {
let tlv_length = self.tlvs.serialized_length();
let total_length = tlv_length + TLV_OVERHEAD;
- let padding_length =
- (total_length + self.round_off - 1) / self.round_off * self.round_off - total_length;
+ let padding_length = total_length.div_ceil(self.round_off) * self.round_off - total_length;
let padding = Some(BlindedPathPadding::new(padding_length));
diff --git a/lightning/src/chain/chaininterface.rs b/lightning/src/chain/chaininterface.rs
index 1f945a5..6c92c86 100644
--- a/lightning/src/chain/chaininterface.rs
+++ b/lightning/src/chain/chaininterface.rs
@@ -24,7 +24,7 @@ pub(crate) fn compute_feerate_sat_per_1000_weight(fee_sat: u64, weight: u64) ->
(fee_sat * 1000 / weight).try_into().unwrap_or(u32::max_value())
}
pub(crate) const fn fee_for_weight(feerate_sat_per_1000_weight: u32, weight: u64) -> u64 {
- ((feerate_sat_per_1000_weight as u64 * weight) + 1000 - 1) / 1000
+ (feerate_sat_per_1000_weight as u64 * weight).div_ceil(1000)
}
/// An interface to send a transaction to the Bitcoin network.
diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs
index 8f74dc2..5c12a75 100644
--- a/lightning/src/ln/channel.rs
+++ b/lightning/src/ln/channel.rs
@@ -3303,15 +3303,12 @@ where
// This will return false if `counterparty_parameters` is `None`, but for a `FundedChannel`, it
// should never be `None`.
debug_assert!(channel_parameters.counterparty_parameters.is_some());
- channel_parameters.counterparty_parameters.as_ref().map_or(
- false,
- |counterparty_parameters| {
- self.context().channel_id().is_v2_channel_id(
- &channel_parameters.holder_pubkeys.revocation_basepoint,
- &counterparty_parameters.pubkeys.revocation_basepoint,
- )
- },
- )
+ channel_parameters.counterparty_parameters.as_ref().is_some_and(|counterparty_parameters| {
+ self.context().channel_id().is_v2_channel_id(
+ &channel_parameters.holder_pubkeys.revocation_basepoint,
+ &counterparty_parameters.pubkeys.revocation_basepoint,
+ )
+ })
}
}
@@ -10178,7 +10175,7 @@ where
proposed_max_feerate as u64 * tx_weight / 1000,
)
} else {
- self.funding.get_value_satoshis() - (self.funding.value_to_self_msat + 999) / 1000
+ self.funding.get_value_satoshis() - self.funding.value_to_self_msat.div_ceil(1000)
};
self.context.closing_fee_limits =
@@ -10686,7 +10683,7 @@ where
debug_assert_eq!(
our_max_fee,
self.funding.get_value_satoshis()
- - (self.funding.value_to_self_msat + 999) / 1000
+ - self.funding.value_to_self_msat.div_ceil(1000)
);
propose_fee!(cmp::min(max_fee_satoshis, our_max_fee));
} else {
diff --git a/lightning/src/ln/functional_test_utils.rs b/lightning/src/ln/functional_test_utils.rs
index d8e59dd..2f3c9a1 100644
--- a/lightning/src/ln/functional_test_utils.rs
+++ b/lightning/src/ln/functional_test_utils.rs
@@ -2004,7 +2004,7 @@ pub fn do_check_spends<F: Fn(&bitcoin::transaction::OutPoint) -> Option<TxOut>>(
// 0FC commitment transactions will have their fee bumped by a child, so don't require that
// they meet the 1sat/vB minimum.
} else if !has_p2a_output {
- let min_fee = (tx.weight().to_wu() as u64 + 3) / 4; // One sat per vbyte (ie per weight/4, rounded up)
+ let min_fee = (tx.weight().to_wu() as u64).div_ceil(4); // One sat per vbyte (ie per weight/4, rounded up)
assert!(total_value_out + min_fee <= total_value_in);
}
tx.verify(get_output).unwrap();
diff --git a/lightning/src/ln/msgs.rs b/lightning/src/ln/msgs.rs
index 354273f..c0c8239 100644
--- a/lightning/src/ln/msgs.rs
+++ b/lightning/src/ln/msgs.rs
@@ -1255,12 +1255,10 @@ impl std::net::ToSocketAddrs for SocketAddress {
SocketAddress::Hostname { ref hostname, port } => {
(hostname.as_str(), *port).to_socket_addrs()
},
- SocketAddress::OnionV2(..) => Err(std::io::Error::new(
- std::io::ErrorKind::Other,
+ SocketAddress::OnionV2(..) => Err(std::io::Error::other(
"Resolution of OnionV2 addresses is currently unsupported.",
)),
- SocketAddress::OnionV3 { .. } => Err(std::io::Error::new(
- std::io::ErrorKind::Other,
+ SocketAddress::OnionV3 { .. } => Err(std::io::Error::other(
"Resolution of OnionV3 addresses is currently unsupported.",
)),
}
diff --git a/lightning/src/offers/async_receive_offer_cache.rs b/lightning/src/offers/async_receive_offer_cache.rs
index 8c1887a..c4442b4 100644
--- a/lightning/src/offers/async_receive_offer_cache.rs
+++ b/lightning/src/offers/async_receive_offer_cache.rs
@@ -268,7 +268,7 @@ impl AsyncReceiveOfferCache {
for offer_opt in self.offers.iter_mut() {
let offer_is_expired = offer_opt
.as_ref()
- .map_or(false, |offer| offer.offer.is_expired_no_std(duration_since_epoch));
+ .is_some_and(|offer| offer.offer.is_expired_no_std(duration_since_epoch));
if offer_is_expired {
offer_opt.take();
offer_was_removed = true;
@@ -486,7 +486,7 @@ impl AsyncReceiveOfferCache {
};
let mut offers = self.offers.iter_mut();
- let offer_entry = offers.find(|o| o.as_ref().map_or(false, |o| o.offer.id() == offer_id));
+ let offer_entry = offers.find(|o| o.as_ref().is_some_and(|o| o.offer.id() == offer_id));
if let Some(Some(ref mut offer)) = offer_entry {
match offer.status {
OfferStatus::Used { invoice_created_at: ref mut inv_created_at }
diff --git a/lightning/src/routing/router.rs b/lightning/src/routing/router.rs
index e3443b5..9b68fdf 100644
--- a/lightning/src/routing/router.rs
+++ b/lightning/src/routing/router.rs
@@ -573,7 +573,7 @@ impl Path {
/// True if this [`Path`] has at least one Trampoline hop.
pub fn has_trampoline_hops(&self) -> bool {
- self.blinded_tail.as_ref().map_or(false, |bt| !bt.trampoline_hops.is_empty())
+ self.blinded_tail.as_ref().is_some_and(|bt| !bt.trampoline_hops.is_empty())
}
}
@@ -1278,8 +1278,8 @@ impl Payee {
#[rustfmt::skip]
fn supports_basic_mpp(&self) -> bool {
match self {
- Self::Clear { features, .. } => features.as_ref().map_or(false, |f| f.supports_basic_mpp()),
- Self::Blinded { features, .. } => features.as_ref().map_or(false, |f| f.supports_basic_mpp()),
+ Self::Clear { features, .. } => features.as_ref().is_some_and(|f| f.supports_basic_mpp()),
+ Self::Blinded { features, .. } => features.as_ref().is_some_and(|f| f.supports_basic_mpp()),
}
}
fn features(&self) -> Option<FeaturesRef<'_>> {
@@ -2450,7 +2450,7 @@ where L::Target: Logger {
let maybe_dummy_payee_node_id = NodeId::from_pubkey(&maybe_dummy_payee_pk);
let our_node_id = NodeId::from_pubkey(&our_node_pubkey);
- if payee_node_id_opt.map_or(false, |payee| payee == our_node_id) {
+ if payee_node_id_opt.is_some_and(|payee| payee == our_node_id) {
return Err("Cannot generate a route to ourselves");
}
if our_node_id == maybe_dummy_payee_node_id {
@@ -2541,8 +2541,7 @@ where L::Target: Logger {
} else if payment_params.payee.supports_basic_mpp() {
true
} else if let Some(payee) = payee_node_id_opt {
- network_nodes.get(&payee).map_or(false, |node| node.announcement_info.as_ref().map_or(false,
- |info| info.features().supports_basic_mpp()))
+ network_nodes.get(&payee).is_some_and(|node| node.announcement_info.as_ref().is_some_and(|info| info.features().supports_basic_mpp()))
} else { false };
let max_total_routing_fee_msat = route_params.max_total_routing_fee_msat.unwrap_or(u64::max_value());
@@ -2701,7 +2700,7 @@ where L::Target: Logger {
// This requirement is currently set to be 1/max_path_count of the payment
// value to ensure we only ever return routes that do not violate this limit.
let minimal_value_contribution_msat: u64 = if allow_mpp {
- (final_value_msat + (payment_params.max_path_count as u64 - 1)) / payment_params.max_path_count as u64
+ final_value_msat.div_ceil(payment_params.max_path_count as u64)
} else {
final_value_msat
};
@@ -3665,9 +3664,9 @@ where L::Target: Logger {
// there are announced channels between the endpoints. If so, the hop might be
// referring to any of the announced channels, as its `short_channel_id` might be
// an alias, in which case we don't take any chances here.
- network_graph.node(&target).map_or(false, |hop_node|
+ network_graph.node(&target).is_some_and(|hop_node|
hop_node.channels.iter().any(|scid| network_graph.channel(*scid)
- .map_or(false, |c| c.as_directed_from(&hop.candidate.source()).is_some()))
+ .is_some_and(|c| c.as_directed_from(&hop.candidate.source()).is_some()))
)
};
diff --git a/lightning/src/sign/mod.rs b/lightning/src/sign/mod.rs
index 5bd24d8..03f3688 100644
--- a/lightning/src/sign/mod.rs
+++ b/lightning/src/sign/mod.rs
@@ -205,7 +205,7 @@ impl StaticPaymentOutputDescriptor {
/// value of at least 1.
pub fn needs_csv_1_for_spend(&self) -> bool {
let chan_params = self.channel_transaction_parameters.as_ref();
- chan_params.map_or(false, |p| p.channel_type_features.supports_anchors_zero_fee_htlc_tx())
+ chan_params.is_some_and(|p| p.channel_type_features.supports_anchors_zero_fee_htlc_tx())
}
}
impl_writeable_tlv_based!(StaticPaymentOutputDescriptor, {
diff --git a/lightning/src/util/base32.rs b/lightning/src/util/base32.rs
index f3d7a10..31e1885 100644
--- a/lightning/src/util/base32.rs
+++ b/lightning/src/util/base32.rs
@@ -46,7 +46,7 @@ impl Alphabet {
// / 5 divides the data length by the number of bits per chunk (5),
// * 8 multiplies the result by the number of characters per chunk (8).
// + 4 rounds up to the nearest character.
- let output_length = (data.len() * 8 + 4) / 5;
+ let output_length = (data.len() * 8).div_ceil(5);
let mut ret = match self {
Self::RFC4648 { padding } => {
let mut ret = Self::encode_data(data, RFC4648_ALPHABET);
@@ -105,7 +105,7 @@ impl Alphabet {
// / 5 divides the data length by the number of bits per chunk (5),
// * 8 multiplies the result by the number of characters per chunk (8).
// + 4 rounds up to the nearest character.
- let cap = (data.len() + 4) / 5 * 8;
+ let cap = data.len().div_ceil(5) * 8;
let mut ret = Vec::with_capacity(cap);
for chunk in data.chunks(5) {
let mut buf = [0u8; 5];
@@ -132,7 +132,7 @@ impl Alphabet {
// / 8 divides the data length by the number of characters per chunk (8),
// * 5 multiplies the result by the number of bits per chunk (5),
// + 7 rounds up to the nearest byte.
- let cap = (data.len() + 7) / 8 * 5;
+ let cap = data.len().div_ceil(8) * 5;
let mut ret = Vec::with_capacity(cap);
for chunk in data.chunks(8) {
let mut buf = [0u8; 8];
diff --git a/lightning/src/util/sweep.rs b/lightning/src/util/sweep.rs
index efeb059..99a6296 100644
--- a/lightning/src/util/sweep.rs
+++ b/lightning/src/util/sweep.rs
@@ -239,7 +239,7 @@ impl OutputSpendStatus {
fn is_delayed(&self, cur_height: u32) -> bool {
match self {
Self::PendingInitialBroadcast { delayed_until_height } => {
- delayed_until_height.map_or(false, |req_height| cur_height < req_height)
+ delayed_until_height.is_some_and(|req_height| cur_height < req_height)
},
Self::PendingFirstConfirmation { .. } => false,
Self::PendingThresholdConfirmations { .. } => false,
diff --git a/rustfmt.toml b/rustfmt.toml
index 027fcfc..4f88472 100644
--- a/rustfmt.toml
+++ b/rustfmt.toml
@@ -1,5 +1,5 @@
use_small_heuristics = "Max"
-fn_args_layout = "Compressed"
+fn_params_layout = "Compressed"
hard_tabs = true
use_field_init_shorthand = true
max_width = 100
Why this scored 20/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.