aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPieter Wuille <pieter.wuille@gmail.com>2013-10-19 18:34:06 +0200
committerPieter Wuille <pieter.wuille@gmail.com>2013-10-26 14:51:46 +0200
commit00588c3fac4822d42ffde46ca55c029a74c378ee (patch)
tree9e3d048531cae00793f32b9e4a05116986cc1f58
parente010af7089b18af838b74a4dc7908885c1600d13 (diff)
Use boost signals for callbacks from main to wallet
-rw-r--r--src/main.cpp115
-rw-r--r--src/main.h27
-rw-r--r--src/rpcrawtransaction.cpp2
-rw-r--r--src/wallet.cpp20
-rw-r--r--src/wallet.h9
5 files changed, 77 insertions, 96 deletions
diff --git a/src/main.cpp b/src/main.cpp
index 6ec261b5f8..b84c53ade1 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -74,75 +74,52 @@ int64 nTransactionFee = 0;
// These functions dispatch to one or all registered wallets
-
-void RegisterWallet(CWallet* pwalletIn)
-{
- {
- LOCK(cs_setpwalletRegistered);
- setpwalletRegistered.insert(pwalletIn);
- }
-}
-
-void UnregisterWallet(CWallet* pwalletIn)
-{
- {
- LOCK(cs_setpwalletRegistered);
- setpwalletRegistered.erase(pwalletIn);
- }
-}
-
-void UnregisterAllWallets()
-{
- LOCK(cs_setpwalletRegistered);
- setpwalletRegistered.clear();
+namespace {
+struct CMainSignals {
+ // Notifies listeners of updated transaction data (passing hash, transaction, and optionally the block it is found in.
+ boost::signals2::signal<void (const uint256 &, const CTransaction &, const CBlock *)> SyncTransaction;
+ // Notifies listeners of an erased transaction (currently disabled, requires transaction replacement).
+ boost::signals2::signal<void (const uint256 &)> EraseTransaction;
+ // Notifies listeners of an updated transaction without new data (for now: a coinbase potentially becoming visible).
+ boost::signals2::signal<void (const uint256 &)> UpdatedTransaction;
+ // Notifies listeners of a new active block chain.
+ boost::signals2::signal<void (const CBlockLocator &)> SetBestChain;
+ // Notifies listeners about an inventory item being seen on the network.
+ boost::signals2::signal<void (const uint256 &)> Inventory;
+ // Tells listeners to broadcast their data.
+ boost::signals2::signal<void ()> Broadcast;
+} g_signals;
}
-// erases transaction with the given hash from all wallets
-void static EraseFromWallets(uint256 hash)
-{
- LOCK(cs_setpwalletRegistered);
- BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
- pwallet->EraseFromWallet(hash);
+void RegisterWallet(CWalletInterface* pwalletIn) {
+ g_signals.SyncTransaction.connect(boost::bind(&CWalletInterface::SyncTransaction, pwalletIn, _1, _2, _3));
+ g_signals.EraseTransaction.connect(boost::bind(&CWalletInterface::EraseFromWallet, pwalletIn, _1));
+ g_signals.UpdatedTransaction.connect(boost::bind(&CWalletInterface::UpdatedTransaction, pwalletIn, _1));
+ g_signals.SetBestChain.connect(boost::bind(&CWalletInterface::SetBestChain, pwalletIn, _1));
+ g_signals.Inventory.connect(boost::bind(&CWalletInterface::Inventory, pwalletIn, _1));
+ g_signals.Broadcast.connect(boost::bind(&CWalletInterface::ResendWalletTransactions, pwalletIn));
}
-// make sure all wallets know about the given transaction, in the given block
-void SyncWithWallets(const uint256 &hash, const CTransaction& tx, const CBlock* pblock, bool fUpdate)
-{
- LOCK(cs_setpwalletRegistered);
- BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
- pwallet->AddToWalletIfInvolvingMe(hash, tx, pblock, fUpdate);
+void UnregisterWallet(CWalletInterface* pwalletIn) {
+ g_signals.Broadcast.disconnect(boost::bind(&CWalletInterface::ResendWalletTransactions, pwalletIn));
+ g_signals.Inventory.disconnect(boost::bind(&CWalletInterface::Inventory, pwalletIn, _1));
+ g_signals.SetBestChain.disconnect(boost::bind(&CWalletInterface::SetBestChain, pwalletIn, _1));
+ g_signals.UpdatedTransaction.disconnect(boost::bind(&CWalletInterface::UpdatedTransaction, pwalletIn, _1));
+ g_signals.EraseTransaction.disconnect(boost::bind(&CWalletInterface::EraseFromWallet, pwalletIn, _1));
+ g_signals.SyncTransaction.disconnect(boost::bind(&CWalletInterface::SyncTransaction, pwalletIn, _1, _2, _3));
}
-// notify wallets about a new best chain
-void static SetBestChain(const CBlockLocator& loc)
-{
- LOCK(cs_setpwalletRegistered);
- BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
- pwallet->SetBestChain(loc);
+void UnregisterAllWallets() {
+ g_signals.Broadcast.disconnect_all_slots();
+ g_signals.Inventory.disconnect_all_slots();
+ g_signals.SetBestChain.disconnect_all_slots();
+ g_signals.UpdatedTransaction.disconnect_all_slots();
+ g_signals.EraseTransaction.disconnect_all_slots();
+ g_signals.SyncTransaction.disconnect_all_slots();
}
-// notify wallets about an updated transaction
-void static UpdatedTransaction(const uint256& hashTx)
-{
- LOCK(cs_setpwalletRegistered);
- BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
- pwallet->UpdatedTransaction(hashTx);
-}
-
-// notify wallets about an incoming inventory (for request counts)
-void static Inventory(const uint256& hash)
-{
- LOCK(cs_setpwalletRegistered);
- BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
- pwallet->Inventory(hash);
-}
-
-// ask wallets to resend their transactions
-void static ResendWalletTransactions()
-{
- LOCK(cs_setpwalletRegistered);
- BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
- pwallet->ResendWalletTransactions();
+void SyncWithWallets(const uint256 &hash, const CTransaction &tx, const CBlock *pblock) {
+ g_signals.SyncTransaction(hash, tx, pblock);
}
//////////////////////////////////////////////////////////////////////////////
@@ -913,8 +890,8 @@ bool CTxMemPool::accept(CValidationState &state, const CTransaction &tx, bool fL
///// are we sure this is ok when loading transactions or restoring block txes
// If updated, erase old tx from wallet
if (ptxOld)
- EraseFromWallets(ptxOld->GetHash());
- SyncWithWallets(hash, tx, NULL, true);
+ g_signals.EraseTransaction(ptxOld->GetHash());
+ g_signals.SyncTransaction(hash, tx, NULL);
LogPrint("mempool", "CTxMemPool::accept() : accepted %s (poolsz %"PRIszu")\n",
hash.ToString().c_str(),
@@ -1974,7 +1951,7 @@ bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, C
// Watch for transactions paying to me
for (unsigned int i = 0; i < block.vtx.size(); i++)
- SyncWithWallets(block.GetTxHash(i), block.vtx[i], &block, true);
+ g_signals.SyncTransaction(block.GetTxHash(i), block.vtx[i], &block);
return true;
}
@@ -2108,7 +2085,7 @@ bool SetBestChain(CValidationState &state, CBlockIndex* pindexNew)
// Update best block in wallet (so we can detect restored wallets)
if ((pindexNew->nHeight % 20160) == 0 || (!fIsInitialDownload && (pindexNew->nHeight % 144) == 0))
- ::SetBestChain(chainActive.GetLocator(pindexNew));
+ g_signals.SetBestChain(chainActive.GetLocator(pindexNew));
// New best block
nTimeBestReceived = GetTime();
@@ -2188,7 +2165,7 @@ bool AddToBlockIndex(CBlock& block, CValidationState& state, const CDiskBlockPos
CheckForkWarningConditions();
// Notify UI to display prev block's coinbase if it was ours
static uint256 hashPrevBestCoinBase;
- UpdatedTransaction(hashPrevBestCoinBase);
+ g_signals.UpdatedTransaction(hashPrevBestCoinBase);
hashPrevBestCoinBase = block.GetTxHash(0);
} else
CheckForkWarningConditionsOnNewFork(pindexNew);
@@ -3311,7 +3288,7 @@ void static ProcessGetData(CNode* pfrom)
}
// Track requests for our stuff.
- Inventory(inv.hash);
+ g_signals.Inventory(inv.hash);
}
}
@@ -3573,7 +3550,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
}
// Track requests for our stuff
- Inventory(inv.hash);
+ g_signals.Inventory(inv.hash);
}
}
@@ -4193,7 +4170,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
// transactions become unconfirmed and spams other nodes.
if (!fReindex && !fImporting && !IsInitialBlockDownload())
{
- ResendWalletTransactions();
+ g_signals.Broadcast();
}
//
diff --git a/src/main.h b/src/main.h
index 76de47071e..82a533749e 100644
--- a/src/main.h
+++ b/src/main.h
@@ -17,7 +17,6 @@
#include <list>
-class CWallet;
class CBlock;
class CBlockIndex;
class CKeyItem;
@@ -81,8 +80,6 @@ extern uint64 nLastBlockTx;
extern uint64 nLastBlockSize;
extern const std::string strMessageMagic;
extern int64 nTimeBestReceived;
-extern CCriticalSection cs_setpwalletRegistered;
-extern std::set<CWallet*> setpwalletRegistered;
extern bool fImporting;
extern bool fReindex;
extern bool fBenchmark;
@@ -108,17 +105,18 @@ class CCoinsView;
class CCoinsViewCache;
class CScriptCheck;
class CValidationState;
+class CWalletInterface;
struct CBlockTemplate;
/** Register a wallet to receive updates from core */
-void RegisterWallet(CWallet* pwalletIn);
+void RegisterWallet(CWalletInterface* pwalletIn);
/** Unregister a wallet from core */
-void UnregisterWallet(CWallet* pwalletIn);
+void UnregisterWallet(CWalletInterface* pwalletIn);
/** Unregister all wallets from core */
void UnregisterAllWallets();
/** Push an updated transaction to all registered wallets */
-void SyncWithWallets(const uint256 &hash, const CTransaction& tx, const CBlock* pblock = NULL, bool fUpdate = false);
+void SyncWithWallets(const uint256 &hash, const CTransaction& tx, const CBlock* pblock = NULL);
/** Register with a network node to receive its signals */
void RegisterNodeSignals(CNodeSignals& nodeSignals);
@@ -190,9 +188,6 @@ bool AbortNode(const std::string &msg);
-
-bool GetWalletFile(CWallet* pwallet, std::string &strWalletFileOut);
-
struct CDiskBlockPos
{
int nFile;
@@ -1256,4 +1251,18 @@ public:
)
};
+
+class CWalletInterface {
+protected:
+ virtual void SyncTransaction(const uint256 &hash, const CTransaction &tx, const CBlock *pblock) =0;
+ virtual void EraseFromWallet(const uint256 &hash) =0;
+ virtual void SetBestChain(const CBlockLocator &locator) =0;
+ virtual void UpdatedTransaction(const uint256 &hash) =0;
+ virtual void Inventory(const uint256 &hash) =0;
+ virtual void ResendWalletTransactions() =0;
+ friend void ::RegisterWallet(CWalletInterface*);
+ friend void ::UnregisterWallet(CWalletInterface*);
+ friend void ::UnregisterAllWallets();
+};
+
#endif
diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp
index d5bd39cb4d..4d1381bc20 100644
--- a/src/rpcrawtransaction.cpp
+++ b/src/rpcrawtransaction.cpp
@@ -560,7 +560,7 @@ Value sendrawtransaction(const Array& params, bool fHelp)
// Not in block, but already in the memory pool; will drop
// through to re-relay it.
} else {
- SyncWithWallets(hashTx, tx, NULL, true);
+ SyncWithWallets(hashTx, tx, NULL);
}
RelayTransaction(tx, hashTx);
diff --git a/src/wallet.cpp b/src/wallet.cpp
index 24813c54ec..bd9e2c7347 100644
--- a/src/wallet.cpp
+++ b/src/wallet.cpp
@@ -505,7 +505,7 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn)
// Add a transaction to the wallet, or update it.
// pblock is optional, but should be provided if the transaction is known to be in a block.
// If fUpdate is true, existing transactions will be updated.
-bool CWallet::AddToWalletIfInvolvingMe(const uint256 &hash, const CTransaction& tx, const CBlock* pblock, bool fUpdate, bool fFindBlock)
+bool CWallet::AddToWalletIfInvolvingMe(const uint256 &hash, const CTransaction& tx, const CBlock* pblock, bool fUpdate)
{
{
LOCK(cs_wallet);
@@ -525,16 +525,20 @@ bool CWallet::AddToWalletIfInvolvingMe(const uint256 &hash, const CTransaction&
return false;
}
-bool CWallet::EraseFromWallet(uint256 hash)
+void CWallet::SyncTransaction(const uint256 &hash, const CTransaction& tx, const CBlock* pblock) {
+ AddToWalletIfInvolvingMe(hash, tx, pblock, true);
+}
+
+void CWallet::EraseFromWallet(const uint256 &hash)
{
if (!fFileBacked)
- return false;
+ return;
{
LOCK(cs_wallet);
if (mapWallet.erase(hash))
CWalletDB(strWalletFile).EraseTx(hash);
}
- return true;
+ return;
}
@@ -1496,14 +1500,6 @@ bool CWallet::SetDefaultKey(const CPubKey &vchPubKey)
return true;
}
-bool GetWalletFile(CWallet* pwallet, string &strWalletFileOut)
-{
- if (!pwallet->fFileBacked)
- return false;
- strWalletFileOut = pwallet->strWalletFile;
- return true;
-}
-
//
// Mark old keypool keys as used,
// and generate all new keys
diff --git a/src/wallet.h b/src/wallet.h
index 7598efc1ab..21510f8c39 100644
--- a/src/wallet.h
+++ b/src/wallet.h
@@ -80,7 +80,7 @@ public:
/** 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.
*/
-class CWallet : public CCryptoKeyStore
+class CWallet : public CCryptoKeyStore, public CWalletInterface
{
private:
bool SelectCoins(int64 nTargetValue, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64& nValueRet) const;
@@ -197,8 +197,9 @@ public:
void MarkDirty();
bool AddToWallet(const CWalletTx& wtxIn);
- bool AddToWalletIfInvolvingMe(const uint256 &hash, const CTransaction& tx, const CBlock* pblock, bool fUpdate = false, bool fFindBlock = false);
- bool EraseFromWallet(uint256 hash);
+ void SyncTransaction(const uint256 &hash, const CTransaction& tx, const CBlock* pblock);
+ bool AddToWalletIfInvolvingMe(const uint256 &hash, const CTransaction& tx, const CBlock* pblock, bool fUpdate);
+ void EraseFromWallet(const uint256 &hash);
void WalletUpdateSpent(const CTransaction& prevout);
int ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate = false);
void ReacceptWalletTransactions();
@@ -887,6 +888,4 @@ private:
std::vector<char> _ssExtra;
};
-bool GetWalletFile(CWallet* pwallet, std::string &strWalletFileOut);
-
#endif