Move mempool SyncWithWallets call into its own thread

This commit is contained in:
Jack Grigg 2019-09-19 21:30:05 +01:00
parent 7c8111f304
commit 3ff68c5052
No known key found for this signature in database
GPG Key ID: 9E8255172BBF9898
5 changed files with 61 additions and 2 deletions

View File

@ -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);

View File

@ -1612,8 +1612,6 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
}
}
SyncWithWallets(tx, NULL);
return true;
}

View File

@ -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

View File

@ -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);

View File

@ -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)
{