LCOV - code coverage report
Current view: top level - src - rpcblockchain.cpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 214 372 57.5 %
Date: 2015-10-12 22:39:14 Functions: 17 25 68.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.11