diff options
Diffstat (limited to 'src/rpc/blockchain.cpp')
-rw-r--r-- | src/rpc/blockchain.cpp | 330 |
1 files changed, 176 insertions, 154 deletions
diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index b7895b86f7..8007cebc37 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2016 The Bitcoin Core developers +// Copyright (c) 2009-2017 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -24,6 +24,7 @@ #include <util.h> #include <utilstrencodings.h> #include <hash.h> +#include <validationinterface.h> #include <warnings.h> #include <stdint.h> @@ -47,18 +48,20 @@ static CUpdatedBlock latestblock; extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry); -double GetDifficulty(const CBlockIndex* blockindex) +/* Calculate the difficulty for a given block index, + * or the block index of the given chain. + */ +double GetDifficulty(const CChain& chain, const CBlockIndex* blockindex) { if (blockindex == nullptr) { - if (chainActive.Tip() == nullptr) + if (chain.Tip() == nullptr) return 1.0; else - blockindex = chainActive.Tip(); + blockindex = chain.Tip(); } int nShift = (blockindex->nBits >> 24) & 0xff; - double dDiff = (double)0x0000ffff / (double)(blockindex->nBits & 0x00ffffff); @@ -76,32 +79,37 @@ double GetDifficulty(const CBlockIndex* blockindex) return dDiff; } +double GetDifficulty(const CBlockIndex* blockindex) +{ + return GetDifficulty(chainActive, blockindex); +} + UniValue blockheaderToJSON(const CBlockIndex* blockindex) { AssertLockHeld(cs_main); UniValue result(UniValue::VOBJ); - result.push_back(Pair("hash", blockindex->GetBlockHash().GetHex())); + result.pushKV("hash", blockindex->GetBlockHash().GetHex()); int confirmations = -1; // Only report confirmations if the block is on the main chain if (chainActive.Contains(blockindex)) confirmations = chainActive.Height() - blockindex->nHeight + 1; - result.push_back(Pair("confirmations", confirmations)); - result.push_back(Pair("height", blockindex->nHeight)); - result.push_back(Pair("version", blockindex->nVersion)); - result.push_back(Pair("versionHex", strprintf("%08x", blockindex->nVersion))); - result.push_back(Pair("merkleroot", blockindex->hashMerkleRoot.GetHex())); - result.push_back(Pair("time", (int64_t)blockindex->nTime)); - result.push_back(Pair("mediantime", (int64_t)blockindex->GetMedianTimePast())); - result.push_back(Pair("nonce", (uint64_t)blockindex->nNonce)); - result.push_back(Pair("bits", strprintf("%08x", blockindex->nBits))); - result.push_back(Pair("difficulty", GetDifficulty(blockindex))); - result.push_back(Pair("chainwork", blockindex->nChainWork.GetHex())); + result.pushKV("confirmations", confirmations); + result.pushKV("height", blockindex->nHeight); + result.pushKV("version", blockindex->nVersion); + result.pushKV("versionHex", strprintf("%08x", blockindex->nVersion)); + result.pushKV("merkleroot", blockindex->hashMerkleRoot.GetHex()); + result.pushKV("time", (int64_t)blockindex->nTime); + result.pushKV("mediantime", (int64_t)blockindex->GetMedianTimePast()); + result.pushKV("nonce", (uint64_t)blockindex->nNonce); + result.pushKV("bits", strprintf("%08x", blockindex->nBits)); + result.pushKV("difficulty", GetDifficulty(blockindex)); + result.pushKV("chainwork", blockindex->nChainWork.GetHex()); if (blockindex->pprev) - result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex())); + result.pushKV("previousblockhash", blockindex->pprev->GetBlockHash().GetHex()); CBlockIndex *pnext = chainActive.Next(blockindex); if (pnext) - result.push_back(Pair("nextblockhash", pnext->GetBlockHash().GetHex())); + result.pushKV("nextblockhash", pnext->GetBlockHash().GetHex()); return result; } @@ -109,19 +117,19 @@ UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool tx { AssertLockHeld(cs_main); UniValue result(UniValue::VOBJ); - result.push_back(Pair("hash", blockindex->GetBlockHash().GetHex())); + result.pushKV("hash", blockindex->GetBlockHash().GetHex()); int confirmations = -1; // Only report confirmations if the block is on the main chain if (chainActive.Contains(blockindex)) confirmations = chainActive.Height() - blockindex->nHeight + 1; - result.push_back(Pair("confirmations", confirmations)); - result.push_back(Pair("strippedsize", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS))); - result.push_back(Pair("size", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION))); - result.push_back(Pair("weight", (int)::GetBlockWeight(block))); - result.push_back(Pair("height", blockindex->nHeight)); - result.push_back(Pair("version", block.nVersion)); - result.push_back(Pair("versionHex", strprintf("%08x", block.nVersion))); - result.push_back(Pair("merkleroot", block.hashMerkleRoot.GetHex())); + result.pushKV("confirmations", confirmations); + result.pushKV("strippedsize", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS)); + result.pushKV("size", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION)); + result.pushKV("weight", (int)::GetBlockWeight(block)); + result.pushKV("height", blockindex->nHeight); + result.pushKV("version", block.nVersion); + result.pushKV("versionHex", strprintf("%08x", block.nVersion)); + result.pushKV("merkleroot", block.hashMerkleRoot.GetHex()); UniValue txs(UniValue::VARR); for(const auto& tx : block.vtx) { @@ -134,19 +142,19 @@ UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool tx else txs.push_back(tx->GetHash().GetHex()); } - result.push_back(Pair("tx", txs)); - result.push_back(Pair("time", block.GetBlockTime())); - result.push_back(Pair("mediantime", (int64_t)blockindex->GetMedianTimePast())); - result.push_back(Pair("nonce", (uint64_t)block.nNonce)); - result.push_back(Pair("bits", strprintf("%08x", block.nBits))); - result.push_back(Pair("difficulty", GetDifficulty(blockindex))); - result.push_back(Pair("chainwork", blockindex->nChainWork.GetHex())); + result.pushKV("tx", txs); + result.pushKV("time", block.GetBlockTime()); + result.pushKV("mediantime", (int64_t)blockindex->GetMedianTimePast()); + result.pushKV("nonce", (uint64_t)block.nNonce); + result.pushKV("bits", strprintf("%08x", block.nBits)); + result.pushKV("difficulty", GetDifficulty(blockindex)); + result.pushKV("chainwork", blockindex->nChainWork.GetHex()); if (blockindex->pprev) - result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex())); + result.pushKV("previousblockhash", blockindex->pprev->GetBlockHash().GetHex()); CBlockIndex *pnext = chainActive.Next(blockindex); if (pnext) - result.push_back(Pair("nextblockhash", pnext->GetBlockHash().GetHex())); + result.pushKV("nextblockhash", pnext->GetBlockHash().GetHex()); return result; } @@ -227,8 +235,8 @@ UniValue waitfornewblock(const JSONRPCRequest& request) block = latestblock; } UniValue ret(UniValue::VOBJ); - ret.push_back(Pair("hash", block.hash.GetHex())); - ret.push_back(Pair("height", block.height)); + ret.pushKV("hash", block.hash.GetHex()); + ret.pushKV("height", block.height); return ret; } @@ -269,8 +277,8 @@ UniValue waitforblock(const JSONRPCRequest& request) } UniValue ret(UniValue::VOBJ); - ret.push_back(Pair("hash", block.hash.GetHex())); - ret.push_back(Pair("height", block.height)); + ret.pushKV("hash", block.hash.GetHex()); + ret.pushKV("height", block.height); return ret; } @@ -311,11 +319,26 @@ UniValue waitforblockheight(const JSONRPCRequest& request) block = latestblock; } UniValue ret(UniValue::VOBJ); - ret.push_back(Pair("hash", block.hash.GetHex())); - ret.push_back(Pair("height", block.height)); + ret.pushKV("hash", block.hash.GetHex()); + ret.pushKV("height", block.height); return ret; } +UniValue syncwithvalidationinterfacequeue(const JSONRPCRequest& request) +{ + if (request.fHelp || request.params.size() > 0) { + throw std::runtime_error( + "syncwithvalidationinterfacequeue\n" + "\nWaits for the validation interface queue to catch up on everything that was there when we entered this function.\n" + "\nExamples:\n" + + HelpExampleCli("syncwithvalidationinterfacequeue","") + + HelpExampleRpc("syncwithvalidationinterfacequeue","") + ); + } + SyncWithValidationInterfaceQueue(); + return NullUniValue; +} + UniValue getdifficulty(const JSONRPCRequest& request) { if (request.fHelp || request.params.size() != 0) @@ -356,18 +379,18 @@ void entryToJSON(UniValue &info, const CTxMemPoolEntry &e) { AssertLockHeld(mempool.cs); - info.push_back(Pair("size", (int)e.GetTxSize())); - info.push_back(Pair("fee", ValueFromAmount(e.GetFee()))); - info.push_back(Pair("modifiedfee", ValueFromAmount(e.GetModifiedFee()))); - info.push_back(Pair("time", e.GetTime())); - info.push_back(Pair("height", (int)e.GetHeight())); - info.push_back(Pair("descendantcount", e.GetCountWithDescendants())); - info.push_back(Pair("descendantsize", e.GetSizeWithDescendants())); - info.push_back(Pair("descendantfees", e.GetModFeesWithDescendants())); - info.push_back(Pair("ancestorcount", e.GetCountWithAncestors())); - info.push_back(Pair("ancestorsize", e.GetSizeWithAncestors())); - info.push_back(Pair("ancestorfees", e.GetModFeesWithAncestors())); - info.push_back(Pair("wtxid", mempool.vTxHashes[e.vTxHashesIdx].first.ToString())); + info.pushKV("size", (int)e.GetTxSize()); + info.pushKV("fee", ValueFromAmount(e.GetFee())); + info.pushKV("modifiedfee", ValueFromAmount(e.GetModifiedFee())); + info.pushKV("time", e.GetTime()); + info.pushKV("height", (int)e.GetHeight()); + info.pushKV("descendantcount", e.GetCountWithDescendants()); + info.pushKV("descendantsize", e.GetSizeWithDescendants()); + info.pushKV("descendantfees", e.GetModFeesWithDescendants()); + info.pushKV("ancestorcount", e.GetCountWithAncestors()); + info.pushKV("ancestorsize", e.GetSizeWithAncestors()); + info.pushKV("ancestorfees", e.GetModFeesWithAncestors()); + info.pushKV("wtxid", mempool.vTxHashes[e.vTxHashesIdx].first.ToString()); const CTransaction& tx = e.GetTx(); std::set<std::string> setDepends; for (const CTxIn& txin : tx.vin) @@ -382,7 +405,7 @@ void entryToJSON(UniValue &info, const CTxMemPoolEntry &e) depends.push_back(dep); } - info.push_back(Pair("depends", depends)); + info.pushKV("depends", depends); } UniValue mempoolToJSON(bool fVerbose) @@ -396,7 +419,7 @@ UniValue mempoolToJSON(bool fVerbose) const uint256& hash = e.GetTx().GetHash(); UniValue info(UniValue::VOBJ); entryToJSON(info, e); - o.push_back(Pair(hash.ToString(), info)); + o.pushKV(hash.ToString(), info); } return o; } @@ -503,7 +526,7 @@ UniValue getmempoolancestors(const JSONRPCRequest& request) const uint256& _hash = e.GetTx().GetHash(); UniValue info(UniValue::VOBJ); entryToJSON(info, e); - o.push_back(Pair(_hash.ToString(), info)); + o.pushKV(_hash.ToString(), info); } return o; } @@ -567,7 +590,7 @@ UniValue getmempooldescendants(const JSONRPCRequest& request) const uint256& _hash = e.GetTx().GetHash(); UniValue info(UniValue::VOBJ); entryToJSON(info, e); - o.push_back(Pair(_hash.ToString(), info)); + o.pushKV(_hash.ToString(), info); } return o; } @@ -929,14 +952,14 @@ UniValue gettxoutsetinfo(const JSONRPCRequest& request) CCoinsStats stats; FlushStateToDisk(); if (GetUTXOStats(pcoinsdbview.get(), stats)) { - ret.push_back(Pair("height", (int64_t)stats.nHeight)); - ret.push_back(Pair("bestblock", stats.hashBlock.GetHex())); - ret.push_back(Pair("transactions", (int64_t)stats.nTransactions)); - ret.push_back(Pair("txouts", (int64_t)stats.nTransactionOutputs)); - ret.push_back(Pair("bogosize", (int64_t)stats.nBogoSize)); - ret.push_back(Pair("hash_serialized_2", stats.hashSerialized.GetHex())); - ret.push_back(Pair("disk_size", stats.nDiskSize)); - ret.push_back(Pair("total_amount", ValueFromAmount(stats.nTotalAmount))); + ret.pushKV("height", (int64_t)stats.nHeight); + ret.pushKV("bestblock", stats.hashBlock.GetHex()); + ret.pushKV("transactions", (int64_t)stats.nTransactions); + ret.pushKV("txouts", (int64_t)stats.nTransactionOutputs); + ret.pushKV("bogosize", (int64_t)stats.nBogoSize); + ret.pushKV("hash_serialized_2", stats.hashSerialized.GetHex()); + ret.pushKV("disk_size", stats.nDiskSize); + ret.pushKV("total_amount", ValueFromAmount(stats.nTotalAmount)); } else { throw JSONRPCError(RPC_INTERNAL_ERROR, "Unable to read UTXO set"); } @@ -1008,17 +1031,17 @@ UniValue gettxout(const JSONRPCRequest& request) BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock()); CBlockIndex *pindex = it->second; - ret.push_back(Pair("bestblock", pindex->GetBlockHash().GetHex())); + ret.pushKV("bestblock", pindex->GetBlockHash().GetHex()); if (coin.nHeight == MEMPOOL_HEIGHT) { - ret.push_back(Pair("confirmations", 0)); + ret.pushKV("confirmations", 0); } else { - ret.push_back(Pair("confirmations", (int64_t)(pindex->nHeight - coin.nHeight + 1))); + ret.pushKV("confirmations", (int64_t)(pindex->nHeight - coin.nHeight + 1)); } - ret.push_back(Pair("value", ValueFromAmount(coin.out.nValue))); + ret.pushKV("value", ValueFromAmount(coin.out.nValue)); UniValue o(UniValue::VOBJ); ScriptPubKeyToUniv(coin.out.scriptPubKey, o, true); - ret.push_back(Pair("scriptPubKey", o)); - ret.push_back(Pair("coinbase", (bool)coin.fCoinBase)); + ret.pushKV("scriptPubKey", o); + ret.pushKV("coinbase", (bool)coin.fCoinBase); return ret; } @@ -1068,16 +1091,16 @@ static UniValue SoftForkMajorityDesc(int version, CBlockIndex* pindex, const Con activated = pindex->nHeight >= consensusParams.BIP65Height; break; } - rv.push_back(Pair("status", activated)); + rv.pushKV("status", activated); return rv; } static UniValue SoftForkDesc(const std::string &name, int version, CBlockIndex* pindex, const Consensus::Params& consensusParams) { UniValue rv(UniValue::VOBJ); - rv.push_back(Pair("id", name)); - rv.push_back(Pair("version", version)); - rv.push_back(Pair("reject", SoftForkMajorityDesc(version, pindex, consensusParams))); + rv.pushKV("id", name); + rv.pushKV("version", version); + rv.pushKV("reject", SoftForkMajorityDesc(version, pindex, consensusParams)); return rv; } @@ -1086,29 +1109,29 @@ static UniValue BIP9SoftForkDesc(const Consensus::Params& consensusParams, Conse UniValue rv(UniValue::VOBJ); const ThresholdState thresholdState = VersionBitsTipState(consensusParams, id); switch (thresholdState) { - case THRESHOLD_DEFINED: rv.push_back(Pair("status", "defined")); break; - case THRESHOLD_STARTED: rv.push_back(Pair("status", "started")); break; - case THRESHOLD_LOCKED_IN: rv.push_back(Pair("status", "locked_in")); break; - case THRESHOLD_ACTIVE: rv.push_back(Pair("status", "active")); break; - case THRESHOLD_FAILED: rv.push_back(Pair("status", "failed")); break; + case THRESHOLD_DEFINED: rv.pushKV("status", "defined"); break; + case THRESHOLD_STARTED: rv.pushKV("status", "started"); break; + case THRESHOLD_LOCKED_IN: rv.pushKV("status", "locked_in"); break; + case THRESHOLD_ACTIVE: rv.pushKV("status", "active"); break; + case THRESHOLD_FAILED: rv.pushKV("status", "failed"); break; } if (THRESHOLD_STARTED == thresholdState) { - rv.push_back(Pair("bit", consensusParams.vDeployments[id].bit)); + rv.pushKV("bit", consensusParams.vDeployments[id].bit); } - rv.push_back(Pair("startTime", consensusParams.vDeployments[id].nStartTime)); - rv.push_back(Pair("timeout", consensusParams.vDeployments[id].nTimeout)); - rv.push_back(Pair("since", VersionBitsTipStateSinceHeight(consensusParams, id))); + rv.pushKV("startTime", consensusParams.vDeployments[id].nStartTime); + rv.pushKV("timeout", consensusParams.vDeployments[id].nTimeout); + rv.pushKV("since", VersionBitsTipStateSinceHeight(consensusParams, id)); if (THRESHOLD_STARTED == thresholdState) { UniValue statsUV(UniValue::VOBJ); BIP9Stats statsStruct = VersionBitsTipStatistics(consensusParams, id); - statsUV.push_back(Pair("period", statsStruct.period)); - statsUV.push_back(Pair("threshold", statsStruct.threshold)); - statsUV.push_back(Pair("elapsed", statsStruct.elapsed)); - statsUV.push_back(Pair("count", statsStruct.count)); - statsUV.push_back(Pair("possible", statsStruct.possible)); - rv.push_back(Pair("statistics", statsUV)); + statsUV.pushKV("period", statsStruct.period); + statsUV.pushKV("threshold", statsStruct.threshold); + statsUV.pushKV("elapsed", statsStruct.elapsed); + statsUV.pushKV("count", statsStruct.count); + statsUV.pushKV("possible", statsStruct.possible); + rv.pushKV("statistics", statsUV); } return rv; } @@ -1119,7 +1142,7 @@ void BIP9SoftForkDescPushBack(UniValue& bip9_softforks, const Consensus::Params& // A timeout value of 0 guarantees a softfork will never be activated. // This is used when softfork codes are merged without specifying the deployment schedule. if (consensusParams.vDeployments[id].nTimeout > 0) - bip9_softforks.push_back(Pair(VersionBitsDeploymentInfo[id].name, BIP9SoftForkDesc(consensusParams, id))); + bip9_softforks.pushKV(VersionBitsDeploymentInfo[id].name, BIP9SoftForkDesc(consensusParams, id)); } UniValue getblockchaininfo(const JSONRPCRequest& request) @@ -1179,17 +1202,17 @@ UniValue getblockchaininfo(const JSONRPCRequest& request) LOCK(cs_main); UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("chain", Params().NetworkIDString())); - obj.push_back(Pair("blocks", (int)chainActive.Height())); - obj.push_back(Pair("headers", pindexBestHeader ? pindexBestHeader->nHeight : -1)); - obj.push_back(Pair("bestblockhash", chainActive.Tip()->GetBlockHash().GetHex())); - obj.push_back(Pair("difficulty", (double)GetDifficulty())); - obj.push_back(Pair("mediantime", (int64_t)chainActive.Tip()->GetMedianTimePast())); - obj.push_back(Pair("verificationprogress", GuessVerificationProgress(Params().TxData(), chainActive.Tip()))); - obj.push_back(Pair("initialblockdownload", IsInitialBlockDownload())); - obj.push_back(Pair("chainwork", chainActive.Tip()->nChainWork.GetHex())); - obj.push_back(Pair("size_on_disk", CalculateCurrentUsage())); - obj.push_back(Pair("pruned", fPruneMode)); + obj.pushKV("chain", Params().NetworkIDString()); + obj.pushKV("blocks", (int)chainActive.Height()); + obj.pushKV("headers", pindexBestHeader ? pindexBestHeader->nHeight : -1); + obj.pushKV("bestblockhash", chainActive.Tip()->GetBlockHash().GetHex()); + obj.pushKV("difficulty", (double)GetDifficulty()); + obj.pushKV("mediantime", (int64_t)chainActive.Tip()->GetMedianTimePast()); + obj.pushKV("verificationprogress", GuessVerificationProgress(Params().TxData(), chainActive.Tip())); + obj.pushKV("initialblockdownload", IsInitialBlockDownload()); + obj.pushKV("chainwork", chainActive.Tip()->nChainWork.GetHex()); + obj.pushKV("size_on_disk", CalculateCurrentUsage()); + obj.pushKV("pruned", fPruneMode); if (fPruneMode) { CBlockIndex* block = chainActive.Tip(); assert(block); @@ -1197,13 +1220,13 @@ UniValue getblockchaininfo(const JSONRPCRequest& request) block = block->pprev; } - obj.push_back(Pair("pruneheight", block->nHeight)); + obj.pushKV("pruneheight", block->nHeight); // if 0, execution bypasses the whole if block. bool automatic_pruning = (gArgs.GetArg("-prune", 0) != 1); - obj.push_back(Pair("automatic_pruning", automatic_pruning)); + obj.pushKV("automatic_pruning", automatic_pruning); if (automatic_pruning) { - obj.push_back(Pair("prune_target_size", nPruneTarget)); + obj.pushKV("prune_target_size", nPruneTarget); } } @@ -1217,10 +1240,10 @@ UniValue getblockchaininfo(const JSONRPCRequest& request) for (int pos = Consensus::DEPLOYMENT_CSV; pos != Consensus::MAX_VERSION_BITS_DEPLOYMENTS; ++pos) { BIP9SoftForkDescPushBack(bip9_softforks, consensusParams, static_cast<Consensus::DeploymentPos>(pos)); } - obj.push_back(Pair("softforks", softforks)); - obj.push_back(Pair("bip9_softforks", bip9_softforks)); + obj.pushKV("softforks", softforks); + obj.pushKV("bip9_softforks", bip9_softforks); - obj.push_back(Pair("warnings", GetWarnings("statusbar"))); + obj.pushKV("warnings", GetWarnings("statusbar")); return obj; } @@ -1308,11 +1331,11 @@ UniValue getchaintips(const JSONRPCRequest& request) for (const CBlockIndex* block : setTips) { UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("height", block->nHeight)); - obj.push_back(Pair("hash", block->phashBlock->GetHex())); + obj.pushKV("height", block->nHeight); + obj.pushKV("hash", block->phashBlock->GetHex()); const int branchLen = block->nHeight - chainActive.FindFork(block)->nHeight; - obj.push_back(Pair("branchlen", branchLen)); + obj.pushKV("branchlen", branchLen); std::string status; if (chainActive.Contains(block)) { @@ -1334,7 +1357,7 @@ UniValue getchaintips(const JSONRPCRequest& request) // No clue. status = "unknown"; } - obj.push_back(Pair("status", status)); + obj.pushKV("status", status); res.push_back(obj); } @@ -1345,12 +1368,13 @@ UniValue getchaintips(const JSONRPCRequest& request) UniValue mempoolInfoToJSON() { UniValue ret(UniValue::VOBJ); - ret.push_back(Pair("size", (int64_t) mempool.size())); - ret.push_back(Pair("bytes", (int64_t) mempool.GetTotalTxSize())); - ret.push_back(Pair("usage", (int64_t) mempool.DynamicMemoryUsage())); + 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.push_back(Pair("maxmempool", (int64_t) maxmempool)); - ret.push_back(Pair("mempoolminfee", ValueFromAmount(mempool.GetMinFee(maxmempool).GetFeePerK()))); + ret.pushKV("maxmempool", (int64_t) maxmempool); + ret.pushKV("mempoolminfee", ValueFromAmount(std::max(mempool.GetMinFee(maxmempool), ::minRelayTxFee).GetFeePerK())); + ret.pushKV("minrelaytxfee", ValueFromAmount(::minRelayTxFee.GetFeePerK())); return ret; } @@ -1367,7 +1391,8 @@ UniValue getmempoolinfo(const JSONRPCRequest& request) " \"bytes\": xxxxx, (numeric) Sum of all virtual transaction sizes as defined in BIP 141. Differs from actual serialized size because witness data is discounted\n" " \"usage\": xxxxx, (numeric) Total memory usage for the mempool\n" " \"maxmempool\": xxxxx, (numeric) Maximum memory usage for the mempool\n" - " \"mempoolminfee\": xxxxx (numeric) Minimum fee rate in " + CURRENCY_UNIT + "/kB for tx to be accepted\n" + " \"mempoolminfee\": xxxxx (numeric) Minimum fee rate in " + CURRENCY_UNIT + "/kB for tx to be accepted. Is the maximum of minrelaytxfee and minimum mempool fee\n" + " \"minrelaytxfee\": xxxxx (numeric) Current minimum relay fee for transactions\n" "}\n" "\nExamples:\n" + HelpExampleCli("getmempoolinfo", "") @@ -1409,7 +1434,7 @@ UniValue preciousblock(const JSONRPCRequest& request) PreciousBlock(state, Params(), pblockindex); if (!state.IsValid()) { - throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason()); + throw JSONRPCError(RPC_DATABASE_ERROR, FormatStateMessage(state)); } return NullUniValue; @@ -1447,7 +1472,7 @@ UniValue invalidateblock(const JSONRPCRequest& request) } if (!state.IsValid()) { - throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason()); + throw JSONRPCError(RPC_DATABASE_ERROR, FormatStateMessage(state)); } return NullUniValue; @@ -1484,7 +1509,7 @@ UniValue reconsiderblock(const JSONRPCRequest& request) ActivateBestChain(state, Params()); if (!state.IsValid()) { - throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason()); + throw JSONRPCError(RPC_DATABASE_ERROR, FormatStateMessage(state)); } return NullUniValue; @@ -1501,12 +1526,13 @@ UniValue getchaintxstats(const JSONRPCRequest& request) "2. \"blockhash\" (string, optional) The hash of the block that ends the window.\n" "\nResult:\n" "{\n" - " \"time\": xxxxx, (numeric) The timestamp for the final block in the window in UNIX format.\n" - " \"txcount\": xxxxx, (numeric) The total number of transactions in the chain up to that point.\n" - " \"window_block_count\": xxxxx, (numeric) Size of the window in number of blocks.\n" - " \"window_tx_count\": xxxxx, (numeric) The number of transactions in the window. Only returned if \"window_block_count\" is > 0.\n" - " \"window_interval\": xxxxx, (numeric) The elapsed time in the window in seconds. Only returned if \"window_block_count\" is > 0.\n" - " \"txrate\": x.xx, (numeric) The average rate of transactions per second in the window. Only returned if \"window_interval\" is > 0.\n" + " \"time\": xxxxx, (numeric) The timestamp for the final block in the window in UNIX format.\n" + " \"txcount\": xxxxx, (numeric) The total number of transactions in the chain up to that point.\n" + " \"window_final_block_hash\": \"...\", (string) The hash of the final block in the window.\n" + " \"window_block_count\": xxxxx, (numeric) Size of the window in number of blocks.\n" + " \"window_tx_count\": xxxxx, (numeric) The number of transactions in the window. Only returned if \"window_block_count\" is > 0.\n" + " \"window_interval\": xxxxx, (numeric) The elapsed time in the window in seconds. Only returned if \"window_block_count\" is > 0.\n" + " \"txrate\": x.xx, (numeric) The average rate of transactions per second in the window. Only returned if \"window_interval\" is > 0.\n" "}\n" "\nExamples:\n" + HelpExampleCli("getchaintxstats", "") @@ -1516,28 +1542,22 @@ UniValue getchaintxstats(const JSONRPCRequest& request) const CBlockIndex* pindex; int blockcount = 30 * 24 * 60 * 60 / Params().GetConsensus().nPowTargetSpacing; // By default: 1 month - bool havehash = !request.params[1].isNull(); - uint256 hash; - if (havehash) { - hash = uint256S(request.params[1].get_str()); - } - - { + if (request.params[1].isNull()) { LOCK(cs_main); - if (havehash) { - auto it = mapBlockIndex.find(hash); - if (it == mapBlockIndex.end()) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); - } - pindex = it->second; - if (!chainActive.Contains(pindex)) { - throw JSONRPCError(RPC_INVALID_PARAMETER, "Block is not in main chain"); - } - } else { - pindex = chainActive.Tip(); + pindex = chainActive.Tip(); + } else { + uint256 hash = uint256S(request.params[1].get_str()); + LOCK(cs_main); + auto it = mapBlockIndex.find(hash); + if (it == mapBlockIndex.end()) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); + } + pindex = it->second; + if (!chainActive.Contains(pindex)) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Block is not in main chain"); } } - + assert(pindex != nullptr); if (request.params[0].isNull()) { @@ -1555,14 +1575,15 @@ UniValue getchaintxstats(const JSONRPCRequest& request) int nTxDiff = pindex->nChainTx - pindexPast->nChainTx; UniValue ret(UniValue::VOBJ); - ret.push_back(Pair("time", (int64_t)pindex->nTime)); - ret.push_back(Pair("txcount", (int64_t)pindex->nChainTx)); - ret.push_back(Pair("window_block_count", blockcount)); + ret.pushKV("time", (int64_t)pindex->nTime); + ret.pushKV("txcount", (int64_t)pindex->nChainTx); + ret.pushKV("window_final_block_hash", pindex->GetBlockHash().GetHex()); + ret.pushKV("window_block_count", blockcount); if (blockcount > 0) { - ret.push_back(Pair("window_tx_count", nTxDiff)); - ret.push_back(Pair("window_interval", nTimeDiff)); + ret.pushKV("window_tx_count", nTxDiff); + ret.pushKV("window_interval", nTimeDiff); if (nTimeDiff > 0) { - ret.push_back(Pair("txrate", ((double)nTxDiff) / nTimeDiff)); + ret.pushKV("txrate", ((double)nTxDiff) / nTimeDiff); } } @@ -1619,6 +1640,7 @@ static const CRPCCommand commands[] = { "hidden", "waitfornewblock", &waitfornewblock, {"timeout"} }, { "hidden", "waitforblock", &waitforblock, {"blockhash","timeout"} }, { "hidden", "waitforblockheight", &waitforblockheight, {"height","timeout"} }, + { "hidden", "syncwithvalidationinterfacequeue", &syncwithvalidationinterfacequeue, {} }, }; void RegisterBlockchainRPCCommands(CRPCTable &t) |