Enable RPC tests to wait on mempool notifications

This commit is contained in:
Jack Grigg 2019-09-20 21:41:49 +01:00
parent 3ff68c5052
commit 9d8322a341
No known key found for this signature in database
GPG Key ID: 9E8255172BBF9898
4 changed files with 33 additions and 1 deletions

View File

@ -57,7 +57,7 @@ def sync_blocks(rpc_connections, wait=1):
def sync_mempools(rpc_connections, wait=1): def sync_mempools(rpc_connections, wait=1):
""" """
Wait until everybody has the same transactions in their memory Wait until everybody has the same transactions in their memory
pools pools, and has notified all internal listeners of them
""" """
while True: while True:
pool = set(rpc_connections[0].getrawmempool()) pool = set(rpc_connections[0].getrawmempool())
@ -69,6 +69,14 @@ def sync_mempools(rpc_connections, wait=1):
break break
time.sleep(wait) time.sleep(wait)
# Now that the mempools are in sync, wait for the internal
# notifications to finish
while True:
notified = [ x.getmempoolinfo()['fullyNotified'] for x in rpc_connections ]
if notified == [ True ] * len(notified):
break
time.sleep(wait)
bitcoind_processes = {} bitcoind_processes = {}
def initialize_datadir(dirname, n): def initialize_datadir(dirname, n):

View File

@ -1185,6 +1185,10 @@ UniValue mempoolInfoToJSON()
ret.push_back(Pair("bytes", (int64_t) mempool.GetTotalTxSize())); ret.push_back(Pair("bytes", (int64_t) mempool.GetTotalTxSize()));
ret.push_back(Pair("usage", (int64_t) mempool.DynamicMemoryUsage())); ret.push_back(Pair("usage", (int64_t) mempool.DynamicMemoryUsage()));
if (Params().NetworkIDString() == "regtest") {
ret.push_back(Pair("fullyNotified", mempool.IsFullyNotified()));
}
return ret; return ret;
} }

View File

@ -105,6 +105,7 @@ bool CTxMemPool::addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry,
mapTx.insert(entry); mapTx.insert(entry);
const CTransaction& tx = mapTx.find(hash)->GetTx(); const CTransaction& tx = mapTx.find(hash)->GetTx();
mapRecentlyAddedTx[tx.GetHash()] = &tx; mapRecentlyAddedTx[tx.GetHash()] = &tx;
nRecentlyAddedSequence += 1;
for (unsigned int i = 0; i < tx.vin.size(); i++) for (unsigned int i = 0; i < tx.vin.size(); i++)
mapNextTx[tx.vin[i].prevout] = CInPoint(&tx, i); mapNextTx[tx.vin[i].prevout] = CInPoint(&tx, i);
BOOST_FOREACH(const JSDescription &joinsplit, tx.vJoinSplit) { BOOST_FOREACH(const JSDescription &joinsplit, tx.vJoinSplit) {
@ -729,9 +730,11 @@ bool CTxMemPool::nullifierExists(const uint256& nullifier, ShieldedType type) co
void CTxMemPool::NotifyRecentlyAdded() void CTxMemPool::NotifyRecentlyAdded()
{ {
uint64_t recentlyAddedSequence;
std::vector<CTransaction> txs; std::vector<CTransaction> txs;
{ {
LOCK(cs); LOCK(cs);
recentlyAddedSequence = nRecentlyAddedSequence;
for (const auto& kv : mapRecentlyAddedTx) { for (const auto& kv : mapRecentlyAddedTx) {
txs.push_back(*(kv.second)); txs.push_back(*(kv.second));
} }
@ -753,6 +756,19 @@ void CTxMemPool::NotifyRecentlyAdded()
PrintExceptionContinue(NULL, "CTxMemPool::NotifyRecentlyAdded()"); PrintExceptionContinue(NULL, "CTxMemPool::NotifyRecentlyAdded()");
} }
} }
// Update the notified sequence number. We only need this in regtest mode,
// and should not lock on cs after calling SyncWithWallets otherwise.
if (Params().NetworkIDString() == "regtest") {
LOCK(cs);
nNotifiedSequence = recentlyAddedSequence;
}
}
bool CTxMemPool::IsFullyNotified() {
assert(Params().NetworkIDString() == "regtest");
LOCK(cs);
return nRecentlyAddedSequence == nNotifiedSequence;
} }
CCoinsViewMemPool::CCoinsViewMemPool(CCoinsView *baseIn, CTxMemPool &mempoolIn) : CCoinsViewBacked(baseIn), mempool(mempoolIn) { } CCoinsViewMemPool::CCoinsViewMemPool(CCoinsView *baseIn, CTxMemPool &mempoolIn) : CCoinsViewBacked(baseIn), mempool(mempoolIn) { }

View File

@ -134,6 +134,9 @@ private:
uint64_t cachedInnerUsage; //!< sum of dynamic memory usage of all the map elements (NOT the maps themselves) 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*> mapRecentlyAddedTx;
uint64_t nRecentlyAddedSequence = 0;
uint64_t nNotifiedSequence = 0;
std::map<uint256, const CTransaction*> mapSproutNullifiers; std::map<uint256, const CTransaction*> mapSproutNullifiers;
std::map<uint256, const CTransaction*> mapSaplingNullifiers; std::map<uint256, const CTransaction*> mapSaplingNullifiers;
@ -219,6 +222,7 @@ public:
bool nullifierExists(const uint256& nullifier, ShieldedType type) const; bool nullifierExists(const uint256& nullifier, ShieldedType type) const;
void NotifyRecentlyAdded(); void NotifyRecentlyAdded();
bool IsFullyNotified();
unsigned long size() unsigned long size()
{ {