]> Git Repo - VerusCoin.git/blame - src/rpcblockchain.cpp
Auto merge of #2704 - bitcartel:fix_qa_shieldcoinbase_hang, r=str4d
[VerusCoin.git] / src / rpcblockchain.cpp
CommitLineData
c625ae04 1// Copyright (c) 2010 Satoshi Nakamoto
f914f1a7 2// Copyright (c) 2009-2014 The Bitcoin Core developers
72fb3d29 3// Distributed under the MIT software license, see the accompanying
c625ae04
JG
4// file COPYING or http://www.opensource.org/licenses/mit-license.php.
5
091b2116
RN
6#include "amount.h"
7#include "chain.h"
8#include "chainparams.h"
ac14bcc1 9#include "checkpoints.h"
da29ecbc 10#include "consensus/validation.h"
51ed9ec9 11#include "main.h"
da29ecbc 12#include "primitives/transaction.h"
ac14bcc1 13#include "rpcserver.h"
51ed9ec9 14#include "sync.h"
ad49c256 15#include "util.h"
51ed9ec9
BD
16
17#include <stdint.h>
18
a10a6e2a 19#include <univalue.h>
c625ae04 20
7d3b1528
S
21#include <regex>
22
c625ae04
JG
23using namespace std;
24
d014114d
JS
25extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry);
26void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex);
4e68391a 27
695a7a88 28double GetDifficultyINTERNAL(const CBlockIndex* blockindex, bool networkDifficulty)
c625ae04
JG
29{
30 // Floating point number that is a multiple of the minimum difficulty,
31 // minimum difficulty = 1.0.
32 if (blockindex == NULL)
33 {
4c6d41b8 34 if (chainActive.Tip() == NULL)
c625ae04
JG
35 return 1.0;
36 else
4c6d41b8 37 blockindex = chainActive.Tip();
c625ae04
JG
38 }
39
333ea3c4
JG
40 uint32_t bits;
41 if (networkDifficulty) {
42 bits = GetNextWorkRequired(blockindex, nullptr, Params().GetConsensus());
43 } else {
44 bits = blockindex->nBits;
695a7a88
JG
45 }
46
333ea3c4 47 uint32_t powLimit =
f50e8313 48 UintToArith256(Params().GetConsensus().powLimit).GetCompact();
333ea3c4 49 int nShift = (bits >> 24) & 0xff;
24809b16 50 int nShiftAmount = (powLimit >> 24) & 0xff;
c625ae04
JG
51
52 double dDiff =
24809b16 53 (double)(powLimit & 0x00ffffff) /
333ea3c4 54 (double)(bits & 0x00ffffff);
c625ae04 55
24809b16 56 while (nShift < nShiftAmount)
c625ae04
JG
57 {
58 dDiff *= 256.0;
59 nShift++;
60 }
24809b16 61 while (nShift > nShiftAmount)
c625ae04
JG
62 {
63 dDiff /= 256.0;
64 nShift--;
65 }
66
67 return dDiff;
68}
69
695a7a88
JG
70double GetDifficulty(const CBlockIndex* blockindex)
71{
72 return GetDifficultyINTERNAL(blockindex, false);
73}
74
75double GetNetworkDifficulty(const CBlockIndex* blockindex)
76{
77 return GetDifficultyINTERNAL(blockindex, true);
78}
79
d3d5483e
PT
80UniValue blockheaderToJSON(const CBlockIndex* blockindex)
81{
82 UniValue result(UniValue::VOBJ);
83 result.push_back(Pair("hash", blockindex->GetBlockHash().GetHex()));
84 int confirmations = -1;
85 // Only report confirmations if the block is on the main chain
86 if (chainActive.Contains(blockindex))
87 confirmations = chainActive.Height() - blockindex->nHeight + 1;
88 result.push_back(Pair("confirmations", confirmations));
89 result.push_back(Pair("height", blockindex->nHeight));
90 result.push_back(Pair("version", blockindex->nVersion));
91 result.push_back(Pair("merkleroot", blockindex->hashMerkleRoot.GetHex()));
92 result.push_back(Pair("time", (int64_t)blockindex->nTime));
0352b37b
JG
93 result.push_back(Pair("nonce", blockindex->nNonce.GetHex()));
94 result.push_back(Pair("solution", HexStr(blockindex->nSolution)));
d3d5483e
PT
95 result.push_back(Pair("bits", strprintf("%08x", blockindex->nBits)));
96 result.push_back(Pair("difficulty", GetDifficulty(blockindex)));
97 result.push_back(Pair("chainwork", blockindex->nChainWork.GetHex()));
98
99 if (blockindex->pprev)
100 result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex()));
101 CBlockIndex *pnext = chainActive.Next(blockindex);
102 if (pnext)
103 result.push_back(Pair("nextblockhash", pnext->GetBlockHash().GetHex()));
104 return result;
105}
106
851f58f9 107UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false)
c625ae04 108{
38fc4b70 109 UniValue result(UniValue::VOBJ);
c625ae04 110 result.push_back(Pair("hash", block.GetHash().GetHex()));
57153d4e
WL
111 int confirmations = -1;
112 // Only report confirmations if the block is on the main chain
113 if (chainActive.Contains(blockindex))
114 confirmations = chainActive.Height() - blockindex->nHeight + 1;
115 result.push_back(Pair("confirmations", confirmations));
c625ae04
JG
116 result.push_back(Pair("size", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION)));
117 result.push_back(Pair("height", blockindex->nHeight));
118 result.push_back(Pair("version", block.nVersion));
119 result.push_back(Pair("merkleroot", block.hashMerkleRoot.GetHex()));
38fc4b70 120 UniValue txs(UniValue::VARR);
c625ae04 121 BOOST_FOREACH(const CTransaction&tx, block.vtx)
73351c36
JS
122 {
123 if(txDetails)
124 {
38fc4b70 125 UniValue objTx(UniValue::VOBJ);
4f152496 126 TxToJSON(tx, uint256(), objTx);
73351c36
JS
127 txs.push_back(objTx);
128 }
129 else
805344dc 130 txs.push_back(tx.GetHash().GetHex());
73351c36 131 }
c625ae04 132 result.push_back(Pair("tx", txs));
d56e30ca 133 result.push_back(Pair("time", block.GetBlockTime()));
fdda3c50 134 result.push_back(Pair("nonce", block.nNonce.GetHex()));
e1dde421 135 result.push_back(Pair("solution", HexStr(block.nSolution)));
645d497a 136 result.push_back(Pair("bits", strprintf("%08x", block.nBits)));
c625ae04 137 result.push_back(Pair("difficulty", GetDifficulty(blockindex)));
1b3656d5 138 result.push_back(Pair("chainwork", blockindex->nChainWork.GetHex()));
0bc1e2c4 139 result.push_back(Pair("anchor", blockindex->hashAnchorEnd.GetHex()));
c625ae04
JG
140
141 if (blockindex->pprev)
142 result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex()));
4c6d41b8 143 CBlockIndex *pnext = chainActive.Next(blockindex);
0fe8010a
PW
144 if (pnext)
145 result.push_back(Pair("nextblockhash", pnext->GetBlockHash().GetHex()));
c625ae04
JG
146 return result;
147}
148
d014114d 149UniValue getblockcount(const UniValue& params, bool fHelp)
c625ae04
JG
150{
151 if (fHelp || params.size() != 0)
152 throw runtime_error(
153 "getblockcount\n"
a6099ef3 154 "\nReturns the number of blocks in the longest block chain.\n"
155 "\nResult:\n"
156 "n (numeric) The current block count\n"
157 "\nExamples:\n"
158 + HelpExampleCli("getblockcount", "")
159 + HelpExampleRpc("getblockcount", "")
160 );
c625ae04 161
4401b2d7 162 LOCK(cs_main);
4c6d41b8 163 return chainActive.Height();
c625ae04
JG
164}
165
d014114d 166UniValue getbestblockhash(const UniValue& params, bool fHelp)
091aa8da
JG
167{
168 if (fHelp || params.size() != 0)
169 throw runtime_error(
170 "getbestblockhash\n"
a6099ef3 171 "\nReturns the hash of the best (tip) block in the longest block chain.\n"
172 "\nResult\n"
173 "\"hex\" (string) the block hash hex encoded\n"
174 "\nExamples\n"
175 + HelpExampleCli("getbestblockhash", "")
176 + HelpExampleRpc("getbestblockhash", "")
177 );
091aa8da 178
4401b2d7 179 LOCK(cs_main);
4c6d41b8 180 return chainActive.Tip()->GetBlockHash().GetHex();
091aa8da 181}
c625ae04 182
d014114d 183UniValue getdifficulty(const UniValue& params, bool fHelp)
c625ae04
JG
184{
185 if (fHelp || params.size() != 0)
186 throw runtime_error(
187 "getdifficulty\n"
a6099ef3 188 "\nReturns the proof-of-work difficulty as a multiple of the minimum difficulty.\n"
189 "\nResult:\n"
190 "n.nnn (numeric) the proof-of-work difficulty as a multiple of the minimum difficulty.\n"
191 "\nExamples:\n"
192 + HelpExampleCli("getdifficulty", "")
193 + HelpExampleRpc("getdifficulty", "")
194 );
c625ae04 195
4401b2d7 196 LOCK(cs_main);
695a7a88 197 return GetNetworkDifficulty();
c625ae04
JG
198}
199
30c163d9 200UniValue mempoolToJSON(bool fVerbose = false)
c625ae04 201{
4d707d51
GA
202 if (fVerbose)
203 {
204 LOCK(mempool.cs);
38fc4b70 205 UniValue o(UniValue::VOBJ);
4d707d51
GA
206 BOOST_FOREACH(const PAIRTYPE(uint256, CTxMemPoolEntry)& entry, mempool.mapTx)
207 {
208 const uint256& hash = entry.first;
209 const CTxMemPoolEntry& e = entry.second;
38fc4b70 210 UniValue info(UniValue::VOBJ);
4d707d51
GA
211 info.push_back(Pair("size", (int)e.GetTxSize()));
212 info.push_back(Pair("fee", ValueFromAmount(e.GetFee())));
d56e30ca 213 info.push_back(Pair("time", e.GetTime()));
4d707d51
GA
214 info.push_back(Pair("height", (int)e.GetHeight()));
215 info.push_back(Pair("startingpriority", e.GetPriority(e.GetHeight())));
216 info.push_back(Pair("currentpriority", e.GetPriority(chainActive.Height())));
217 const CTransaction& tx = e.GetTx();
218 set<string> setDepends;
219 BOOST_FOREACH(const CTxIn& txin, tx.vin)
220 {
221 if (mempool.exists(txin.prevout.hash))
222 setDepends.insert(txin.prevout.hash.ToString());
223 }
ed21d5bd 224
b47f3aea 225 UniValue depends(UniValue::VARR);
ed21d5bd
JG
226 BOOST_FOREACH(const string& dep, setDepends)
227 {
228 depends.push_back(dep);
229 }
230
4d707d51
GA
231 info.push_back(Pair("depends", depends));
232 o.push_back(Pair(hash.ToString(), info));
233 }
234 return o;
235 }
236 else
237 {
238 vector<uint256> vtxid;
239 mempool.queryHashes(vtxid);
c625ae04 240
38fc4b70 241 UniValue a(UniValue::VARR);
4d707d51
GA
242 BOOST_FOREACH(const uint256& hash, vtxid)
243 a.push_back(hash.ToString());
244
245 return a;
246 }
c625ae04
JG
247}
248
30c163d9
PJ
249UniValue getrawmempool(const UniValue& params, bool fHelp)
250{
251 if (fHelp || params.size() > 1)
252 throw runtime_error(
253 "getrawmempool ( verbose )\n"
254 "\nReturns all transaction ids in memory pool as a json array of string transaction ids.\n"
255 "\nArguments:\n"
256 "1. verbose (boolean, optional, default=false) true for a json object, false for array of transaction ids\n"
257 "\nResult: (for verbose = false):\n"
258 "[ (json array of string)\n"
259 " \"transactionid\" (string) The transaction id\n"
260 " ,...\n"
261 "]\n"
262 "\nResult: (for verbose = true):\n"
263 "{ (json object)\n"
264 " \"transactionid\" : { (json object)\n"
265 " \"size\" : n, (numeric) transaction size in bytes\n"
091b2116 266 " \"fee\" : n, (numeric) transaction fee in " + CURRENCY_UNIT + "\n"
30c163d9
PJ
267 " \"time\" : n, (numeric) local time transaction entered pool in seconds since 1 Jan 1970 GMT\n"
268 " \"height\" : n, (numeric) block height when transaction entered pool\n"
269 " \"startingpriority\" : n, (numeric) priority when transaction entered pool\n"
270 " \"currentpriority\" : n, (numeric) transaction priority now\n"
271 " \"depends\" : [ (array) unconfirmed transactions used as inputs for this transaction\n"
272 " \"transactionid\", (string) parent transaction id\n"
273 " ... ]\n"
274 " }, ...\n"
275 "}\n"
276 "\nExamples\n"
277 + HelpExampleCli("getrawmempool", "true")
278 + HelpExampleRpc("getrawmempool", "true")
279 );
280
281 LOCK(cs_main);
282
283 bool fVerbose = false;
284 if (params.size() > 0)
285 fVerbose = params[0].get_bool();
286
287 return mempoolToJSON(fVerbose);
288}
289
d014114d 290UniValue getblockhash(const UniValue& params, bool fHelp)
c625ae04
JG
291{
292 if (fHelp || params.size() != 1)
293 throw runtime_error(
a6099ef3 294 "getblockhash index\n"
295 "\nReturns hash of block in best-block-chain at index provided.\n"
296 "\nArguments:\n"
297 "1. index (numeric, required) The block index\n"
298 "\nResult:\n"
299 "\"hash\" (string) The block hash\n"
300 "\nExamples:\n"
301 + HelpExampleCli("getblockhash", "1000")
302 + HelpExampleRpc("getblockhash", "1000")
303 );
c625ae04 304
4401b2d7
EL
305 LOCK(cs_main);
306
c625ae04 307 int nHeight = params[0].get_int();
4c6d41b8 308 if (nHeight < 0 || nHeight > chainActive.Height())
6261e6e6 309 throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range");
c625ae04 310
4c6d41b8
PW
311 CBlockIndex* pblockindex = chainActive[nHeight];
312 return pblockindex->GetBlockHash().GetHex();
c625ae04
JG
313}
314
d3d5483e
PT
315UniValue getblockheader(const UniValue& params, bool fHelp)
316{
317 if (fHelp || params.size() < 1 || params.size() > 2)
318 throw runtime_error(
319 "getblockheader \"hash\" ( verbose )\n"
320 "\nIf verbose is false, returns a string that is serialized, hex-encoded data for blockheader 'hash'.\n"
321 "If verbose is true, returns an Object with information about blockheader <hash>.\n"
322 "\nArguments:\n"
323 "1. \"hash\" (string, required) The block hash\n"
324 "2. verbose (boolean, optional, default=true) true for a json object, false for the hex encoded data\n"
325 "\nResult (for verbose = true):\n"
326 "{\n"
327 " \"hash\" : \"hash\", (string) the block hash (same as provided)\n"
328 " \"confirmations\" : n, (numeric) The number of confirmations, or -1 if the block is not on the main chain\n"
329 " \"height\" : n, (numeric) The block height or index\n"
330 " \"version\" : n, (numeric) The block version\n"
331 " \"merkleroot\" : \"xxxx\", (string) The merkle root\n"
332 " \"time\" : ttt, (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)\n"
333 " \"nonce\" : n, (numeric) The nonce\n"
334 " \"bits\" : \"1d00ffff\", (string) The bits\n"
335 " \"difficulty\" : x.xxx, (numeric) The difficulty\n"
336 " \"previousblockhash\" : \"hash\", (string) The hash of the previous block\n"
337 " \"nextblockhash\" : \"hash\" (string) The hash of the next block\n"
338 "}\n"
339 "\nResult (for verbose=false):\n"
340 "\"data\" (string) A string that is serialized, hex-encoded data for block 'hash'.\n"
341 "\nExamples:\n"
342 + HelpExampleCli("getblockheader", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
343 + HelpExampleRpc("getblockheader", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
344 );
345
346 LOCK(cs_main);
347
348 std::string strHash = params[0].get_str();
349 uint256 hash(uint256S(strHash));
350
351 bool fVerbose = true;
352 if (params.size() > 1)
353 fVerbose = params[1].get_bool();
354
355 if (mapBlockIndex.count(hash) == 0)
356 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
357
358 CBlockIndex* pblockindex = mapBlockIndex[hash];
359
360 if (!fVerbose)
361 {
362 CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION);
363 ssBlock << pblockindex->GetBlockHeader();
364 std::string strHex = HexStr(ssBlock.begin(), ssBlock.end());
365 return strHex;
366 }
367
368 return blockheaderToJSON(pblockindex);
369}
370
d014114d 371UniValue getblock(const UniValue& params, bool fHelp)
c625ae04 372{
23319521 373 if (fHelp || params.size() < 1 || params.size() > 2)
c625ae04 374 throw runtime_error(
7d3b1528
S
375 "getblock \"hash|height\" ( verbose )\n"
376 "\nIf verbose is false, returns a string that is serialized, hex-encoded data for block 'hash|height'.\n"
377 "If verbose is true, returns an Object with information about block <hash|height>.\n"
a6099ef3 378 "\nArguments:\n"
7d3b1528 379 "1. \"hash|height\" (string, required) The block hash or height\n"
a6099ef3 380 "2. verbose (boolean, optional, default=true) true for a json object, false for the hex encoded data\n"
381 "\nResult (for verbose = true):\n"
382 "{\n"
7d3b1528 383 " \"hash\" : \"hash\", (string) the block hash (same as provided hash)\n"
57153d4e 384 " \"confirmations\" : n, (numeric) The number of confirmations, or -1 if the block is not on the main chain\n"
a6099ef3 385 " \"size\" : n, (numeric) The block size\n"
7d3b1528 386 " \"height\" : n, (numeric) The block height or index (same as provided height)\n"
a6099ef3 387 " \"version\" : n, (numeric) The block version\n"
388 " \"merkleroot\" : \"xxxx\", (string) The merkle root\n"
389 " \"tx\" : [ (array of string) The transaction ids\n"
390 " \"transactionid\" (string) The transaction id\n"
391 " ,...\n"
392 " ],\n"
393 " \"time\" : ttt, (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)\n"
394 " \"nonce\" : n, (numeric) The nonce\n"
7d3b1528 395 " \"bits\" : \"1d00ffff\", (string) The bits\n"
a6099ef3 396 " \"difficulty\" : x.xxx, (numeric) The difficulty\n"
397 " \"previousblockhash\" : \"hash\", (string) The hash of the previous block\n"
398 " \"nextblockhash\" : \"hash\" (string) The hash of the next block\n"
399 "}\n"
400 "\nResult (for verbose=false):\n"
401 "\"data\" (string) A string that is serialized, hex-encoded data for block 'hash'.\n"
402 "\nExamples:\n"
403 + HelpExampleCli("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
404 + HelpExampleRpc("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
7d3b1528
S
405 + HelpExampleCli("getblock", "12800")
406 + HelpExampleRpc("getblock", "12800")
23319521 407 );
c625ae04 408
4401b2d7
EL
409 LOCK(cs_main);
410
c625ae04 411 std::string strHash = params[0].get_str();
7d3b1528
S
412
413 // If height is supplied, find the hash
414 if (strHash.size() < (2 * sizeof(uint256))) {
415 // std::stoi allows characters, whereas we want to be strict
416 regex r("[[:digit:]]+");
417 if (!regex_match(strHash, r)) {
418 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid block height parameter");
419 }
420
421 int nHeight = -1;
422 try {
423 nHeight = std::stoi(strHash);
424 }
425 catch (const std::exception &e) {
426 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid block height parameter");
427 }
428
429 if (nHeight < 0 || nHeight > chainActive.Height()) {
430 throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range");
431 }
432 strHash = chainActive[nHeight]->GetBlockHash().GetHex();
433 }
434
34cdc411 435 uint256 hash(uint256S(strHash));
c625ae04 436
23319521
LD
437 bool fVerbose = true;
438 if (params.size() > 1)
439 fVerbose = params[1].get_bool();
440
c625ae04 441 if (mapBlockIndex.count(hash) == 0)
738835d7 442 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
c625ae04
JG
443
444 CBlock block;
445 CBlockIndex* pblockindex = mapBlockIndex[hash];
954d2e72 446
03c56872
JS
447 if (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0)
448 throw JSONRPCError(RPC_INTERNAL_ERROR, "Block not available (pruned data)");
449
954d2e72
RDP
450 if(!ReadBlockFromDisk(block, pblockindex))
451 throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk");
c625ae04 452
23319521
LD
453 if (!fVerbose)
454 {
455 CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION);
456 ssBlock << block;
457 std::string strHex = HexStr(ssBlock.begin(), ssBlock.end());
458 return strHex;
459 }
460
c625ae04
JG
461 return blockToJSON(block, pblockindex);
462}
463
d014114d 464UniValue gettxoutsetinfo(const UniValue& params, bool fHelp)
beeb5761
PW
465{
466 if (fHelp || params.size() != 0)
467 throw runtime_error(
468 "gettxoutsetinfo\n"
a6099ef3 469 "\nReturns statistics about the unspent transaction output set.\n"
470 "Note this call may take some time.\n"
471 "\nResult:\n"
472 "{\n"
473 " \"height\":n, (numeric) The current block height (index)\n"
474 " \"bestblock\": \"hex\", (string) the best block hash hex\n"
475 " \"transactions\": n, (numeric) The number of transactions\n"
476 " \"txouts\": n, (numeric) The number of output transactions\n"
477 " \"bytes_serialized\": n, (numeric) The serialized size\n"
478 " \"hash_serialized\": \"hash\", (string) The serialized hash\n"
479 " \"total_amount\": x.xxx (numeric) The total amount\n"
480 "}\n"
481 "\nExamples:\n"
482 + HelpExampleCli("gettxoutsetinfo", "")
483 + HelpExampleRpc("gettxoutsetinfo", "")
484 );
beeb5761 485
38fc4b70 486 UniValue ret(UniValue::VOBJ);
beeb5761
PW
487
488 CCoinsStats stats;
51ce901a 489 FlushStateToDisk();
beeb5761 490 if (pcoinsTip->GetStats(stats)) {
4b61a6a4 491 ret.push_back(Pair("height", (int64_t)stats.nHeight));
e31aa7c9 492 ret.push_back(Pair("bestblock", stats.hashBlock.GetHex()));
4b61a6a4
KD
493 ret.push_back(Pair("transactions", (int64_t)stats.nTransactions));
494 ret.push_back(Pair("txouts", (int64_t)stats.nTransactionOutputs));
495 ret.push_back(Pair("bytes_serialized", (int64_t)stats.nSerializedSize));
e31aa7c9
PW
496 ret.push_back(Pair("hash_serialized", stats.hashSerialized.GetHex()));
497 ret.push_back(Pair("total_amount", ValueFromAmount(stats.nTotalAmount)));
beeb5761
PW
498 }
499 return ret;
500}
c625ae04 501
d014114d 502UniValue gettxout(const UniValue& params, bool fHelp)
beeb5761
PW
503{
504 if (fHelp || params.size() < 2 || params.size() > 3)
505 throw runtime_error(
a6099ef3 506 "gettxout \"txid\" n ( includemempool )\n"
507 "\nReturns details about an unspent transaction output.\n"
508 "\nArguments:\n"
509 "1. \"txid\" (string, required) The transaction id\n"
510 "2. n (numeric, required) vout value\n"
511 "3. includemempool (boolean, optional) Whether to included the mem pool\n"
512 "\nResult:\n"
513 "{\n"
514 " \"bestblock\" : \"hash\", (string) the block hash\n"
515 " \"confirmations\" : n, (numeric) The number of confirmations\n"
091b2116 516 " \"value\" : x.xxx, (numeric) The transaction value in " + CURRENCY_UNIT + "\n"
a6099ef3 517 " \"scriptPubKey\" : { (json object)\n"
518 " \"asm\" : \"code\", (string) \n"
519 " \"hex\" : \"hex\", (string) \n"
520 " \"reqSigs\" : n, (numeric) Number of required signatures\n"
521 " \"type\" : \"pubkeyhash\", (string) The type, eg pubkeyhash\n"
c1652849
JG
522 " \"addresses\" : [ (array of string) array of Zcash addresses\n"
523 " \"zcashaddress\" (string) Zcash address\n"
a6099ef3 524 " ,...\n"
525 " ]\n"
526 " },\n"
d2c1e4a8
BA
527 " \"version\" : n, (numeric) The version\n"
528 " \"coinbase\" : true|false (boolean) Coinbase or not\n"
a6099ef3 529 "}\n"
530
531 "\nExamples:\n"
532 "\nGet unspent transactions\n"
533 + HelpExampleCli("listunspent", "") +
534 "\nView the details\n"
535 + HelpExampleCli("gettxout", "\"txid\" 1") +
536 "\nAs a json rpc call\n"
537 + HelpExampleRpc("gettxout", "\"txid\", 1")
538 );
c625ae04 539
4401b2d7
EL
540 LOCK(cs_main);
541
38fc4b70 542 UniValue ret(UniValue::VOBJ);
beeb5761
PW
543
544 std::string strHash = params[0].get_str();
34cdc411 545 uint256 hash(uint256S(strHash));
beeb5761
PW
546 int n = params[1].get_int();
547 bool fMempool = true;
548 if (params.size() > 2)
549 fMempool = params[2].get_bool();
550
551 CCoins coins;
552 if (fMempool) {
553 LOCK(mempool.cs);
7c70438d 554 CCoinsViewMemPool view(pcoinsTip, mempool);
beeb5761 555 if (!view.GetCoins(hash, coins))
ed21d5bd 556 return NullUniValue;
beeb5761
PW
557 mempool.pruneSpent(hash, coins); // TODO: this should be done by the CCoinsViewMemPool
558 } else {
559 if (!pcoinsTip->GetCoins(hash, coins))
ed21d5bd 560 return NullUniValue;
beeb5761
PW
561 }
562 if (n<0 || (unsigned int)n>=coins.vout.size() || coins.vout[n].IsNull())
ed21d5bd 563 return NullUniValue;
beeb5761 564
145d5be8 565 BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock());
84674082
PW
566 CBlockIndex *pindex = it->second;
567 ret.push_back(Pair("bestblock", pindex->GetBlockHash().GetHex()));
beeb5761
PW
568 if ((unsigned int)coins.nHeight == MEMPOOL_HEIGHT)
569 ret.push_back(Pair("confirmations", 0));
570 else
84674082 571 ret.push_back(Pair("confirmations", pindex->nHeight - coins.nHeight + 1));
4e68391a 572 ret.push_back(Pair("value", ValueFromAmount(coins.vout[n].nValue)));
38fc4b70 573 UniValue o(UniValue::VOBJ);
be066fad 574 ScriptPubKeyToJSON(coins.vout[n].scriptPubKey, o, true);
beeb5761
PW
575 ret.push_back(Pair("scriptPubKey", o));
576 ret.push_back(Pair("version", coins.nVersion));
577 ret.push_back(Pair("coinbase", coins.fCoinBase));
578
579 return ret;
580}
c625ae04 581
d014114d 582UniValue verifychain(const UniValue& params, bool fHelp)
f5906533
JG
583{
584 if (fHelp || params.size() > 2)
585 throw runtime_error(
a6099ef3 586 "verifychain ( checklevel numblocks )\n"
587 "\nVerifies blockchain database.\n"
588 "\nArguments:\n"
6943cb9b
PK
589 "1. checklevel (numeric, optional, 0-4, default=3) How thorough the block verification is.\n"
590 "2. numblocks (numeric, optional, default=288, 0=all) The number of blocks to check.\n"
a6099ef3 591 "\nResult:\n"
592 "true|false (boolean) Verified or not\n"
593 "\nExamples:\n"
594 + HelpExampleCli("verifychain", "")
595 + HelpExampleRpc("verifychain", "")
596 );
f5906533 597
4401b2d7
EL
598 LOCK(cs_main);
599
f5906533
JG
600 int nCheckLevel = GetArg("-checklevel", 3);
601 int nCheckDepth = GetArg("-checkblocks", 288);
602 if (params.size() > 0)
603 nCheckLevel = params[0].get_int();
604 if (params.size() > 1)
605 nCheckDepth = params[1].get_int();
606
2e280311 607 return CVerifyDB().VerifyDB(pcoinsTip, nCheckLevel, nCheckDepth);
f5906533 608}
c625ae04 609
ba1da90b 610/** Implementation of IsSuperMajority with better feedback */
0d37ae3a 611static UniValue SoftForkMajorityDesc(int minVersion, CBlockIndex* pindex, int nRequired, const Consensus::Params& consensusParams)
ba1da90b
WL
612{
613 int nFound = 0;
614 CBlockIndex* pstart = pindex;
615 for (int i = 0; i < consensusParams.nMajorityWindow && pstart != NULL; i++)
616 {
617 if (pstart->nVersion >= minVersion)
618 ++nFound;
619 pstart = pstart->pprev;
620 }
621
0d37ae3a 622 UniValue rv(UniValue::VOBJ);
ba1da90b
WL
623 rv.push_back(Pair("status", nFound >= nRequired));
624 rv.push_back(Pair("found", nFound));
625 rv.push_back(Pair("required", nRequired));
626 rv.push_back(Pair("window", consensusParams.nMajorityWindow));
627 return rv;
628}
629
0d37ae3a 630static UniValue SoftForkDesc(const std::string &name, int version, CBlockIndex* pindex, const Consensus::Params& consensusParams)
ba1da90b 631{
0d37ae3a 632 UniValue rv(UniValue::VOBJ);
ba1da90b
WL
633 rv.push_back(Pair("id", name));
634 rv.push_back(Pair("version", version));
635 rv.push_back(Pair("enforce", SoftForkMajorityDesc(version, pindex, consensusParams.nMajorityEnforceBlockUpgrade, consensusParams)));
636 rv.push_back(Pair("reject", SoftForkMajorityDesc(version, pindex, consensusParams.nMajorityRejectBlockOutdated, consensusParams)));
637 return rv;
638}
639
d014114d 640UniValue getblockchaininfo(const UniValue& params, bool fHelp)
d387b8ec
WL
641{
642 if (fHelp || params.size() != 0)
643 throw runtime_error(
644 "getblockchaininfo\n"
645 "Returns an object containing various state info regarding block chain processing.\n"
646 "\nResult:\n"
647 "{\n"
f6984e81 648 " \"chain\": \"xxxx\", (string) current network name as defined in BIP70 (main, test, regtest)\n"
d387b8ec 649 " \"blocks\": xxxxxx, (numeric) the current number of blocks processed in the server\n"
ad6e6017 650 " \"headers\": xxxxxx, (numeric) the current number of headers we have validated\n"
d387b8ec
WL
651 " \"bestblockhash\": \"...\", (string) the hash of the currently best block\n"
652 " \"difficulty\": xxxxxx, (numeric) the current difficulty\n"
653 " \"verificationprogress\": xxxx, (numeric) estimate of verification progress [0..1]\n"
654 " \"chainwork\": \"xxxx\" (string) total amount of work in active chain, in hexadecimal\n"
5d6e1aa6 655 " \"commitments\": xxxxxx, (numeric) the current number of note commitments in the commitment tree\n"
ba1da90b
WL
656 " \"softforks\": [ (array) status of softforks in progress\n"
657 " {\n"
658 " \"id\": \"xxxx\", (string) name of softfork\n"
659 " \"version\": xx, (numeric) block version\n"
660 " \"enforce\": { (object) progress toward enforcing the softfork rules for new-version blocks\n"
661 " \"status\": xx, (boolean) true if threshold reached\n"
662 " \"found\": xx, (numeric) number of blocks with the new version found\n"
663 " \"required\": xx, (numeric) number of blocks required to trigger\n"
664 " \"window\": xx, (numeric) maximum size of examined window of recent blocks\n"
665 " },\n"
666 " \"reject\": { ... } (object) progress toward rejecting pre-softfork blocks (same fields as \"enforce\")\n"
667 " }, ...\n"
668 " ]\n"
d387b8ec
WL
669 "}\n"
670 "\nExamples:\n"
671 + HelpExampleCli("getblockchaininfo", "")
672 + HelpExampleRpc("getblockchaininfo", "")
673 );
674
4401b2d7
EL
675 LOCK(cs_main);
676
38fc4b70 677 UniValue obj(UniValue::VOBJ);
f5ae6c98
PK
678 obj.push_back(Pair("chain", Params().NetworkIDString()));
679 obj.push_back(Pair("blocks", (int)chainActive.Height()));
ad6e6017 680 obj.push_back(Pair("headers", pindexBestHeader ? pindexBestHeader->nHeight : -1));
f5ae6c98 681 obj.push_back(Pair("bestblockhash", chainActive.Tip()->GetBlockHash().GetHex()));
695a7a88 682 obj.push_back(Pair("difficulty", (double)GetNetworkDifficulty()));
11982d36 683 obj.push_back(Pair("verificationprogress", Checkpoints::GuessVerificationProgress(Params().Checkpoints(), chainActive.Tip())));
f5ae6c98 684 obj.push_back(Pair("chainwork", chainActive.Tip()->nChainWork.GetHex()));
1b2e5555 685 obj.push_back(Pair("pruned", fPruneMode));
ba1da90b 686
5d6e1aa6
JG
687 ZCIncrementalMerkleTree tree;
688 pcoinsTip->GetAnchorAt(pcoinsTip->GetBestAnchor(), tree);
689 obj.push_back(Pair("commitments", tree.size()));
690
ba1da90b
WL
691 const Consensus::Params& consensusParams = Params().GetConsensus();
692 CBlockIndex* tip = chainActive.Tip();
0d37ae3a 693 UniValue softforks(UniValue::VARR);
ba1da90b
WL
694 softforks.push_back(SoftForkDesc("bip34", 2, tip, consensusParams));
695 softforks.push_back(SoftForkDesc("bip66", 3, tip, consensusParams));
6af25b0f 696 softforks.push_back(SoftForkDesc("bip65", 4, tip, consensusParams));
ba1da90b
WL
697 obj.push_back(Pair("softforks", softforks));
698
1b2e5555
JS
699 if (fPruneMode)
700 {
701 CBlockIndex *block = chainActive.Tip();
702 while (block && block->pprev && (block->pprev->nStatus & BLOCK_HAVE_DATA))
703 block = block->pprev;
704
705 obj.push_back(Pair("pruneheight", block->nHeight));
706 }
d387b8ec
WL
707 return obj;
708}
b33bd7a3 709
72fb3d29 710/** Comparison function for sorting the getchaintips heads. */
b33bd7a3
DK
711struct CompareBlocksByHeight
712{
713 bool operator()(const CBlockIndex* a, const CBlockIndex* b) const
714 {
715 /* Make sure that unequal blocks with the same height do not compare
771d5002 716 equal. Use the pointers themselves to make a distinction. */
b33bd7a3
DK
717
718 if (a->nHeight != b->nHeight)
719 return (a->nHeight > b->nHeight);
720
721 return a < b;
722 }
723};
724
d014114d 725UniValue getchaintips(const UniValue& params, bool fHelp)
b33bd7a3
DK
726{
727 if (fHelp || params.size() != 0)
728 throw runtime_error(
729 "getchaintips\n"
730 "Return information about all known tips in the block tree,"
731 " including the main chain as well as orphaned branches.\n"
732 "\nResult:\n"
733 "[\n"
734 " {\n"
735 " \"height\": xxxx, (numeric) height of the chain tip\n"
736 " \"hash\": \"xxxx\", (string) block hash of the tip\n"
737 " \"branchlen\": 0 (numeric) zero for main chain\n"
1b91be49 738 " \"status\": \"active\" (string) \"active\" for the main chain\n"
b33bd7a3
DK
739 " },\n"
740 " {\n"
741 " \"height\": xxxx,\n"
742 " \"hash\": \"xxxx\",\n"
743 " \"branchlen\": 1 (numeric) length of branch connecting the tip to the main chain\n"
1b91be49 744 " \"status\": \"xxxx\" (string) status of the chain (active, valid-fork, valid-headers, headers-only, invalid)\n"
b33bd7a3
DK
745 " }\n"
746 "]\n"
32b93a1b
PW
747 "Possible values for status:\n"
748 "1. \"invalid\" This branch contains at least one invalid block\n"
749 "2. \"headers-only\" Not all blocks for this branch are available, but the headers are valid\n"
750 "3. \"valid-headers\" All blocks are available for this branch, but they were never fully validated\n"
751 "4. \"valid-fork\" This branch is not part of the active chain, but is fully validated\n"
752 "5. \"active\" This is the tip of the active main chain, which is certainly valid\n"
b33bd7a3
DK
753 "\nExamples:\n"
754 + HelpExampleCli("getchaintips", "")
755 + HelpExampleRpc("getchaintips", "")
756 );
757
4401b2d7
EL
758 LOCK(cs_main);
759
b33bd7a3
DK
760 /* Build up a list of chain tips. We start with the list of all
761 known blocks, and successively remove blocks that appear as pprev
762 of another block. */
763 std::set<const CBlockIndex*, CompareBlocksByHeight> setTips;
764 BOOST_FOREACH(const PAIRTYPE(const uint256, CBlockIndex*)& item, mapBlockIndex)
765 setTips.insert(item.second);
766 BOOST_FOREACH(const PAIRTYPE(const uint256, CBlockIndex*)& item, mapBlockIndex)
767 {
768 const CBlockIndex* pprev = item.second->pprev;
769 if (pprev)
770 setTips.erase(pprev);
771 }
772
1b91be49
PW
773 // Always report the currently active tip.
774 setTips.insert(chainActive.Tip());
775
b33bd7a3 776 /* Construct the output array. */
38fc4b70 777 UniValue res(UniValue::VARR);
b33bd7a3
DK
778 BOOST_FOREACH(const CBlockIndex* block, setTips)
779 {
38fc4b70 780 UniValue obj(UniValue::VOBJ);
b33bd7a3
DK
781 obj.push_back(Pair("height", block->nHeight));
782 obj.push_back(Pair("hash", block->phashBlock->GetHex()));
783
784 const int branchLen = block->nHeight - chainActive.FindFork(block)->nHeight;
785 obj.push_back(Pair("branchlen", branchLen));
786
1b91be49
PW
787 string status;
788 if (chainActive.Contains(block)) {
789 // This block is part of the currently active chain.
790 status = "active";
791 } else if (block->nStatus & BLOCK_FAILED_MASK) {
792 // This block or one of its ancestors is invalid.
793 status = "invalid";
794 } else if (block->nChainTx == 0) {
795 // This block cannot be connected because full block data for it or one of its parents is missing.
796 status = "headers-only";
797 } else if (block->IsValid(BLOCK_VALID_SCRIPTS)) {
798 // This block is fully validated, but no longer part of the active chain. It was probably the active block once, but was reorganized.
799 status = "valid-fork";
800 } else if (block->IsValid(BLOCK_VALID_TREE)) {
801 // The headers for this block are valid, but it has not been validated. It was probably never part of the most-work chain.
802 status = "valid-headers";
803 } else {
804 // No clue.
805 status = "unknown";
806 }
807 obj.push_back(Pair("status", status));
808
b33bd7a3
DK
809 res.push_back(obj);
810 }
811
812 return res;
813}
6f2c26a4 814
30c163d9
PJ
815UniValue mempoolInfoToJSON()
816{
817 UniValue ret(UniValue::VOBJ);
818 ret.push_back(Pair("size", (int64_t) mempool.size()));
819 ret.push_back(Pair("bytes", (int64_t) mempool.GetTotalTxSize()));
820 ret.push_back(Pair("usage", (int64_t) mempool.DynamicMemoryUsage()));
821
822 return ret;
823}
824
d014114d 825UniValue getmempoolinfo(const UniValue& params, bool fHelp)
6f2c26a4
JG
826{
827 if (fHelp || params.size() != 0)
828 throw runtime_error(
829 "getmempoolinfo\n"
830 "\nReturns details on the active state of the TX memory pool.\n"
831 "\nResult:\n"
832 "{\n"
833 " \"size\": xxxxx (numeric) Current tx count\n"
834 " \"bytes\": xxxxx (numeric) Sum of all tx sizes\n"
bde5c8b0 835 " \"usage\": xxxxx (numeric) Total memory usage for the mempool\n"
6f2c26a4
JG
836 "}\n"
837 "\nExamples:\n"
838 + HelpExampleCli("getmempoolinfo", "")
839 + HelpExampleRpc("getmempoolinfo", "")
840 );
841
30c163d9 842 return mempoolInfoToJSON();
6f2c26a4
JG
843}
844
d014114d 845UniValue invalidateblock(const UniValue& params, bool fHelp)
9b0a8d31
PW
846{
847 if (fHelp || params.size() != 1)
848 throw runtime_error(
849 "invalidateblock \"hash\"\n"
850 "\nPermanently marks a block as invalid, as if it violated a consensus rule.\n"
851 "\nArguments:\n"
852 "1. hash (string, required) the hash of the block to mark as invalid\n"
853 "\nResult:\n"
854 "\nExamples:\n"
855 + HelpExampleCli("invalidateblock", "\"blockhash\"")
856 + HelpExampleRpc("invalidateblock", "\"blockhash\"")
857 );
858
859 std::string strHash = params[0].get_str();
34cdc411 860 uint256 hash(uint256S(strHash));
9b0a8d31
PW
861 CValidationState state;
862
863 {
864 LOCK(cs_main);
865 if (mapBlockIndex.count(hash) == 0)
866 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
867
868 CBlockIndex* pblockindex = mapBlockIndex[hash];
869 InvalidateBlock(state, pblockindex);
870 }
871
872 if (state.IsValid()) {
873 ActivateBestChain(state);
874 }
875
876 if (!state.IsValid()) {
877 throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason());
878 }
879
9756b7bd 880 return NullUniValue;
9b0a8d31
PW
881}
882
d014114d 883UniValue reconsiderblock(const UniValue& params, bool fHelp)
9b0a8d31
PW
884{
885 if (fHelp || params.size() != 1)
886 throw runtime_error(
887 "reconsiderblock \"hash\"\n"
888 "\nRemoves invalidity status of a block and its descendants, reconsider them for activation.\n"
889 "This can be used to undo the effects of invalidateblock.\n"
890 "\nArguments:\n"
891 "1. hash (string, required) the hash of the block to reconsider\n"
892 "\nResult:\n"
893 "\nExamples:\n"
894 + HelpExampleCli("reconsiderblock", "\"blockhash\"")
895 + HelpExampleRpc("reconsiderblock", "\"blockhash\"")
896 );
897
898 std::string strHash = params[0].get_str();
34cdc411 899 uint256 hash(uint256S(strHash));
9b0a8d31
PW
900 CValidationState state;
901
902 {
903 LOCK(cs_main);
904 if (mapBlockIndex.count(hash) == 0)
905 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
906
907 CBlockIndex* pblockindex = mapBlockIndex[hash];
908 ReconsiderBlock(state, pblockindex);
909 }
910
911 if (state.IsValid()) {
912 ActivateBestChain(state);
913 }
914
915 if (!state.IsValid()) {
916 throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason());
917 }
918
9756b7bd 919 return NullUniValue;
9b0a8d31 920}
This page took 0.266692 seconds and 4 git commands to generate.