aboutsummaryrefslogtreecommitdiff
path: root/src/wallet
diff options
context:
space:
mode:
Diffstat (limited to 'src/wallet')
-rw-r--r--src/wallet/init.cpp3
-rw-r--r--src/wallet/wallet.cpp21
-rw-r--r--src/wallet/wallet.h8
3 files changed, 29 insertions, 3 deletions
diff --git a/src/wallet/init.cpp b/src/wallet/init.cpp
index 76a7eaa681..a8096dc671 100644
--- a/src/wallet/init.cpp
+++ b/src/wallet/init.cpp
@@ -211,8 +211,9 @@ void StartWallets(CScheduler& scheduler)
pwallet->postInitProcess();
}
- // Run a thread to flush wallet periodically
+ // Schedule periodic wallet flushes and tx rebroadcasts
scheduler.scheduleEvery(MaybeCompactWalletDB, 500);
+ scheduler.scheduleEvery(MaybeResendWalletTxs, 1000);
}
void FlushWallets()
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index 243b51a1e6..cf477982ca 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -2114,8 +2114,21 @@ bool CWalletTx::IsEquivalentTo(const CWalletTx& _tx) const
return CTransaction(tx1) == CTransaction(tx2);
}
+// Rebroadcast transactions from the wallet. We do this on a random timer
+// to slightly obfuscate which transactions come from our wallet.
+//
+// Ideally, we'd only resend transactions that we think should have been
+// mined in the most recent block. Any transaction that wasn't in the top
+// blockweight of transactions in the mempool shouldn't have been mined,
+// and so is probably just sitting in the mempool waiting to be confirmed.
+// Rebroadcasting does nothing to speed up confirmation and only damages
+// privacy.
void CWallet::ResendWalletTransactions(interfaces::Chain::Lock& locked_chain)
{
+ // During reindex, importing and IBD, old wallet transactions become
+ // unconfirmed. Don't resend them as that would spam other nodes.
+ if (!chain().isReadyToBroadcast()) return;
+
// Do this infrequently and randomly to avoid giving away
// that these are our transactions.
if (GetTime() < nNextResend || !fBroadcastTransactions) return;
@@ -2149,7 +2162,13 @@ void CWallet::ResendWalletTransactions(interfaces::Chain::Lock& locked_chain)
/** @} */ // end of mapWallet
-
+void MaybeResendWalletTxs()
+{
+ for (const std::shared_ptr<CWallet>& pwallet : GetWallets()) {
+ auto locked_chain = pwallet->chain().lock();
+ pwallet->ResendWalletTransactions(*locked_chain);
+ }
+}
/** @defgroup Actions
diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h
index cef58c6419..a0c5f63cee 100644
--- a/src/wallet/wallet.h
+++ b/src/wallet/wallet.h
@@ -949,7 +949,7 @@ public:
ScanResult ScanForWalletTransactions(const uint256& first_block, const uint256& last_block, const WalletRescanReserver& reserver, bool fUpdate);
void TransactionRemovedFromMempool(const CTransactionRef &ptx) override;
void ReacceptWalletTransactions(interfaces::Chain::Lock& locked_chain) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
- void ResendWalletTransactions(interfaces::Chain::Lock& locked_chain) override;
+ void ResendWalletTransactions(interfaces::Chain::Lock& locked_chain);
struct Balance {
CAmount m_mine_trusted{0}; //!< Trusted, at depth=GetBalance.min_depth or more
CAmount m_mine_untrusted_pending{0}; //!< Untrusted, but in mempool (pending)
@@ -1232,6 +1232,12 @@ public:
friend struct WalletTestingSetup;
};
+/**
+ * Called periodically by the schedule thread. Prompts individual wallets to resend
+ * their transactions. Actual rebroadcast schedule is managed by the wallets themselves.
+ */
+void MaybeResendWalletTxs();
+
/** A key allocated from the key pool. */
class CReserveKey final : public CReserveScript
{