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.
5
6 #include "amount.h"
7 #include "chain.h"
8 #include "chainparams.h"
9 #include "checkpoints.h"
10 #include "coins.h"
11 #include "consensus/validation.h"
12 #include "main.h"
13 #include "policy/policy.h"
14 #include "primitives/transaction.h"
15 #include "rpc/server.h"
16 #include "streams.h"
17 #include "sync.h"
18 #include "txmempool.h"
19 #include "util.h"
20 #include "utilstrencodings.h"
21 #include "hash.h"
22
23 #include <stdint.h>
24
25 #include <univalue.h>
26
27 #include <boost/thread/thread.hpp> // boost::thread::interrupt
28
29 using namespace std;
30
31 extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry);
32 void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex);
33
GetDifficulty(const CBlockIndex * blockindex)34 double GetDifficulty(const CBlockIndex* blockindex)
35 {
36 // Floating point number that is a multiple of the minimum difficulty,
37 // minimum difficulty = 1.0.
38 if (blockindex == NULL)
39 {
40 if (chainActive.Tip() == NULL)
41 return 1.0;
42 else
43 blockindex = chainActive.Tip();
44 }
45
46 int nShift = (blockindex->nBits >> 24) & 0xff;
47
48 double dDiff =
49 (double)0x0000ffff / (double)(blockindex->nBits & 0x00ffffff);
50
51 while (nShift < 29)
52 {
53 dDiff *= 256.0;
54 nShift++;
55 }
56 while (nShift > 29)
57 {
58 dDiff /= 256.0;
59 nShift--;
60 }
61
62 return dDiff;
63 }
64
blockheaderToJSON(const CBlockIndex * blockindex)65 UniValue blockheaderToJSON(const CBlockIndex* blockindex)
66 {
67 UniValue result(UniValue::VOBJ);
68 result.push_back(Pair("hash", blockindex->GetBlockHash().GetHex()));
69 int confirmations = -1;
70 // Only report confirmations if the block is on the main chain
71 if (chainActive.Contains(blockindex))
72 confirmations = chainActive.Height() - blockindex->nHeight + 1;
73 result.push_back(Pair("confirmations", confirmations));
74 result.push_back(Pair("height", blockindex->nHeight));
75 result.push_back(Pair("version", blockindex->nVersion));
76 result.push_back(Pair("versionHex", strprintf("%08x", blockindex->nVersion)));
77 result.push_back(Pair("merkleroot", blockindex->hashMerkleRoot.GetHex()));
78 result.push_back(Pair("time", (int64_t)blockindex->nTime));
79 result.push_back(Pair("mediantime", (int64_t)blockindex->GetMedianTimePast()));
80 result.push_back(Pair("nonce", (uint64_t)blockindex->nNonce));
81 result.push_back(Pair("bits", strprintf("%08x", blockindex->nBits)));
82 result.push_back(Pair("difficulty", GetDifficulty(blockindex)));
83 result.push_back(Pair("chainwork", blockindex->nChainWork.GetHex()));
84
85 if (blockindex->pprev)
86 result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex()));
87 CBlockIndex *pnext = chainActive.Next(blockindex);
88 if (pnext)
89 result.push_back(Pair("nextblockhash", pnext->GetBlockHash().GetHex()));
90 return result;
91 }
92
blockToJSON(const CBlock & block,const CBlockIndex * blockindex,bool txDetails=false)93 UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false)
94 {
95 UniValue result(UniValue::VOBJ);
96 result.push_back(Pair("hash", blockindex->GetBlockHash().GetHex()));
97 int confirmations = -1;
98 // Only report confirmations if the block is on the main chain
99 if (chainActive.Contains(blockindex))
100 confirmations = chainActive.Height() - blockindex->nHeight + 1;
101 result.push_back(Pair("confirmations", confirmations));
102 result.push_back(Pair("strippedsize", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS)));
103 result.push_back(Pair("size", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION)));
104 result.push_back(Pair("weight", (int)::GetBlockWeight(block)));
105 result.push_back(Pair("height", blockindex->nHeight));
106 result.push_back(Pair("version", block.nVersion));
107 result.push_back(Pair("versionHex", strprintf("%08x", block.nVersion)));
108 result.push_back(Pair("merkleroot", block.hashMerkleRoot.GetHex()));
109 UniValue txs(UniValue::VARR);
110 BOOST_FOREACH(const CTransaction&tx, block.vtx)
111 {
112 if(txDetails)
113 {
114 UniValue objTx(UniValue::VOBJ);
115 TxToJSON(tx, uint256(), objTx);
116 txs.push_back(objTx);
117 }
118 else
119 txs.push_back(tx.GetHash().GetHex());
120 }
121 result.push_back(Pair("tx", txs));
122 result.push_back(Pair("time", block.GetBlockTime()));
123 result.push_back(Pair("mediantime", (int64_t)blockindex->GetMedianTimePast()));
124 result.push_back(Pair("nonce", (uint64_t)block.nNonce));
125 result.push_back(Pair("bits", strprintf("%08x", block.nBits)));
126 result.push_back(Pair("difficulty", GetDifficulty(blockindex)));
127 result.push_back(Pair("chainwork", blockindex->nChainWork.GetHex()));
128
129 if (blockindex->pprev)
130 result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex()));
131 CBlockIndex *pnext = chainActive.Next(blockindex);
132 if (pnext)
133 result.push_back(Pair("nextblockhash", pnext->GetBlockHash().GetHex()));
134 return result;
135 }
136
getblockcount(const UniValue & params,bool fHelp)137 UniValue getblockcount(const UniValue& params, bool fHelp)
138 {
139 if (fHelp || params.size() != 0)
140 throw runtime_error(
141 "getblockcount\n"
142 "\nReturns the number of blocks in the longest block chain.\n"
143 "\nResult:\n"
144 "n (numeric) The current block count\n"
145 "\nExamples:\n"
146 + HelpExampleCli("getblockcount", "")
147 + HelpExampleRpc("getblockcount", "")
148 );
149
150 LOCK(cs_main);
151 return chainActive.Height();
152 }
153
getbestblockhash(const UniValue & params,bool fHelp)154 UniValue getbestblockhash(const UniValue& params, bool fHelp)
155 {
156 if (fHelp || params.size() != 0)
157 throw runtime_error(
158 "getbestblockhash\n"
159 "\nReturns the hash of the best (tip) block in the longest block chain.\n"
160 "\nResult\n"
161 "\"hex\" (string) the block hash hex encoded\n"
162 "\nExamples\n"
163 + HelpExampleCli("getbestblockhash", "")
164 + HelpExampleRpc("getbestblockhash", "")
165 );
166
167 LOCK(cs_main);
168 return chainActive.Tip()->GetBlockHash().GetHex();
169 }
170
getdifficulty(const UniValue & params,bool fHelp)171 UniValue getdifficulty(const UniValue& params, bool fHelp)
172 {
173 if (fHelp || params.size() != 0)
174 throw runtime_error(
175 "getdifficulty\n"
176 "\nReturns the proof-of-work difficulty as a multiple of the minimum difficulty.\n"
177 "\nResult:\n"
178 "n.nnn (numeric) the proof-of-work difficulty as a multiple of the minimum difficulty.\n"
179 "\nExamples:\n"
180 + HelpExampleCli("getdifficulty", "")
181 + HelpExampleRpc("getdifficulty", "")
182 );
183
184 LOCK(cs_main);
185 return GetDifficulty();
186 }
187
EntryDescriptionString()188 std::string EntryDescriptionString()
189 {
190 return " \"size\" : n, (numeric) transaction size in bytes\n"
191 " \"fee\" : n, (numeric) transaction fee in " + CURRENCY_UNIT + "\n"
192 " \"modifiedfee\" : n, (numeric) transaction fee with fee deltas used for mining priority\n"
193 " \"time\" : n, (numeric) local time transaction entered pool in seconds since 1 Jan 1970 GMT\n"
194 " \"height\" : n, (numeric) block height when transaction entered pool\n"
195 " \"startingpriority\" : n, (numeric) priority when transaction entered pool\n"
196 " \"currentpriority\" : n, (numeric) transaction priority now\n"
197 " \"descendantcount\" : n, (numeric) number of in-mempool descendant transactions (including this one)\n"
198 " \"descendantsize\" : n, (numeric) size of in-mempool descendants (including this one)\n"
199 " \"descendantfees\" : n, (numeric) modified fees (see above) of in-mempool descendants (including this one)\n"
200 " \"ancestorcount\" : n, (numeric) number of in-mempool ancestor transactions (including this one)\n"
201 " \"ancestorsize\" : n, (numeric) size of in-mempool ancestors (including this one)\n"
202 " \"ancestorfees\" : n, (numeric) modified fees (see above) of in-mempool ancestors (including this one)\n"
203 " \"depends\" : [ (array) unconfirmed transactions used as inputs for this transaction\n"
204 " \"transactionid\", (string) parent transaction id\n"
205 " ... ]\n";
206 }
207
entryToJSON(UniValue & info,const CTxMemPoolEntry & e)208 void entryToJSON(UniValue &info, const CTxMemPoolEntry &e)
209 {
210 AssertLockHeld(mempool.cs);
211
212 info.push_back(Pair("size", (int)e.GetTxSize()));
213 info.push_back(Pair("fee", ValueFromAmount(e.GetFee())));
214 info.push_back(Pair("modifiedfee", ValueFromAmount(e.GetModifiedFee())));
215 info.push_back(Pair("time", e.GetTime()));
216 info.push_back(Pair("height", (int)e.GetHeight()));
217 info.push_back(Pair("startingpriority", e.GetPriority(e.GetHeight())));
218 info.push_back(Pair("currentpriority", e.GetPriority(chainActive.Height())));
219 info.push_back(Pair("descendantcount", e.GetCountWithDescendants()));
220 info.push_back(Pair("descendantsize", e.GetSizeWithDescendants()));
221 info.push_back(Pair("descendantfees", e.GetModFeesWithDescendants()));
222 info.push_back(Pair("ancestorcount", e.GetCountWithAncestors()));
223 info.push_back(Pair("ancestorsize", e.GetSizeWithAncestors()));
224 info.push_back(Pair("ancestorfees", e.GetModFeesWithAncestors()));
225 const CTransaction& tx = e.GetTx();
226 set<string> setDepends;
227 BOOST_FOREACH(const CTxIn& txin, tx.vin)
228 {
229 if (mempool.exists(txin.prevout.hash))
230 setDepends.insert(txin.prevout.hash.ToString());
231 }
232
233 UniValue depends(UniValue::VARR);
234 BOOST_FOREACH(const string& dep, setDepends)
235 {
236 depends.push_back(dep);
237 }
238
239 info.push_back(Pair("depends", depends));
240 }
241
mempoolToJSON(bool fVerbose=false)242 UniValue mempoolToJSON(bool fVerbose = false)
243 {
244 if (fVerbose)
245 {
246 LOCK(mempool.cs);
247 UniValue o(UniValue::VOBJ);
248 BOOST_FOREACH(const CTxMemPoolEntry& e, mempool.mapTx)
249 {
250 const uint256& hash = e.GetTx().GetHash();
251 UniValue info(UniValue::VOBJ);
252 entryToJSON(info, e);
253 o.push_back(Pair(hash.ToString(), info));
254 }
255 return o;
256 }
257 else
258 {
259 vector<uint256> vtxid;
260 mempool.queryHashes(vtxid);
261
262 UniValue a(UniValue::VARR);
263 BOOST_FOREACH(const uint256& hash, vtxid)
264 a.push_back(hash.ToString());
265
266 return a;
267 }
268 }
269
getrawmempool(const UniValue & params,bool fHelp)270 UniValue getrawmempool(const UniValue& params, bool fHelp)
271 {
272 if (fHelp || params.size() > 1)
273 throw runtime_error(
274 "getrawmempool ( verbose )\n"
275 "\nReturns all transaction ids in memory pool as a json array of string transaction ids.\n"
276 "\nArguments:\n"
277 "1. verbose (boolean, optional, default=false) true for a json object, false for array of transaction ids\n"
278 "\nResult: (for verbose = false):\n"
279 "[ (json array of string)\n"
280 " \"transactionid\" (string) The transaction id\n"
281 " ,...\n"
282 "]\n"
283 "\nResult: (for verbose = true):\n"
284 "{ (json object)\n"
285 " \"transactionid\" : { (json object)\n"
286 + EntryDescriptionString()
287 + " }, ...\n"
288 "}\n"
289 "\nExamples\n"
290 + HelpExampleCli("getrawmempool", "true")
291 + HelpExampleRpc("getrawmempool", "true")
292 );
293
294 bool fVerbose = false;
295 if (params.size() > 0)
296 fVerbose = params[0].get_bool();
297
298 return mempoolToJSON(fVerbose);
299 }
300
getmempoolancestors(const UniValue & params,bool fHelp)301 UniValue getmempoolancestors(const UniValue& params, bool fHelp)
302 {
303 if (fHelp || params.size() < 1 || params.size() > 2) {
304 throw runtime_error(
305 "getmempoolancestors txid (verbose)\n"
306 "\nIf txid is in the mempool, returns all in-mempool ancestors.\n"
307 "\nArguments:\n"
308 "1. \"txid\" (string, required) The transaction id (must be in mempool)\n"
309 "2. verbose (boolean, optional, default=false) true for a json object, false for array of transaction ids\n"
310 "\nResult (for verbose=false):\n"
311 "[ (json array of strings)\n"
312 " \"transactionid\" (string) The transaction id of an in-mempool ancestor transaction\n"
313 " ,...\n"
314 "]\n"
315 "\nResult (for verbose=true):\n"
316 "{ (json object)\n"
317 " \"transactionid\" : { (json object)\n"
318 + EntryDescriptionString()
319 + " }, ...\n"
320 "}\n"
321 "\nExamples\n"
322 + HelpExampleCli("getmempoolancestors", "\"mytxid\"")
323 + HelpExampleRpc("getmempoolancestors", "\"mytxid\"")
324 );
325 }
326
327 bool fVerbose = false;
328 if (params.size() > 1)
329 fVerbose = params[1].get_bool();
330
331 uint256 hash = ParseHashV(params[0], "parameter 1");
332
333 LOCK(mempool.cs);
334
335 CTxMemPool::txiter it = mempool.mapTx.find(hash);
336 if (it == mempool.mapTx.end()) {
337 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not in mempool");
338 }
339
340 CTxMemPool::setEntries setAncestors;
341 uint64_t noLimit = std::numeric_limits<uint64_t>::max();
342 std::string dummy;
343 mempool.CalculateMemPoolAncestors(*it, setAncestors, noLimit, noLimit, noLimit, noLimit, dummy, false);
344
345 if (!fVerbose) {
346 UniValue o(UniValue::VARR);
347 BOOST_FOREACH(CTxMemPool::txiter ancestorIt, setAncestors) {
348 o.push_back(ancestorIt->GetTx().GetHash().ToString());
349 }
350
351 return o;
352 } else {
353 UniValue o(UniValue::VOBJ);
354 BOOST_FOREACH(CTxMemPool::txiter ancestorIt, setAncestors) {
355 const CTxMemPoolEntry &e = *ancestorIt;
356 const uint256& hash = e.GetTx().GetHash();
357 UniValue info(UniValue::VOBJ);
358 entryToJSON(info, e);
359 o.push_back(Pair(hash.ToString(), info));
360 }
361 return o;
362 }
363 }
364
getmempooldescendants(const UniValue & params,bool fHelp)365 UniValue getmempooldescendants(const UniValue& params, bool fHelp)
366 {
367 if (fHelp || params.size() < 1 || params.size() > 2) {
368 throw runtime_error(
369 "getmempooldescendants txid (verbose)\n"
370 "\nIf txid is in the mempool, returns all in-mempool descendants.\n"
371 "\nArguments:\n"
372 "1. \"txid\" (string, required) The transaction id (must be in mempool)\n"
373 "2. verbose (boolean, optional, default=false) true for a json object, false for array of transaction ids\n"
374 "\nResult (for verbose=false):\n"
375 "[ (json array of strings)\n"
376 " \"transactionid\" (string) The transaction id of an in-mempool descendant transaction\n"
377 " ,...\n"
378 "]\n"
379 "\nResult (for verbose=true):\n"
380 "{ (json object)\n"
381 " \"transactionid\" : { (json object)\n"
382 + EntryDescriptionString()
383 + " }, ...\n"
384 "}\n"
385 "\nExamples\n"
386 + HelpExampleCli("getmempooldescendants", "\"mytxid\"")
387 + HelpExampleRpc("getmempooldescendants", "\"mytxid\"")
388 );
389 }
390
391 bool fVerbose = false;
392 if (params.size() > 1)
393 fVerbose = params[1].get_bool();
394
395 uint256 hash = ParseHashV(params[0], "parameter 1");
396
397 LOCK(mempool.cs);
398
399 CTxMemPool::txiter it = mempool.mapTx.find(hash);
400 if (it == mempool.mapTx.end()) {
401 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not in mempool");
402 }
403
404 CTxMemPool::setEntries setDescendants;
405 mempool.CalculateDescendants(it, setDescendants);
406 // CTxMemPool::CalculateDescendants will include the given tx
407 setDescendants.erase(it);
408
409 if (!fVerbose) {
410 UniValue o(UniValue::VARR);
411 BOOST_FOREACH(CTxMemPool::txiter descendantIt, setDescendants) {
412 o.push_back(descendantIt->GetTx().GetHash().ToString());
413 }
414
415 return o;
416 } else {
417 UniValue o(UniValue::VOBJ);
418 BOOST_FOREACH(CTxMemPool::txiter descendantIt, setDescendants) {
419 const CTxMemPoolEntry &e = *descendantIt;
420 const uint256& hash = e.GetTx().GetHash();
421 UniValue info(UniValue::VOBJ);
422 entryToJSON(info, e);
423 o.push_back(Pair(hash.ToString(), info));
424 }
425 return o;
426 }
427 }
428
getmempoolentry(const UniValue & params,bool fHelp)429 UniValue getmempoolentry(const UniValue& params, bool fHelp)
430 {
431 if (fHelp || params.size() != 1) {
432 throw runtime_error(
433 "getmempoolentry txid\n"
434 "\nReturns mempool data for given transaction\n"
435 "\nArguments:\n"
436 "1. \"txid\" (string, required) The transaction id (must be in mempool)\n"
437 "\nResult:\n"
438 "{ (json object)\n"
439 + EntryDescriptionString()
440 + "}\n"
441 "\nExamples\n"
442 + HelpExampleCli("getmempoolentry", "\"mytxid\"")
443 + HelpExampleRpc("getmempoolentry", "\"mytxid\"")
444 );
445 }
446
447 uint256 hash = ParseHashV(params[0], "parameter 1");
448
449 LOCK(mempool.cs);
450
451 CTxMemPool::txiter it = mempool.mapTx.find(hash);
452 if (it == mempool.mapTx.end()) {
453 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not in mempool");
454 }
455
456 const CTxMemPoolEntry &e = *it;
457 UniValue info(UniValue::VOBJ);
458 entryToJSON(info, e);
459 return info;
460 }
461
getblockhash(const UniValue & params,bool fHelp)462 UniValue getblockhash(const UniValue& params, bool fHelp)
463 {
464 if (fHelp || params.size() != 1)
465 throw runtime_error(
466 "getblockhash index\n"
467 "\nReturns hash of block in best-block-chain at index provided.\n"
468 "\nArguments:\n"
469 "1. index (numeric, required) The block index\n"
470 "\nResult:\n"
471 "\"hash\" (string) The block hash\n"
472 "\nExamples:\n"
473 + HelpExampleCli("getblockhash", "1000")
474 + HelpExampleRpc("getblockhash", "1000")
475 );
476
477 LOCK(cs_main);
478
479 int nHeight = params[0].get_int();
480 if (nHeight < 0 || nHeight > chainActive.Height())
481 throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range");
482
483 CBlockIndex* pblockindex = chainActive[nHeight];
484 return pblockindex->GetBlockHash().GetHex();
485 }
486
getblockheader(const UniValue & params,bool fHelp)487 UniValue getblockheader(const UniValue& params, bool fHelp)
488 {
489 if (fHelp || params.size() < 1 || params.size() > 2)
490 throw runtime_error(
491 "getblockheader \"hash\" ( verbose )\n"
492 "\nIf verbose is false, returns a string that is serialized, hex-encoded data for blockheader 'hash'.\n"
493 "If verbose is true, returns an Object with information about blockheader <hash>.\n"
494 "\nArguments:\n"
495 "1. \"hash\" (string, required) The block hash\n"
496 "2. verbose (boolean, optional, default=true) true for a json object, false for the hex encoded data\n"
497 "\nResult (for verbose = true):\n"
498 "{\n"
499 " \"hash\" : \"hash\", (string) the block hash (same as provided)\n"
500 " \"confirmations\" : n, (numeric) The number of confirmations, or -1 if the block is not on the main chain\n"
501 " \"height\" : n, (numeric) The block height or index\n"
502 " \"version\" : n, (numeric) The block version\n"
503 " \"versionHex\" : \"00000000\", (string) The block version formatted in hexadecimal\n"
504 " \"merkleroot\" : \"xxxx\", (string) The merkle root\n"
505 " \"time\" : ttt, (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)\n"
506 " \"mediantime\" : ttt, (numeric) The median block time in seconds since epoch (Jan 1 1970 GMT)\n"
507 " \"nonce\" : n, (numeric) The nonce\n"
508 " \"bits\" : \"1d00ffff\", (string) The bits\n"
509 " \"difficulty\" : x.xxx, (numeric) The difficulty\n"
510 " \"previousblockhash\" : \"hash\", (string) The hash of the previous block\n"
511 " \"nextblockhash\" : \"hash\", (string) The hash of the next block\n"
512 " \"chainwork\" : \"0000...1f3\" (string) Expected number of hashes required to produce the current chain (in hex)\n"
513 "}\n"
514 "\nResult (for verbose=false):\n"
515 "\"data\" (string) A string that is serialized, hex-encoded data for block 'hash'.\n"
516 "\nExamples:\n"
517 + HelpExampleCli("getblockheader", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
518 + HelpExampleRpc("getblockheader", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
519 );
520
521 LOCK(cs_main);
522
523 std::string strHash = params[0].get_str();
524 uint256 hash(uint256S(strHash));
525
526 bool fVerbose = true;
527 if (params.size() > 1)
528 fVerbose = params[1].get_bool();
529
530 if (mapBlockIndex.count(hash) == 0)
531 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
532
533 CBlockIndex* pblockindex = mapBlockIndex[hash];
534
535 if (!fVerbose)
536 {
537 CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION);
538 ssBlock << pblockindex->GetBlockHeader();
539 std::string strHex = HexStr(ssBlock.begin(), ssBlock.end());
540 return strHex;
541 }
542
543 return blockheaderToJSON(pblockindex);
544 }
545
getblock(const UniValue & params,bool fHelp)546 UniValue getblock(const UniValue& params, bool fHelp)
547 {
548 if (fHelp || params.size() < 1 || params.size() > 2)
549 throw runtime_error(
550 "getblock \"hash\" ( verbose )\n"
551 "\nIf verbose is false, returns a string that is serialized, hex-encoded data for block 'hash'.\n"
552 "If verbose is true, returns an Object with information about block <hash>.\n"
553 "\nArguments:\n"
554 "1. \"hash\" (string, required) The block hash\n"
555 "2. verbose (boolean, optional, default=true) true for a json object, false for the hex encoded data\n"
556 "\nResult (for verbose = true):\n"
557 "{\n"
558 " \"hash\" : \"hash\", (string) the block hash (same as provided)\n"
559 " \"confirmations\" : n, (numeric) The number of confirmations, or -1 if the block is not on the main chain\n"
560 " \"size\" : n, (numeric) The block size\n"
561 " \"strippedsize\" : n, (numeric) The block size excluding witness data\n"
562 " \"weight\" : n (numeric) The block weight (BIP 141)\n"
563 " \"height\" : n, (numeric) The block height or index\n"
564 " \"version\" : n, (numeric) The block version\n"
565 " \"versionHex\" : \"00000000\", (string) The block version formatted in hexadecimal\n"
566 " \"merkleroot\" : \"xxxx\", (string) The merkle root\n"
567 " \"tx\" : [ (array of string) The transaction ids\n"
568 " \"transactionid\" (string) The transaction id\n"
569 " ,...\n"
570 " ],\n"
571 " \"time\" : ttt, (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)\n"
572 " \"mediantime\" : ttt, (numeric) The median block time in seconds since epoch (Jan 1 1970 GMT)\n"
573 " \"nonce\" : n, (numeric) The nonce\n"
574 " \"bits\" : \"1d00ffff\", (string) The bits\n"
575 " \"difficulty\" : x.xxx, (numeric) The difficulty\n"
576 " \"chainwork\" : \"xxxx\", (string) Expected number of hashes required to produce the chain up to this block (in hex)\n"
577 " \"previousblockhash\" : \"hash\", (string) The hash of the previous block\n"
578 " \"nextblockhash\" : \"hash\" (string) The hash of the next block\n"
579 "}\n"
580 "\nResult (for verbose=false):\n"
581 "\"data\" (string) A string that is serialized, hex-encoded data for block 'hash'.\n"
582 "\nExamples:\n"
583 + HelpExampleCli("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
584 + HelpExampleRpc("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
585 );
586
587 LOCK(cs_main);
588
589 std::string strHash = params[0].get_str();
590 uint256 hash(uint256S(strHash));
591
592 bool fVerbose = true;
593 if (params.size() > 1)
594 fVerbose = params[1].get_bool();
595
596 if (mapBlockIndex.count(hash) == 0)
597 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
598
599 CBlock block;
600 CBlockIndex* pblockindex = mapBlockIndex[hash];
601
602 if (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0)
603 throw JSONRPCError(RPC_INTERNAL_ERROR, "Block not available (pruned data)");
604
605 if(!ReadBlockFromDisk(block, pblockindex, Params().GetConsensus()))
606 throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk");
607
608 if (!fVerbose)
609 {
610 CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION | RPCSerializationFlags());
611 ssBlock << block;
612 std::string strHex = HexStr(ssBlock.begin(), ssBlock.end());
613 return strHex;
614 }
615
616 return blockToJSON(block, pblockindex);
617 }
618
619 struct CCoinsStats
620 {
621 int nHeight;
622 uint256 hashBlock;
623 uint64_t nTransactions;
624 uint64_t nTransactionOutputs;
625 uint64_t nSerializedSize;
626 uint256 hashSerialized;
627 CAmount nTotalAmount;
628
CCoinsStatsCCoinsStats629 CCoinsStats() : nHeight(0), nTransactions(0), nTransactionOutputs(0), nSerializedSize(0), nTotalAmount(0) {}
630 };
631
632 //! Calculate statistics about the unspent transaction output set
GetUTXOStats(CCoinsView * view,CCoinsStats & stats)633 static bool GetUTXOStats(CCoinsView *view, CCoinsStats &stats)
634 {
635 boost::scoped_ptr<CCoinsViewCursor> pcursor(view->Cursor());
636
637 CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION);
638 stats.hashBlock = pcursor->GetBestBlock();
639 {
640 LOCK(cs_main);
641 stats.nHeight = mapBlockIndex.find(stats.hashBlock)->second->nHeight;
642 }
643 ss << stats.hashBlock;
644 CAmount nTotalAmount = 0;
645 while (pcursor->Valid()) {
646 boost::this_thread::interruption_point();
647 uint256 key;
648 CCoins coins;
649 if (pcursor->GetKey(key) && pcursor->GetValue(coins)) {
650 stats.nTransactions++;
651 ss << key;
652 for (unsigned int i=0; i<coins.vout.size(); i++) {
653 const CTxOut &out = coins.vout[i];
654 if (!out.IsNull()) {
655 stats.nTransactionOutputs++;
656 ss << VARINT(i+1);
657 ss << out;
658 nTotalAmount += out.nValue;
659 }
660 }
661 stats.nSerializedSize += 32 + pcursor->GetValueSize();
662 ss << VARINT(0);
663 } else {
664 return error("%s: unable to read value", __func__);
665 }
666 pcursor->Next();
667 }
668 stats.hashSerialized = ss.GetHash();
669 stats.nTotalAmount = nTotalAmount;
670 return true;
671 }
672
gettxoutsetinfo(const UniValue & params,bool fHelp)673 UniValue gettxoutsetinfo(const UniValue& params, bool fHelp)
674 {
675 if (fHelp || params.size() != 0)
676 throw runtime_error(
677 "gettxoutsetinfo\n"
678 "\nReturns statistics about the unspent transaction output set.\n"
679 "Note this call may take some time.\n"
680 "\nResult:\n"
681 "{\n"
682 " \"height\":n, (numeric) The current block height (index)\n"
683 " \"bestblock\": \"hex\", (string) the best block hash hex\n"
684 " \"transactions\": n, (numeric) The number of transactions\n"
685 " \"txouts\": n, (numeric) The number of output transactions\n"
686 " \"bytes_serialized\": n, (numeric) The serialized size\n"
687 " \"hash_serialized\": \"hash\", (string) The serialized hash\n"
688 " \"total_amount\": x.xxx (numeric) The total amount\n"
689 "}\n"
690 "\nExamples:\n"
691 + HelpExampleCli("gettxoutsetinfo", "")
692 + HelpExampleRpc("gettxoutsetinfo", "")
693 );
694
695 UniValue ret(UniValue::VOBJ);
696
697 CCoinsStats stats;
698 FlushStateToDisk();
699 if (GetUTXOStats(pcoinsTip, stats)) {
700 ret.push_back(Pair("height", (int64_t)stats.nHeight));
701 ret.push_back(Pair("bestblock", stats.hashBlock.GetHex()));
702 ret.push_back(Pair("transactions", (int64_t)stats.nTransactions));
703 ret.push_back(Pair("txouts", (int64_t)stats.nTransactionOutputs));
704 ret.push_back(Pair("bytes_serialized", (int64_t)stats.nSerializedSize));
705 ret.push_back(Pair("hash_serialized", stats.hashSerialized.GetHex()));
706 ret.push_back(Pair("total_amount", ValueFromAmount(stats.nTotalAmount)));
707 } else {
708 throw JSONRPCError(RPC_INTERNAL_ERROR, "Unable to read UTXO set");
709 }
710 return ret;
711 }
712
gettxout(const UniValue & params,bool fHelp)713 UniValue gettxout(const UniValue& params, bool fHelp)
714 {
715 if (fHelp || params.size() < 2 || params.size() > 3)
716 throw runtime_error(
717 "gettxout \"txid\" n ( includemempool )\n"
718 "\nReturns details about an unspent transaction output.\n"
719 "\nArguments:\n"
720 "1. \"txid\" (string, required) The transaction id\n"
721 "2. n (numeric, required) vout number\n"
722 "3. includemempool (boolean, optional) Whether to include the mempool\n"
723 "\nResult:\n"
724 "{\n"
725 " \"bestblock\" : \"hash\", (string) the block hash\n"
726 " \"confirmations\" : n, (numeric) The number of confirmations\n"
727 " \"value\" : x.xxx, (numeric) The transaction value in " + CURRENCY_UNIT + "\n"
728 " \"scriptPubKey\" : { (json object)\n"
729 " \"asm\" : \"code\", (string) \n"
730 " \"hex\" : \"hex\", (string) \n"
731 " \"reqSigs\" : n, (numeric) Number of required signatures\n"
732 " \"type\" : \"pubkeyhash\", (string) The type, eg pubkeyhash\n"
733 " \"addresses\" : [ (array of string) array of zetacoin addresses\n"
734 " \"zetacoinaddress\" (string) zetacoin address\n"
735 " ,...\n"
736 " ]\n"
737 " },\n"
738 " \"version\" : n, (numeric) The version\n"
739 " \"coinbase\" : true|false (boolean) Coinbase or not\n"
740 "}\n"
741
742 "\nExamples:\n"
743 "\nGet unspent transactions\n"
744 + HelpExampleCli("listunspent", "") +
745 "\nView the details\n"
746 + HelpExampleCli("gettxout", "\"txid\" 1") +
747 "\nAs a json rpc call\n"
748 + HelpExampleRpc("gettxout", "\"txid\", 1")
749 );
750
751 LOCK(cs_main);
752
753 UniValue ret(UniValue::VOBJ);
754
755 std::string strHash = params[0].get_str();
756 uint256 hash(uint256S(strHash));
757 int n = params[1].get_int();
758 bool fMempool = true;
759 if (params.size() > 2)
760 fMempool = params[2].get_bool();
761
762 CCoins coins;
763 if (fMempool) {
764 LOCK(mempool.cs);
765 CCoinsViewMemPool view(pcoinsTip, mempool);
766 if (!view.GetCoins(hash, coins))
767 return NullUniValue;
768 mempool.pruneSpent(hash, coins); // TODO: this should be done by the CCoinsViewMemPool
769 } else {
770 if (!pcoinsTip->GetCoins(hash, coins))
771 return NullUniValue;
772 }
773 if (n<0 || (unsigned int)n>=coins.vout.size() || coins.vout[n].IsNull())
774 return NullUniValue;
775
776 BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock());
777 CBlockIndex *pindex = it->second;
778 ret.push_back(Pair("bestblock", pindex->GetBlockHash().GetHex()));
779 if ((unsigned int)coins.nHeight == MEMPOOL_HEIGHT)
780 ret.push_back(Pair("confirmations", 0));
781 else
782 ret.push_back(Pair("confirmations", pindex->nHeight - coins.nHeight + 1));
783 ret.push_back(Pair("value", ValueFromAmount(coins.vout[n].nValue)));
784 UniValue o(UniValue::VOBJ);
785 ScriptPubKeyToJSON(coins.vout[n].scriptPubKey, o, true);
786 ret.push_back(Pair("scriptPubKey", o));
787 ret.push_back(Pair("version", coins.nVersion));
788 ret.push_back(Pair("coinbase", coins.fCoinBase));
789
790 return ret;
791 }
792
verifychain(const UniValue & params,bool fHelp)793 UniValue verifychain(const UniValue& params, bool fHelp)
794 {
795 int nCheckLevel = GetArg("-checklevel", DEFAULT_CHECKLEVEL);
796 int nCheckDepth = GetArg("-checkblocks", DEFAULT_CHECKBLOCKS);
797 if (fHelp || params.size() > 2)
798 throw runtime_error(
799 "verifychain ( checklevel numblocks )\n"
800 "\nVerifies blockchain database.\n"
801 "\nArguments:\n"
802 "1. checklevel (numeric, optional, 0-4, default=" + strprintf("%d", nCheckLevel) + ") How thorough the block verification is.\n"
803 "2. numblocks (numeric, optional, default=" + strprintf("%d", nCheckDepth) + ", 0=all) The number of blocks to check.\n"
804 "\nResult:\n"
805 "true|false (boolean) Verified or not\n"
806 "\nExamples:\n"
807 + HelpExampleCli("verifychain", "")
808 + HelpExampleRpc("verifychain", "")
809 );
810
811 LOCK(cs_main);
812
813 if (params.size() > 0)
814 nCheckLevel = params[0].get_int();
815 if (params.size() > 1)
816 nCheckDepth = params[1].get_int();
817
818 return CVerifyDB().VerifyDB(Params(), pcoinsTip, nCheckLevel, nCheckDepth);
819 }
820
BIP9SoftForkDesc(const std::string & name,const Consensus::Params & consensusParams,Consensus::DeploymentPos id)821 static UniValue BIP9SoftForkDesc(const std::string& name, const Consensus::Params& consensusParams, Consensus::DeploymentPos id)
822 {
823 UniValue rv(UniValue::VOBJ);
824 rv.push_back(Pair("id", name));
825 switch (VersionBitsTipState(consensusParams, id)) {
826 case THRESHOLD_DEFINED: rv.push_back(Pair("status", "defined")); break;
827 case THRESHOLD_STARTED: rv.push_back(Pair("status", "started")); break;
828 case THRESHOLD_LOCKED_IN: rv.push_back(Pair("status", "locked_in")); break;
829 case THRESHOLD_ACTIVE: rv.push_back(Pair("status", "active")); break;
830 case THRESHOLD_FAILED: rv.push_back(Pair("status", "failed")); break;
831 }
832 return rv;
833 }
834
BIP9SoftForkDesc(const Consensus::Params & consensusParams,Consensus::DeploymentPos id)835 static UniValue BIP9SoftForkDesc(const Consensus::Params& consensusParams, Consensus::DeploymentPos id)
836 {
837 UniValue rv(UniValue::VOBJ);
838 const ThresholdState thresholdState = VersionBitsTipState(consensusParams, id);
839 switch (thresholdState) {
840 case THRESHOLD_DEFINED: rv.push_back(Pair("status", "defined")); break;
841 case THRESHOLD_STARTED: rv.push_back(Pair("status", "started")); break;
842 case THRESHOLD_LOCKED_IN: rv.push_back(Pair("status", "locked_in")); break;
843 case THRESHOLD_ACTIVE: rv.push_back(Pair("status", "active")); break;
844 case THRESHOLD_FAILED: rv.push_back(Pair("status", "failed")); break;
845 }
846 if (THRESHOLD_STARTED == thresholdState)
847 {
848 rv.push_back(Pair("bit", consensusParams.vDeployments[id].bit));
849 }
850 rv.push_back(Pair("startTime", consensusParams.vDeployments[id].nStartTime));
851 rv.push_back(Pair("timeout", consensusParams.vDeployments[id].nTimeout));
852 return rv;
853 }
854
BIP9SoftForkDescPushBack(UniValue & bip9_softforks,const std::string & name,const Consensus::Params & consensusParams,Consensus::DeploymentPos id)855 void BIP9SoftForkDescPushBack(UniValue& bip9_softforks, const std::string &name, const Consensus::Params& consensusParams, Consensus::DeploymentPos id)
856 {
857 // Deployments with timeout value of 0 are hidden.
858 // A timeout value of 0 guarantees a softfork will never be activated.
859 // This is used when softfork codes are merged without specifying the deployment schedule.
860 if (consensusParams.vDeployments[id].nTimeout > 0)
861 bip9_softforks.push_back(Pair(name, BIP9SoftForkDesc(consensusParams, id)));
862 }
863
getblockchaininfo(const UniValue & params,bool fHelp)864 UniValue getblockchaininfo(const UniValue& params, bool fHelp)
865 {
866 if (fHelp || params.size() != 0)
867 throw runtime_error(
868 "getblockchaininfo\n"
869 "Returns an object containing various state info regarding block chain processing.\n"
870 "\nResult:\n"
871 "{\n"
872 " \"chain\": \"xxxx\", (string) current network name as defined in BIP70 (main, test, regtest)\n"
873 " \"blocks\": xxxxxx, (numeric) the current number of blocks processed in the server\n"
874 " \"headers\": xxxxxx, (numeric) the current number of headers we have validated\n"
875 " \"bestblockhash\": \"...\", (string) the hash of the currently best block\n"
876 " \"difficulty\": xxxxxx, (numeric) the current difficulty\n"
877 " \"mediantime\": xxxxxx, (numeric) median time for the current best block\n"
878 " \"verificationprogress\": xxxx, (numeric) estimate of verification progress [0..1]\n"
879 " \"chainwork\": \"xxxx\" (string) total amount of work in active chain, in hexadecimal\n"
880 " \"pruned\": xx, (boolean) if the blocks are subject to pruning\n"
881 " \"pruneheight\": xxxxxx, (numeric) lowest-height complete block stored\n"
882 " \"softforks\": [ (array) status of softforks in progress\n"
883 " {\n"
884 " \"id\": \"xxxx\", (string) name of softfork\n"
885 " \"version\": xx, (numeric) block version\n"
886 " \"enforce\": { (object) progress toward enforcing the softfork rules for new-version blocks\n"
887 " \"status\": xx, (boolean) true if threshold reached\n"
888 " \"found\": xx, (numeric) number of blocks with the new version found\n"
889 " \"required\": xx, (numeric) number of blocks required to trigger\n"
890 " \"window\": xx, (numeric) maximum size of examined window of recent blocks\n"
891 " },\n"
892 " \"reject\": { ... } (object) progress toward rejecting pre-softfork blocks (same fields as \"enforce\")\n"
893 " }, ...\n"
894 " ],\n"
895 " \"bip9_softforks\": { (object) status of BIP9 softforks in progress\n"
896 " \"xxxx\" : { (string) name of the softfork\n"
897 " \"status\": \"xxxx\", (string) one of \"defined\", \"started\", \"locked_in\", \"active\", \"failed\"\n"
898 " \"bit\": xx, (numeric) the bit (0-28) in the block version field used to signal this softfork (only for \"started\" status)\n"
899 " \"startTime\": xx, (numeric) the minimum median time past of a block at which the bit gains its meaning\n"
900 " \"timeout\": xx (numeric) the median time past of a block at which the deployment is considered failed if not yet locked in\n"
901 " }\n"
902 " }\n"
903 "}\n"
904 "\nExamples:\n"
905 + HelpExampleCli("getblockchaininfo", "")
906 + HelpExampleRpc("getblockchaininfo", "")
907 );
908
909 LOCK(cs_main);
910
911 UniValue obj(UniValue::VOBJ);
912 obj.push_back(Pair("chain", Params().NetworkIDString()));
913 obj.push_back(Pair("blocks", (int)chainActive.Height()));
914 obj.push_back(Pair("headers", pindexBestHeader ? pindexBestHeader->nHeight : -1));
915 obj.push_back(Pair("bestblockhash", chainActive.Tip()->GetBlockHash().GetHex()));
916 obj.push_back(Pair("difficulty", (double)GetDifficulty()));
917 obj.push_back(Pair("mediantime", (int64_t)chainActive.Tip()->GetMedianTimePast()));
918 obj.push_back(Pair("verificationprogress", Checkpoints::GuessVerificationProgress(Params().Checkpoints(), chainActive.Tip())));
919 obj.push_back(Pair("chainwork", chainActive.Tip()->nChainWork.GetHex()));
920 obj.push_back(Pair("pruned", fPruneMode));
921
922 const Consensus::Params& consensusParams = Params().GetConsensus();
923 CBlockIndex* tip = chainActive.Tip();
924 UniValue softforks(UniValue::VARR);
925 UniValue bip9_softforks(UniValue::VOBJ);
926 BIP9SoftForkDescPushBack(bip9_softforks, "csv", consensusParams, Consensus::DEPLOYMENT_CSV);
927 BIP9SoftForkDescPushBack(bip9_softforks, "segwit", consensusParams, Consensus::DEPLOYMENT_SEGWIT);
928 obj.push_back(Pair("softforks", softforks));
929 obj.push_back(Pair("bip9_softforks", bip9_softforks));
930
931 if (fPruneMode)
932 {
933 CBlockIndex *block = chainActive.Tip();
934 while (block && block->pprev && (block->pprev->nStatus & BLOCK_HAVE_DATA))
935 block = block->pprev;
936
937 obj.push_back(Pair("pruneheight", block->nHeight));
938 }
939 return obj;
940 }
941
942 /** Comparison function for sorting the getchaintips heads. */
943 struct CompareBlocksByHeight
944 {
operator ()CompareBlocksByHeight945 bool operator()(const CBlockIndex* a, const CBlockIndex* b) const
946 {
947 /* Make sure that unequal blocks with the same height do not compare
948 equal. Use the pointers themselves to make a distinction. */
949
950 if (a->nHeight != b->nHeight)
951 return (a->nHeight > b->nHeight);
952
953 return a < b;
954 }
955 };
956
getchaintips(const UniValue & params,bool fHelp)957 UniValue getchaintips(const UniValue& params, bool fHelp)
958 {
959 if (fHelp || params.size() != 0)
960 throw runtime_error(
961 "getchaintips\n"
962 "Return information about all known tips in the block tree,"
963 " including the main chain as well as orphaned branches.\n"
964 "\nResult:\n"
965 "[\n"
966 " {\n"
967 " \"height\": xxxx, (numeric) height of the chain tip\n"
968 " \"hash\": \"xxxx\", (string) block hash of the tip\n"
969 " \"branchlen\": 0 (numeric) zero for main chain\n"
970 " \"status\": \"active\" (string) \"active\" for the main chain\n"
971 " },\n"
972 " {\n"
973 " \"height\": xxxx,\n"
974 " \"hash\": \"xxxx\",\n"
975 " \"branchlen\": 1 (numeric) length of branch connecting the tip to the main chain\n"
976 " \"status\": \"xxxx\" (string) status of the chain (active, valid-fork, valid-headers, headers-only, invalid)\n"
977 " }\n"
978 "]\n"
979 "Possible values for status:\n"
980 "1. \"invalid\" This branch contains at least one invalid block\n"
981 "2. \"headers-only\" Not all blocks for this branch are available, but the headers are valid\n"
982 "3. \"valid-headers\" All blocks are available for this branch, but they were never fully validated\n"
983 "4. \"valid-fork\" This branch is not part of the active chain, but is fully validated\n"
984 "5. \"active\" This is the tip of the active main chain, which is certainly valid\n"
985 "\nExamples:\n"
986 + HelpExampleCli("getchaintips", "")
987 + HelpExampleRpc("getchaintips", "")
988 );
989
990 LOCK(cs_main);
991
992 /*
993 * Idea: the set of chain tips is chainActive.tip, plus orphan blocks which do not have another orphan building off of them.
994 * Algorithm:
995 * - Make one pass through mapBlockIndex, picking out the orphan blocks, and also storing a set of the orphan block's pprev pointers.
996 * - Iterate through the orphan blocks. If the block isn't pointed to by another orphan, it is a chain tip.
997 * - add chainActive.Tip()
998 */
999 std::set<const CBlockIndex*, CompareBlocksByHeight> setTips;
1000 std::set<const CBlockIndex*> setOrphans;
1001 std::set<const CBlockIndex*> setPrevs;
1002
1003 BOOST_FOREACH(const PAIRTYPE(const uint256, CBlockIndex*)& item, mapBlockIndex)
1004 {
1005 if (!chainActive.Contains(item.second)) {
1006 setOrphans.insert(item.second);
1007 setPrevs.insert(item.second->pprev);
1008 }
1009 }
1010
1011 for (std::set<const CBlockIndex*>::iterator it = setOrphans.begin(); it != setOrphans.end(); ++it)
1012 {
1013 if (setPrevs.erase(*it) == 0) {
1014 setTips.insert(*it);
1015 }
1016 }
1017
1018 // Always report the currently active tip.
1019 setTips.insert(chainActive.Tip());
1020
1021 /* Construct the output array. */
1022 UniValue res(UniValue::VARR);
1023 BOOST_FOREACH(const CBlockIndex* block, setTips)
1024 {
1025 UniValue obj(UniValue::VOBJ);
1026 obj.push_back(Pair("height", block->nHeight));
1027 obj.push_back(Pair("hash", block->phashBlock->GetHex()));
1028
1029 const int branchLen = block->nHeight - chainActive.FindFork(block)->nHeight;
1030 obj.push_back(Pair("branchlen", branchLen));
1031
1032 string status;
1033 if (chainActive.Contains(block)) {
1034 // This block is part of the currently active chain.
1035 status = "active";
1036 } else if (block->nStatus & BLOCK_FAILED_MASK) {
1037 // This block or one of its ancestors is invalid.
1038 status = "invalid";
1039 } else if (block->nChainTx == 0) {
1040 // This block cannot be connected because full block data for it or one of its parents is missing.
1041 status = "headers-only";
1042 } else if (block->IsValid(BLOCK_VALID_SCRIPTS)) {
1043 // This block is fully validated, but no longer part of the active chain. It was probably the active block once, but was reorganized.
1044 status = "valid-fork";
1045 } else if (block->IsValid(BLOCK_VALID_TREE)) {
1046 // The headers for this block are valid, but it has not been validated. It was probably never part of the most-work chain.
1047 status = "valid-headers";
1048 } else {
1049 // No clue.
1050 status = "unknown";
1051 }
1052 obj.push_back(Pair("status", status));
1053
1054 res.push_back(obj);
1055 }
1056
1057 return res;
1058 }
1059
mempoolInfoToJSON()1060 UniValue mempoolInfoToJSON()
1061 {
1062 UniValue ret(UniValue::VOBJ);
1063 ret.push_back(Pair("size", (int64_t) mempool.size()));
1064 ret.push_back(Pair("bytes", (int64_t) mempool.GetTotalTxSize()));
1065 ret.push_back(Pair("usage", (int64_t) mempool.DynamicMemoryUsage()));
1066 size_t maxmempool = GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000;
1067 ret.push_back(Pair("maxmempool", (int64_t) maxmempool));
1068 ret.push_back(Pair("mempoolminfee", ValueFromAmount(mempool.GetMinFee(maxmempool).GetFeePerK())));
1069
1070 return ret;
1071 }
1072
getmempoolinfo(const UniValue & params,bool fHelp)1073 UniValue getmempoolinfo(const UniValue& params, bool fHelp)
1074 {
1075 if (fHelp || params.size() != 0)
1076 throw runtime_error(
1077 "getmempoolinfo\n"
1078 "\nReturns details on the active state of the TX memory pool.\n"
1079 "\nResult:\n"
1080 "{\n"
1081 " \"size\": xxxxx, (numeric) Current tx count\n"
1082 " \"bytes\": xxxxx, (numeric) Sum of all tx sizes\n"
1083 " \"usage\": xxxxx, (numeric) Total memory usage for the mempool\n"
1084 " \"maxmempool\": xxxxx, (numeric) Maximum memory usage for the mempool\n"
1085 " \"mempoolminfee\": xxxxx (numeric) Minimum fee for tx to be accepted\n"
1086 "}\n"
1087 "\nExamples:\n"
1088 + HelpExampleCli("getmempoolinfo", "")
1089 + HelpExampleRpc("getmempoolinfo", "")
1090 );
1091
1092 return mempoolInfoToJSON();
1093 }
1094
invalidateblock(const UniValue & params,bool fHelp)1095 UniValue invalidateblock(const UniValue& params, bool fHelp)
1096 {
1097 if (fHelp || params.size() != 1)
1098 throw runtime_error(
1099 "invalidateblock \"hash\"\n"
1100 "\nPermanently marks a block as invalid, as if it violated a consensus rule.\n"
1101 "\nArguments:\n"
1102 "1. hash (string, required) the hash of the block to mark as invalid\n"
1103 "\nResult:\n"
1104 "\nExamples:\n"
1105 + HelpExampleCli("invalidateblock", "\"blockhash\"")
1106 + HelpExampleRpc("invalidateblock", "\"blockhash\"")
1107 );
1108
1109 std::string strHash = params[0].get_str();
1110 uint256 hash(uint256S(strHash));
1111 CValidationState state;
1112
1113 {
1114 LOCK(cs_main);
1115 if (mapBlockIndex.count(hash) == 0)
1116 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
1117
1118 CBlockIndex* pblockindex = mapBlockIndex[hash];
1119 InvalidateBlock(state, Params(), pblockindex);
1120 }
1121
1122 if (state.IsValid()) {
1123 ActivateBestChain(state, Params());
1124 }
1125
1126 if (!state.IsValid()) {
1127 throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason());
1128 }
1129
1130 return NullUniValue;
1131 }
1132
reconsiderblock(const UniValue & params,bool fHelp)1133 UniValue reconsiderblock(const UniValue& params, bool fHelp)
1134 {
1135 if (fHelp || params.size() != 1)
1136 throw runtime_error(
1137 "reconsiderblock \"hash\"\n"
1138 "\nRemoves invalidity status of a block and its descendants, reconsider them for activation.\n"
1139 "This can be used to undo the effects of invalidateblock.\n"
1140 "\nArguments:\n"
1141 "1. hash (string, required) the hash of the block to reconsider\n"
1142 "\nResult:\n"
1143 "\nExamples:\n"
1144 + HelpExampleCli("reconsiderblock", "\"blockhash\"")
1145 + HelpExampleRpc("reconsiderblock", "\"blockhash\"")
1146 );
1147
1148 std::string strHash = params[0].get_str();
1149 uint256 hash(uint256S(strHash));
1150
1151 {
1152 LOCK(cs_main);
1153 if (mapBlockIndex.count(hash) == 0)
1154 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
1155
1156 CBlockIndex* pblockindex = mapBlockIndex[hash];
1157 ResetBlockFailureFlags(pblockindex);
1158 }
1159
1160 CValidationState state;
1161 ActivateBestChain(state, Params());
1162
1163 if (!state.IsValid()) {
1164 throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason());
1165 }
1166
1167 return NullUniValue;
1168 }
1169
1170 static const CRPCCommand commands[] =
1171 { // category name actor (function) okSafeMode
1172 // --------------------- ------------------------ ----------------------- ----------
1173 { "blockchain", "getblockchaininfo", &getblockchaininfo, true },
1174 { "blockchain", "getbestblockhash", &getbestblockhash, true },
1175 { "blockchain", "getblockcount", &getblockcount, true },
1176 { "blockchain", "getblock", &getblock, true },
1177 { "blockchain", "getblockhash", &getblockhash, true },
1178 { "blockchain", "getblockheader", &getblockheader, true },
1179 { "blockchain", "getchaintips", &getchaintips, true },
1180 { "blockchain", "getdifficulty", &getdifficulty, true },
1181 { "blockchain", "getmempoolancestors", &getmempoolancestors, true },
1182 { "blockchain", "getmempooldescendants", &getmempooldescendants, true },
1183 { "blockchain", "getmempoolentry", &getmempoolentry, true },
1184 { "blockchain", "getmempoolinfo", &getmempoolinfo, true },
1185 { "blockchain", "getrawmempool", &getrawmempool, true },
1186 { "blockchain", "gettxout", &gettxout, true },
1187 { "blockchain", "gettxoutsetinfo", &gettxoutsetinfo, true },
1188 { "blockchain", "verifychain", &verifychain, true },
1189
1190 /* Not shown in help */
1191 { "hidden", "invalidateblock", &invalidateblock, true },
1192 { "hidden", "reconsiderblock", &reconsiderblock, true },
1193 };
1194
RegisterBlockchainRPCCommands(CRPCTable & tableRPC)1195 void RegisterBlockchainRPCCommands(CRPCTable &tableRPC)
1196 {
1197 for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++)
1198 tableRPC.appendCommand(commands[vcidx].name, &commands[vcidx]);
1199 }
1200