Skip to content

Commit 5bf0d1e

Browse files
authored
Merge pull request #4175 from TheBlueMatt/2025-10-msrv-less-box
Reduce `Box`ing using `impl Trait` in trait methods post-MSRV-bump
2 parents 3fa7611 + b1f1ee2 commit 5bf0d1e

File tree

25 files changed

+441
-401
lines changed

25 files changed

+441
-401
lines changed

.github/workflows/build.yml

Lines changed: 5 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -62,52 +62,35 @@ jobs:
6262
- name: Set RUSTFLAGS to deny warnings
6363
if: "matrix.toolchain == '1.75.0'"
6464
run: echo "RUSTFLAGS=-D warnings" >> "$GITHUB_ENV"
65-
- name: Run CI script
66-
shell: bash # Default on Winblows is powershell
67-
run: CI_ENV=1 CI_MINIMIZE_DISK_USAGE=1 ./ci/ci-tests.sh
68-
69-
build-tx-sync:
70-
strategy:
71-
fail-fast: false
72-
matrix:
73-
platform: [ ubuntu-latest, macos-latest ]
74-
toolchain: [ stable, beta, 1.75.0 ]
75-
runs-on: ${{ matrix.platform }}
76-
steps:
77-
- name: Checkout source code
78-
uses: actions/checkout@v4
79-
- name: Install Rust ${{ matrix.toolchain }} toolchain
80-
run: |
81-
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile=minimal --default-toolchain ${{ matrix.toolchain }}
82-
- name: Set RUSTFLAGS to deny warnings
83-
if: "matrix.toolchain == '1.75.0'"
84-
run: echo "RUSTFLAGS=-D warnings" >> "$GITHUB_ENV"
8565
- name: Enable caching for bitcoind
66+
if: matrix.platform != 'windows-latest'
8667
id: cache-bitcoind
8768
uses: actions/cache@v4
8869
with:
8970
path: bin/bitcoind-${{ runner.os }}-${{ runner.arch }}
9071
key: bitcoind-${{ runner.os }}-${{ runner.arch }}
9172
- name: Enable caching for electrs
73+
if: matrix.platform != 'windows-latest'
9274
id: cache-electrs
9375
uses: actions/cache@v4
9476
with:
9577
path: bin/electrs-${{ runner.os }}-${{ runner.arch }}
9678
key: electrs-${{ runner.os }}-${{ runner.arch }}
9779
- name: Download bitcoind/electrs
98-
if: "steps.cache-bitcoind.outputs.cache-hit != 'true' || steps.cache-electrs.outputs.cache-hit != 'true'"
80+
if: "matrix.platform != 'windows-latest' && (steps.cache-bitcoind.outputs.cache-hit != 'true' || steps.cache-electrs.outputs.cache-hit != 'true')"
9981
run: |
10082
source ./contrib/download_bitcoind_electrs.sh
10183
mkdir bin
10284
mv "$BITCOIND_EXE" bin/bitcoind-${{ runner.os }}-${{ runner.arch }}
10385
mv "$ELECTRS_EXE" bin/electrs-${{ runner.os }}-${{ runner.arch }}
10486
- name: Set bitcoind/electrs environment variables
87+
if: matrix.platform != 'windows-latest'
10588
run: |
10689
echo "BITCOIND_EXE=$( pwd )/bin/bitcoind-${{ runner.os }}-${{ runner.arch }}" >> "$GITHUB_ENV"
10790
echo "ELECTRS_EXE=$( pwd )/bin/electrs-${{ runner.os }}-${{ runner.arch }}" >> "$GITHUB_ENV"
10891
- name: Run CI script
10992
shell: bash # Default on Winblows is powershell
110-
run: CI_ENV=1 CI_MINIMIZE_DISK_USAGE=1 ./ci/ci-tx-sync-tests.sh
93+
run: CI_ENV=1 CI_MINIMIZE_DISK_USAGE=1 ./ci/ci-tests.sh
11194

11295
coverage:
11396
needs: fuzz

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@ members = [
1616
"lightning-macros",
1717
"lightning-dns-resolver",
1818
"lightning-liquidity",
19+
"lightning-transaction-sync",
1920
"possiblyrandom",
2021
]
2122

2223
exclude = [
23-
"lightning-transaction-sync",
2424
"lightning-tests",
2525
"ext-functional-test-demo",
2626
"no-std-check",

ci/check-lint.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,8 @@ CLIPPY() {
107107
-A clippy::useless_conversion \
108108
-A clippy::manual_repeat_n `# to be removed once we hit MSRV 1.86` \
109109
-A clippy::manual_is_multiple_of `# to be removed once we hit MSRV 1.87` \
110-
-A clippy::uninlined-format-args
110+
-A clippy::uninlined-format-args \
111+
-A clippy::manual-async-fn # Not really sure why this is even a warning when there's a Send bound
111112
}
112113

113114
CLIPPY

ci/ci-tests.sh

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
#shellcheck disable=SC2002,SC2207
33
set -eox pipefail
44

5-
# Currently unused as we don't have to pin anything for MSRV:
65
RUSTC_MINOR_VERSION=$(rustc --version | awk '{ split($2,a,"."); print a[2] }')
76

87
# Some crates require pinning to meet our MSRV even for our downstream users,
@@ -20,6 +19,9 @@ PIN_RELEASE_DEPS # pin the release dependencies in our main workspace
2019
# proptest 1.9.0 requires rustc 1.82.0
2120
[ "$RUSTC_MINOR_VERSION" -lt 82 ] && cargo update -p proptest --precise "1.8.0" --verbose
2221

22+
# Starting with version 1.2.0, the `idna_adapter` crate has an MSRV of rustc 1.81.0.
23+
[ "$RUSTC_MINOR_VERSION" -lt 81 ] && cargo update -p idna_adapter --precise "1.1.0" --verbose
24+
2325
export RUST_BACKTRACE=1
2426

2527
echo -e "\n\nChecking the workspace, except lightning-transaction-sync."
@@ -57,6 +59,23 @@ cargo check -p lightning-block-sync --verbose --color always --features rpc-clie
5759
cargo test -p lightning-block-sync --verbose --color always --features rpc-client,rest-client,tokio
5860
cargo check -p lightning-block-sync --verbose --color always --features rpc-client,rest-client,tokio
5961

62+
echo -e "\n\nChecking Transaction Sync Clients with features."
63+
cargo check -p lightning-transaction-sync --verbose --color always --features esplora-blocking
64+
cargo check -p lightning-transaction-sync --verbose --color always --features esplora-async
65+
cargo check -p lightning-transaction-sync --verbose --color always --features esplora-async-https
66+
cargo check -p lightning-transaction-sync --verbose --color always --features electrum
67+
68+
if [ -z "$CI_ENV" ] && [[ -z "$BITCOIND_EXE" || -z "$ELECTRS_EXE" ]]; then
69+
echo -e "\n\nSkipping testing Transaction Sync Clients due to BITCOIND_EXE or ELECTRS_EXE being unset."
70+
cargo check -p lightning-transaction-sync --tests
71+
else
72+
echo -e "\n\nTesting Transaction Sync Clients with features."
73+
cargo test -p lightning-transaction-sync --verbose --color always --features esplora-blocking
74+
cargo test -p lightning-transaction-sync --verbose --color always --features esplora-async
75+
cargo test -p lightning-transaction-sync --verbose --color always --features esplora-async-https
76+
cargo test -p lightning-transaction-sync --verbose --color always --features electrum
77+
fi
78+
6079
echo -e "\n\nChecking and testing lightning-persister with features"
6180
cargo test -p lightning-persister --verbose --color always --features tokio
6281
cargo check -p lightning-persister --verbose --color always --features tokio

ci/ci-tx-sync-tests.sh

Lines changed: 0 additions & 39 deletions
This file was deleted.

lightning-background-processor/src/lib.rs

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ use lightning::events::ReplayEvent;
4141
use lightning::events::{Event, PathFailure};
4242
use lightning::util::ser::Writeable;
4343

44+
#[cfg(not(c_bindings))]
45+
use lightning::io::Error;
4446
use lightning::ln::channelmanager::AChannelManager;
4547
use lightning::ln::msgs::OnionMessageHandler;
4648
use lightning::ln::peer_handler::APeerManager;
@@ -51,6 +53,8 @@ use lightning::routing::utxo::UtxoLookup;
5153
use lightning::sign::{
5254
ChangeDestinationSource, ChangeDestinationSourceSync, EntropySource, OutputSpender,
5355
};
56+
#[cfg(not(c_bindings))]
57+
use lightning::util::async_poll::MaybeSend;
5458
use lightning::util::logger::Logger;
5559
use lightning::util::persist::{
5660
KVStore, KVStoreSync, KVStoreSyncWrapper, CHANNEL_MANAGER_PERSISTENCE_KEY,
@@ -83,7 +87,11 @@ use std::time::Instant;
8387
#[cfg(not(feature = "std"))]
8488
use alloc::boxed::Box;
8589
#[cfg(all(not(c_bindings), not(feature = "std")))]
90+
use alloc::string::String;
91+
#[cfg(all(not(c_bindings), not(feature = "std")))]
8692
use alloc::sync::Arc;
93+
#[cfg(all(not(c_bindings), not(feature = "std")))]
94+
use alloc::vec::Vec;
8795

8896
/// `BackgroundProcessor` takes care of tasks that (1) need to happen periodically to keep
8997
/// Rust-Lightning running properly, and (2) either can or should be run in the background. Its
@@ -416,6 +424,37 @@ pub const NO_ONION_MESSENGER: Option<
416424
>,
417425
> = None;
418426

427+
#[cfg(not(c_bindings))]
428+
/// A panicking implementation of [`KVStore`] that is used in [`NO_LIQUIDITY_MANAGER`].
429+
pub struct DummyKVStore;
430+
431+
#[cfg(not(c_bindings))]
432+
impl KVStore for DummyKVStore {
433+
fn read(
434+
&self, _: &str, _: &str, _: &str,
435+
) -> impl core::future::Future<Output = Result<Vec<u8>, Error>> + MaybeSend + 'static {
436+
async { unimplemented!() }
437+
}
438+
439+
fn write(
440+
&self, _: &str, _: &str, _: &str, _: Vec<u8>,
441+
) -> impl core::future::Future<Output = Result<(), Error>> + MaybeSend + 'static {
442+
async { unimplemented!() }
443+
}
444+
445+
fn remove(
446+
&self, _: &str, _: &str, _: &str, _: bool,
447+
) -> impl core::future::Future<Output = Result<(), Error>> + MaybeSend + 'static {
448+
async { unimplemented!() }
449+
}
450+
451+
fn list(
452+
&self, _: &str, _: &str,
453+
) -> impl core::future::Future<Output = Result<Vec<String>, Error>> + MaybeSend + 'static {
454+
async { unimplemented!() }
455+
}
456+
}
457+
419458
/// When initializing a background processor without a liquidity manager, this can be used to avoid
420459
/// specifying a concrete `LiquidityManager` type.
421460
#[cfg(not(c_bindings))]
@@ -430,8 +469,8 @@ pub const NO_LIQUIDITY_MANAGER: Option<
430469
CM = &DynChannelManager,
431470
Filter = dyn chain::Filter + Send + Sync,
432471
C = &(dyn chain::Filter + Send + Sync),
433-
KVStore = dyn lightning::util::persist::KVStore + Send + Sync,
434-
K = &(dyn lightning::util::persist::KVStore + Send + Sync),
472+
KVStore = DummyKVStore,
473+
K = &DummyKVStore,
435474
TimeProvider = dyn lightning_liquidity::utils::time::TimeProvider + Send + Sync,
436475
TP = &(dyn lightning_liquidity::utils::time::TimeProvider + Send + Sync),
437476
BroadcasterInterface = dyn lightning::chain::chaininterface::BroadcasterInterface

lightning-block-sync/src/gossip.rs

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//! current UTXO set. This module defines an implementation of the LDK API required to do so
33
//! against a [`BlockSource`] which implements a few additional methods for accessing the UTXO set.
44
5-
use crate::{AsyncBlockSourceResult, BlockData, BlockSource, BlockSourceError};
5+
use crate::{BlockData, BlockSource, BlockSourceError, BlockSourceResult};
66

77
use bitcoin::block::Block;
88
use bitcoin::constants::ChainHash;
@@ -18,7 +18,7 @@ use lightning::util::native_async::FutureSpawner;
1818
use std::collections::VecDeque;
1919
use std::future::Future;
2020
use std::ops::Deref;
21-
use std::pin::Pin;
21+
use std::pin::{pin, Pin};
2222
use std::sync::{Arc, Mutex};
2323
use std::task::Poll;
2424

@@ -35,11 +35,13 @@ pub trait UtxoSource: BlockSource + 'static {
3535
/// for gossip validation.
3636
fn get_block_hash_by_height<'a>(
3737
&'a self, block_height: u32,
38-
) -> AsyncBlockSourceResult<'a, BlockHash>;
38+
) -> impl Future<Output = BlockSourceResult<BlockHash>> + Send + 'a;
3939

4040
/// Returns true if the given output has *not* been spent, i.e. is a member of the current UTXO
4141
/// set.
42-
fn is_output_unspent<'a>(&'a self, outpoint: OutPoint) -> AsyncBlockSourceResult<'a, bool>;
42+
fn is_output_unspent<'a>(
43+
&'a self, outpoint: OutPoint,
44+
) -> impl Future<Output = BlockSourceResult<bool>> + Send + 'a;
4345
}
4446

4547
#[cfg(feature = "tokio")]
@@ -55,34 +57,37 @@ impl FutureSpawner for TokioSpawner {
5557
/// A trivial future which joins two other futures and polls them at the same time, returning only
5658
/// once both complete.
5759
pub(crate) struct Joiner<
58-
A: Future<Output = Result<(BlockHash, Option<u32>), BlockSourceError>> + Unpin,
59-
B: Future<Output = Result<BlockHash, BlockSourceError>> + Unpin,
60+
'a,
61+
A: Future<Output = Result<(BlockHash, Option<u32>), BlockSourceError>>,
62+
B: Future<Output = Result<BlockHash, BlockSourceError>>,
6063
> {
61-
pub a: A,
62-
pub b: B,
64+
pub a: Pin<&'a mut A>,
65+
pub b: Pin<&'a mut B>,
6366
a_res: Option<(BlockHash, Option<u32>)>,
6467
b_res: Option<BlockHash>,
6568
}
6669

6770
impl<
68-
A: Future<Output = Result<(BlockHash, Option<u32>), BlockSourceError>> + Unpin,
69-
B: Future<Output = Result<BlockHash, BlockSourceError>> + Unpin,
70-
> Joiner<A, B>
71+
'a,
72+
A: Future<Output = Result<(BlockHash, Option<u32>), BlockSourceError>>,
73+
B: Future<Output = Result<BlockHash, BlockSourceError>>,
74+
> Joiner<'a, A, B>
7175
{
72-
fn new(a: A, b: B) -> Self {
76+
fn new(a: Pin<&'a mut A>, b: Pin<&'a mut B>) -> Self {
7377
Self { a, b, a_res: None, b_res: None }
7478
}
7579
}
7680

7781
impl<
78-
A: Future<Output = Result<(BlockHash, Option<u32>), BlockSourceError>> + Unpin,
79-
B: Future<Output = Result<BlockHash, BlockSourceError>> + Unpin,
80-
> Future for Joiner<A, B>
82+
'a,
83+
A: Future<Output = Result<(BlockHash, Option<u32>), BlockSourceError>>,
84+
B: Future<Output = Result<BlockHash, BlockSourceError>>,
85+
> Future for Joiner<'a, A, B>
8186
{
8287
type Output = Result<((BlockHash, Option<u32>), BlockHash), BlockSourceError>;
8388
fn poll(mut self: Pin<&mut Self>, ctx: &mut core::task::Context<'_>) -> Poll<Self::Output> {
8489
if self.a_res.is_none() {
85-
match Pin::new(&mut self.a).poll(ctx) {
90+
match self.a.as_mut().poll(ctx) {
8691
Poll::Ready(res) => {
8792
if let Ok(ok) = res {
8893
self.a_res = Some(ok);
@@ -94,7 +99,7 @@ impl<
9499
}
95100
}
96101
if self.b_res.is_none() {
97-
match Pin::new(&mut self.b).poll(ctx) {
102+
match self.b.as_mut().poll(ctx) {
98103
Poll::Ready(res) => {
99104
if let Ok(ok) = res {
100105
self.b_res = Some(ok);
@@ -200,10 +205,12 @@ where
200205
}
201206
}
202207

203-
let ((_, tip_height_opt), block_hash) =
204-
Joiner::new(source.get_best_block(), source.get_block_hash_by_height(block_height))
205-
.await
206-
.map_err(|_| UtxoLookupError::UnknownTx)?;
208+
let ((_, tip_height_opt), block_hash) = Joiner::new(
209+
pin!(source.get_best_block()),
210+
pin!(source.get_block_hash_by_height(block_height)),
211+
)
212+
.await
213+
.map_err(|_| UtxoLookupError::UnknownTx)?;
207214
if let Some(tip_height) = tip_height_opt {
208215
// If the block doesn't yet have five confirmations, error out.
209216
//

lightning-block-sync/src/lib.rs

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ use lightning::chain::{BestBlock, Listen};
5353

5454
use std::future::Future;
5555
use std::ops::Deref;
56-
use std::pin::Pin;
5756

5857
/// Abstract type for retrieving block headers and data.
5958
pub trait BlockSource: Sync + Send {
@@ -65,31 +64,28 @@ pub trait BlockSource: Sync + Send {
6564
/// when `height_hint` is `None`.
6665
fn get_header<'a>(
6766
&'a self, header_hash: &'a BlockHash, height_hint: Option<u32>,
68-
) -> AsyncBlockSourceResult<'a, BlockHeaderData>;
67+
) -> impl Future<Output = BlockSourceResult<BlockHeaderData>> + Send + 'a;
6968

7069
/// Returns the block for a given hash. A headers-only block source should return a `Transient`
7170
/// error.
72-
fn get_block<'a>(&'a self, header_hash: &'a BlockHash)
73-
-> AsyncBlockSourceResult<'a, BlockData>;
71+
fn get_block<'a>(
72+
&'a self, header_hash: &'a BlockHash,
73+
) -> impl Future<Output = BlockSourceResult<BlockData>> + Send + 'a;
7474

7575
/// Returns the hash of the best block and, optionally, its height.
7676
///
7777
/// When polling a block source, [`Poll`] implementations may pass the height to [`get_header`]
7878
/// to allow for a more efficient lookup.
7979
///
8080
/// [`get_header`]: Self::get_header
81-
fn get_best_block(&self) -> AsyncBlockSourceResult<'_, (BlockHash, Option<u32>)>;
81+
fn get_best_block<'a>(
82+
&'a self,
83+
) -> impl Future<Output = BlockSourceResult<(BlockHash, Option<u32>)>> + Send + 'a;
8284
}
8385

8486
/// Result type for `BlockSource` requests.
8587
pub type BlockSourceResult<T> = Result<T, BlockSourceError>;
8688

87-
// TODO: Replace with BlockSourceResult once `async` trait functions are supported. For details,
88-
// see: https://areweasyncyet.rs.
89-
/// Result type for asynchronous `BlockSource` requests.
90-
pub type AsyncBlockSourceResult<'a, T> =
91-
Pin<Box<dyn Future<Output = BlockSourceResult<T>> + 'a + Send>>;
92-
9389
/// Error type for `BlockSource` requests.
9490
///
9591
/// Transient errors may be resolved when re-polling, but no attempt will be made to re-poll on

0 commit comments

Comments
 (0)