1
// Copyright (c) 2010 Satoshi Nakamoto
2
// Copyright (c) 2009-2015 The Bitcoin Core developers
3
// Distributed under the MIT software license, see the accompanying
4
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
8
#include "chainparams.h"
9
#include "checkpoints.h"
11
#include "consensus/validation.h"
13
#include "policy/policy.h"
14
#include "primitives/transaction.h"
15
#include "rpcserver.h"
18
#include "txmempool.h"
20
#include "utilstrencodings.h"
28
extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry);
29
void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex);
31
double GetDifficulty(const CBlockIndex* blockindex)
33
// Floating point number that is a multiple of the minimum difficulty,
34
// minimum difficulty = 1.0.
35
if (blockindex == NULL)
37
if (chainActive.Tip() == NULL)
40
blockindex = chainActive.Tip();
43
int nShift = (blockindex->nBits >> 24) & 0xff;
46
(double)0x0000ffff / (double)(blockindex->nBits & 0x00ffffff);
62
UniValue blockheaderToJSON(const CBlockIndex* blockindex)
64
UniValue result(UniValue::VOBJ);
65
result.push_back(Pair("hash", blockindex->GetBlockHash().GetHex()));
66
int confirmations = -1;
67
// Only report confirmations if the block is on the main chain
68
if (chainActive.Contains(blockindex))
69
confirmations = chainActive.Height() - blockindex->nHeight + 1;
70
result.push_back(Pair("confirmations", confirmations));
71
result.push_back(Pair("height", blockindex->nHeight));
72
result.push_back(Pair("version", blockindex->nVersion));
73
result.push_back(Pair("merkleroot", blockindex->hashMerkleRoot.GetHex()));
74
result.push_back(Pair("time", (int64_t)blockindex->nTime));
75
result.push_back(Pair("mediantime", (int64_t)blockindex->GetMedianTimePast()));
76
result.push_back(Pair("nonce", (uint64_t)blockindex->nNonce));
77
result.push_back(Pair("bits", strprintf("%08x", blockindex->nBits)));
78
result.push_back(Pair("difficulty", GetDifficulty(blockindex)));
79
result.push_back(Pair("chainwork", blockindex->nChainWork.GetHex()));
81
if (blockindex->pprev)
82
result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex()));
83
CBlockIndex *pnext = chainActive.Next(blockindex);
85
result.push_back(Pair("nextblockhash", pnext->GetBlockHash().GetHex()));
89
UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false)
91
UniValue result(UniValue::VOBJ);
92
result.push_back(Pair("hash", block.GetHash().GetHex()));
93
int confirmations = -1;
94
// Only report confirmations if the block is on the main chain
95
if (chainActive.Contains(blockindex))
96
confirmations = chainActive.Height() - blockindex->nHeight + 1;
97
result.push_back(Pair("confirmations", confirmations));
98
result.push_back(Pair("size", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION)));
99
result.push_back(Pair("height", blockindex->nHeight));
100
result.push_back(Pair("version", block.nVersion));
101
result.push_back(Pair("merkleroot", block.hashMerkleRoot.GetHex()));
102
UniValue txs(UniValue::VARR);
103
BOOST_FOREACH(const CTransaction&tx, block.vtx)
107
UniValue objTx(UniValue::VOBJ);
108
TxToJSON(tx, uint256(), objTx);
109
txs.push_back(objTx);
112
txs.push_back(tx.GetHash().GetHex());
114
result.push_back(Pair("tx", txs));
115
result.push_back(Pair("time", block.GetBlockTime()));
116
result.push_back(Pair("mediantime", (int64_t)blockindex->GetMedianTimePast()));
117
result.push_back(Pair("nonce", (uint64_t)block.nNonce));
118
result.push_back(Pair("bits", strprintf("%08x", block.nBits)));
119
result.push_back(Pair("difficulty", GetDifficulty(blockindex)));
120
result.push_back(Pair("chainwork", blockindex->nChainWork.GetHex()));
122
if (blockindex->pprev)
123
result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex()));
124
CBlockIndex *pnext = chainActive.Next(blockindex);
126
result.push_back(Pair("nextblockhash", pnext->GetBlockHash().GetHex()));
130
UniValue getblockcount(const UniValue& params, bool fHelp)
132
if (fHelp || params.size() != 0)
135
"\nReturns the number of blocks in the longest block chain.\n"
137
"n (numeric) The current block count\n"
139
+ HelpExampleCli("getblockcount", "")
140
+ HelpExampleRpc("getblockcount", "")
144
return chainActive.Height();
147
UniValue getbestblockhash(const UniValue& params, bool fHelp)
149
if (fHelp || params.size() != 0)
152
"\nReturns the hash of the best (tip) block in the longest block chain.\n"
154
"\"hex\" (string) the block hash hex encoded\n"
156
+ HelpExampleCli("getbestblockhash", "")
157
+ HelpExampleRpc("getbestblockhash", "")
161
return chainActive.Tip()->GetBlockHash().GetHex();
164
UniValue getdifficulty(const UniValue& params, bool fHelp)
166
if (fHelp || params.size() != 0)
169
"\nReturns the proof-of-work difficulty as a multiple of the minimum difficulty.\n"
171
"n.nnn (numeric) the proof-of-work difficulty as a multiple of the minimum difficulty.\n"
173
+ HelpExampleCli("getdifficulty", "")
174
+ HelpExampleRpc("getdifficulty", "")
178
return GetDifficulty();
181
UniValue mempoolToJSON(bool fVerbose = false)
186
UniValue o(UniValue::VOBJ);
187
BOOST_FOREACH(const CTxMemPoolEntry& e, mempool.mapTx)
189
const uint256& hash = e.GetTx().GetHash();
190
UniValue info(UniValue::VOBJ);
191
info.push_back(Pair("size", (int)e.GetTxSize()));
192
info.push_back(Pair("fee", ValueFromAmount(e.GetFee())));
193
info.push_back(Pair("modifiedfee", ValueFromAmount(e.GetModifiedFee())));
194
info.push_back(Pair("time", e.GetTime()));
195
info.push_back(Pair("height", (int)e.GetHeight()));
196
info.push_back(Pair("startingpriority", e.GetPriority(e.GetHeight())));
197
info.push_back(Pair("currentpriority", e.GetPriority(chainActive.Height())));
198
info.push_back(Pair("descendantcount", e.GetCountWithDescendants()));
199
info.push_back(Pair("descendantsize", e.GetSizeWithDescendants()));
200
info.push_back(Pair("descendantfees", e.GetModFeesWithDescendants()));
201
const CTransaction& tx = e.GetTx();
202
set<string> setDepends;
203
BOOST_FOREACH(const CTxIn& txin, tx.vin)
205
if (mempool.exists(txin.prevout.hash))
206
setDepends.insert(txin.prevout.hash.ToString());
209
UniValue depends(UniValue::VARR);
210
BOOST_FOREACH(const string& dep, setDepends)
212
depends.push_back(dep);
215
info.push_back(Pair("depends", depends));
216
o.push_back(Pair(hash.ToString(), info));
222
vector<uint256> vtxid;
223
mempool.queryHashes(vtxid);
225
UniValue a(UniValue::VARR);
226
BOOST_FOREACH(const uint256& hash, vtxid)
227
a.push_back(hash.ToString());
233
UniValue getrawmempool(const UniValue& params, bool fHelp)
235
if (fHelp || params.size() > 1)
237
"getrawmempool ( verbose )\n"
238
"\nReturns all transaction ids in memory pool as a json array of string transaction ids.\n"
240
"1. verbose (boolean, optional, default=false) true for a json object, false for array of transaction ids\n"
241
"\nResult: (for verbose = false):\n"
242
"[ (json array of string)\n"
243
" \"transactionid\" (string) The transaction id\n"
246
"\nResult: (for verbose = true):\n"
248
" \"transactionid\" : { (json object)\n"
249
" \"size\" : n, (numeric) transaction size in bytes\n"
250
" \"fee\" : n, (numeric) transaction fee in " + CURRENCY_UNIT + "\n"
251
" \"modifiedfee\" : n, (numeric) transaction fee with fee deltas used for mining priority\n"
252
" \"time\" : n, (numeric) local time transaction entered pool in seconds since 1 Jan 1970 GMT\n"
253
" \"height\" : n, (numeric) block height when transaction entered pool\n"
254
" \"startingpriority\" : n, (numeric) priority when transaction entered pool\n"
255
" \"currentpriority\" : n, (numeric) transaction priority now\n"
256
" \"descendantcount\" : n, (numeric) number of in-mempool descendant transactions (including this one)\n"
257
" \"descendantsize\" : n, (numeric) size of in-mempool descendants (including this one)\n"
258
" \"descendantfees\" : n, (numeric) modified fees (see above) of in-mempool descendants (including this one)\n"
259
" \"depends\" : [ (array) unconfirmed transactions used as inputs for this transaction\n"
260
" \"transactionid\", (string) parent transaction id\n"
265
+ HelpExampleCli("getrawmempool", "true")
266
+ HelpExampleRpc("getrawmempool", "true")
271
bool fVerbose = false;
272
if (params.size() > 0)
273
fVerbose = params[0].get_bool();
275
return mempoolToJSON(fVerbose);
278
UniValue getblockhash(const UniValue& params, bool fHelp)
280
if (fHelp || params.size() != 1)
282
"getblockhash index\n"
283
"\nReturns hash of block in best-block-chain at index provided.\n"
285
"1. index (numeric, required) The block index\n"
287
"\"hash\" (string) The block hash\n"
289
+ HelpExampleCli("getblockhash", "1000")
290
+ HelpExampleRpc("getblockhash", "1000")
295
int nHeight = params[0].get_int();
296
if (nHeight < 0 || nHeight > chainActive.Height())
297
throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range");
299
CBlockIndex* pblockindex = chainActive[nHeight];
300
return pblockindex->GetBlockHash().GetHex();
303
UniValue getblockheader(const UniValue& params, bool fHelp)
305
if (fHelp || params.size() < 1 || params.size() > 2)
307
"getblockheader \"hash\" ( verbose )\n"
308
"\nIf verbose is false, returns a string that is serialized, hex-encoded data for blockheader 'hash'.\n"
309
"If verbose is true, returns an Object with information about blockheader <hash>.\n"
311
"1. \"hash\" (string, required) The block hash\n"
312
"2. verbose (boolean, optional, default=true) true for a json object, false for the hex encoded data\n"
313
"\nResult (for verbose = true):\n"
315
" \"hash\" : \"hash\", (string) the block hash (same as provided)\n"
316
" \"confirmations\" : n, (numeric) The number of confirmations, or -1 if the block is not on the main chain\n"
317
" \"height\" : n, (numeric) The block height or index\n"
318
" \"version\" : n, (numeric) The block version\n"
319
" \"merkleroot\" : \"xxxx\", (string) The merkle root\n"
320
" \"time\" : ttt, (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)\n"
321
" \"mediantime\" : ttt, (numeric) The median block time in seconds since epoch (Jan 1 1970 GMT)\n"
322
" \"nonce\" : n, (numeric) The nonce\n"
323
" \"bits\" : \"1d00ffff\", (string) The bits\n"
324
" \"difficulty\" : x.xxx, (numeric) The difficulty\n"
325
" \"previousblockhash\" : \"hash\", (string) The hash of the previous block\n"
326
" \"nextblockhash\" : \"hash\", (string) The hash of the next block\n"
327
" \"chainwork\" : \"0000...1f3\" (string) Expected number of hashes required to produce the current chain (in hex)\n"
329
"\nResult (for verbose=false):\n"
330
"\"data\" (string) A string that is serialized, hex-encoded data for block 'hash'.\n"
332
+ HelpExampleCli("getblockheader", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
333
+ HelpExampleRpc("getblockheader", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
338
std::string strHash = params[0].get_str();
339
uint256 hash(uint256S(strHash));
341
bool fVerbose = true;
342
if (params.size() > 1)
343
fVerbose = params[1].get_bool();
345
if (mapBlockIndex.count(hash) == 0)
346
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
348
CBlockIndex* pblockindex = mapBlockIndex[hash];
352
CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION);
353
ssBlock << pblockindex->GetBlockHeader();
354
std::string strHex = HexStr(ssBlock.begin(), ssBlock.end());
358
return blockheaderToJSON(pblockindex);
361
UniValue getblock(const UniValue& params, bool fHelp)
363
if (fHelp || params.size() < 1 || params.size() > 2)
365
"getblock \"hash\" ( verbose )\n"
366
"\nIf verbose is false, returns a string that is serialized, hex-encoded data for block 'hash'.\n"
367
"If verbose is true, returns an Object with information about block <hash>.\n"
369
"1. \"hash\" (string, required) The block hash\n"
370
"2. verbose (boolean, optional, default=true) true for a json object, false for the hex encoded data\n"
371
"\nResult (for verbose = true):\n"
373
" \"hash\" : \"hash\", (string) the block hash (same as provided)\n"
374
" \"confirmations\" : n, (numeric) The number of confirmations, or -1 if the block is not on the main chain\n"
375
" \"size\" : n, (numeric) The block size\n"
376
" \"height\" : n, (numeric) The block height or index\n"
377
" \"version\" : n, (numeric) The block version\n"
378
" \"merkleroot\" : \"xxxx\", (string) The merkle root\n"
379
" \"tx\" : [ (array of string) The transaction ids\n"
380
" \"transactionid\" (string) The transaction id\n"
383
" \"time\" : ttt, (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)\n"
384
" \"mediantime\" : ttt, (numeric) The median block time in seconds since epoch (Jan 1 1970 GMT)\n"
385
" \"nonce\" : n, (numeric) The nonce\n"
386
" \"bits\" : \"1d00ffff\", (string) The bits\n"
387
" \"difficulty\" : x.xxx, (numeric) The difficulty\n"
388
" \"chainwork\" : \"xxxx\", (string) Expected number of hashes required to produce the chain up to this block (in hex)\n"
389
" \"previousblockhash\" : \"hash\", (string) The hash of the previous block\n"
390
" \"nextblockhash\" : \"hash\" (string) The hash of the next block\n"
392
"\nResult (for verbose=false):\n"
393
"\"data\" (string) A string that is serialized, hex-encoded data for block 'hash'.\n"
395
+ HelpExampleCli("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
396
+ HelpExampleRpc("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
401
std::string strHash = params[0].get_str();
402
uint256 hash(uint256S(strHash));
404
bool fVerbose = true;
405
if (params.size() > 1)
406
fVerbose = params[1].get_bool();
408
if (mapBlockIndex.count(hash) == 0)
409
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
412
CBlockIndex* pblockindex = mapBlockIndex[hash];
414
if (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0)
415
throw JSONRPCError(RPC_INTERNAL_ERROR, "Block not available (pruned data)");
417
if(!ReadBlockFromDisk(block, pblockindex, Params().GetConsensus()))
418
throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk");
422
CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION);
424
std::string strHex = HexStr(ssBlock.begin(), ssBlock.end());
428
return blockToJSON(block, pblockindex);
431
UniValue gettxoutsetinfo(const UniValue& params, bool fHelp)
433
if (fHelp || params.size() != 0)
436
"\nReturns statistics about the unspent transaction output set.\n"
437
"Note this call may take some time.\n"
440
" \"height\":n, (numeric) The current block height (index)\n"
441
" \"bestblock\": \"hex\", (string) the best block hash hex\n"
442
" \"transactions\": n, (numeric) The number of transactions\n"
443
" \"txouts\": n, (numeric) The number of output transactions\n"
444
" \"bytes_serialized\": n, (numeric) The serialized size\n"
445
" \"hash_serialized\": \"hash\", (string) The serialized hash\n"
446
" \"total_amount\": x.xxx (numeric) The total amount\n"
449
+ HelpExampleCli("gettxoutsetinfo", "")
450
+ HelpExampleRpc("gettxoutsetinfo", "")
453
UniValue ret(UniValue::VOBJ);
457
if (pcoinsTip->GetStats(stats)) {
458
ret.push_back(Pair("height", (int64_t)stats.nHeight));
459
ret.push_back(Pair("bestblock", stats.hashBlock.GetHex()));
460
ret.push_back(Pair("transactions", (int64_t)stats.nTransactions));
461
ret.push_back(Pair("txouts", (int64_t)stats.nTransactionOutputs));
462
ret.push_back(Pair("bytes_serialized", (int64_t)stats.nSerializedSize));
463
ret.push_back(Pair("hash_serialized", stats.hashSerialized.GetHex()));
464
ret.push_back(Pair("total_amount", ValueFromAmount(stats.nTotalAmount)));
469
UniValue gettxout(const UniValue& params, bool fHelp)
471
if (fHelp || params.size() < 2 || params.size() > 3)
473
"gettxout \"txid\" n ( includemempool )\n"
474
"\nReturns details about an unspent transaction output.\n"
476
"1. \"txid\" (string, required) The transaction id\n"
477
"2. n (numeric, required) vout value\n"
478
"3. includemempool (boolean, optional) Whether to included the mem pool\n"
481
" \"bestblock\" : \"hash\", (string) the block hash\n"
482
" \"confirmations\" : n, (numeric) The number of confirmations\n"
483
" \"value\" : x.xxx, (numeric) The transaction value in " + CURRENCY_UNIT + "\n"
484
" \"scriptPubKey\" : { (json object)\n"
485
" \"asm\" : \"code\", (string) \n"
486
" \"hex\" : \"hex\", (string) \n"
487
" \"reqSigs\" : n, (numeric) Number of required signatures\n"
488
" \"type\" : \"pubkeyhash\", (string) The type, eg pubkeyhash\n"
489
" \"addresses\" : [ (array of string) array of bitcoin addresses\n"
490
" \"bitcoinaddress\" (string) bitcoin address\n"
494
" \"version\" : n, (numeric) The version\n"
495
" \"coinbase\" : true|false (boolean) Coinbase or not\n"
499
"\nGet unspent transactions\n"
500
+ HelpExampleCli("listunspent", "") +
501
"\nView the details\n"
502
+ HelpExampleCli("gettxout", "\"txid\" 1") +
503
"\nAs a json rpc call\n"
504
+ HelpExampleRpc("gettxout", "\"txid\", 1")
509
UniValue ret(UniValue::VOBJ);
511
std::string strHash = params[0].get_str();
512
uint256 hash(uint256S(strHash));
513
int n = params[1].get_int();
514
bool fMempool = true;
515
if (params.size() > 2)
516
fMempool = params[2].get_bool();
521
CCoinsViewMemPool view(pcoinsTip, mempool);
522
if (!view.GetCoins(hash, coins))
524
mempool.pruneSpent(hash, coins); // TODO: this should be done by the CCoinsViewMemPool
526
if (!pcoinsTip->GetCoins(hash, coins))
529
if (n<0 || (unsigned int)n>=coins.vout.size() || coins.vout[n].IsNull())
532
BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock());
533
CBlockIndex *pindex = it->second;
534
ret.push_back(Pair("bestblock", pindex->GetBlockHash().GetHex()));
535
if ((unsigned int)coins.nHeight == MEMPOOL_HEIGHT)
536
ret.push_back(Pair("confirmations", 0));
538
ret.push_back(Pair("confirmations", pindex->nHeight - coins.nHeight + 1));
539
ret.push_back(Pair("value", ValueFromAmount(coins.vout[n].nValue)));
540
UniValue o(UniValue::VOBJ);
541
ScriptPubKeyToJSON(coins.vout[n].scriptPubKey, o, true);
542
ret.push_back(Pair("scriptPubKey", o));
543
ret.push_back(Pair("version", coins.nVersion));
544
ret.push_back(Pair("coinbase", coins.fCoinBase));
549
UniValue verifychain(const UniValue& params, bool fHelp)
551
int nCheckLevel = GetArg("-checklevel", DEFAULT_CHECKLEVEL);
552
int nCheckDepth = GetArg("-checkblocks", DEFAULT_CHECKBLOCKS);
553
if (fHelp || params.size() > 2)
555
"verifychain ( checklevel numblocks )\n"
556
"\nVerifies blockchain database.\n"
558
"1. checklevel (numeric, optional, 0-4, default=" + strprintf("%d", nCheckLevel) + ") How thorough the block verification is.\n"
559
"2. numblocks (numeric, optional, default=" + strprintf("%d", nCheckDepth) + ", 0=all) The number of blocks to check.\n"
561
"true|false (boolean) Verified or not\n"
563
+ HelpExampleCli("verifychain", "")
564
+ HelpExampleRpc("verifychain", "")
569
if (params.size() > 0)
570
nCheckLevel = params[0].get_int();
571
if (params.size() > 1)
572
nCheckDepth = params[1].get_int();
574
return CVerifyDB().VerifyDB(Params(), pcoinsTip, nCheckLevel, nCheckDepth);
577
/** Implementation of IsSuperMajority with better feedback */
578
static UniValue SoftForkMajorityDesc(int minVersion, CBlockIndex* pindex, int nRequired, const Consensus::Params& consensusParams)
581
CBlockIndex* pstart = pindex;
582
for (int i = 0; i < consensusParams.nMajorityWindow && pstart != NULL; i++)
584
if (pstart->nVersion >= minVersion)
586
pstart = pstart->pprev;
589
UniValue rv(UniValue::VOBJ);
590
rv.push_back(Pair("status", nFound >= nRequired));
591
rv.push_back(Pair("found", nFound));
592
rv.push_back(Pair("required", nRequired));
593
rv.push_back(Pair("window", consensusParams.nMajorityWindow));
597
static UniValue SoftForkDesc(const std::string &name, int version, CBlockIndex* pindex, const Consensus::Params& consensusParams)
599
UniValue rv(UniValue::VOBJ);
600
rv.push_back(Pair("id", name));
601
rv.push_back(Pair("version", version));
602
rv.push_back(Pair("enforce", SoftForkMajorityDesc(version, pindex, consensusParams.nMajorityEnforceBlockUpgrade, consensusParams)));
603
rv.push_back(Pair("reject", SoftForkMajorityDesc(version, pindex, consensusParams.nMajorityRejectBlockOutdated, consensusParams)));
607
static UniValue BIP9SoftForkDesc(const std::string& name, const Consensus::Params& consensusParams, Consensus::DeploymentPos id)
609
UniValue rv(UniValue::VOBJ);
610
rv.push_back(Pair("id", name));
611
switch (VersionBitsTipState(consensusParams, id)) {
612
case THRESHOLD_DEFINED: rv.push_back(Pair("status", "defined")); break;
613
case THRESHOLD_STARTED: rv.push_back(Pair("status", "started")); break;
614
case THRESHOLD_LOCKED_IN: rv.push_back(Pair("status", "locked_in")); break;
615
case THRESHOLD_ACTIVE: rv.push_back(Pair("status", "active")); break;
616
case THRESHOLD_FAILED: rv.push_back(Pair("status", "failed")); break;
621
UniValue getblockchaininfo(const UniValue& params, bool fHelp)
623
if (fHelp || params.size() != 0)
625
"getblockchaininfo\n"
626
"Returns an object containing various state info regarding block chain processing.\n"
629
" \"chain\": \"xxxx\", (string) current network name as defined in BIP70 (main, test, regtest)\n"
630
" \"blocks\": xxxxxx, (numeric) the current number of blocks processed in the server\n"
631
" \"headers\": xxxxxx, (numeric) the current number of headers we have validated\n"
632
" \"bestblockhash\": \"...\", (string) the hash of the currently best block\n"
633
" \"difficulty\": xxxxxx, (numeric) the current difficulty\n"
634
" \"mediantime\": xxxxxx, (numeric) median time for the current best block\n"
635
" \"verificationprogress\": xxxx, (numeric) estimate of verification progress [0..1]\n"
636
" \"chainwork\": \"xxxx\" (string) total amount of work in active chain, in hexadecimal\n"
637
" \"pruned\": xx, (boolean) if the blocks are subject to pruning\n"
638
" \"pruneheight\": xxxxxx, (numeric) heighest block available\n"
639
" \"softforks\": [ (array) status of softforks in progress\n"
641
" \"id\": \"xxxx\", (string) name of softfork\n"
642
" \"version\": xx, (numeric) block version\n"
643
" \"enforce\": { (object) progress toward enforcing the softfork rules for new-version blocks\n"
644
" \"status\": xx, (boolean) true if threshold reached\n"
645
" \"found\": xx, (numeric) number of blocks with the new version found\n"
646
" \"required\": xx, (numeric) number of blocks required to trigger\n"
647
" \"window\": xx, (numeric) maximum size of examined window of recent blocks\n"
649
" \"reject\": { ... } (object) progress toward rejecting pre-softfork blocks (same fields as \"enforce\")\n"
652
" \"bip9_softforks\": [ (array) status of BIP9 softforks in progress\n"
654
" \"id\": \"xxxx\", (string) name of the softfork\n"
655
" \"status\": \"xxxx\", (string) one of \"defined\", \"started\", \"lockedin\", \"active\", \"failed\"\n"
660
+ HelpExampleCli("getblockchaininfo", "")
661
+ HelpExampleRpc("getblockchaininfo", "")
666
UniValue obj(UniValue::VOBJ);
667
obj.push_back(Pair("chain", Params().NetworkIDString()));
668
obj.push_back(Pair("blocks", (int)chainActive.Height()));
669
obj.push_back(Pair("headers", pindexBestHeader ? pindexBestHeader->nHeight : -1));
670
obj.push_back(Pair("bestblockhash", chainActive.Tip()->GetBlockHash().GetHex()));
671
obj.push_back(Pair("difficulty", (double)GetDifficulty()));
672
obj.push_back(Pair("mediantime", (int64_t)chainActive.Tip()->GetMedianTimePast()));
673
obj.push_back(Pair("verificationprogress", Checkpoints::GuessVerificationProgress(Params().Checkpoints(), chainActive.Tip())));
674
obj.push_back(Pair("chainwork", chainActive.Tip()->nChainWork.GetHex()));
675
obj.push_back(Pair("pruned", fPruneMode));
677
const Consensus::Params& consensusParams = Params().GetConsensus();
678
CBlockIndex* tip = chainActive.Tip();
679
UniValue softforks(UniValue::VARR);
680
UniValue bip9_softforks(UniValue::VARR);
681
softforks.push_back(SoftForkDesc("bip34", 2, tip, consensusParams));
682
softforks.push_back(SoftForkDesc("bip66", 3, tip, consensusParams));
683
softforks.push_back(SoftForkDesc("bip65", 4, tip, consensusParams));
684
bip9_softforks.push_back(BIP9SoftForkDesc("csv", consensusParams, Consensus::DEPLOYMENT_CSV));
685
obj.push_back(Pair("softforks", softforks));
686
obj.push_back(Pair("bip9_softforks", bip9_softforks));
690
CBlockIndex *block = chainActive.Tip();
691
while (block && block->pprev && (block->pprev->nStatus & BLOCK_HAVE_DATA))
692
block = block->pprev;
694
obj.push_back(Pair("pruneheight", block->nHeight));
699
/** Comparison function for sorting the getchaintips heads. */
700
struct CompareBlocksByHeight
702
bool operator()(const CBlockIndex* a, const CBlockIndex* b) const
704
/* Make sure that unequal blocks with the same height do not compare
705
equal. Use the pointers themselves to make a distinction. */
707
if (a->nHeight != b->nHeight)
708
return (a->nHeight > b->nHeight);
714
UniValue getchaintips(const UniValue& params, bool fHelp)
716
if (fHelp || params.size() != 0)
719
"Return information about all known tips in the block tree,"
720
" including the main chain as well as orphaned branches.\n"
724
" \"height\": xxxx, (numeric) height of the chain tip\n"
725
" \"hash\": \"xxxx\", (string) block hash of the tip\n"
726
" \"branchlen\": 0 (numeric) zero for main chain\n"
727
" \"status\": \"active\" (string) \"active\" for the main chain\n"
730
" \"height\": xxxx,\n"
731
" \"hash\": \"xxxx\",\n"
732
" \"branchlen\": 1 (numeric) length of branch connecting the tip to the main chain\n"
733
" \"status\": \"xxxx\" (string) status of the chain (active, valid-fork, valid-headers, headers-only, invalid)\n"
736
"Possible values for status:\n"
737
"1. \"invalid\" This branch contains at least one invalid block\n"
738
"2. \"headers-only\" Not all blocks for this branch are available, but the headers are valid\n"
739
"3. \"valid-headers\" All blocks are available for this branch, but they were never fully validated\n"
740
"4. \"valid-fork\" This branch is not part of the active chain, but is fully validated\n"
741
"5. \"active\" This is the tip of the active main chain, which is certainly valid\n"
743
+ HelpExampleCli("getchaintips", "")
744
+ HelpExampleRpc("getchaintips", "")
749
/* Build up a list of chain tips. We start with the list of all
750
known blocks, and successively remove blocks that appear as pprev
752
std::set<const CBlockIndex*, CompareBlocksByHeight> setTips;
753
BOOST_FOREACH(const PAIRTYPE(const uint256, CBlockIndex*)& item, mapBlockIndex)
754
setTips.insert(item.second);
755
BOOST_FOREACH(const PAIRTYPE(const uint256, CBlockIndex*)& item, mapBlockIndex)
757
const CBlockIndex* pprev = item.second->pprev;
759
setTips.erase(pprev);
762
// Always report the currently active tip.
763
setTips.insert(chainActive.Tip());
765
/* Construct the output array. */
766
UniValue res(UniValue::VARR);
767
BOOST_FOREACH(const CBlockIndex* block, setTips)
769
UniValue obj(UniValue::VOBJ);
770
obj.push_back(Pair("height", block->nHeight));
771
obj.push_back(Pair("hash", block->phashBlock->GetHex()));
773
const int branchLen = block->nHeight - chainActive.FindFork(block)->nHeight;
774
obj.push_back(Pair("branchlen", branchLen));
777
if (chainActive.Contains(block)) {
778
// This block is part of the currently active chain.
780
} else if (block->nStatus & BLOCK_FAILED_MASK) {
781
// This block or one of its ancestors is invalid.
783
} else if (block->nChainTx == 0) {
784
// This block cannot be connected because full block data for it or one of its parents is missing.
785
status = "headers-only";
786
} else if (block->IsValid(BLOCK_VALID_SCRIPTS)) {
787
// This block is fully validated, but no longer part of the active chain. It was probably the active block once, but was reorganized.
788
status = "valid-fork";
789
} else if (block->IsValid(BLOCK_VALID_TREE)) {
790
// The headers for this block are valid, but it has not been validated. It was probably never part of the most-work chain.
791
status = "valid-headers";
796
obj.push_back(Pair("status", status));
804
UniValue mempoolInfoToJSON()
806
UniValue ret(UniValue::VOBJ);
807
ret.push_back(Pair("size", (int64_t) mempool.size()));
808
ret.push_back(Pair("bytes", (int64_t) mempool.GetTotalTxSize()));
809
ret.push_back(Pair("usage", (int64_t) mempool.DynamicMemoryUsage()));
810
size_t maxmempool = GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000;
811
ret.push_back(Pair("maxmempool", (int64_t) maxmempool));
812
ret.push_back(Pair("mempoolminfee", ValueFromAmount(mempool.GetMinFee(maxmempool).GetFeePerK())));
817
UniValue getmempoolinfo(const UniValue& params, bool fHelp)
819
if (fHelp || params.size() != 0)
822
"\nReturns details on the active state of the TX memory pool.\n"
825
" \"size\": xxxxx, (numeric) Current tx count\n"
826
" \"bytes\": xxxxx, (numeric) Sum of all tx sizes\n"
827
" \"usage\": xxxxx, (numeric) Total memory usage for the mempool\n"
828
" \"maxmempool\": xxxxx, (numeric) Maximum memory usage for the mempool\n"
829
" \"mempoolminfee\": xxxxx (numeric) Minimum fee for tx to be accepted\n"
832
+ HelpExampleCli("getmempoolinfo", "")
833
+ HelpExampleRpc("getmempoolinfo", "")
836
return mempoolInfoToJSON();
839
UniValue invalidateblock(const UniValue& params, bool fHelp)
841
if (fHelp || params.size() != 1)
843
"invalidateblock \"hash\"\n"
844
"\nPermanently marks a block as invalid, as if it violated a consensus rule.\n"
846
"1. hash (string, required) the hash of the block to mark as invalid\n"
849
+ HelpExampleCli("invalidateblock", "\"blockhash\"")
850
+ HelpExampleRpc("invalidateblock", "\"blockhash\"")
853
std::string strHash = params[0].get_str();
854
uint256 hash(uint256S(strHash));
855
CValidationState state;
859
if (mapBlockIndex.count(hash) == 0)
860
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
862
CBlockIndex* pblockindex = mapBlockIndex[hash];
863
InvalidateBlock(state, Params().GetConsensus(), pblockindex);
866
if (state.IsValid()) {
867
ActivateBestChain(state, Params());
870
if (!state.IsValid()) {
871
throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason());
877
UniValue reconsiderblock(const UniValue& params, bool fHelp)
879
if (fHelp || params.size() != 1)
881
"reconsiderblock \"hash\"\n"
882
"\nRemoves invalidity status of a block and its descendants, reconsider them for activation.\n"
883
"This can be used to undo the effects of invalidateblock.\n"
885
"1. hash (string, required) the hash of the block to reconsider\n"
888
+ HelpExampleCli("reconsiderblock", "\"blockhash\"")
889
+ HelpExampleRpc("reconsiderblock", "\"blockhash\"")
892
std::string strHash = params[0].get_str();
893
uint256 hash(uint256S(strHash));
894
CValidationState state;
898
if (mapBlockIndex.count(hash) == 0)
899
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
901
CBlockIndex* pblockindex = mapBlockIndex[hash];
902
ReconsiderBlock(state, pblockindex);
905
if (state.IsValid()) {
906
ActivateBestChain(state, Params());
909
if (!state.IsValid()) {
910
throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason());