Skip to content

Commit 495f713

Browse files
committed
Drop required Boxing of KVStore Futures
Now that our MSRV is 1.75, we can return `impl Trait` from trait methods. Here we use this to clean up `KVStore` methods, dropping the `Pin<Box<dyn ...>>` we had to use to have trait methods return a concrete type. Sadly, there's two places where we can't drop a `Box::pin` until we switch to edition 2024.
1 parent 3c87ea5 commit 495f713

File tree

6 files changed

+139
-107
lines changed

6 files changed

+139
-107
lines changed

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

lightning-background-processor/src/lib.rs

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,11 @@ use std::time::Instant;
8383
#[cfg(not(feature = "std"))]
8484
use alloc::boxed::Box;
8585
#[cfg(all(not(c_bindings), not(feature = "std")))]
86+
use alloc::string::String;
87+
#[cfg(all(not(c_bindings), not(feature = "std")))]
8688
use alloc::sync::Arc;
89+
#[cfg(all(not(c_bindings), not(feature = "std")))]
90+
use alloc::vec::Vec;
8791

8892
/// `BackgroundProcessor` takes care of tasks that (1) need to happen periodically to keep
8993
/// Rust-Lightning running properly, and (2) either can or should be run in the background. Its
@@ -416,6 +420,39 @@ pub const NO_ONION_MESSENGER: Option<
416420
>,
417421
> = None;
418422

423+
#[cfg(not(c_bindings))]
424+
/// A panicking implementation of [`KVStore`] that is used in [`NO_LIQUIDITY_MANAGER`].
425+
pub struct DummyKVStore;
426+
427+
#[cfg(not(c_bindings))]
428+
impl KVStore for DummyKVStore {
429+
fn read(
430+
&self, _: &str, _: &str, _: &str,
431+
) -> impl core::future::Future<Output = Result<Vec<u8>, lightning::io::Error>> + Send + 'static
432+
{
433+
async { unimplemented!() }
434+
}
435+
436+
fn write(
437+
&self, _: &str, _: &str, _: &str, _: Vec<u8>,
438+
) -> impl core::future::Future<Output = Result<(), lightning::io::Error>> + Send + 'static {
439+
async { unimplemented!() }
440+
}
441+
442+
fn remove(
443+
&self, _: &str, _: &str, _: &str,
444+
) -> impl core::future::Future<Output = Result<(), lightning::io::Error>> + Send + 'static {
445+
async { unimplemented!() }
446+
}
447+
448+
fn list(
449+
&self, _: &str, _: &str,
450+
) -> impl core::future::Future<Output = Result<Vec<String>, lightning::io::Error>> + Send + 'static
451+
{
452+
async { unimplemented!() }
453+
}
454+
}
455+
419456
/// When initializing a background processor without a liquidity manager, this can be used to avoid
420457
/// specifying a concrete `LiquidityManager` type.
421458
#[cfg(not(c_bindings))]
@@ -430,8 +467,8 @@ pub const NO_LIQUIDITY_MANAGER: Option<
430467
CM = &DynChannelManager,
431468
Filter = dyn chain::Filter + Send + Sync,
432469
C = &(dyn chain::Filter + Send + Sync),
433-
KVStore = dyn lightning::util::persist::KVStore + Send + Sync,
434-
K = &(dyn lightning::util::persist::KVStore + Send + Sync),
470+
KVStore = DummyKVStore,
471+
K = &DummyKVStore,
435472
TimeProvider = dyn lightning_liquidity::utils::time::TimeProvider + Send + Sync,
436473
TP = &(dyn lightning_liquidity::utils::time::TimeProvider + Send + Sync),
437474
BroadcasterInterface = dyn lightning::chain::chaininterface::BroadcasterInterface

lightning-persister/src/fs_store.rs

Lines changed: 50 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@ use std::sync::{Arc, Mutex, RwLock};
1414
#[cfg(feature = "tokio")]
1515
use core::future::Future;
1616
#[cfg(feature = "tokio")]
17-
use core::pin::Pin;
18-
#[cfg(feature = "tokio")]
1917
use lightning::util::persist::KVStore;
2018

2119
#[cfg(target_os = "windows")]
@@ -459,93 +457,85 @@ impl FilesystemStoreInner {
459457
impl KVStore for FilesystemStore {
460458
fn read(
461459
&self, primary_namespace: &str, secondary_namespace: &str, key: &str,
462-
) -> Pin<Box<dyn Future<Output = Result<Vec<u8>, lightning::io::Error>> + 'static + Send>> {
460+
) -> impl Future<Output = Result<Vec<u8>, lightning::io::Error>> + 'static + Send {
463461
let this = Arc::clone(&self.inner);
464-
let path = match this.get_checked_dest_file_path(
462+
let path = this.get_checked_dest_file_path(
465463
primary_namespace,
466464
secondary_namespace,
467465
Some(key),
468466
"read",
469-
) {
470-
Ok(path) => path,
471-
Err(e) => return Box::pin(async move { Err(e) }),
472-
};
467+
);
473468

474-
Box::pin(async move {
469+
async move {
470+
let path = match path {
471+
Ok(path) => path,
472+
Err(e) => return Err(e),
473+
};
475474
tokio::task::spawn_blocking(move || this.read(path)).await.unwrap_or_else(|e| {
476475
Err(lightning::io::Error::new(lightning::io::ErrorKind::Other, e))
477476
})
478-
})
477+
}
479478
}
480479

481480
fn write(
482481
&self, primary_namespace: &str, secondary_namespace: &str, key: &str, buf: Vec<u8>,
483-
) -> Pin<Box<dyn Future<Output = Result<(), lightning::io::Error>> + 'static + Send>> {
482+
) -> impl Future<Output = Result<(), lightning::io::Error>> + 'static + Send {
484483
let this = Arc::clone(&self.inner);
485-
let path = match this.get_checked_dest_file_path(
486-
primary_namespace,
487-
secondary_namespace,
488-
Some(key),
489-
"write",
490-
) {
491-
Ok(path) => path,
492-
Err(e) => return Box::pin(async move { Err(e) }),
493-
};
494-
495-
let (inner_lock_ref, version) = self.get_new_version_and_lock_ref(path.clone());
496-
Box::pin(async move {
484+
let path = this
485+
.get_checked_dest_file_path(primary_namespace, secondary_namespace, Some(key), "write")
486+
.map(|path| (self.get_new_version_and_lock_ref(path.clone()), path));
487+
488+
async move {
489+
let ((inner_lock_ref, version), path) = match path {
490+
Ok(res) => res,
491+
Err(e) => return Err(e),
492+
};
497493
tokio::task::spawn_blocking(move || {
498494
this.write_version(inner_lock_ref, path, buf, version)
499495
})
500496
.await
501497
.unwrap_or_else(|e| Err(lightning::io::Error::new(lightning::io::ErrorKind::Other, e)))
502-
})
498+
}
503499
}
504500

505501
fn remove(
506502
&self, primary_namespace: &str, secondary_namespace: &str, key: &str,
507-
) -> Pin<Box<dyn Future<Output = Result<(), lightning::io::Error>> + 'static + Send>> {
503+
) -> impl Future<Output = Result<(), lightning::io::Error>> + 'static + Send {
508504
let this = Arc::clone(&self.inner);
509-
let path = match this.get_checked_dest_file_path(
510-
primary_namespace,
511-
secondary_namespace,
512-
Some(key),
513-
"remove",
514-
) {
515-
Ok(path) => path,
516-
Err(e) => return Box::pin(async move { Err(e) }),
517-
};
518-
519-
let (inner_lock_ref, version) = self.get_new_version_and_lock_ref(path.clone());
520-
Box::pin(async move {
505+
let path = this
506+
.get_checked_dest_file_path(primary_namespace, secondary_namespace, Some(key), "remove")
507+
.map(|path| (self.get_new_version_and_lock_ref(path.clone()), path));
508+
509+
async move {
510+
let ((inner_lock_ref, version), path) = match path {
511+
Ok(res) => res,
512+
Err(e) => return Err(e),
513+
};
521514
tokio::task::spawn_blocking(move || this.remove_version(inner_lock_ref, path, version))
522515
.await
523516
.unwrap_or_else(|e| {
524517
Err(lightning::io::Error::new(lightning::io::ErrorKind::Other, e))
525518
})
526-
})
519+
}
527520
}
528521

529522
fn list(
530523
&self, primary_namespace: &str, secondary_namespace: &str,
531-
) -> Pin<Box<dyn Future<Output = Result<Vec<String>, lightning::io::Error>> + 'static + Send>> {
524+
) -> impl Future<Output = Result<Vec<String>, lightning::io::Error>> + 'static + Send {
532525
let this = Arc::clone(&self.inner);
533526

534-
let path = match this.get_checked_dest_file_path(
535-
primary_namespace,
536-
secondary_namespace,
537-
None,
538-
"list",
539-
) {
540-
Ok(path) => path,
541-
Err(e) => return Box::pin(async move { Err(e) }),
542-
};
527+
let path =
528+
this.get_checked_dest_file_path(primary_namespace, secondary_namespace, None, "list");
543529

544-
Box::pin(async move {
530+
async move {
531+
let path = match path {
532+
Ok(path) => path,
533+
Err(e) => return Err(e),
534+
};
545535
tokio::task::spawn_blocking(move || this.list(path)).await.unwrap_or_else(|e| {
546536
Err(lightning::io::Error::new(lightning::io::ErrorKind::Other, e))
547537
})
548-
})
538+
}
549539
}
550540
}
551541

@@ -753,24 +743,24 @@ mod tests {
753743
let fs_store = Arc::new(FilesystemStore::new(temp_path));
754744
assert_eq!(fs_store.state_size(), 0);
755745

756-
let async_fs_store: Arc<dyn KVStore> = fs_store.clone();
746+
let async_fs_store = Arc::clone(&fs_store);
757747

758748
let data1 = vec![42u8; 32];
759749
let data2 = vec![43u8; 32];
760750

761-
let primary_namespace = "testspace";
762-
let secondary_namespace = "testsubspace";
751+
let primary = "testspace";
752+
let secondary = "testsubspace";
763753
let key = "testkey";
764754

765755
// Test writing the same key twice with different data. Execute the asynchronous part out of order to ensure
766756
// that eventual consistency works.
767-
let fut1 = async_fs_store.write(primary_namespace, secondary_namespace, key, data1);
757+
let fut1 = KVStore::write(&*async_fs_store, primary, secondary, key, data1);
768758
assert_eq!(fs_store.state_size(), 1);
769759

770-
let fut2 = async_fs_store.remove(primary_namespace, secondary_namespace, key);
760+
let fut2 = KVStore::remove(&*async_fs_store, primary, secondary, key);
771761
assert_eq!(fs_store.state_size(), 1);
772762

773-
let fut3 = async_fs_store.write(primary_namespace, secondary_namespace, key, data2.clone());
763+
let fut3 = KVStore::write(&*async_fs_store, primary, secondary, key, data2.clone());
774764
assert_eq!(fs_store.state_size(), 1);
775765

776766
fut3.await.unwrap();
@@ -783,21 +773,18 @@ mod tests {
783773
assert_eq!(fs_store.state_size(), 0);
784774

785775
// Test list.
786-
let listed_keys =
787-
async_fs_store.list(primary_namespace, secondary_namespace).await.unwrap();
776+
let listed_keys = KVStore::list(&*async_fs_store, primary, secondary).await.unwrap();
788777
assert_eq!(listed_keys.len(), 1);
789778
assert_eq!(listed_keys[0], key);
790779

791780
// Test read. We expect to read data2, as the write call was initiated later.
792-
let read_data =
793-
async_fs_store.read(primary_namespace, secondary_namespace, key).await.unwrap();
781+
let read_data = KVStore::read(&*async_fs_store, primary, secondary, key).await.unwrap();
794782
assert_eq!(data2, &*read_data);
795783

796784
// Test remove.
797-
async_fs_store.remove(primary_namespace, secondary_namespace, key).await.unwrap();
785+
KVStore::remove(&*async_fs_store, primary, secondary, key).await.unwrap();
798786

799-
let listed_keys =
800-
async_fs_store.list(primary_namespace, secondary_namespace).await.unwrap();
787+
let listed_keys = KVStore::list(&*async_fs_store, primary, secondary).await.unwrap();
801788
assert_eq!(listed_keys.len(), 0);
802789
}
803790

0 commit comments

Comments
 (0)