mirror of
https://github.com/Retropex/bitcoin.git
synced 2025-05-19 22:50:44 +02:00
Remove use CValidationInterface in wallet code
This commit does not change behavior.
This commit is contained in:
parent
d8a62db8bf
commit
91868e6288
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include <chain.h>
|
#include <chain.h>
|
||||||
#include <chainparams.h>
|
#include <chainparams.h>
|
||||||
|
#include <interfaces/handler.h>
|
||||||
#include <interfaces/wallet.h>
|
#include <interfaces/wallet.h>
|
||||||
#include <net.h>
|
#include <net.h>
|
||||||
#include <policy/fees.h>
|
#include <policy/fees.h>
|
||||||
@ -22,6 +23,7 @@
|
|||||||
#include <uint256.h>
|
#include <uint256.h>
|
||||||
#include <util/system.h>
|
#include <util/system.h>
|
||||||
#include <validation.h>
|
#include <validation.h>
|
||||||
|
#include <validationinterface.h>
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
@ -161,6 +163,55 @@ class LockingStateImpl : public LockImpl, public UniqueLock<CCriticalSection>
|
|||||||
using UniqueLock::UniqueLock;
|
using UniqueLock::UniqueLock;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class NotificationsHandlerImpl : public Handler, CValidationInterface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit NotificationsHandlerImpl(Chain& chain, Chain::Notifications& notifications)
|
||||||
|
: m_chain(chain), m_notifications(¬ifications)
|
||||||
|
{
|
||||||
|
RegisterValidationInterface(this);
|
||||||
|
}
|
||||||
|
~NotificationsHandlerImpl() override { disconnect(); }
|
||||||
|
void disconnect() override
|
||||||
|
{
|
||||||
|
if (m_notifications) {
|
||||||
|
m_notifications = nullptr;
|
||||||
|
UnregisterValidationInterface(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void TransactionAddedToMempool(const CTransactionRef& tx) override
|
||||||
|
{
|
||||||
|
m_notifications->TransactionAddedToMempool(tx);
|
||||||
|
}
|
||||||
|
void TransactionRemovedFromMempool(const CTransactionRef& tx) override
|
||||||
|
{
|
||||||
|
m_notifications->TransactionRemovedFromMempool(tx);
|
||||||
|
}
|
||||||
|
void BlockConnected(const std::shared_ptr<const CBlock>& block,
|
||||||
|
const CBlockIndex* index,
|
||||||
|
const std::vector<CTransactionRef>& tx_conflicted) override
|
||||||
|
{
|
||||||
|
m_notifications->BlockConnected(*block, tx_conflicted);
|
||||||
|
}
|
||||||
|
void BlockDisconnected(const std::shared_ptr<const CBlock>& block) override
|
||||||
|
{
|
||||||
|
m_notifications->BlockDisconnected(*block);
|
||||||
|
}
|
||||||
|
void ChainStateFlushed(const CBlockLocator& locator) override { m_notifications->ChainStateFlushed(locator); }
|
||||||
|
void ResendWalletTransactions(int64_t best_block_time, CConnman*) override
|
||||||
|
{
|
||||||
|
// `cs_main` is always held when this method is called, so it is safe to
|
||||||
|
// call `assumeLocked`. This is awkward, and the `assumeLocked` method
|
||||||
|
// should be able to be removed entirely if `ResendWalletTransactions`
|
||||||
|
// is replaced by a wallet timer as suggested in
|
||||||
|
// https://github.com/bitcoin/bitcoin/issues/15619
|
||||||
|
auto locked_chain = m_chain.assumeLocked();
|
||||||
|
m_notifications->ResendWalletTransactions(*locked_chain, best_block_time);
|
||||||
|
}
|
||||||
|
Chain& m_chain;
|
||||||
|
Chain::Notifications* m_notifications;
|
||||||
|
};
|
||||||
|
|
||||||
class ChainImpl : public Chain
|
class ChainImpl : public Chain
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -254,6 +305,11 @@ public:
|
|||||||
void initWarning(const std::string& message) override { InitWarning(message); }
|
void initWarning(const std::string& message) override { InitWarning(message); }
|
||||||
void initError(const std::string& message) override { InitError(message); }
|
void initError(const std::string& message) override { InitError(message); }
|
||||||
void loadWallet(std::unique_ptr<Wallet> wallet) override { ::uiInterface.LoadWallet(wallet); }
|
void loadWallet(std::unique_ptr<Wallet> wallet) override { ::uiInterface.LoadWallet(wallet); }
|
||||||
|
std::unique_ptr<Handler> handleNotifications(Notifications& notifications) override
|
||||||
|
{
|
||||||
|
return MakeUnique<NotificationsHandlerImpl>(*this, notifications);
|
||||||
|
}
|
||||||
|
void waitForNotifications() override { SyncWithValidationInterfaceQueue(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -25,6 +25,7 @@ struct FeeCalculation;
|
|||||||
|
|
||||||
namespace interfaces {
|
namespace interfaces {
|
||||||
|
|
||||||
|
class Handler;
|
||||||
class Wallet;
|
class Wallet;
|
||||||
|
|
||||||
//! Interface giving clients (wallet processes, maybe other analysis tools in
|
//! Interface giving clients (wallet processes, maybe other analysis tools in
|
||||||
@ -40,6 +41,12 @@ class Wallet;
|
|||||||
//! asynchronously
|
//! asynchronously
|
||||||
//! (https://github.com/bitcoin/bitcoin/pull/10973#issuecomment-380101269).
|
//! (https://github.com/bitcoin/bitcoin/pull/10973#issuecomment-380101269).
|
||||||
//!
|
//!
|
||||||
|
//! * The isPotentialTip() and waitForNotifications() methods are too low-level
|
||||||
|
//! and should be replaced with a higher level
|
||||||
|
//! waitForNotificationsUpTo(block_hash) method that the wallet can call
|
||||||
|
//! instead
|
||||||
|
//! (https://github.com/bitcoin/bitcoin/pull/10973#discussion_r266995234).
|
||||||
|
//!
|
||||||
//! * The relayTransactions() and submitToMemoryPool() methods could be replaced
|
//! * The relayTransactions() and submitToMemoryPool() methods could be replaced
|
||||||
//! with a higher-level broadcastTransaction method
|
//! with a higher-level broadcastTransaction method
|
||||||
//! (https://github.com/bitcoin/bitcoin/pull/14978#issuecomment-459373984).
|
//! (https://github.com/bitcoin/bitcoin/pull/14978#issuecomment-459373984).
|
||||||
@ -217,6 +224,25 @@ public:
|
|||||||
|
|
||||||
//! Send wallet load notification to the GUI.
|
//! Send wallet load notification to the GUI.
|
||||||
virtual void loadWallet(std::unique_ptr<Wallet> wallet) = 0;
|
virtual void loadWallet(std::unique_ptr<Wallet> wallet) = 0;
|
||||||
|
|
||||||
|
//! Chain notifications.
|
||||||
|
class Notifications
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~Notifications() {}
|
||||||
|
virtual void TransactionAddedToMempool(const CTransactionRef& tx) {}
|
||||||
|
virtual void TransactionRemovedFromMempool(const CTransactionRef& ptx) {}
|
||||||
|
virtual void BlockConnected(const CBlock& block, const std::vector<CTransactionRef>& tx_conflicted) {}
|
||||||
|
virtual void BlockDisconnected(const CBlock& block) {}
|
||||||
|
virtual void ChainStateFlushed(const CBlockLocator& locator) {}
|
||||||
|
virtual void ResendWalletTransactions(Lock& locked_chain, int64_t best_block_time) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Register handler for notifications.
|
||||||
|
virtual std::unique_ptr<Handler> handleNotifications(Notifications& notifications) = 0;
|
||||||
|
|
||||||
|
//! Wait for pending notifications to be handled.
|
||||||
|
virtual void waitForNotifications() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
//! Interface to let node manage chain clients (wallets, or maybe tools for
|
//! Interface to let node manage chain clients (wallets, or maybe tools for
|
||||||
|
@ -13,12 +13,7 @@ WalletTestingSetup::WalletTestingSetup(const std::string& chainName):
|
|||||||
{
|
{
|
||||||
bool fFirstRun;
|
bool fFirstRun;
|
||||||
m_wallet.LoadWallet(fFirstRun);
|
m_wallet.LoadWallet(fFirstRun);
|
||||||
RegisterValidationInterface(&m_wallet);
|
m_wallet.m_chain_notifications_handler = m_chain->handleNotifications(m_wallet);
|
||||||
|
|
||||||
RegisterWalletRPCCommands(tableRPC);
|
RegisterWalletRPCCommands(tableRPC);
|
||||||
}
|
}
|
||||||
|
|
||||||
WalletTestingSetup::~WalletTestingSetup()
|
|
||||||
{
|
|
||||||
UnregisterValidationInterface(&m_wallet);
|
|
||||||
}
|
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
*/
|
*/
|
||||||
struct WalletTestingSetup: public TestingSetup {
|
struct WalletTestingSetup: public TestingSetup {
|
||||||
explicit WalletTestingSetup(const std::string& chainName = CBaseChainParams::MAIN);
|
explicit WalletTestingSetup(const std::string& chainName = CBaseChainParams::MAIN);
|
||||||
~WalletTestingSetup();
|
|
||||||
|
|
||||||
std::unique_ptr<interfaces::Chain> m_chain = interfaces::MakeChain();
|
std::unique_ptr<interfaces::Chain> m_chain = interfaces::MakeChain();
|
||||||
CWallet m_wallet;
|
CWallet m_wallet;
|
||||||
|
@ -96,7 +96,7 @@ static void ReleaseWallet(CWallet* wallet)
|
|||||||
wallet->WalletLogPrintf("Releasing wallet\n");
|
wallet->WalletLogPrintf("Releasing wallet\n");
|
||||||
wallet->BlockUntilSyncedToCurrentChain();
|
wallet->BlockUntilSyncedToCurrentChain();
|
||||||
wallet->Flush();
|
wallet->Flush();
|
||||||
UnregisterValidationInterface(wallet);
|
wallet->m_chain_notifications_handler.reset();
|
||||||
delete wallet;
|
delete wallet;
|
||||||
// Wallet is now released, notify UnloadWallet, if any.
|
// Wallet is now released, notify UnloadWallet, if any.
|
||||||
{
|
{
|
||||||
@ -1243,7 +1243,8 @@ void CWallet::TransactionRemovedFromMempool(const CTransactionRef &ptx) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWallet::BlockConnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex *pindex, const std::vector<CTransactionRef>& vtxConflicted) {
|
void CWallet::BlockConnected(const CBlock& block, const std::vector<CTransactionRef>& vtxConflicted) {
|
||||||
|
const uint256& block_hash = block.GetHash();
|
||||||
auto locked_chain = chain().lock();
|
auto locked_chain = chain().lock();
|
||||||
LOCK(cs_wallet);
|
LOCK(cs_wallet);
|
||||||
// TODO: Temporarily ensure that mempool removals are notified before
|
// TODO: Temporarily ensure that mempool removals are notified before
|
||||||
@ -1258,19 +1259,19 @@ void CWallet::BlockConnected(const std::shared_ptr<const CBlock>& pblock, const
|
|||||||
SyncTransaction(ptx, {} /* block hash */, 0 /* position in block */);
|
SyncTransaction(ptx, {} /* block hash */, 0 /* position in block */);
|
||||||
TransactionRemovedFromMempool(ptx);
|
TransactionRemovedFromMempool(ptx);
|
||||||
}
|
}
|
||||||
for (size_t i = 0; i < pblock->vtx.size(); i++) {
|
for (size_t i = 0; i < block.vtx.size(); i++) {
|
||||||
SyncTransaction(pblock->vtx[i], pindex->GetBlockHash(), i);
|
SyncTransaction(block.vtx[i], block_hash, i);
|
||||||
TransactionRemovedFromMempool(pblock->vtx[i]);
|
TransactionRemovedFromMempool(block.vtx[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_last_block_processed = pindex->GetBlockHash();
|
m_last_block_processed = block_hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWallet::BlockDisconnected(const std::shared_ptr<const CBlock>& pblock) {
|
void CWallet::BlockDisconnected(const CBlock& block) {
|
||||||
auto locked_chain = chain().lock();
|
auto locked_chain = chain().lock();
|
||||||
LOCK(cs_wallet);
|
LOCK(cs_wallet);
|
||||||
|
|
||||||
for (const CTransactionRef& ptx : pblock->vtx) {
|
for (const CTransactionRef& ptx : block.vtx) {
|
||||||
SyncTransaction(ptx, {} /* block hash */, 0 /* position in block */);
|
SyncTransaction(ptx, {} /* block hash */, 0 /* position in block */);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1297,7 +1298,7 @@ void CWallet::BlockUntilSyncedToCurrentChain() {
|
|||||||
// ...otherwise put a callback in the validation interface queue and wait
|
// ...otherwise put a callback in the validation interface queue and wait
|
||||||
// for the queue to drain enough to execute it (indicating we are caught up
|
// for the queue to drain enough to execute it (indicating we are caught up
|
||||||
// at least with the time we entered this function).
|
// at least with the time we entered this function).
|
||||||
SyncWithValidationInterfaceQueue();
|
chain().waitForNotifications();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2137,7 +2138,7 @@ std::vector<uint256> CWallet::ResendWalletTransactionsBefore(interfaces::Chain::
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWallet::ResendWalletTransactions(int64_t nBestBlockTime, CConnman* connman)
|
void CWallet::ResendWalletTransactions(interfaces::Chain::Lock& locked_chain, int64_t nBestBlockTime)
|
||||||
{
|
{
|
||||||
// Do this infrequently and randomly to avoid giving away
|
// Do this infrequently and randomly to avoid giving away
|
||||||
// that these are our transactions.
|
// that these are our transactions.
|
||||||
@ -2155,8 +2156,7 @@ void CWallet::ResendWalletTransactions(int64_t nBestBlockTime, CConnman* connman
|
|||||||
|
|
||||||
// Rebroadcast unconfirmed txes older than 5 minutes before the last
|
// Rebroadcast unconfirmed txes older than 5 minutes before the last
|
||||||
// block was found:
|
// block was found:
|
||||||
auto locked_chain = chain().assumeLocked(); // Temporary. Removed in upcoming lock cleanup
|
std::vector<uint256> relayed = ResendWalletTransactionsBefore(locked_chain, nBestBlockTime-5*60);
|
||||||
std::vector<uint256> relayed = ResendWalletTransactionsBefore(*locked_chain, nBestBlockTime-5*60);
|
|
||||||
if (!relayed.empty())
|
if (!relayed.empty())
|
||||||
WalletLogPrintf("%s: rebroadcast %u unconfirmed transactions\n", __func__, relayed.size());
|
WalletLogPrintf("%s: rebroadcast %u unconfirmed transactions\n", __func__, relayed.size());
|
||||||
}
|
}
|
||||||
@ -4385,8 +4385,8 @@ std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(interfaces::Chain& chain,
|
|||||||
|
|
||||||
chain.loadWallet(interfaces::MakeWallet(walletInstance));
|
chain.loadWallet(interfaces::MakeWallet(walletInstance));
|
||||||
|
|
||||||
// Register with the validation interface. It's ok to do this after rescan since we're still holding cs_main.
|
// Register with the validation interface. It's ok to do this after rescan since we're still holding locked_chain.
|
||||||
RegisterValidationInterface(walletInstance.get());
|
walletInstance->m_chain_notifications_handler = chain.handleNotifications(*walletInstance);
|
||||||
|
|
||||||
walletInstance->SetBroadcastTransactions(gArgs.GetBoolArg("-walletbroadcast", DEFAULT_WALLETBROADCAST));
|
walletInstance->SetBroadcastTransactions(gArgs.GetBoolArg("-walletbroadcast", DEFAULT_WALLETBROADCAST));
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include <amount.h>
|
#include <amount.h>
|
||||||
#include <interfaces/chain.h>
|
#include <interfaces/chain.h>
|
||||||
|
#include <interfaces/handler.h>
|
||||||
#include <outputtype.h>
|
#include <outputtype.h>
|
||||||
#include <policy/feerate.h>
|
#include <policy/feerate.h>
|
||||||
#include <streams.h>
|
#include <streams.h>
|
||||||
@ -637,7 +638,7 @@ class WalletRescanReserver; //forward declarations for ScanForWalletTransactions
|
|||||||
* A CWallet is an extension of a keystore, which also maintains a set of transactions and balances,
|
* A CWallet is an extension of a keystore, which also maintains a set of transactions and balances,
|
||||||
* and provides the ability to create new transactions.
|
* and provides the ability to create new transactions.
|
||||||
*/
|
*/
|
||||||
class CWallet final : public CCryptoKeyStore, public CValidationInterface
|
class CWallet final : public CCryptoKeyStore, private interfaces::Chain::Notifications
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
std::atomic<bool> fAbortRescan{false};
|
std::atomic<bool> fAbortRescan{false};
|
||||||
@ -808,6 +809,9 @@ public:
|
|||||||
|
|
||||||
std::set<COutPoint> setLockedCoins GUARDED_BY(cs_wallet);
|
std::set<COutPoint> setLockedCoins GUARDED_BY(cs_wallet);
|
||||||
|
|
||||||
|
/** Registered interfaces::Chain::Notifications handler. */
|
||||||
|
std::unique_ptr<interfaces::Handler> m_chain_notifications_handler;
|
||||||
|
|
||||||
/** Interface for accessing chain state. */
|
/** Interface for accessing chain state. */
|
||||||
interfaces::Chain& chain() const { return m_chain; }
|
interfaces::Chain& chain() const { return m_chain; }
|
||||||
|
|
||||||
@ -920,8 +924,8 @@ public:
|
|||||||
bool AddToWallet(const CWalletTx& wtxIn, bool fFlushOnClose=true);
|
bool AddToWallet(const CWalletTx& wtxIn, bool fFlushOnClose=true);
|
||||||
void LoadToWallet(const CWalletTx& wtxIn) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
void LoadToWallet(const CWalletTx& wtxIn) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
||||||
void TransactionAddedToMempool(const CTransactionRef& tx) override;
|
void TransactionAddedToMempool(const CTransactionRef& tx) override;
|
||||||
void BlockConnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex *pindex, const std::vector<CTransactionRef>& vtxConflicted) override;
|
void BlockConnected(const CBlock& block, const std::vector<CTransactionRef>& vtxConflicted) override;
|
||||||
void BlockDisconnected(const std::shared_ptr<const CBlock>& pblock) override;
|
void BlockDisconnected(const CBlock& block) override;
|
||||||
int64_t RescanFromTime(int64_t startTime, const WalletRescanReserver& reserver, bool update);
|
int64_t RescanFromTime(int64_t startTime, const WalletRescanReserver& reserver, bool update);
|
||||||
|
|
||||||
struct ScanResult {
|
struct ScanResult {
|
||||||
@ -942,7 +946,7 @@ public:
|
|||||||
ScanResult ScanForWalletTransactions(const uint256& first_block, const uint256& last_block, const WalletRescanReserver& reserver, bool fUpdate);
|
ScanResult ScanForWalletTransactions(const uint256& first_block, const uint256& last_block, const WalletRescanReserver& reserver, bool fUpdate);
|
||||||
void TransactionRemovedFromMempool(const CTransactionRef &ptx) override;
|
void TransactionRemovedFromMempool(const CTransactionRef &ptx) override;
|
||||||
void ReacceptWalletTransactions();
|
void ReacceptWalletTransactions();
|
||||||
void ResendWalletTransactions(int64_t nBestBlockTime, CConnman* connman) override EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
void ResendWalletTransactions(interfaces::Chain::Lock& locked_chain, int64_t nBestBlockTime) override;
|
||||||
// ResendWalletTransactionsBefore may only be called if fBroadcastTransactions!
|
// ResendWalletTransactionsBefore may only be called if fBroadcastTransactions!
|
||||||
std::vector<uint256> ResendWalletTransactionsBefore(interfaces::Chain::Lock& locked_chain, int64_t nTime);
|
std::vector<uint256> ResendWalletTransactionsBefore(interfaces::Chain::Lock& locked_chain, int64_t nTime);
|
||||||
CAmount GetBalance(const isminefilter& filter=ISMINE_SPENDABLE, const int min_depth=0) const;
|
CAmount GetBalance(const isminefilter& filter=ISMINE_SPENDABLE, const int min_depth=0) const;
|
||||||
@ -1220,6 +1224,8 @@ public:
|
|||||||
|
|
||||||
/** Add a KeyOriginInfo to the wallet */
|
/** Add a KeyOriginInfo to the wallet */
|
||||||
bool AddKeyOrigin(const CPubKey& pubkey, const KeyOriginInfo& info);
|
bool AddKeyOrigin(const CPubKey& pubkey, const KeyOriginInfo& info);
|
||||||
|
|
||||||
|
friend struct WalletTestingSetup;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** A key allocated from the key pool. */
|
/** A key allocated from the key pool. */
|
||||||
|
Loading…
Reference in New Issue
Block a user