Changeset View
Changeset View
Standalone View
Standalone View
src/rpc/blockchain.cpp
Show First 20 Lines • Show All 54 Lines • ▼ Show 20 Lines | while (nShift > 29) { | ||||
dDiff /= 256.0; | dDiff /= 256.0; | ||||
nShift--; | nShift--; | ||||
} | } | ||||
return dDiff; | return dDiff; | ||||
} | } | ||||
double GetDifficulty(const CBlockIndex *blockindex) { | double GetDifficulty(const CBlockIndex *blockindex) { | ||||
// Floating point number that is a multiple of the minimum difficulty, | assert(blockindex); | ||||
// minimum difficulty = 1.0. | |||||
if (blockindex == nullptr) { | |||||
return 1.0; | |||||
} | |||||
return GetDifficultyFromBits(blockindex->nBits); | return GetDifficultyFromBits(blockindex->nBits); | ||||
} | } | ||||
UniValue blockheaderToJSON(const CBlockIndex *blockindex) { | static int ComputeNextBlockAndDepth(const CBlockIndex *tip, | ||||
AssertLockHeld(cs_main); | const CBlockIndex *blockindex, | ||||
const CBlockIndex *&next) { | |||||
next = tip->GetAncestor(blockindex->nHeight + 1); | |||||
if (next && next->pprev == blockindex) { | |||||
return tip->nHeight - blockindex->nHeight + 1; | |||||
} | |||||
next = nullptr; | |||||
return blockindex == tip ? 1 : -1; | |||||
} | |||||
UniValue blockheaderToJSON(const CBlockIndex *tip, | |||||
const CBlockIndex *blockindex) { | |||||
UniValue result(UniValue::VOBJ); | UniValue result(UniValue::VOBJ); | ||||
result.pushKV("hash", blockindex->GetBlockHash().GetHex()); | result.pushKV("hash", blockindex->GetBlockHash().GetHex()); | ||||
int confirmations = -1; | const CBlockIndex *pnext; | ||||
// Only report confirmations if the block is on the main chain | int confirmations = ComputeNextBlockAndDepth(tip, blockindex, pnext); | ||||
if (chainActive.Contains(blockindex)) { | |||||
confirmations = chainActive.Height() - blockindex->nHeight + 1; | |||||
} | |||||
result.pushKV("confirmations", confirmations); | result.pushKV("confirmations", confirmations); | ||||
result.pushKV("height", blockindex->nHeight); | result.pushKV("height", blockindex->nHeight); | ||||
result.pushKV("version", blockindex->nVersion); | result.pushKV("version", blockindex->nVersion); | ||||
result.pushKV("versionHex", strprintf("%08x", blockindex->nVersion)); | result.pushKV("versionHex", strprintf("%08x", blockindex->nVersion)); | ||||
result.pushKV("merkleroot", blockindex->hashMerkleRoot.GetHex()); | result.pushKV("merkleroot", blockindex->hashMerkleRoot.GetHex()); | ||||
result.pushKV("time", int64_t(blockindex->nTime)); | result.pushKV("time", int64_t(blockindex->nTime)); | ||||
result.pushKV("mediantime", int64_t(blockindex->GetMedianTimePast())); | result.pushKV("mediantime", int64_t(blockindex->GetMedianTimePast())); | ||||
result.pushKV("nonce", uint64_t(blockindex->nNonce)); | result.pushKV("nonce", uint64_t(blockindex->nNonce)); | ||||
result.pushKV("bits", strprintf("%08x", blockindex->nBits)); | result.pushKV("bits", strprintf("%08x", blockindex->nBits)); | ||||
result.pushKV("difficulty", GetDifficulty(blockindex)); | result.pushKV("difficulty", GetDifficulty(blockindex)); | ||||
result.pushKV("chainwork", blockindex->nChainWork.GetHex()); | result.pushKV("chainwork", blockindex->nChainWork.GetHex()); | ||||
if (blockindex->pprev) { | if (blockindex->pprev) { | ||||
result.pushKV("previousblockhash", | result.pushKV("previousblockhash", | ||||
blockindex->pprev->GetBlockHash().GetHex()); | blockindex->pprev->GetBlockHash().GetHex()); | ||||
} | } | ||||
CBlockIndex *pnext = chainActive.Next(blockindex); | |||||
if (pnext) { | if (pnext) { | ||||
result.pushKV("nextblockhash", pnext->GetBlockHash().GetHex()); | result.pushKV("nextblockhash", pnext->GetBlockHash().GetHex()); | ||||
} | } | ||||
return result; | return result; | ||||
} | } | ||||
UniValue blockToJSON(const CBlock &block, const CBlockIndex *blockindex, | UniValue blockToJSON(const CBlock &block, const CBlockIndex *tip, | ||||
bool txDetails) { | const CBlockIndex *blockindex, bool txDetails) { | ||||
AssertLockHeld(cs_main); | |||||
UniValue result(UniValue::VOBJ); | UniValue result(UniValue::VOBJ); | ||||
result.pushKV("hash", blockindex->GetBlockHash().GetHex()); | result.pushKV("hash", blockindex->GetBlockHash().GetHex()); | ||||
int confirmations = -1; | const CBlockIndex *pnext; | ||||
// Only report confirmations if the block is on the main chain | int confirmations = ComputeNextBlockAndDepth(tip, blockindex, pnext); | ||||
if (chainActive.Contains(blockindex)) { | |||||
confirmations = chainActive.Height() - blockindex->nHeight + 1; | |||||
} | |||||
result.pushKV("confirmations", confirmations); | result.pushKV("confirmations", confirmations); | ||||
result.pushKV( | result.pushKV( | ||||
"size", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION)); | "size", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION)); | ||||
result.pushKV("height", blockindex->nHeight); | result.pushKV("height", blockindex->nHeight); | ||||
result.pushKV("version", block.nVersion); | result.pushKV("version", block.nVersion); | ||||
result.pushKV("versionHex", strprintf("%08x", block.nVersion)); | result.pushKV("versionHex", strprintf("%08x", block.nVersion)); | ||||
result.pushKV("merkleroot", block.hashMerkleRoot.GetHex()); | result.pushKV("merkleroot", block.hashMerkleRoot.GetHex()); | ||||
UniValue txs(UniValue::VARR); | UniValue txs(UniValue::VARR); | ||||
Show All 13 Lines | UniValue blockToJSON(const CBlock &block, const CBlockIndex *tip, | ||||
result.pushKV("bits", strprintf("%08x", block.nBits)); | result.pushKV("bits", strprintf("%08x", block.nBits)); | ||||
result.pushKV("difficulty", GetDifficulty(blockindex)); | result.pushKV("difficulty", GetDifficulty(blockindex)); | ||||
result.pushKV("chainwork", blockindex->nChainWork.GetHex()); | result.pushKV("chainwork", blockindex->nChainWork.GetHex()); | ||||
if (blockindex->pprev) { | if (blockindex->pprev) { | ||||
result.pushKV("previousblockhash", | result.pushKV("previousblockhash", | ||||
blockindex->pprev->GetBlockHash().GetHex()); | blockindex->pprev->GetBlockHash().GetHex()); | ||||
} | } | ||||
CBlockIndex *pnext = chainActive.Next(blockindex); | |||||
if (pnext) { | if (pnext) { | ||||
result.pushKV("nextblockhash", pnext->GetBlockHash().GetHex()); | result.pushKV("nextblockhash", pnext->GetBlockHash().GetHex()); | ||||
} | } | ||||
return result; | return result; | ||||
} | } | ||||
static UniValue getblockcount(const Config &config, | static UniValue getblockcount(const Config &config, | ||||
const JSONRPCRequest &request) { | const JSONRPCRequest &request) { | ||||
▲ Show 20 Lines • Show All 644 Lines • ▼ Show 20 Lines | static UniValue getblockheader(const Config &config, | ||||
if (!fVerbose) { | if (!fVerbose) { | ||||
CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION); | CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION); | ||||
ssBlock << pblockindex->GetBlockHeader(); | ssBlock << pblockindex->GetBlockHeader(); | ||||
std::string strHex = HexStr(ssBlock.begin(), ssBlock.end()); | std::string strHex = HexStr(ssBlock.begin(), ssBlock.end()); | ||||
return strHex; | return strHex; | ||||
} | } | ||||
return blockheaderToJSON(pblockindex); | return blockheaderToJSON(chainActive.Tip(), pblockindex); | ||||
} | } | ||||
static UniValue getblock(const Config &config, const JSONRPCRequest &request) { | static UniValue getblock(const Config &config, const JSONRPCRequest &request) { | ||||
if (request.fHelp || request.params.size() < 1 || | if (request.fHelp || request.params.size() < 1 || | ||||
request.params.size() > 2) { | request.params.size() > 2) { | ||||
throw std::runtime_error( | throw std::runtime_error( | ||||
"getblock \"blockhash\" ( verbosity )\n" | "getblock \"blockhash\" ( verbosity )\n" | ||||
"\nIf verbosity is 0 or false, returns a string that is " | "\nIf verbosity is 0 or false, returns a string that is " | ||||
▲ Show 20 Lines • Show All 93 Lines • ▼ Show 20 Lines | static UniValue getblock(const Config &config, const JSONRPCRequest &request) { | ||||
if (verbosity <= 0) { | if (verbosity <= 0) { | ||||
CDataStream ssBlock(SER_NETWORK, | CDataStream ssBlock(SER_NETWORK, | ||||
PROTOCOL_VERSION | RPCSerializationFlags()); | PROTOCOL_VERSION | RPCSerializationFlags()); | ||||
ssBlock << block; | ssBlock << block; | ||||
std::string strHex = HexStr(ssBlock.begin(), ssBlock.end()); | std::string strHex = HexStr(ssBlock.begin(), ssBlock.end()); | ||||
return strHex; | return strHex; | ||||
} | } | ||||
return blockToJSON(block, pblockindex, verbosity >= 2); | return blockToJSON(block, chainActive.Tip(), pblockindex, verbosity >= 2); | ||||
} | } | ||||
struct CCoinsStats { | struct CCoinsStats { | ||||
int nHeight; | int nHeight; | ||||
uint256 hashBlock; | uint256 hashBlock; | ||||
uint64_t nTransactions; | uint64_t nTransactions; | ||||
uint64_t nTransactionOutputs; | uint64_t nTransactionOutputs; | ||||
uint64_t nBogoSize; | uint64_t nBogoSize; | ||||
▲ Show 20 Lines • Show All 294 Lines • ▼ Show 20 Lines | if (!request.params[1].isNull()) { | ||||
nCheckDepth = request.params[1].get_int(); | nCheckDepth = request.params[1].get_int(); | ||||
} | } | ||||
return CVerifyDB().VerifyDB(config, pcoinsTip.get(), nCheckLevel, | return CVerifyDB().VerifyDB(config, pcoinsTip.get(), nCheckLevel, | ||||
nCheckDepth); | nCheckDepth); | ||||
} | } | ||||
/** Implementation of IsSuperMajority with better feedback */ | /** Implementation of IsSuperMajority with better feedback */ | ||||
static UniValue SoftForkMajorityDesc(int version, CBlockIndex *pindex, | static UniValue SoftForkMajorityDesc(int version, const CBlockIndex *pindex, | ||||
const Consensus::Params &consensusParams) { | const Consensus::Params &consensusParams) { | ||||
UniValue rv(UniValue::VOBJ); | UniValue rv(UniValue::VOBJ); | ||||
bool activated = false; | bool activated = false; | ||||
switch (version) { | switch (version) { | ||||
case 2: | case 2: | ||||
activated = pindex->nHeight >= consensusParams.BIP34Height; | activated = pindex->nHeight >= consensusParams.BIP34Height; | ||||
break; | break; | ||||
case 3: | case 3: | ||||
activated = pindex->nHeight >= consensusParams.BIP66Height; | activated = pindex->nHeight >= consensusParams.BIP66Height; | ||||
break; | break; | ||||
case 4: | case 4: | ||||
activated = pindex->nHeight >= consensusParams.BIP65Height; | activated = pindex->nHeight >= consensusParams.BIP65Height; | ||||
break; | break; | ||||
case 5: | case 5: | ||||
activated = pindex->nHeight >= consensusParams.CSVHeight; | activated = pindex->nHeight >= consensusParams.CSVHeight; | ||||
break; | break; | ||||
} | } | ||||
rv.pushKV("status", activated); | rv.pushKV("status", activated); | ||||
return rv; | return rv; | ||||
} | } | ||||
static UniValue SoftForkDesc(const std::string &name, int version, | static UniValue SoftForkDesc(const std::string &name, int version, | ||||
CBlockIndex *pindex, | const CBlockIndex *pindex, | ||||
const Consensus::Params &consensusParams) { | const Consensus::Params &consensusParams) { | ||||
UniValue rv(UniValue::VOBJ); | UniValue rv(UniValue::VOBJ); | ||||
rv.pushKV("id", name); | rv.pushKV("id", name); | ||||
rv.pushKV("version", version); | rv.pushKV("version", version); | ||||
rv.pushKV("reject", SoftForkMajorityDesc(version, pindex, consensusParams)); | rv.pushKV("reject", SoftForkMajorityDesc(version, pindex, consensusParams)); | ||||
return rv; | return rv; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 49 Lines • ▼ Show 20 Lines | if (request.fHelp || request.params.size() != 0) { | ||||
"}\n" | "}\n" | ||||
"\nExamples:\n" + | "\nExamples:\n" + | ||||
HelpExampleCli("getblockchaininfo", "") + | HelpExampleCli("getblockchaininfo", "") + | ||||
HelpExampleRpc("getblockchaininfo", "")); | HelpExampleRpc("getblockchaininfo", "")); | ||||
} | } | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
const CBlockIndex *tip = chainActive.Tip(); | |||||
UniValue obj(UniValue::VOBJ); | UniValue obj(UniValue::VOBJ); | ||||
obj.pushKV("chain", config.GetChainParams().NetworkIDString()); | obj.pushKV("chain", config.GetChainParams().NetworkIDString()); | ||||
obj.pushKV("blocks", int(chainActive.Height())); | obj.pushKV("blocks", int(chainActive.Height())); | ||||
obj.pushKV("headers", pindexBestHeader ? pindexBestHeader->nHeight : -1); | obj.pushKV("headers", pindexBestHeader ? pindexBestHeader->nHeight : -1); | ||||
obj.pushKV("bestblockhash", chainActive.Tip()->GetBlockHash().GetHex()); | obj.pushKV("bestblockhash", tip->GetBlockHash().GetHex()); | ||||
obj.pushKV("difficulty", double(GetDifficulty(chainActive.Tip()))); | obj.pushKV("difficulty", double(GetDifficulty(tip))); | ||||
obj.pushKV("mediantime", int64_t(chainActive.Tip()->GetMedianTimePast())); | obj.pushKV("mediantime", int64_t(tip->GetMedianTimePast())); | ||||
obj.pushKV("verificationprogress", | obj.pushKV("verificationprogress", | ||||
GuessVerificationProgress(config.GetChainParams().TxData(), | GuessVerificationProgress(Params().TxData(), tip)); | ||||
jasonbcox: I'll leave it to you to verify that there was an out-of-order backport or a backport soon to be… | |||||
markblundebergAuthorUnsubmitted Done Inline ActionsYep --> D3101 markblundeberg: Yep --> D3101 | |||||
chainActive.Tip())); | obj.pushKV("chainwork", tip->nChainWork.GetHex()); | ||||
obj.pushKV("chainwork", chainActive.Tip()->nChainWork.GetHex()); | |||||
obj.pushKV("size_on_disk", CalculateCurrentUsage()); | obj.pushKV("size_on_disk", CalculateCurrentUsage()); | ||||
obj.pushKV("pruned", fPruneMode); | obj.pushKV("pruned", fPruneMode); | ||||
if (fPruneMode) { | if (fPruneMode) { | ||||
CBlockIndex *block = chainActive.Tip(); | const CBlockIndex *block = tip; | ||||
assert(block); | assert(block); | ||||
while (block->pprev && (block->pprev->nStatus.hasData())) { | while (block->pprev && (block->pprev->nStatus.hasData())) { | ||||
block = block->pprev; | block = block->pprev; | ||||
} | } | ||||
obj.pushKV("pruneheight", block->nHeight); | obj.pushKV("pruneheight", block->nHeight); | ||||
// if 0, execution bypasses the whole if block. | // if 0, execution bypasses the whole if block. | ||||
bool automatic_pruning = (gArgs.GetArg("-prune", 0) != 1); | bool automatic_pruning = (gArgs.GetArg("-prune", 0) != 1); | ||||
obj.pushKV("automatic_pruning", automatic_pruning); | obj.pushKV("automatic_pruning", automatic_pruning); | ||||
if (automatic_pruning) { | if (automatic_pruning) { | ||||
obj.pushKV("prune_target_size", nPruneTarget); | obj.pushKV("prune_target_size", nPruneTarget); | ||||
} | } | ||||
} | } | ||||
const Consensus::Params &consensusParams = | const Consensus::Params &consensusParams = | ||||
config.GetChainParams().GetConsensus(); | config.GetChainParams().GetConsensus(); | ||||
CBlockIndex *tip = chainActive.Tip(); | |||||
UniValue softforks(UniValue::VARR); | UniValue softforks(UniValue::VARR); | ||||
softforks.push_back(SoftForkDesc("bip34", 2, tip, consensusParams)); | softforks.push_back(SoftForkDesc("bip34", 2, tip, consensusParams)); | ||||
softforks.push_back(SoftForkDesc("bip66", 3, tip, consensusParams)); | softforks.push_back(SoftForkDesc("bip66", 3, tip, consensusParams)); | ||||
softforks.push_back(SoftForkDesc("bip65", 4, tip, consensusParams)); | softforks.push_back(SoftForkDesc("bip65", 4, tip, consensusParams)); | ||||
softforks.push_back(SoftForkDesc("csv", 5, tip, consensusParams)); | softforks.push_back(SoftForkDesc("csv", 5, tip, consensusParams)); | ||||
obj.pushKV("softforks", softforks); | obj.pushKV("softforks", softforks); | ||||
obj.pushKV("warnings", GetWarnings("statusbar")); | obj.pushKV("warnings", GetWarnings("statusbar")); | ||||
▲ Show 20 Lines • Show All 578 Lines • Show Last 20 Lines |
I'll leave it to you to verify that there was an out-of-order backport or a backport soon to be completed regarding the missing obj.pushKV("initialblockdownload", IsInitialBlockDownload());