]> Untitled Git - bdk/commitdiff
fix(wallet): allow PersistedWallet<P> to be Send + Sync even if P is !Sync
authorSteve Myers <steve@notmandatory.org>
Thu, 6 Mar 2025 03:12:02 +0000 (21:12 -0600)
committerSteve Myers <steve@notmandatory.org>
Mon, 10 Mar 2025 21:41:22 +0000 (16:41 -0500)
The goal of this change is to ensure that PersistWallet<P> remains Send and Sync, even if the functions implemented on it
have a &mut P parameter and P is not Sync.

The reason to change PersistWallet<P>'s _marker field type from PhatonData<P> to PhantomData<fn(&mut P)> is to tell the
Rust compiler that this struct is a "consumer" of &mut P, but it does not own P and therefore should not be tied to its
lifetime.

crates/wallet/src/wallet/persisted.rs
crates/wallet/tests/wallet.rs

index 1bc0a7884ea70b4d3342fb3a1219bf861579d58f..28a6ec78cef13d3e1d42ee4085e5a67bdb7d8d1f 100644 (file)
@@ -120,7 +120,7 @@ pub trait AsyncWalletPersister {
 #[derive(Debug)]
 pub struct PersistedWallet<P> {
     inner: Wallet,
-    marker: PhantomData<P>,
+    _marker: PhantomData<fn(&mut P)>,
 }
 
 impl<P> Deref for PersistedWallet<P> {
@@ -155,7 +155,7 @@ impl<P: WalletPersister> PersistedWallet<P> {
         }
         Ok(Self {
             inner,
-            marker: PhantomData,
+            _marker: PhantomData,
         })
     }
 
@@ -169,7 +169,7 @@ impl<P: WalletPersister> PersistedWallet<P> {
             .map(|opt| {
                 opt.map(|inner| PersistedWallet {
                     inner,
-                    marker: PhantomData,
+                    _marker: PhantomData,
                 })
             })
             .map_err(LoadWithPersistError::InvalidChangeSet)
@@ -214,7 +214,7 @@ impl<P: AsyncWalletPersister> PersistedWallet<P> {
         }
         Ok(Self {
             inner,
-            marker: PhantomData,
+            _marker: PhantomData,
         })
     }
 
@@ -230,7 +230,7 @@ impl<P: AsyncWalletPersister> PersistedWallet<P> {
             .map(|opt| {
                 opt.map(|inner| PersistedWallet {
                     inner,
-                    marker: PhantomData,
+                    _marker: PhantomData,
                 })
             })
             .map_err(LoadWithPersistError::InvalidChangeSet)
index f42f0bcd57b1c9868aff3629e798319f5975e0a7..35cbd85d4f29619aa900414440277fd790b6bd72 100644 (file)
@@ -12,7 +12,9 @@ use bdk_wallet::psbt::PsbtUtils;
 use bdk_wallet::signer::{SignOptions, SignerError};
 use bdk_wallet::test_utils::*;
 use bdk_wallet::tx_builder::AddForeignUtxoError;
-use bdk_wallet::{AddressInfo, Balance, ChangeSet, Update, Wallet, WalletPersister, WalletTx};
+use bdk_wallet::{
+    AddressInfo, Balance, ChangeSet, PersistedWallet, Update, Wallet, WalletPersister, WalletTx,
+};
 use bdk_wallet::{KeychainKind, LoadError, LoadMismatch, LoadWithPersistError};
 use bitcoin::constants::{ChainHash, COINBASE_MATURITY};
 use bitcoin::hashes::Hash;
@@ -4209,6 +4211,7 @@ fn test_tx_cancellation() {
 fn test_thread_safety() {
     fn thread_safe<T: Send + Sync>() {}
     thread_safe::<Wallet>(); // compiles only if true
+    thread_safe::<PersistedWallet<bdk_chain::rusqlite::Connection>>();
 }
 
 #[test]