mirror of
https://github.com/dashpay/dash.git
synced 2024-12-25 20:12:57 +01:00
merge bitcoin#15473: bench: Benchmark MempoolToJSON
This commit is contained in:
parent
f1cd71785d
commit
544823b272
@ -34,6 +34,7 @@ bench_bench_dash_SOURCES = \
|
||||
bench/mempool_eviction.cpp \
|
||||
bench/nanobench.h \
|
||||
bench/nanobench.cpp \
|
||||
bench/rpc_mempool.cpp \
|
||||
bench/util_time.cpp \
|
||||
bench/base58.cpp \
|
||||
bench/bech32.cpp \
|
||||
@ -58,7 +59,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)
|
||||
|
42
src/bench/rpc_mempool.cpp
Normal file
42
src/bench/rpc_mempool.cpp
Normal file
@ -0,0 +1,42 @@
|
||||
// Copyright (c) 2011-2019 The Bitcoin 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::Bench& bench)
|
||||
{
|
||||
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.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);
|
||||
}
|
||||
|
||||
bench.minEpochIterations(40).run([&] {
|
||||
(void)MempoolToJSON(pool, /*verbose*/ true);
|
||||
});
|
||||
}
|
||||
|
||||
BENCHMARK(RpcMempool);
|
@ -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");
|
||||
@ -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");
|
||||
|
@ -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()));
|
||||
@ -491,7 +491,7 @@ static void entryToJSON(UniValue &info, const CTxMemPoolEntry &e) EXCLUSIVE_LOCK
|
||||
std::set<std::string> setDepends;
|
||||
for (const CTxIn& txin : tx.vin)
|
||||
{
|
||||
if (mempool.exists(txin.prevout.hash))
|
||||
if (pool.exists(txin.prevout.hash))
|
||||
setDepends.insert(txin.prevout.hash.ToString());
|
||||
}
|
||||
|
||||
@ -504,8 +504,8 @@ static void entryToJSON(UniValue &info, const CTxMemPoolEntry &e) EXCLUSIVE_LOCK
|
||||
info.pushKV("depends", depends);
|
||||
|
||||
UniValue spent(UniValue::VARR);
|
||||
const CTxMemPool::txiter &it = mempool.mapTx.find(tx.GetHash());
|
||||
const CTxMemPool::setEntries &setChildren = mempool.GetMemPoolChildren(it);
|
||||
const CTxMemPool::txiter& it = pool.mapTx.find(tx.GetHash());
|
||||
const CTxMemPool::setEntries& setChildren = pool.GetMemPoolChildren(it);
|
||||
for (CTxMemPool::txiter childiter : setChildren) {
|
||||
spent.push_back(childiter->GetTx().GetHash().ToString());
|
||||
}
|
||||
@ -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)
|
||||
@ -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)
|
||||
@ -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;
|
||||
@ -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;
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -1731,15 +1727,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());
|
||||
ret.pushKV("size", (int64_t)pool.size());
|
||||
ret.pushKV("bytes", (int64_t)pool.GetTotalTxSize());
|
||||
ret.pushKV("usage", (int64_t)pool.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());
|
||||
|
||||
@ -1768,7 +1764,7 @@ static UniValue getmempoolinfo(const JSONRPCRequest& request)
|
||||
+ HelpExampleRpc("getmempoolinfo", "")
|
||||
);
|
||||
|
||||
return mempoolInfoToJSON();
|
||||
return MempoolInfoToJSON(::mempool);
|
||||
}
|
||||
|
||||
static UniValue preciousblock(const JSONRPCRequest& request)
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
class CBlock;
|
||||
class CBlockIndex;
|
||||
class CTxMemPool;
|
||||
class UniValue;
|
||||
|
||||
static constexpr int NUM_GETBLOCKSTATS_PERCENTILES = 5;
|
||||
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -192,7 +192,7 @@ private:
|
||||
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;
|
||||
@ -629,7 +629,7 @@ public:
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user