Move mempool SyncWithWallets call into its own thread
This commit is contained in:
parent
7c8111f304
commit
3ff68c5052
20
src/init.cpp
20
src/init.cpp
|
@ -663,6 +663,22 @@ void ThreadImport(std::vector<boost::filesystem::path> vImportFiles)
|
|||
}
|
||||
}
|
||||
|
||||
void ThreadNotifyRecentlyAdded()
|
||||
{
|
||||
while (true) {
|
||||
// Run the notifier on an integer second in the steady clock.
|
||||
auto now = std::chrono::steady_clock::now().time_since_epoch();
|
||||
auto nextFire = std::chrono::duration_cast<std::chrono::seconds>(
|
||||
now + std::chrono::seconds(1));
|
||||
std::this_thread::sleep_until(
|
||||
std::chrono::time_point<std::chrono::steady_clock>(nextFire));
|
||||
|
||||
boost::this_thread::interruption_point();
|
||||
|
||||
mempool.NotifyRecentlyAdded();
|
||||
}
|
||||
}
|
||||
|
||||
/** Sanity checks
|
||||
* Ensure that Bitcoin is running in a usable environment with all
|
||||
* necessary library support.
|
||||
|
@ -1859,6 +1875,10 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
|||
LogPrintf("mapAddressBook.size() = %u\n", pwalletMain ? pwalletMain->mapAddressBook.size() : 0);
|
||||
#endif
|
||||
|
||||
// Start the thread that notifies listeners of transactions that have been
|
||||
// recently added to the mempool.
|
||||
threadGroup.create_thread(boost::bind(&TraceThread<void (*)()>, "txnotify", &ThreadNotifyRecentlyAdded));
|
||||
|
||||
if (GetBoolArg("-listenonion", DEFAULT_LISTEN_ONION))
|
||||
StartTorControl(threadGroup, scheduler);
|
||||
|
||||
|
|
|
@ -1612,8 +1612,6 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
|
|||
}
|
||||
}
|
||||
|
||||
SyncWithWallets(tx, NULL);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "timedata.h"
|
||||
#include "util.h"
|
||||
#include "utilmoneystr.h"
|
||||
#include "validationinterface.h"
|
||||
#include "version.h"
|
||||
|
||||
using namespace std;
|
||||
|
@ -103,6 +104,7 @@ bool CTxMemPool::addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry,
|
|||
LOCK(cs);
|
||||
mapTx.insert(entry);
|
||||
const CTransaction& tx = mapTx.find(hash)->GetTx();
|
||||
mapRecentlyAddedTx[tx.GetHash()] = &tx;
|
||||
for (unsigned int i = 0; i < tx.vin.size(); i++)
|
||||
mapNextTx[tx.vin[i].prevout] = CInPoint(&tx, i);
|
||||
BOOST_FOREACH(const JSDescription &joinsplit, tx.vJoinSplit) {
|
||||
|
@ -262,6 +264,7 @@ void CTxMemPool::remove(const CTransaction &origTx, std::list<CTransaction>& rem
|
|||
txToRemove.push_back(it->second.ptx->GetHash());
|
||||
}
|
||||
}
|
||||
mapRecentlyAddedTx.erase(hash);
|
||||
BOOST_FOREACH(const CTxIn& txin, tx.vin)
|
||||
mapNextTx.erase(txin.prevout);
|
||||
BOOST_FOREACH(const JSDescription& joinsplit, tx.vJoinSplit) {
|
||||
|
@ -724,6 +727,34 @@ bool CTxMemPool::nullifierExists(const uint256& nullifier, ShieldedType type) co
|
|||
}
|
||||
}
|
||||
|
||||
void CTxMemPool::NotifyRecentlyAdded()
|
||||
{
|
||||
std::vector<CTransaction> txs;
|
||||
{
|
||||
LOCK(cs);
|
||||
for (const auto& kv : mapRecentlyAddedTx) {
|
||||
txs.push_back(*(kv.second));
|
||||
}
|
||||
mapRecentlyAddedTx.clear();
|
||||
}
|
||||
|
||||
// A race condition can occur here between these SyncWithWallets calls, and
|
||||
// the ones triggered by block logic (in ConnectTip and DisconnectTip). It
|
||||
// is harmless because calling SyncWithWallets(_, NULL) does not alter the
|
||||
// wallet transaction's block information.
|
||||
for (auto tx : txs) {
|
||||
try {
|
||||
SyncWithWallets(tx, NULL);
|
||||
} catch (const boost::thread_interrupted&) {
|
||||
throw;
|
||||
} catch (const std::exception& e) {
|
||||
PrintExceptionContinue(&e, "CTxMemPool::NotifyRecentlyAdded()");
|
||||
} catch (...) {
|
||||
PrintExceptionContinue(NULL, "CTxMemPool::NotifyRecentlyAdded()");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CCoinsViewMemPool::CCoinsViewMemPool(CCoinsView *baseIn, CTxMemPool &mempoolIn) : CCoinsViewBacked(baseIn), mempool(mempoolIn) { }
|
||||
|
||||
bool CCoinsViewMemPool::GetNullifier(const uint256 &nf, ShieldedType type) const
|
||||
|
|
|
@ -133,6 +133,7 @@ private:
|
|||
uint64_t totalTxSize = 0; //!< sum of all mempool tx' byte sizes
|
||||
uint64_t cachedInnerUsage; //!< sum of dynamic memory usage of all the map elements (NOT the maps themselves)
|
||||
|
||||
std::map<uint256, const CTransaction*> mapRecentlyAddedTx;
|
||||
std::map<uint256, const CTransaction*> mapSproutNullifiers;
|
||||
std::map<uint256, const CTransaction*> mapSaplingNullifiers;
|
||||
|
||||
|
@ -217,6 +218,8 @@ public:
|
|||
|
||||
bool nullifierExists(const uint256& nullifier, ShieldedType type) const;
|
||||
|
||||
void NotifyRecentlyAdded();
|
||||
|
||||
unsigned long size()
|
||||
{
|
||||
LOCK(cs);
|
||||
|
|
|
@ -1659,6 +1659,13 @@ bool CWallet::UpdatedNoteData(const CWalletTx& wtxIn, CWalletTx& wtx)
|
|||
* 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.
|
||||
*
|
||||
* If pblock is null, this transaction has either recently entered the mempool from the
|
||||
* network, is re-entering the mempool after a block was disconnected, or is exiting the
|
||||
* mempool because it conflicts with another transaction. In all these cases, if there is
|
||||
* an existing wallet transaction, the wallet transaction's Merkle branch data is _not_
|
||||
* updated; instead, the transaction being in the mempool or conflicted is determined on
|
||||
* the fly in CMerkleTx::GetDepthInMainChain().
|
||||
*/
|
||||
bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue