Skip to content

Commit

Permalink
(Partial)Merge bitcoin#15473: bench: Benchmark MempoolToJSON
Browse files Browse the repository at this point in the history
  • Loading branch information
vijaydasmp committed Oct 22, 2021
1 parent 3eb87e7 commit ed87626
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 28 deletions.
5 changes: 4 additions & 1 deletion src/Makefile.bench.include
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ bench_bench_dash_SOURCES = \
bench/gcs_filter.cpp \
bench/merkle_root.cpp \
bench/mempool_eviction.cpp \
bench/rpc_mempool.cpp \
bench/nanobench.h \
bench/nanobench.cpp \
bench/util_time.cpp \
Expand All @@ -56,7 +57,9 @@ bench_bench_dash_LDADD = \
$(LIBLEVELDB_SSE42) \
$(LIBMEMENV) \
$(LIBSECP256K1) \
$(LIBUNIVALUE)
$(LIBUNIVALUE) \
$(EVENT_PTHREADS_LIBS) \
$(EVENT_LIBS)

if ENABLE_ZMQ
bench_bench_dash_LDADD += $(LIBBITCOIN_ZMQ) $(ZMQ_LIBS)
Expand Down
44 changes: 44 additions & 0 deletions src/bench/rpc_mempool.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright (c) 2011-2019 The Bitcoin Core developers
// Copyright (c) 2014-2021 The Dash Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <bench/bench.h>
#include <policy/policy.h>
#include <rpc/blockchain.h>
#include <txmempool.h>

#include <univalue.h>

#include <list>
#include <vector>

static void AddTx(const CTransactionRef& tx, const CAmount& fee, CTxMemPool& pool) EXCLUSIVE_LOCKS_REQUIRED(cs_main, pool.cs)
{
LockPoints lp;
pool.addUnchecked(CTxMemPoolEntry(tx, fee, /* time */ 0, /* height */ 1, /* spendsCoinbase */ false, /* sigOpCost */ 4, lp));
}

static void RpcMempool(benchmark::State& state)
{
CTxMemPool pool;
LOCK2(cs_main, pool.cs);

for (int i = 0; i < 1000; ++i) {
CMutableTransaction tx = CMutableTransaction();
tx.vin.resize(1);
tx.vin[0].scriptSig = CScript() << OP_1;
tx.vin[0].scriptWitness.stack.push_back({1});
tx.vout.resize(1);
tx.vout[0].scriptPubKey = CScript() << OP_1 << OP_EQUAL;
tx.vout[0].nValue = i;
const CTransactionRef tx_r{MakeTransactionRef(tx)};
AddTx(tx_r, /* fee */ i, pool);
}

while (state.KeepRunning()) {
(void)MempoolToJSON(pool, /*verbose*/ true);
}
}

BENCHMARK(RpcMempool);
4 changes: 2 additions & 2 deletions src/rest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ static bool rest_mempool_info(HTTPRequest* req, const std::string& strURIPart)

switch (rf) {
case RetFormat::JSON: {
UniValue mempoolInfoObject = mempoolInfoToJSON();
UniValue mempoolInfoObject = MempoolInfoToJSON(::mempool);

std::string strJSON = mempoolInfoObject.write() + "\n";
req->WriteHeader("Content-Type", "application/json");
Expand All @@ -317,7 +317,7 @@ static bool rest_mempool_contents(HTTPRequest* req, const std::string& strURIPar

switch (rf) {
case RetFormat::JSON: {
UniValue mempoolObject = mempoolToJSON(true);
UniValue mempoolObject = MempoolToJSON(::mempool, true);

std::string strJSON = mempoolObject.write() + "\n";
req->WriteHeader("Content-Type", "application/json");
Expand Down
36 changes: 16 additions & 20 deletions src/rpc/blockchain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -465,9 +465,9 @@ static std::string EntryDescriptionString()
" \"instantlock\" : true|false (boolean) True if this transaction was locked via InstantSend\n";
}

static void entryToJSON(UniValue &info, const CTxMemPoolEntry &e) EXCLUSIVE_LOCKS_REQUIRED(::mempool.cs)
static void entryToJSON(const CTxMemPool& pool, UniValue& info, const CTxMemPoolEntry& e) EXCLUSIVE_LOCKS_REQUIRED(pool.cs)
{
AssertLockHeld(mempool.cs);
AssertLockHeld(pool.cs);

UniValue fees(UniValue::VOBJ);
fees.pushKV("base", ValueFromAmount(e.GetFee()));
Expand Down Expand Up @@ -514,28 +514,24 @@ static void entryToJSON(UniValue &info, const CTxMemPoolEntry &e) EXCLUSIVE_LOCK
info.pushKV("instantlock", llmq::quorumInstantSendManager->IsLocked(tx.GetHash()));
}

UniValue mempoolToJSON(bool fVerbose)
UniValue MempoolToJSON(const CTxMemPool& pool, bool verbose)
{
if (fVerbose)
{
LOCK(mempool.cs);
if (verbose) {
LOCK(pool.cs);
UniValue o(UniValue::VOBJ);
for (const CTxMemPoolEntry& e : mempool.mapTx)
{
for (const CTxMemPoolEntry& e : pool.mapTx) {
const uint256& hash = e.GetTx().GetHash();
UniValue info(UniValue::VOBJ);
entryToJSON(info, e);
entryToJSON(pool, info, e);
// Mempool has unique entries so there is no advantage in using
// UniValue::pushKV, which checks if the key already exists in O(N).
// UniValue::__pushKV is used instead which currently is O(1).
o.__pushKV(hash.ToString(), info);
}
return o;
}
else
{
} else {
std::vector<uint256> vtxid;
mempool.queryHashes(vtxid);
pool.queryHashes(vtxid);

UniValue a(UniValue::VARR);
for (const uint256& hash : vtxid)
Expand Down Expand Up @@ -578,7 +574,7 @@ static UniValue getrawmempool(const JSONRPCRequest& request)
if (!request.params[0].isNull())
fVerbose = request.params[0].get_bool();

return mempoolToJSON(fVerbose);
return MempoolToJSON(::mempool, fVerbose);
}

static UniValue getmempoolancestors(const JSONRPCRequest& request)
Expand Down Expand Up @@ -643,7 +639,7 @@ static UniValue getmempoolancestors(const JSONRPCRequest& request)
const CTxMemPoolEntry &e = *ancestorIt;
const uint256& _hash = e.GetTx().GetHash();
UniValue info(UniValue::VOBJ);
entryToJSON(info, e);
entryToJSON(::mempool, info, e);
o.pushKV(_hash.ToString(), info);
}
return o;
Expand Down Expand Up @@ -712,7 +708,7 @@ static UniValue getmempooldescendants(const JSONRPCRequest& request)
const CTxMemPoolEntry &e = *descendantIt;
const uint256& _hash = e.GetTx().GetHash();
UniValue info(UniValue::VOBJ);
entryToJSON(info, e);
entryToJSON(::mempool, info, e);
o.pushKV(_hash.ToString(), info);
}
return o;
Expand Down Expand Up @@ -752,7 +748,7 @@ static UniValue getmempoolentry(const JSONRPCRequest& request)

const CTxMemPoolEntry &e = *it;
UniValue info(UniValue::VOBJ);
entryToJSON(info, e);
entryToJSON(::mempool, info, e);
return info;
}

Expand Down Expand Up @@ -1726,15 +1722,15 @@ static UniValue getchaintips(const JSONRPCRequest& request)
return res;
}

UniValue mempoolInfoToJSON()
UniValue MempoolInfoToJSON(const CTxMemPool& pool)
{
UniValue ret(UniValue::VOBJ);
ret.pushKV("size", (int64_t) mempool.size());
ret.pushKV("bytes", (int64_t) mempool.GetTotalTxSize());
ret.pushKV("usage", (int64_t) mempool.DynamicMemoryUsage());
size_t maxmempool = gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000;
ret.pushKV("maxmempool", (int64_t) maxmempool);
ret.pushKV("mempoolminfee", ValueFromAmount(std::max(mempool.GetMinFee(maxmempool), ::minRelayTxFee).GetFeePerK()));
ret.pushKV("mempoolminfee", ValueFromAmount(std::max(pool.GetMinFee(maxmempool), ::minRelayTxFee).GetFeePerK()));
ret.pushKV("minrelaytxfee", ValueFromAmount(::minRelayTxFee.GetFeePerK()));
ret.pushKV("instantsendlocks", (int64_t)llmq::quorumInstantSendManager->GetInstantSendLockCount());

Expand Down Expand Up @@ -1763,7 +1759,7 @@ static UniValue getmempoolinfo(const JSONRPCRequest& request)
+ HelpExampleRpc("getmempoolinfo", "")
);

return mempoolInfoToJSON();
return MempoolInfoToJSON(::mempool);
}

static UniValue preciousblock(const JSONRPCRequest& request)
Expand Down
5 changes: 3 additions & 2 deletions src/rpc/blockchain.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

class CBlock;
class CBlockIndex;
class CTxMemPool;
class UniValue;

static constexpr int NUM_GETBLOCKSTATS_PERCENTILES = 5;
Expand All @@ -30,10 +31,10 @@ void RPCNotifyBlockChange(bool ibd, const CBlockIndex *);
UniValue blockToJSON(const CBlock& block, const CBlockIndex* tip, const CBlockIndex* blockindex, bool txDetails = false);

/** Mempool information to JSON */
UniValue mempoolInfoToJSON();
UniValue MempoolInfoToJSON(const CTxMemPool& pool);

/** Mempool to JSON */
UniValue mempoolToJSON(bool fVerbose = false);
UniValue MempoolToJSON(const CTxMemPool& pool, bool verbose = false);

/** Block header to JSON */
UniValue blockheaderToJSON(const CBlockIndex* tip, const CBlockIndex* blockindex);
Expand Down
2 changes: 1 addition & 1 deletion src/txmempool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1183,7 +1183,7 @@ std::vector<CTxMemPool::indexed_transaction_set::const_iterator> CTxMemPool::Get
return iters;
}

void CTxMemPool::queryHashes(std::vector<uint256>& vtxid)
void CTxMemPool::queryHashes(std::vector<uint256>& vtxid) const
{
LOCK(cs);
auto iters = GetSortedDepthAndScore();
Expand Down
4 changes: 2 additions & 2 deletions src/txmempool.h
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ struct update_lock_points
const LockPoints& lp;
};

// extracts a transaction hash from CTxMempoolEntry or CTransactionRef
// extracts a transaction hash from CTxMemPoolEntry or CTransactionRef
struct mempoolentry_txid
{
typedef uint256 result_type;
Expand Down Expand Up @@ -629,7 +629,7 @@ class CTxMemPool
void clear();
void _clear() EXCLUSIVE_LOCKS_REQUIRED(cs); //lock free
bool CompareDepthAndScore(const uint256& hasha, const uint256& hashb);
void queryHashes(std::vector<uint256>& vtxid);
void queryHashes(std::vector<uint256>& vtxid) const;
bool isSpent(const COutPoint& outpoint) const;
unsigned int GetTransactionsUpdated() const;
void AddTransactionsUpdated(unsigned int n);
Expand Down

0 comments on commit ed87626

Please sign in to comment.