From a0eaff8a1d18ebba33cdea4cd1efaddeb55519e7 Mon Sep 17 00:00:00 2001 From: Daniel Cousens Date: Fri, 15 Jan 2016 11:55:17 +1100 Subject: move rpc* to rpc/ --- src/rpc/blockchain.cpp | 891 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 891 insertions(+) create mode 100644 src/rpc/blockchain.cpp (limited to 'src/rpc/blockchain.cpp') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp new file mode 100644 index 000000000..de6bda4ea --- /dev/null +++ b/src/rpc/blockchain.cpp @@ -0,0 +1,891 @@ +// Copyright (c) 2010 Satoshi Nakamoto +// Copyright (c) 2009-2015 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "amount.h" +#include "chain.h" +#include "chainparams.h" +#include "checkpoints.h" +#include "coins.h" +#include "consensus/validation.h" +#include "main.h" +#include "policy/policy.h" +#include "primitives/transaction.h" +#include "rpc/server.h" +#include "streams.h" +#include "sync.h" +#include "txmempool.h" +#include "util.h" +#include "utilstrencodings.h" + +#include + +#include + +using namespace std; + +extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry); +void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex); + +double GetDifficulty(const CBlockIndex* blockindex) +{ + // Floating point number that is a multiple of the minimum difficulty, + // minimum difficulty = 1.0. + if (blockindex == NULL) + { + if (chainActive.Tip() == NULL) + return 1.0; + else + blockindex = chainActive.Tip(); + } + + int nShift = (blockindex->nBits >> 24) & 0xff; + + double dDiff = + (double)0x0000ffff / (double)(blockindex->nBits & 0x00ffffff); + + while (nShift < 29) + { + dDiff *= 256.0; + nShift++; + } + while (nShift > 29) + { + dDiff /= 256.0; + nShift--; + } + + return dDiff; +} + +UniValue blockheaderToJSON(const CBlockIndex* blockindex) +{ + UniValue result(UniValue::VOBJ); + result.push_back(Pair("hash", blockindex->GetBlockHash().GetHex())); + int confirmations = -1; + // Only report confirmations if the block is on the main chain + if (chainActive.Contains(blockindex)) + confirmations = chainActive.Height() - blockindex->nHeight + 1; + result.push_back(Pair("confirmations", confirmations)); + result.push_back(Pair("height", blockindex->nHeight)); + result.push_back(Pair("version", blockindex->nVersion)); + result.push_back(Pair("merkleroot", blockindex->hashMerkleRoot.GetHex())); + result.push_back(Pair("time", (int64_t)blockindex->nTime)); + result.push_back(Pair("mediantime", (int64_t)blockindex->GetMedianTimePast())); + result.push_back(Pair("nonce", (uint64_t)blockindex->nNonce)); + result.push_back(Pair("bits", strprintf("%08x", blockindex->nBits))); + result.push_back(Pair("difficulty", GetDifficulty(blockindex))); + result.push_back(Pair("chainwork", blockindex->nChainWork.GetHex())); + + if (blockindex->pprev) + result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex())); + CBlockIndex *pnext = chainActive.Next(blockindex); + if (pnext) + result.push_back(Pair("nextblockhash", pnext->GetBlockHash().GetHex())); + return result; +} + +UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false) +{ + UniValue result(UniValue::VOBJ); + result.push_back(Pair("hash", block.GetHash().GetHex())); + int confirmations = -1; + // Only report confirmations if the block is on the main chain + if (chainActive.Contains(blockindex)) + confirmations = chainActive.Height() - blockindex->nHeight + 1; + result.push_back(Pair("confirmations", confirmations)); + result.push_back(Pair("size", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION))); + result.push_back(Pair("height", blockindex->nHeight)); + result.push_back(Pair("version", block.nVersion)); + result.push_back(Pair("merkleroot", block.hashMerkleRoot.GetHex())); + UniValue txs(UniValue::VARR); + BOOST_FOREACH(const CTransaction&tx, block.vtx) + { + if(txDetails) + { + UniValue objTx(UniValue::VOBJ); + TxToJSON(tx, uint256(), objTx); + txs.push_back(objTx); + } + else + txs.push_back(tx.GetHash().GetHex()); + } + result.push_back(Pair("tx", txs)); + result.push_back(Pair("time", block.GetBlockTime())); + result.push_back(Pair("mediantime", (int64_t)blockindex->GetMedianTimePast())); + result.push_back(Pair("nonce", (uint64_t)block.nNonce)); + result.push_back(Pair("bits", strprintf("%08x", block.nBits))); + result.push_back(Pair("difficulty", GetDifficulty(blockindex))); + result.push_back(Pair("chainwork", blockindex->nChainWork.GetHex())); + + if (blockindex->pprev) + result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex())); + CBlockIndex *pnext = chainActive.Next(blockindex); + if (pnext) + result.push_back(Pair("nextblockhash", pnext->GetBlockHash().GetHex())); + return result; +} + +UniValue getblockcount(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() != 0) + throw runtime_error( + "getblockcount\n" + "\nReturns the number of blocks in the longest block chain.\n" + "\nResult:\n" + "n (numeric) The current block count\n" + "\nExamples:\n" + + HelpExampleCli("getblockcount", "") + + HelpExampleRpc("getblockcount", "") + ); + + LOCK(cs_main); + return chainActive.Height(); +} + +UniValue getbestblockhash(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() != 0) + throw runtime_error( + "getbestblockhash\n" + "\nReturns the hash of the best (tip) block in the longest block chain.\n" + "\nResult\n" + "\"hex\" (string) the block hash hex encoded\n" + "\nExamples\n" + + HelpExampleCli("getbestblockhash", "") + + HelpExampleRpc("getbestblockhash", "") + ); + + LOCK(cs_main); + return chainActive.Tip()->GetBlockHash().GetHex(); +} + +UniValue getdifficulty(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() != 0) + throw runtime_error( + "getdifficulty\n" + "\nReturns the proof-of-work difficulty as a multiple of the minimum difficulty.\n" + "\nResult:\n" + "n.nnn (numeric) the proof-of-work difficulty as a multiple of the minimum difficulty.\n" + "\nExamples:\n" + + HelpExampleCli("getdifficulty", "") + + HelpExampleRpc("getdifficulty", "") + ); + + LOCK(cs_main); + return GetDifficulty(); +} + +UniValue mempoolToJSON(bool fVerbose = false) +{ + if (fVerbose) + { + LOCK(mempool.cs); + UniValue o(UniValue::VOBJ); + BOOST_FOREACH(const CTxMemPoolEntry& e, mempool.mapTx) + { + const uint256& hash = e.GetTx().GetHash(); + UniValue info(UniValue::VOBJ); + info.push_back(Pair("size", (int)e.GetTxSize())); + info.push_back(Pair("fee", ValueFromAmount(e.GetFee()))); + info.push_back(Pair("modifiedfee", ValueFromAmount(e.GetModifiedFee()))); + info.push_back(Pair("time", e.GetTime())); + info.push_back(Pair("height", (int)e.GetHeight())); + info.push_back(Pair("startingpriority", e.GetPriority(e.GetHeight()))); + info.push_back(Pair("currentpriority", e.GetPriority(chainActive.Height()))); + info.push_back(Pair("descendantcount", e.GetCountWithDescendants())); + info.push_back(Pair("descendantsize", e.GetSizeWithDescendants())); + info.push_back(Pair("descendantfees", e.GetModFeesWithDescendants())); + const CTransaction& tx = e.GetTx(); + set setDepends; + BOOST_FOREACH(const CTxIn& txin, tx.vin) + { + if (mempool.exists(txin.prevout.hash)) + setDepends.insert(txin.prevout.hash.ToString()); + } + + UniValue depends(UniValue::VARR); + BOOST_FOREACH(const string& dep, setDepends) + { + depends.push_back(dep); + } + + info.push_back(Pair("depends", depends)); + o.push_back(Pair(hash.ToString(), info)); + } + return o; + } + else + { + vector vtxid; + mempool.queryHashes(vtxid); + + UniValue a(UniValue::VARR); + BOOST_FOREACH(const uint256& hash, vtxid) + a.push_back(hash.ToString()); + + return a; + } +} + +UniValue getrawmempool(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() > 1) + throw runtime_error( + "getrawmempool ( verbose )\n" + "\nReturns all transaction ids in memory pool as a json array of string transaction ids.\n" + "\nArguments:\n" + "1. verbose (boolean, optional, default=false) true for a json object, false for array of transaction ids\n" + "\nResult: (for verbose = false):\n" + "[ (json array of string)\n" + " \"transactionid\" (string) The transaction id\n" + " ,...\n" + "]\n" + "\nResult: (for verbose = true):\n" + "{ (json object)\n" + " \"transactionid\" : { (json object)\n" + " \"size\" : n, (numeric) transaction size in bytes\n" + " \"fee\" : n, (numeric) transaction fee in " + CURRENCY_UNIT + "\n" + " \"modifiedfee\" : n, (numeric) transaction fee with fee deltas used for mining priority\n" + " \"time\" : n, (numeric) local time transaction entered pool in seconds since 1 Jan 1970 GMT\n" + " \"height\" : n, (numeric) block height when transaction entered pool\n" + " \"startingpriority\" : n, (numeric) priority when transaction entered pool\n" + " \"currentpriority\" : n, (numeric) transaction priority now\n" + " \"descendantcount\" : n, (numeric) number of in-mempool descendant transactions (including this one)\n" + " \"descendantsize\" : n, (numeric) size of in-mempool descendants (including this one)\n" + " \"descendantfees\" : n, (numeric) modified fees (see above) of in-mempool descendants (including this one)\n" + " \"depends\" : [ (array) unconfirmed transactions used as inputs for this transaction\n" + " \"transactionid\", (string) parent transaction id\n" + " ... ]\n" + " }, ...\n" + "}\n" + "\nExamples\n" + + HelpExampleCli("getrawmempool", "true") + + HelpExampleRpc("getrawmempool", "true") + ); + + LOCK(cs_main); + + bool fVerbose = false; + if (params.size() > 0) + fVerbose = params[0].get_bool(); + + return mempoolToJSON(fVerbose); +} + +UniValue getblockhash(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() != 1) + throw runtime_error( + "getblockhash index\n" + "\nReturns hash of block in best-block-chain at index provided.\n" + "\nArguments:\n" + "1. index (numeric, required) The block index\n" + "\nResult:\n" + "\"hash\" (string) The block hash\n" + "\nExamples:\n" + + HelpExampleCli("getblockhash", "1000") + + HelpExampleRpc("getblockhash", "1000") + ); + + LOCK(cs_main); + + int nHeight = params[0].get_int(); + if (nHeight < 0 || nHeight > chainActive.Height()) + throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range"); + + CBlockIndex* pblockindex = chainActive[nHeight]; + return pblockindex->GetBlockHash().GetHex(); +} + +UniValue getblockheader(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() < 1 || params.size() > 2) + throw runtime_error( + "getblockheader \"hash\" ( verbose )\n" + "\nIf verbose is false, returns a string that is serialized, hex-encoded data for blockheader 'hash'.\n" + "If verbose is true, returns an Object with information about blockheader .\n" + "\nArguments:\n" + "1. \"hash\" (string, required) The block hash\n" + "2. verbose (boolean, optional, default=true) true for a json object, false for the hex encoded data\n" + "\nResult (for verbose = true):\n" + "{\n" + " \"hash\" : \"hash\", (string) the block hash (same as provided)\n" + " \"confirmations\" : n, (numeric) The number of confirmations, or -1 if the block is not on the main chain\n" + " \"height\" : n, (numeric) The block height or index\n" + " \"version\" : n, (numeric) The block version\n" + " \"merkleroot\" : \"xxxx\", (string) The merkle root\n" + " \"time\" : ttt, (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)\n" + " \"mediantime\" : ttt, (numeric) The median block time in seconds since epoch (Jan 1 1970 GMT)\n" + " \"nonce\" : n, (numeric) The nonce\n" + " \"bits\" : \"1d00ffff\", (string) The bits\n" + " \"difficulty\" : x.xxx, (numeric) The difficulty\n" + " \"previousblockhash\" : \"hash\", (string) The hash of the previous block\n" + " \"nextblockhash\" : \"hash\", (string) The hash of the next block\n" + " \"chainwork\" : \"0000...1f3\" (string) Expected number of hashes required to produce the current chain (in hex)\n" + "}\n" + "\nResult (for verbose=false):\n" + "\"data\" (string) A string that is serialized, hex-encoded data for block 'hash'.\n" + "\nExamples:\n" + + HelpExampleCli("getblockheader", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"") + + HelpExampleRpc("getblockheader", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"") + ); + + LOCK(cs_main); + + std::string strHash = params[0].get_str(); + uint256 hash(uint256S(strHash)); + + bool fVerbose = true; + if (params.size() > 1) + fVerbose = params[1].get_bool(); + + if (mapBlockIndex.count(hash) == 0) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); + + CBlockIndex* pblockindex = mapBlockIndex[hash]; + + if (!fVerbose) + { + CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION); + ssBlock << pblockindex->GetBlockHeader(); + std::string strHex = HexStr(ssBlock.begin(), ssBlock.end()); + return strHex; + } + + return blockheaderToJSON(pblockindex); +} + +UniValue getblock(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() < 1 || params.size() > 2) + throw runtime_error( + "getblock \"hash\" ( verbose )\n" + "\nIf verbose is false, returns a string that is serialized, hex-encoded data for block 'hash'.\n" + "If verbose is true, returns an Object with information about block .\n" + "\nArguments:\n" + "1. \"hash\" (string, required) The block hash\n" + "2. verbose (boolean, optional, default=true) true for a json object, false for the hex encoded data\n" + "\nResult (for verbose = true):\n" + "{\n" + " \"hash\" : \"hash\", (string) the block hash (same as provided)\n" + " \"confirmations\" : n, (numeric) The number of confirmations, or -1 if the block is not on the main chain\n" + " \"size\" : n, (numeric) The block size\n" + " \"height\" : n, (numeric) The block height or index\n" + " \"version\" : n, (numeric) The block version\n" + " \"merkleroot\" : \"xxxx\", (string) The merkle root\n" + " \"tx\" : [ (array of string) The transaction ids\n" + " \"transactionid\" (string) The transaction id\n" + " ,...\n" + " ],\n" + " \"time\" : ttt, (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)\n" + " \"mediantime\" : ttt, (numeric) The median block time in seconds since epoch (Jan 1 1970 GMT)\n" + " \"nonce\" : n, (numeric) The nonce\n" + " \"bits\" : \"1d00ffff\", (string) The bits\n" + " \"difficulty\" : x.xxx, (numeric) The difficulty\n" + " \"chainwork\" : \"xxxx\", (string) Expected number of hashes required to produce the chain up to this block (in hex)\n" + " \"previousblockhash\" : \"hash\", (string) The hash of the previous block\n" + " \"nextblockhash\" : \"hash\" (string) The hash of the next block\n" + "}\n" + "\nResult (for verbose=false):\n" + "\"data\" (string) A string that is serialized, hex-encoded data for block 'hash'.\n" + "\nExamples:\n" + + HelpExampleCli("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"") + + HelpExampleRpc("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"") + ); + + LOCK(cs_main); + + std::string strHash = params[0].get_str(); + uint256 hash(uint256S(strHash)); + + bool fVerbose = true; + if (params.size() > 1) + fVerbose = params[1].get_bool(); + + if (mapBlockIndex.count(hash) == 0) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); + + CBlock block; + CBlockIndex* pblockindex = mapBlockIndex[hash]; + + if (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0) + throw JSONRPCError(RPC_INTERNAL_ERROR, "Block not available (pruned data)"); + + if(!ReadBlockFromDisk(block, pblockindex, Params().GetConsensus())) + throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk"); + + if (!fVerbose) + { + CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION); + ssBlock << block; + std::string strHex = HexStr(ssBlock.begin(), ssBlock.end()); + return strHex; + } + + return blockToJSON(block, pblockindex); +} + +UniValue gettxoutsetinfo(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() != 0) + throw runtime_error( + "gettxoutsetinfo\n" + "\nReturns statistics about the unspent transaction output set.\n" + "Note this call may take some time.\n" + "\nResult:\n" + "{\n" + " \"height\":n, (numeric) The current block height (index)\n" + " \"bestblock\": \"hex\", (string) the best block hash hex\n" + " \"transactions\": n, (numeric) The number of transactions\n" + " \"txouts\": n, (numeric) The number of output transactions\n" + " \"bytes_serialized\": n, (numeric) The serialized size\n" + " \"hash_serialized\": \"hash\", (string) The serialized hash\n" + " \"total_amount\": x.xxx (numeric) The total amount\n" + "}\n" + "\nExamples:\n" + + HelpExampleCli("gettxoutsetinfo", "") + + HelpExampleRpc("gettxoutsetinfo", "") + ); + + UniValue ret(UniValue::VOBJ); + + CCoinsStats stats; + FlushStateToDisk(); + if (pcoinsTip->GetStats(stats)) { + ret.push_back(Pair("height", (int64_t)stats.nHeight)); + ret.push_back(Pair("bestblock", stats.hashBlock.GetHex())); + ret.push_back(Pair("transactions", (int64_t)stats.nTransactions)); + ret.push_back(Pair("txouts", (int64_t)stats.nTransactionOutputs)); + ret.push_back(Pair("bytes_serialized", (int64_t)stats.nSerializedSize)); + ret.push_back(Pair("hash_serialized", stats.hashSerialized.GetHex())); + ret.push_back(Pair("total_amount", ValueFromAmount(stats.nTotalAmount))); + } + return ret; +} + +UniValue gettxout(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() < 2 || params.size() > 3) + throw runtime_error( + "gettxout \"txid\" n ( includemempool )\n" + "\nReturns details about an unspent transaction output.\n" + "\nArguments:\n" + "1. \"txid\" (string, required) The transaction id\n" + "2. n (numeric, required) vout number\n" + "3. includemempool (boolean, optional) Whether to include the mem pool\n" + "\nResult:\n" + "{\n" + " \"bestblock\" : \"hash\", (string) the block hash\n" + " \"confirmations\" : n, (numeric) The number of confirmations\n" + " \"value\" : x.xxx, (numeric) The transaction value in " + CURRENCY_UNIT + "\n" + " \"scriptPubKey\" : { (json object)\n" + " \"asm\" : \"code\", (string) \n" + " \"hex\" : \"hex\", (string) \n" + " \"reqSigs\" : n, (numeric) Number of required signatures\n" + " \"type\" : \"pubkeyhash\", (string) The type, eg pubkeyhash\n" + " \"addresses\" : [ (array of string) array of bitcoin addresses\n" + " \"bitcoinaddress\" (string) bitcoin address\n" + " ,...\n" + " ]\n" + " },\n" + " \"version\" : n, (numeric) The version\n" + " \"coinbase\" : true|false (boolean) Coinbase or not\n" + "}\n" + + "\nExamples:\n" + "\nGet unspent transactions\n" + + HelpExampleCli("listunspent", "") + + "\nView the details\n" + + HelpExampleCli("gettxout", "\"txid\" 1") + + "\nAs a json rpc call\n" + + HelpExampleRpc("gettxout", "\"txid\", 1") + ); + + LOCK(cs_main); + + UniValue ret(UniValue::VOBJ); + + std::string strHash = params[0].get_str(); + uint256 hash(uint256S(strHash)); + int n = params[1].get_int(); + bool fMempool = true; + if (params.size() > 2) + fMempool = params[2].get_bool(); + + CCoins coins; + if (fMempool) { + LOCK(mempool.cs); + CCoinsViewMemPool view(pcoinsTip, mempool); + if (!view.GetCoins(hash, coins)) + return NullUniValue; + mempool.pruneSpent(hash, coins); // TODO: this should be done by the CCoinsViewMemPool + } else { + if (!pcoinsTip->GetCoins(hash, coins)) + return NullUniValue; + } + if (n<0 || (unsigned int)n>=coins.vout.size() || coins.vout[n].IsNull()) + return NullUniValue; + + BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock()); + CBlockIndex *pindex = it->second; + ret.push_back(Pair("bestblock", pindex->GetBlockHash().GetHex())); + if ((unsigned int)coins.nHeight == MEMPOOL_HEIGHT) + ret.push_back(Pair("confirmations", 0)); + else + ret.push_back(Pair("confirmations", pindex->nHeight - coins.nHeight + 1)); + ret.push_back(Pair("value", ValueFromAmount(coins.vout[n].nValue))); + UniValue o(UniValue::VOBJ); + ScriptPubKeyToJSON(coins.vout[n].scriptPubKey, o, true); + ret.push_back(Pair("scriptPubKey", o)); + ret.push_back(Pair("version", coins.nVersion)); + ret.push_back(Pair("coinbase", coins.fCoinBase)); + + return ret; +} + +UniValue verifychain(const UniValue& params, bool fHelp) +{ + int nCheckLevel = GetArg("-checklevel", DEFAULT_CHECKLEVEL); + int nCheckDepth = GetArg("-checkblocks", DEFAULT_CHECKBLOCKS); + if (fHelp || params.size() > 2) + throw runtime_error( + "verifychain ( checklevel numblocks )\n" + "\nVerifies blockchain database.\n" + "\nArguments:\n" + "1. checklevel (numeric, optional, 0-4, default=" + strprintf("%d", nCheckLevel) + ") How thorough the block verification is.\n" + "2. numblocks (numeric, optional, default=" + strprintf("%d", nCheckDepth) + ", 0=all) The number of blocks to check.\n" + "\nResult:\n" + "true|false (boolean) Verified or not\n" + "\nExamples:\n" + + HelpExampleCli("verifychain", "") + + HelpExampleRpc("verifychain", "") + ); + + LOCK(cs_main); + + if (params.size() > 0) + nCheckLevel = params[0].get_int(); + if (params.size() > 1) + nCheckDepth = params[1].get_int(); + + return CVerifyDB().VerifyDB(Params(), pcoinsTip, nCheckLevel, nCheckDepth); +} + +/** Implementation of IsSuperMajority with better feedback */ +static UniValue SoftForkMajorityDesc(int minVersion, CBlockIndex* pindex, int nRequired, const Consensus::Params& consensusParams) +{ + int nFound = 0; + CBlockIndex* pstart = pindex; + for (int i = 0; i < consensusParams.nMajorityWindow && pstart != NULL; i++) + { + if (pstart->nVersion >= minVersion) + ++nFound; + pstart = pstart->pprev; + } + + UniValue rv(UniValue::VOBJ); + rv.push_back(Pair("status", nFound >= nRequired)); + rv.push_back(Pair("found", nFound)); + rv.push_back(Pair("required", nRequired)); + rv.push_back(Pair("window", consensusParams.nMajorityWindow)); + return rv; +} + +static UniValue SoftForkDesc(const std::string &name, int version, CBlockIndex* pindex, const Consensus::Params& consensusParams) +{ + UniValue rv(UniValue::VOBJ); + rv.push_back(Pair("id", name)); + rv.push_back(Pair("version", version)); + rv.push_back(Pair("enforce", SoftForkMajorityDesc(version, pindex, consensusParams.nMajorityEnforceBlockUpgrade, consensusParams))); + rv.push_back(Pair("reject", SoftForkMajorityDesc(version, pindex, consensusParams.nMajorityRejectBlockOutdated, consensusParams))); + return rv; +} + +UniValue getblockchaininfo(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() != 0) + throw runtime_error( + "getblockchaininfo\n" + "Returns an object containing various state info regarding block chain processing.\n" + "\nResult:\n" + "{\n" + " \"chain\": \"xxxx\", (string) current network name as defined in BIP70 (main, test, regtest)\n" + " \"blocks\": xxxxxx, (numeric) the current number of blocks processed in the server\n" + " \"headers\": xxxxxx, (numeric) the current number of headers we have validated\n" + " \"bestblockhash\": \"...\", (string) the hash of the currently best block\n" + " \"difficulty\": xxxxxx, (numeric) the current difficulty\n" + " \"mediantime\": xxxxxx, (numeric) median time for the current best block\n" + " \"verificationprogress\": xxxx, (numeric) estimate of verification progress [0..1]\n" + " \"chainwork\": \"xxxx\" (string) total amount of work in active chain, in hexadecimal\n" + " \"pruned\": xx, (boolean) if the blocks are subject to pruning\n" + " \"pruneheight\": xxxxxx, (numeric) heighest block available\n" + " \"softforks\": [ (array) status of softforks in progress\n" + " {\n" + " \"id\": \"xxxx\", (string) name of softfork\n" + " \"version\": xx, (numeric) block version\n" + " \"enforce\": { (object) progress toward enforcing the softfork rules for new-version blocks\n" + " \"status\": xx, (boolean) true if threshold reached\n" + " \"found\": xx, (numeric) number of blocks with the new version found\n" + " \"required\": xx, (numeric) number of blocks required to trigger\n" + " \"window\": xx, (numeric) maximum size of examined window of recent blocks\n" + " },\n" + " \"reject\": { ... } (object) progress toward rejecting pre-softfork blocks (same fields as \"enforce\")\n" + " }, ...\n" + " ]\n" + "}\n" + "\nExamples:\n" + + HelpExampleCli("getblockchaininfo", "") + + HelpExampleRpc("getblockchaininfo", "") + ); + + LOCK(cs_main); + + UniValue obj(UniValue::VOBJ); + obj.push_back(Pair("chain", Params().NetworkIDString())); + obj.push_back(Pair("blocks", (int)chainActive.Height())); + obj.push_back(Pair("headers", pindexBestHeader ? pindexBestHeader->nHeight : -1)); + obj.push_back(Pair("bestblockhash", chainActive.Tip()->GetBlockHash().GetHex())); + obj.push_back(Pair("difficulty", (double)GetDifficulty())); + obj.push_back(Pair("mediantime", (int64_t)chainActive.Tip()->GetMedianTimePast())); + obj.push_back(Pair("verificationprogress", Checkpoints::GuessVerificationProgress(Params().Checkpoints(), chainActive.Tip()))); + obj.push_back(Pair("chainwork", chainActive.Tip()->nChainWork.GetHex())); + obj.push_back(Pair("pruned", fPruneMode)); + + const Consensus::Params& consensusParams = Params().GetConsensus(); + CBlockIndex* tip = chainActive.Tip(); + UniValue softforks(UniValue::VARR); + softforks.push_back(SoftForkDesc("bip34", 2, tip, consensusParams)); + softforks.push_back(SoftForkDesc("bip66", 3, tip, consensusParams)); + softforks.push_back(SoftForkDesc("bip65", 4, tip, consensusParams)); + obj.push_back(Pair("softforks", softforks)); + + if (fPruneMode) + { + CBlockIndex *block = chainActive.Tip(); + while (block && block->pprev && (block->pprev->nStatus & BLOCK_HAVE_DATA)) + block = block->pprev; + + obj.push_back(Pair("pruneheight", block->nHeight)); + } + return obj; +} + +/** Comparison function for sorting the getchaintips heads. */ +struct CompareBlocksByHeight +{ + bool operator()(const CBlockIndex* a, const CBlockIndex* b) const + { + /* Make sure that unequal blocks with the same height do not compare + equal. Use the pointers themselves to make a distinction. */ + + if (a->nHeight != b->nHeight) + return (a->nHeight > b->nHeight); + + return a < b; + } +}; + +UniValue getchaintips(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() != 0) + throw runtime_error( + "getchaintips\n" + "Return information about all known tips in the block tree," + " including the main chain as well as orphaned branches.\n" + "\nResult:\n" + "[\n" + " {\n" + " \"height\": xxxx, (numeric) height of the chain tip\n" + " \"hash\": \"xxxx\", (string) block hash of the tip\n" + " \"branchlen\": 0 (numeric) zero for main chain\n" + " \"status\": \"active\" (string) \"active\" for the main chain\n" + " },\n" + " {\n" + " \"height\": xxxx,\n" + " \"hash\": \"xxxx\",\n" + " \"branchlen\": 1 (numeric) length of branch connecting the tip to the main chain\n" + " \"status\": \"xxxx\" (string) status of the chain (active, valid-fork, valid-headers, headers-only, invalid)\n" + " }\n" + "]\n" + "Possible values for status:\n" + "1. \"invalid\" This branch contains at least one invalid block\n" + "2. \"headers-only\" Not all blocks for this branch are available, but the headers are valid\n" + "3. \"valid-headers\" All blocks are available for this branch, but they were never fully validated\n" + "4. \"valid-fork\" This branch is not part of the active chain, but is fully validated\n" + "5. \"active\" This is the tip of the active main chain, which is certainly valid\n" + "\nExamples:\n" + + HelpExampleCli("getchaintips", "") + + HelpExampleRpc("getchaintips", "") + ); + + LOCK(cs_main); + + /* Build up a list of chain tips. We start with the list of all + known blocks, and successively remove blocks that appear as pprev + of another block. */ + std::set setTips; + BOOST_FOREACH(const PAIRTYPE(const uint256, CBlockIndex*)& item, mapBlockIndex) + setTips.insert(item.second); + BOOST_FOREACH(const PAIRTYPE(const uint256, CBlockIndex*)& item, mapBlockIndex) + { + const CBlockIndex* pprev = item.second->pprev; + if (pprev) + setTips.erase(pprev); + } + + // Always report the currently active tip. + setTips.insert(chainActive.Tip()); + + /* Construct the output array. */ + UniValue res(UniValue::VARR); + BOOST_FOREACH(const CBlockIndex* block, setTips) + { + UniValue obj(UniValue::VOBJ); + obj.push_back(Pair("height", block->nHeight)); + obj.push_back(Pair("hash", block->phashBlock->GetHex())); + + const int branchLen = block->nHeight - chainActive.FindFork(block)->nHeight; + obj.push_back(Pair("branchlen", branchLen)); + + string status; + if (chainActive.Contains(block)) { + // This block is part of the currently active chain. + status = "active"; + } else if (block->nStatus & BLOCK_FAILED_MASK) { + // This block or one of its ancestors is invalid. + status = "invalid"; + } else if (block->nChainTx == 0) { + // This block cannot be connected because full block data for it or one of its parents is missing. + status = "headers-only"; + } else if (block->IsValid(BLOCK_VALID_SCRIPTS)) { + // This block is fully validated, but no longer part of the active chain. It was probably the active block once, but was reorganized. + status = "valid-fork"; + } else if (block->IsValid(BLOCK_VALID_TREE)) { + // The headers for this block are valid, but it has not been validated. It was probably never part of the most-work chain. + status = "valid-headers"; + } else { + // No clue. + status = "unknown"; + } + obj.push_back(Pair("status", status)); + + res.push_back(obj); + } + + return res; +} + +UniValue mempoolInfoToJSON() +{ + UniValue ret(UniValue::VOBJ); + ret.push_back(Pair("size", (int64_t) mempool.size())); + ret.push_back(Pair("bytes", (int64_t) mempool.GetTotalTxSize())); + ret.push_back(Pair("usage", (int64_t) mempool.DynamicMemoryUsage())); + size_t maxmempool = GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000; + ret.push_back(Pair("maxmempool", (int64_t) maxmempool)); + ret.push_back(Pair("mempoolminfee", ValueFromAmount(mempool.GetMinFee(maxmempool).GetFeePerK()))); + + return ret; +} + +UniValue getmempoolinfo(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() != 0) + throw runtime_error( + "getmempoolinfo\n" + "\nReturns details on the active state of the TX memory pool.\n" + "\nResult:\n" + "{\n" + " \"size\": xxxxx, (numeric) Current tx count\n" + " \"bytes\": xxxxx, (numeric) Sum of all tx sizes\n" + " \"usage\": xxxxx, (numeric) Total memory usage for the mempool\n" + " \"maxmempool\": xxxxx, (numeric) Maximum memory usage for the mempool\n" + " \"mempoolminfee\": xxxxx (numeric) Minimum fee for tx to be accepted\n" + "}\n" + "\nExamples:\n" + + HelpExampleCli("getmempoolinfo", "") + + HelpExampleRpc("getmempoolinfo", "") + ); + + return mempoolInfoToJSON(); +} + +UniValue invalidateblock(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() != 1) + throw runtime_error( + "invalidateblock \"hash\"\n" + "\nPermanently marks a block as invalid, as if it violated a consensus rule.\n" + "\nArguments:\n" + "1. hash (string, required) the hash of the block to mark as invalid\n" + "\nResult:\n" + "\nExamples:\n" + + HelpExampleCli("invalidateblock", "\"blockhash\"") + + HelpExampleRpc("invalidateblock", "\"blockhash\"") + ); + + std::string strHash = params[0].get_str(); + uint256 hash(uint256S(strHash)); + CValidationState state; + + { + LOCK(cs_main); + if (mapBlockIndex.count(hash) == 0) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); + + CBlockIndex* pblockindex = mapBlockIndex[hash]; + InvalidateBlock(state, Params().GetConsensus(), pblockindex); + } + + if (state.IsValid()) { + ActivateBestChain(state, Params()); + } + + if (!state.IsValid()) { + throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason()); + } + + return NullUniValue; +} + +UniValue reconsiderblock(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() != 1) + throw runtime_error( + "reconsiderblock \"hash\"\n" + "\nRemoves invalidity status of a block and its descendants, reconsider them for activation.\n" + "This can be used to undo the effects of invalidateblock.\n" + "\nArguments:\n" + "1. hash (string, required) the hash of the block to reconsider\n" + "\nResult:\n" + "\nExamples:\n" + + HelpExampleCli("reconsiderblock", "\"blockhash\"") + + HelpExampleRpc("reconsiderblock", "\"blockhash\"") + ); + + std::string strHash = params[0].get_str(); + uint256 hash(uint256S(strHash)); + CValidationState state; + + { + LOCK(cs_main); + if (mapBlockIndex.count(hash) == 0) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); + + CBlockIndex* pblockindex = mapBlockIndex[hash]; + ReconsiderBlock(state, pblockindex); + } + + if (state.IsValid()) { + ActivateBestChain(state, Params()); + } + + if (!state.IsValid()) { + throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason()); + } + + return NullUniValue; +} -- cgit v1.2.3 From a6ee0caa4e5a6459f49995ac2dfd40e2444f7c04 Mon Sep 17 00:00:00 2001 From: Pavel Vasin Date: Sat, 12 Mar 2016 17:11:59 +0300 Subject: use cached block hash in blockToJSON() --- src/rpc/blockchain.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/rpc/blockchain.cpp') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index de6bda4ea..da57973da 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -89,7 +89,7 @@ UniValue blockheaderToJSON(const CBlockIndex* blockindex) UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false) { UniValue result(UniValue::VOBJ); - result.push_back(Pair("hash", block.GetHash().GetHex())); + result.push_back(Pair("hash", blockindex->GetBlockHash().GetHex())); int confirmations = -1; // Only report confirmations if the block is on the main chain if (chainActive.Contains(blockindex)) -- cgit v1.2.3 From d23f6c6a0d2dc8a3f5f159faf7a40157259a8f8f Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Thu, 3 Mar 2016 21:00:03 +0100 Subject: Softfork status report in RPC --- src/rpc/blockchain.cpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'src/rpc/blockchain.cpp') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index da57973da..a110dff0d 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -604,6 +604,20 @@ static UniValue SoftForkDesc(const std::string &name, int version, CBlockIndex* return rv; } +static UniValue BIP9SoftForkDesc(const std::string& name, const Consensus::Params& consensusParams, Consensus::DeploymentPos id) +{ + UniValue rv(UniValue::VOBJ); + rv.push_back(Pair("id", name)); + switch (VersionBitsTipState(consensusParams, id)) { + case THRESHOLD_DEFINED: rv.push_back(Pair("status", "defined")); break; + case THRESHOLD_STARTED: rv.push_back(Pair("status", "started")); break; + case THRESHOLD_LOCKED_IN: rv.push_back(Pair("status", "locked_in")); break; + case THRESHOLD_ACTIVE: rv.push_back(Pair("status", "active")); break; + case THRESHOLD_FAILED: rv.push_back(Pair("status", "failed")); break; + } + return rv; +} + UniValue getblockchaininfo(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) @@ -634,6 +648,12 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp) " },\n" " \"reject\": { ... } (object) progress toward rejecting pre-softfork blocks (same fields as \"enforce\")\n" " }, ...\n" + " ],\n" + " \"bip9_softforks\": [ (array) status of BIP9 softforks in progress\n" + " {\n" + " \"id\": \"xxxx\", (string) name of the softfork\n" + " \"status\": \"xxxx\", (string) one of \"defined\", \"started\", \"lockedin\", \"active\", \"failed\"\n" + " }\n" " ]\n" "}\n" "\nExamples:\n" @@ -657,10 +677,12 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp) const Consensus::Params& consensusParams = Params().GetConsensus(); CBlockIndex* tip = chainActive.Tip(); UniValue softforks(UniValue::VARR); + UniValue bip9_softforks(UniValue::VARR); softforks.push_back(SoftForkDesc("bip34", 2, tip, consensusParams)); softforks.push_back(SoftForkDesc("bip66", 3, tip, consensusParams)); softforks.push_back(SoftForkDesc("bip65", 4, tip, consensusParams)); obj.push_back(Pair("softforks", softforks)); + obj.push_back(Pair("bip9_softforks", bip9_softforks)); if (fPruneMode) { -- cgit v1.2.3 From 65751a3cf2421a9419172949cad9dc49b7383551 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Sat, 20 Feb 2016 23:37:13 +0100 Subject: Add CHECKSEQUENCEVERIFY softfork through BIP9 --- src/rpc/blockchain.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/rpc/blockchain.cpp') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index a110dff0d..f5d75c20b 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -681,6 +681,7 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp) softforks.push_back(SoftForkDesc("bip34", 2, tip, consensusParams)); softforks.push_back(SoftForkDesc("bip66", 3, tip, consensusParams)); softforks.push_back(SoftForkDesc("bip65", 4, tip, consensusParams)); + bip9_softforks.push_back(BIP9SoftForkDesc("csv", consensusParams, Consensus::DEPLOYMENT_CSV)); obj.push_back(Pair("softforks", softforks)); obj.push_back(Pair("bip9_softforks", bip9_softforks)); -- cgit v1.2.3 From fb8a8cf2e610920e9eee61c19ed6080af064bb43 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 29 Mar 2016 19:43:02 +0200 Subject: rpc: Register calls where they are defined Split out methods to every module, apart from 'help' and 'stop' which are implemented in rpcserver.cpp itself. - This makes it easier to add or remove RPC commands - no longer everything that includes rpcserver.h has to be rebuilt when there's a change there. - Cleans up `rpc/server.h` by getting rid of the huge cluttered list of function definitions. - Removes most of the bitcoin-specific code from rpcserver.cpp and .h. Continues #7307 for the non-wallet. --- src/rpc/blockchain.cpp | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'src/rpc/blockchain.cpp') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index a110dff0d..b947609b1 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -911,3 +911,31 @@ UniValue reconsiderblock(const UniValue& params, bool fHelp) return NullUniValue; } + +static const CRPCCommand commands[] = +{ // category name actor (function) okSafeMode + // --------------------- ------------------------ ----------------------- ---------- + { "blockchain", "getblockchaininfo", &getblockchaininfo, true }, + { "blockchain", "getbestblockhash", &getbestblockhash, true }, + { "blockchain", "getblockcount", &getblockcount, true }, + { "blockchain", "getblock", &getblock, true }, + { "blockchain", "getblockhash", &getblockhash, true }, + { "blockchain", "getblockheader", &getblockheader, true }, + { "blockchain", "getchaintips", &getchaintips, true }, + { "blockchain", "getdifficulty", &getdifficulty, true }, + { "blockchain", "getmempoolinfo", &getmempoolinfo, true }, + { "blockchain", "getrawmempool", &getrawmempool, true }, + { "blockchain", "gettxout", &gettxout, true }, + { "blockchain", "gettxoutsetinfo", &gettxoutsetinfo, true }, + { "blockchain", "verifychain", &verifychain, true }, + + /* Not shown in help */ + { "hidden", "invalidateblock", &invalidateblock, true }, + { "hidden", "reconsiderblock", &reconsiderblock, true }, +}; + +void RegisterBlockchainRPCCommands(CRPCTable &tableRPC) +{ + for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++) + tableRPC.appendCommand(commands[vcidx].name, &commands[vcidx]); +} -- cgit v1.2.3 From 92107d574d35d803399ee4dc9d3a1fb6a82a9229 Mon Sep 17 00:00:00 2001 From: mruddy Date: Mon, 4 Apr 2016 22:21:00 +0000 Subject: RPC: add versionHex in getblock and getblockheader JSON results; expand data in getblockchaininfo bip9_softforks field. --- src/rpc/blockchain.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'src/rpc/blockchain.cpp') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index f1c9d9f7a..34637b9f7 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -70,6 +70,7 @@ UniValue blockheaderToJSON(const CBlockIndex* blockindex) result.push_back(Pair("confirmations", confirmations)); result.push_back(Pair("height", blockindex->nHeight)); result.push_back(Pair("version", blockindex->nVersion)); + result.push_back(Pair("versionHex", strprintf("%08x", blockindex->nVersion))); result.push_back(Pair("merkleroot", blockindex->hashMerkleRoot.GetHex())); result.push_back(Pair("time", (int64_t)blockindex->nTime)); result.push_back(Pair("mediantime", (int64_t)blockindex->GetMedianTimePast())); @@ -98,6 +99,7 @@ UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool tx result.push_back(Pair("size", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION))); result.push_back(Pair("height", blockindex->nHeight)); result.push_back(Pair("version", block.nVersion)); + result.push_back(Pair("versionHex", strprintf("%08x", block.nVersion))); result.push_back(Pair("merkleroot", block.hashMerkleRoot.GetHex())); UniValue txs(UniValue::VARR); BOOST_FOREACH(const CTransaction&tx, block.vtx) @@ -316,6 +318,7 @@ UniValue getblockheader(const UniValue& params, bool fHelp) " \"confirmations\" : n, (numeric) The number of confirmations, or -1 if the block is not on the main chain\n" " \"height\" : n, (numeric) The block height or index\n" " \"version\" : n, (numeric) The block version\n" + " \"versionHex\" : \"00000000\", (string) The block version formatted in hexadecimal\n" " \"merkleroot\" : \"xxxx\", (string) The merkle root\n" " \"time\" : ttt, (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)\n" " \"mediantime\" : ttt, (numeric) The median block time in seconds since epoch (Jan 1 1970 GMT)\n" @@ -375,6 +378,7 @@ UniValue getblock(const UniValue& params, bool fHelp) " \"size\" : n, (numeric) The block size\n" " \"height\" : n, (numeric) The block height or index\n" " \"version\" : n, (numeric) The block version\n" + " \"versionHex\" : \"00000000\", (string) The block version formatted in hexadecimal\n" " \"merkleroot\" : \"xxxx\", (string) The merkle root\n" " \"tx\" : [ (array of string) The transaction ids\n" " \"transactionid\" (string) The transaction id\n" @@ -608,13 +612,20 @@ static UniValue BIP9SoftForkDesc(const std::string& name, const Consensus::Param { UniValue rv(UniValue::VOBJ); rv.push_back(Pair("id", name)); - switch (VersionBitsTipState(consensusParams, id)) { + const ThresholdState thresholdState = VersionBitsTipState(consensusParams, id); + switch (thresholdState) { case THRESHOLD_DEFINED: rv.push_back(Pair("status", "defined")); break; case THRESHOLD_STARTED: rv.push_back(Pair("status", "started")); break; case THRESHOLD_LOCKED_IN: rv.push_back(Pair("status", "locked_in")); break; case THRESHOLD_ACTIVE: rv.push_back(Pair("status", "active")); break; case THRESHOLD_FAILED: rv.push_back(Pair("status", "failed")); break; } + if (THRESHOLD_STARTED == thresholdState) + { + rv.push_back(Pair("bit", consensusParams.vDeployments[id].bit)); + } + rv.push_back(Pair("startTime", consensusParams.vDeployments[id].nStartTime)); + rv.push_back(Pair("timeout", consensusParams.vDeployments[id].nTimeout)); return rv; } @@ -653,6 +664,9 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp) " {\n" " \"id\": \"xxxx\", (string) name of the softfork\n" " \"status\": \"xxxx\", (string) one of \"defined\", \"started\", \"lockedin\", \"active\", \"failed\"\n" + " \"bit\": xx, (numeric) the bit, 0-28, in the block version field used to signal this soft fork\n" + " \"startTime\": xx, (numeric) the minimum median time past of a block at which the bit gains its meaning\n" + " \"timeout\": xx (numeric) the median time past of a block at which the deployment is considered failed if not yet locked in\n" " }\n" " ]\n" "}\n" -- cgit v1.2.3 From 85c807c9ead3215021503348e75851900dfa08db Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Tue, 12 Apr 2016 15:44:18 +0930 Subject: getblockchaininfo: make bip9_softforks an object, not an array. We can't change "softforks", but it seems far more logical to use tags in an object rather than using an "id" field in an array. For example, to get the csv status before, you need to iterate the array to find the entry with 'id' field equal to "csv": jq '.bip9_softforks | map(select(.id == "csv"))[] | .status' Now: jq '.bip9_softforks.csv.status' There is no issue with fork names being incompatible with JSON tags, since we're selecting them ourselves. Signed-off-by: Rusty Russell --- src/rpc/blockchain.cpp | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'src/rpc/blockchain.cpp') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 34637b9f7..7a01a10b7 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -608,10 +608,9 @@ static UniValue SoftForkDesc(const std::string &name, int version, CBlockIndex* return rv; } -static UniValue BIP9SoftForkDesc(const std::string& name, const Consensus::Params& consensusParams, Consensus::DeploymentPos id) +static UniValue BIP9SoftForkDesc(const Consensus::Params& consensusParams, Consensus::DeploymentPos id) { UniValue rv(UniValue::VOBJ); - rv.push_back(Pair("id", name)); const ThresholdState thresholdState = VersionBitsTipState(consensusParams, id); switch (thresholdState) { case THRESHOLD_DEFINED: rv.push_back(Pair("status", "defined")); break; @@ -660,15 +659,14 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp) " \"reject\": { ... } (object) progress toward rejecting pre-softfork blocks (same fields as \"enforce\")\n" " }, ...\n" " ],\n" - " \"bip9_softforks\": [ (array) status of BIP9 softforks in progress\n" - " {\n" - " \"id\": \"xxxx\", (string) name of the softfork\n" + " \"bip9_softforks\": { (object) status of BIP9 softforks in progress\n" + " \"xxxx\" : { (string) name of the softfork\n" " \"status\": \"xxxx\", (string) one of \"defined\", \"started\", \"lockedin\", \"active\", \"failed\"\n" " \"bit\": xx, (numeric) the bit, 0-28, in the block version field used to signal this soft fork\n" " \"startTime\": xx, (numeric) the minimum median time past of a block at which the bit gains its meaning\n" " \"timeout\": xx (numeric) the median time past of a block at which the deployment is considered failed if not yet locked in\n" " }\n" - " ]\n" + " }\n" "}\n" "\nExamples:\n" + HelpExampleCli("getblockchaininfo", "") @@ -691,11 +689,11 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp) const Consensus::Params& consensusParams = Params().GetConsensus(); CBlockIndex* tip = chainActive.Tip(); UniValue softforks(UniValue::VARR); - UniValue bip9_softforks(UniValue::VARR); + UniValue bip9_softforks(UniValue::VOBJ); softforks.push_back(SoftForkDesc("bip34", 2, tip, consensusParams)); softforks.push_back(SoftForkDesc("bip66", 3, tip, consensusParams)); softforks.push_back(SoftForkDesc("bip65", 4, tip, consensusParams)); - bip9_softforks.push_back(BIP9SoftForkDesc("csv", consensusParams, Consensus::DEPLOYMENT_CSV)); + bip9_softforks.push_back(Pair("csv", BIP9SoftForkDesc(consensusParams, Consensus::DEPLOYMENT_CSV))); obj.push_back(Pair("softforks", softforks)); obj.push_back(Pair("bip9_softforks", bip9_softforks)); -- cgit v1.2.3 From 509cb006d514cece5ab7680094f033c8dc8a2318 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 28 Mar 2016 18:18:30 +0200 Subject: txdb: Add Cursor() method to CCoinsView to iterate over UTXO set Add a method Cursor() to CCoinsView that returns a cursor which can be used to iterate over the whole UTXO set. - rpc: Change gettxoutsetinfo to use new Cursor method - txdb: Remove GetStats method - Now that GetStats is implemented in terms of Cursor, remove it. --- src/rpc/blockchain.cpp | 58 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) (limited to 'src/rpc/blockchain.cpp') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 34637b9f7..8dbfbd5ff 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -18,11 +18,14 @@ #include "txmempool.h" #include "util.h" #include "utilstrencodings.h" +#include "hash.h" #include #include +#include // boost::thread::interrupt + using namespace std; extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry); @@ -432,6 +435,59 @@ UniValue getblock(const UniValue& params, bool fHelp) return blockToJSON(block, pblockindex); } +struct CCoinsStats +{ + int nHeight; + uint256 hashBlock; + uint64_t nTransactions; + uint64_t nTransactionOutputs; + uint64_t nSerializedSize; + uint256 hashSerialized; + CAmount nTotalAmount; + + CCoinsStats() : nHeight(0), nTransactions(0), nTransactionOutputs(0), nSerializedSize(0), nTotalAmount(0) {} +}; + +//! Calculate statistics about the unspent transaction output set +static bool GetUTXOStats(CCoinsView *view, CCoinsStats &stats) +{ + boost::scoped_ptr pcursor(view->Cursor()); + + CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION); + stats.hashBlock = pcursor->GetBestBlock(); + { + LOCK(cs_main); + stats.nHeight = mapBlockIndex.find(stats.hashBlock)->second->nHeight; + } + ss << stats.hashBlock; + CAmount nTotalAmount = 0; + while (pcursor->Valid()) { + boost::this_thread::interruption_point(); + uint256 key; + CCoins coins; + if (pcursor->GetKey(key) && pcursor->GetValue(coins)) { + stats.nTransactions++; + for (unsigned int i=0; iGetValueSize(); + ss << VARINT(0); + } else { + return error("%s: unable to read value", __func__); + } + pcursor->Next(); + } + stats.hashSerialized = ss.GetHash(); + stats.nTotalAmount = nTotalAmount; + return true; +} + UniValue gettxoutsetinfo(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) @@ -458,7 +514,7 @@ UniValue gettxoutsetinfo(const UniValue& params, bool fHelp) CCoinsStats stats; FlushStateToDisk(); - if (pcoinsTip->GetStats(stats)) { + if (GetUTXOStats(pcoinsTip, stats)) { ret.push_back(Pair("height", (int64_t)stats.nHeight)); ret.push_back(Pair("bestblock", stats.hashBlock.GetHex())); ret.push_back(Pair("transactions", (int64_t)stats.nTransactions)); -- cgit v1.2.3 From 76212bbc6a13298d7154ac16c0b989aca5471de8 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Sat, 9 Apr 2016 07:59:49 +0200 Subject: rpc: make sure `gettxoutsetinfo` hash has txids The key (transaction id for the following outputs) should be serialized to the HashWriter. This is a problem as it means different transactions in the same position with the same outputs will potentially result in the same hash. Fixes primary concern of #7758. --- src/rpc/blockchain.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/rpc/blockchain.cpp') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index b85b2f6b5..88f6278b2 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -467,6 +467,7 @@ static bool GetUTXOStats(CCoinsView *view, CCoinsStats &stats) CCoins coins; if (pcursor->GetKey(key) && pcursor->GetValue(coins)) { stats.nTransactions++; + ss << key; for (unsigned int i=0; i Date: Mon, 18 Apr 2016 12:10:47 -0400 Subject: Speed up getchaintips. --- src/rpc/blockchain.cpp | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) (limited to 'src/rpc/blockchain.cpp') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 34637b9f7..3db827d9a 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -760,17 +760,30 @@ UniValue getchaintips(const UniValue& params, bool fHelp) LOCK(cs_main); - /* Build up a list of chain tips. We start with the list of all - known blocks, and successively remove blocks that appear as pprev - of another block. */ + /* + * Idea: the set of chain tips is chainActive.tip, plus orphan blocks which do not have another orphan building off of them. + * Algorithm: + * - Make one pass through mapBlockIndex, picking out the orphan blocks, and also storing a set of the orphan block's pprev pointers. + * - Iterate through the orphan blocks. If the block isn't pointed to by another orphan, it is a chain tip. + * - add chainActive.Tip() + */ std::set setTips; - BOOST_FOREACH(const PAIRTYPE(const uint256, CBlockIndex*)& item, mapBlockIndex) - setTips.insert(item.second); + std::set setOrphans; + std::set setPrevs; + BOOST_FOREACH(const PAIRTYPE(const uint256, CBlockIndex*)& item, mapBlockIndex) { - const CBlockIndex* pprev = item.second->pprev; - if (pprev) - setTips.erase(pprev); + if (!chainActive.Contains(item.second)) { + setOrphans.insert(item.second); + setPrevs.insert(item.second->pprev); + } + } + + for (std::set::iterator it = setOrphans.begin(); it != setOrphans.end(); ++it) + { + if (setPrevs.erase(*it) == 0) { + setTips.insert(*it); + } } // Always report the currently active tip. -- cgit v1.2.3 From d0a6353dec48f365c38de3c76b42f67eda737ed5 Mon Sep 17 00:00:00 2001 From: face Date: Sun, 17 Apr 2016 10:58:50 +0300 Subject: Pass CChainParams to DisconnectTip() --- src/rpc/blockchain.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/rpc/blockchain.cpp') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index b85b2f6b5..2670a85c4 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -928,7 +928,7 @@ UniValue invalidateblock(const UniValue& params, bool fHelp) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); CBlockIndex* pblockindex = mapBlockIndex[hash]; - InvalidateBlock(state, Params().GetConsensus(), pblockindex); + InvalidateBlock(state, Params(), pblockindex); } if (state.IsValid()) { -- cgit v1.2.3 From addb9d2a092b4fd0384d4ff82e9607e5411eab97 Mon Sep 17 00:00:00 2001 From: instagibbs Date: Fri, 6 May 2016 12:53:23 -0400 Subject: Remove state arg from ReconsiderBlock --- src/rpc/blockchain.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'src/rpc/blockchain.cpp') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 6960415e2..d221012af 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -973,7 +973,6 @@ UniValue reconsiderblock(const UniValue& params, bool fHelp) std::string strHash = params[0].get_str(); uint256 hash(uint256S(strHash)); - CValidationState state; { LOCK(cs_main); @@ -981,12 +980,11 @@ UniValue reconsiderblock(const UniValue& params, bool fHelp) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); CBlockIndex* pblockindex = mapBlockIndex[hash]; - ReconsiderBlock(state, pblockindex); + ReconsiderBlock(pblockindex); } - if (state.IsValid()) { - ActivateBestChain(state, Params()); - } + CValidationState state; + ActivateBestChain(state, Params()); if (!state.IsValid()) { throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason()); -- cgit v1.2.3 From 657e07efa34ffe9d8614a618e00452c9ee7c0e0d Mon Sep 17 00:00:00 2001 From: instagibbs Date: Mon, 9 May 2016 11:26:37 -0400 Subject: Rename ReconsiderBlock func to reflect real behavior --- src/rpc/blockchain.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/rpc/blockchain.cpp') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index d221012af..cf3c73c4d 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -980,7 +980,7 @@ UniValue reconsiderblock(const UniValue& params, bool fHelp) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); CBlockIndex* pblockindex = mapBlockIndex[hash]; - ReconsiderBlock(pblockindex); + ResetBlockFailureFlags(pblockindex); } CValidationState state; -- cgit v1.2.3 From 5ec0cde371149e5be6ca5e9803183021b10928f8 Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Mon, 4 Jan 2016 13:43:17 -0500 Subject: Refactor logic for converting mempool entries to JSON --- src/rpc/blockchain.cpp | 90 ++++++++++++++++++++++++++++---------------------- 1 file changed, 51 insertions(+), 39 deletions(-) (limited to 'src/rpc/blockchain.cpp') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index cf3c73c4d..fe628097a 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -183,6 +183,54 @@ UniValue getdifficulty(const UniValue& params, bool fHelp) return GetDifficulty(); } +std::string EntryDescriptionString() +{ + return " \"size\" : n, (numeric) transaction size in bytes\n" + " \"fee\" : n, (numeric) transaction fee in " + CURRENCY_UNIT + "\n" + " \"modifiedfee\" : n, (numeric) transaction fee with fee deltas used for mining priority\n" + " \"time\" : n, (numeric) local time transaction entered pool in seconds since 1 Jan 1970 GMT\n" + " \"height\" : n, (numeric) block height when transaction entered pool\n" + " \"startingpriority\" : n, (numeric) priority when transaction entered pool\n" + " \"currentpriority\" : n, (numeric) transaction priority now\n" + " \"descendantcount\" : n, (numeric) number of in-mempool descendant transactions (including this one)\n" + " \"descendantsize\" : n, (numeric) size of in-mempool descendants (including this one)\n" + " \"descendantfees\" : n, (numeric) modified fees (see above) of in-mempool descendants (including this one)\n" + " \"depends\" : [ (array) unconfirmed transactions used as inputs for this transaction\n" + " \"transactionid\", (string) parent transaction id\n" + " ... ]\n"; +} + +void entryToJSON(UniValue &info, const CTxMemPoolEntry &e) +{ + AssertLockHeld(mempool.cs); + + info.push_back(Pair("size", (int)e.GetTxSize())); + info.push_back(Pair("fee", ValueFromAmount(e.GetFee()))); + info.push_back(Pair("modifiedfee", ValueFromAmount(e.GetModifiedFee()))); + info.push_back(Pair("time", e.GetTime())); + info.push_back(Pair("height", (int)e.GetHeight())); + info.push_back(Pair("startingpriority", e.GetPriority(e.GetHeight()))); + info.push_back(Pair("currentpriority", e.GetPriority(chainActive.Height()))); + info.push_back(Pair("descendantcount", e.GetCountWithDescendants())); + info.push_back(Pair("descendantsize", e.GetSizeWithDescendants())); + info.push_back(Pair("descendantfees", e.GetModFeesWithDescendants())); + const CTransaction& tx = e.GetTx(); + set setDepends; + BOOST_FOREACH(const CTxIn& txin, tx.vin) + { + if (mempool.exists(txin.prevout.hash)) + setDepends.insert(txin.prevout.hash.ToString()); + } + + UniValue depends(UniValue::VARR); + BOOST_FOREACH(const string& dep, setDepends) + { + depends.push_back(dep); + } + + info.push_back(Pair("depends", depends)); +} + UniValue mempoolToJSON(bool fVerbose = false) { if (fVerbose) @@ -193,31 +241,7 @@ UniValue mempoolToJSON(bool fVerbose = false) { const uint256& hash = e.GetTx().GetHash(); UniValue info(UniValue::VOBJ); - info.push_back(Pair("size", (int)e.GetTxSize())); - info.push_back(Pair("fee", ValueFromAmount(e.GetFee()))); - info.push_back(Pair("modifiedfee", ValueFromAmount(e.GetModifiedFee()))); - info.push_back(Pair("time", e.GetTime())); - info.push_back(Pair("height", (int)e.GetHeight())); - info.push_back(Pair("startingpriority", e.GetPriority(e.GetHeight()))); - info.push_back(Pair("currentpriority", e.GetPriority(chainActive.Height()))); - info.push_back(Pair("descendantcount", e.GetCountWithDescendants())); - info.push_back(Pair("descendantsize", e.GetSizeWithDescendants())); - info.push_back(Pair("descendantfees", e.GetModFeesWithDescendants())); - const CTransaction& tx = e.GetTx(); - set setDepends; - BOOST_FOREACH(const CTxIn& txin, tx.vin) - { - if (mempool.exists(txin.prevout.hash)) - setDepends.insert(txin.prevout.hash.ToString()); - } - - UniValue depends(UniValue::VARR); - BOOST_FOREACH(const string& dep, setDepends) - { - depends.push_back(dep); - } - - info.push_back(Pair("depends", depends)); + entryToJSON(info, e); o.push_back(Pair(hash.ToString(), info)); } return o; @@ -251,20 +275,8 @@ UniValue getrawmempool(const UniValue& params, bool fHelp) "\nResult: (for verbose = true):\n" "{ (json object)\n" " \"transactionid\" : { (json object)\n" - " \"size\" : n, (numeric) transaction size in bytes\n" - " \"fee\" : n, (numeric) transaction fee in " + CURRENCY_UNIT + "\n" - " \"modifiedfee\" : n, (numeric) transaction fee with fee deltas used for mining priority\n" - " \"time\" : n, (numeric) local time transaction entered pool in seconds since 1 Jan 1970 GMT\n" - " \"height\" : n, (numeric) block height when transaction entered pool\n" - " \"startingpriority\" : n, (numeric) priority when transaction entered pool\n" - " \"currentpriority\" : n, (numeric) transaction priority now\n" - " \"descendantcount\" : n, (numeric) number of in-mempool descendant transactions (including this one)\n" - " \"descendantsize\" : n, (numeric) size of in-mempool descendants (including this one)\n" - " \"descendantfees\" : n, (numeric) modified fees (see above) of in-mempool descendants (including this one)\n" - " \"depends\" : [ (array) unconfirmed transactions used as inputs for this transaction\n" - " \"transactionid\", (string) parent transaction id\n" - " ... ]\n" - " }, ...\n" + + EntryDescriptionString() + + " }, ...\n" "}\n" "\nExamples\n" + HelpExampleCli("getrawmempool", "true") -- cgit v1.2.3 From 8f7b5dc4afb28e38ce0223339b8ce77aa0a47845 Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Mon, 4 Jan 2016 13:58:59 -0500 Subject: Add getmempoolancestors RPC call --- src/rpc/blockchain.cpp | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) (limited to 'src/rpc/blockchain.cpp') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index fe628097a..6c005068d 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -292,6 +292,70 @@ UniValue getrawmempool(const UniValue& params, bool fHelp) return mempoolToJSON(fVerbose); } +UniValue getmempoolancestors(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() < 1 || params.size() > 2) { + throw runtime_error( + "getmempoolancestors txid (verbose)\n" + "\nIf txid is in the mempool, returns all in-mempool ancestors.\n" + "\nArguments:\n" + "1. \"txid\" (string, required) The transaction id (must be in mempool)\n" + "2. verbose (boolean, optional, default=false) true for a json object, false for array of transaction ids\n" + "\nResult (for verbose=false):\n" + "[ (json array of string)\n" + " \"transactionid\" (string) The transaction id of an in-mempool ancestor transaction\n" + " ,...\n" + "]\n" + "\nResult (for verbose=true):\n" + "{ (json object)\n" + " \"transactionid\" : { (json object)\n" + + EntryDescriptionString() + + " }, ...\n" + "}\n" + "\nExamples\n" + + HelpExampleCli("getmempoolancestors", "\"mytxid\"") + + HelpExampleRpc("getmempoolancestors", "\"mytxid\"") + ); + } + + bool fVerbose = false; + if (params.size() > 1) + fVerbose = params[1].get_bool(); + + uint256 hash = ParseHashV(params[0], "parameter 1"); + + LOCK(mempool.cs); + + CTxMemPool::txiter it = mempool.mapTx.find(hash); + if (it == mempool.mapTx.end()) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not in mempool"); + } + + CTxMemPool::setEntries setAncestors; + uint64_t noLimit = std::numeric_limits::max(); + std::string dummy; + mempool.CalculateMemPoolAncestors(*it, setAncestors, noLimit, noLimit, noLimit, noLimit, dummy, false); + + if (!fVerbose) { + UniValue o(UniValue::VARR); + BOOST_FOREACH(CTxMemPool::txiter ancestorIt, setAncestors) { + o.push_back(ancestorIt->GetTx().GetHash().ToString()); + } + + return o; + } else { + UniValue o(UniValue::VOBJ); + BOOST_FOREACH(CTxMemPool::txiter ancestorIt, setAncestors) { + const CTxMemPoolEntry &e = *ancestorIt; + const uint256& hash = e.GetTx().GetHash(); + UniValue info(UniValue::VOBJ); + entryToJSON(info, e); + o.push_back(Pair(hash.ToString(), info)); + } + return o; + } +} + UniValue getblockhash(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 1) @@ -1016,6 +1080,7 @@ static const CRPCCommand commands[] = { "blockchain", "getblockheader", &getblockheader, true }, { "blockchain", "getchaintips", &getchaintips, true }, { "blockchain", "getdifficulty", &getdifficulty, true }, + { "blockchain", "getmempoolancestors", &getmempoolancestors, true }, { "blockchain", "getmempoolinfo", &getmempoolinfo, true }, { "blockchain", "getrawmempool", &getrawmempool, true }, { "blockchain", "gettxout", &gettxout, true }, -- cgit v1.2.3 From 0dfd86956dcd2ac8a2223437e9bbd4f29bd35fce Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Mon, 4 Jan 2016 14:48:22 -0500 Subject: Add getmempooldescendants RPC call --- src/rpc/blockchain.cpp | 67 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) (limited to 'src/rpc/blockchain.cpp') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 6c005068d..e53ed1c1b 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -302,7 +302,7 @@ UniValue getmempoolancestors(const UniValue& params, bool fHelp) "1. \"txid\" (string, required) The transaction id (must be in mempool)\n" "2. verbose (boolean, optional, default=false) true for a json object, false for array of transaction ids\n" "\nResult (for verbose=false):\n" - "[ (json array of string)\n" + "[ (json array of strings)\n" " \"transactionid\" (string) The transaction id of an in-mempool ancestor transaction\n" " ,...\n" "]\n" @@ -356,6 +356,70 @@ UniValue getmempoolancestors(const UniValue& params, bool fHelp) } } +UniValue getmempooldescendants(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() < 1 || params.size() > 2) { + throw runtime_error( + "getmempooldescendants txid (verbose)\n" + "\nIf txid is in the mempool, returns all in-mempool descendants.\n" + "\nArguments:\n" + "1. \"txid\" (string, required) The transaction id (must be in mempool)\n" + "2. verbose (boolean, optional, default=false) true for a json object, false for array of transaction ids\n" + "\nResult (for verbose=false):\n" + "[ (json array of strings)\n" + " \"transactionid\" (string) The transaction id of an in-mempool descendant transaction\n" + " ,...\n" + "]\n" + "\nResult (for verbose=true):\n" + "{ (json object)\n" + " \"transactionid\" : { (json object)\n" + + EntryDescriptionString() + + " }, ...\n" + "}\n" + "\nExamples\n" + + HelpExampleCli("getmempooldescendants", "\"mytxid\"") + + HelpExampleRpc("getmempooldescendants", "\"mytxid\"") + ); + } + + bool fVerbose = false; + if (params.size() > 1) + fVerbose = params[1].get_bool(); + + uint256 hash = ParseHashV(params[0], "parameter 1"); + + LOCK(mempool.cs); + + CTxMemPool::txiter it = mempool.mapTx.find(hash); + if (it == mempool.mapTx.end()) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not in mempool"); + } + + CTxMemPool::setEntries setDescendants; + mempool.CalculateDescendants(it, setDescendants); + // CTxMemPool::CalculateDescendants will include the given tx + setDescendants.erase(it); + + if (!fVerbose) { + UniValue o(UniValue::VARR); + BOOST_FOREACH(CTxMemPool::txiter descendantIt, setDescendants) { + o.push_back(descendantIt->GetTx().GetHash().ToString()); + } + + return o; + } else { + UniValue o(UniValue::VOBJ); + BOOST_FOREACH(CTxMemPool::txiter descendantIt, setDescendants) { + const CTxMemPoolEntry &e = *descendantIt; + const uint256& hash = e.GetTx().GetHash(); + UniValue info(UniValue::VOBJ); + entryToJSON(info, e); + o.push_back(Pair(hash.ToString(), info)); + } + return o; + } +} + UniValue getblockhash(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 1) @@ -1081,6 +1145,7 @@ static const CRPCCommand commands[] = { "blockchain", "getchaintips", &getchaintips, true }, { "blockchain", "getdifficulty", &getdifficulty, true }, { "blockchain", "getmempoolancestors", &getmempoolancestors, true }, + { "blockchain", "getmempooldescendants", &getmempooldescendants, true }, { "blockchain", "getmempoolinfo", &getmempoolinfo, true }, { "blockchain", "getrawmempool", &getrawmempool, true }, { "blockchain", "gettxout", &gettxout, true }, -- cgit v1.2.3 From b09b8135ae1c4df103c68543c931e479fbb907ab Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Mon, 4 Jan 2016 14:57:58 -0500 Subject: Add getmempoolentry RPC call --- src/rpc/blockchain.cpp | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) (limited to 'src/rpc/blockchain.cpp') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index e53ed1c1b..6a07bb8c4 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -420,6 +420,39 @@ UniValue getmempooldescendants(const UniValue& params, bool fHelp) } } +UniValue getmempoolentry(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() != 1) { + throw runtime_error( + "getmempoolentry txid\n" + "\nReturns mempool data for given transaction\n" + "\nArguments:\n" + "1. \"txid\" (string, required) The transaction id (must be in mempool)\n" + "\nResult:\n" + "{ (json object)\n" + + EntryDescriptionString() + + "}\n" + "\nExamples\n" + + HelpExampleCli("getmempoolentry", "\"mytxid\"") + + HelpExampleRpc("getmempoolentry", "\"mytxid\"") + ); + } + + uint256 hash = ParseHashV(params[0], "parameter 1"); + + LOCK(mempool.cs); + + CTxMemPool::txiter it = mempool.mapTx.find(hash); + if (it == mempool.mapTx.end()) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not in mempool"); + } + + const CTxMemPoolEntry &e = *it; + UniValue info(UniValue::VOBJ); + entryToJSON(info, e); + return info; +} + UniValue getblockhash(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 1) @@ -1146,6 +1179,7 @@ static const CRPCCommand commands[] = { "blockchain", "getdifficulty", &getdifficulty, true }, { "blockchain", "getmempoolancestors", &getmempoolancestors, true }, { "blockchain", "getmempooldescendants", &getmempooldescendants, true }, + { "blockchain", "getmempoolentry", &getmempoolentry, true }, { "blockchain", "getmempoolinfo", &getmempoolinfo, true }, { "blockchain", "getrawmempool", &getrawmempool, true }, { "blockchain", "gettxout", &gettxout, true }, -- cgit v1.2.3 From 7f6eda80438be452a0b6e079737fb6fe00bb26b7 Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Tue, 17 May 2016 08:42:35 -0400 Subject: Add ancestor statistics to mempool entry RPC output --- src/rpc/blockchain.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/rpc/blockchain.cpp') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 6a07bb8c4..1bb365d36 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -195,6 +195,9 @@ std::string EntryDescriptionString() " \"descendantcount\" : n, (numeric) number of in-mempool descendant transactions (including this one)\n" " \"descendantsize\" : n, (numeric) size of in-mempool descendants (including this one)\n" " \"descendantfees\" : n, (numeric) modified fees (see above) of in-mempool descendants (including this one)\n" + " \"ancestorcount\" : n, (numeric) number of in-mempool ancestor transactions (including this one)\n" + " \"ancestorsize\" : n, (numeric) size of in-mempool ancestors (including this one)\n" + " \"ancestorfees\" : n, (numeric) modified fees (see above) of in-mempool ancestors (including this one)\n" " \"depends\" : [ (array) unconfirmed transactions used as inputs for this transaction\n" " \"transactionid\", (string) parent transaction id\n" " ... ]\n"; @@ -214,6 +217,9 @@ void entryToJSON(UniValue &info, const CTxMemPoolEntry &e) info.push_back(Pair("descendantcount", e.GetCountWithDescendants())); info.push_back(Pair("descendantsize", e.GetSizeWithDescendants())); info.push_back(Pair("descendantfees", e.GetModFeesWithDescendants())); + info.push_back(Pair("ancestorcount", e.GetCountWithAncestors())); + info.push_back(Pair("ancestorsize", e.GetSizeWithAncestors())); + info.push_back(Pair("ancestorfees", e.GetModFeesWithAncestors())); const CTransaction& tx = e.GetTx(); set setDepends; BOOST_FOREACH(const CTxIn& txin, tx.vin) -- cgit v1.2.3 From 8b49040854be2e26b66366aeae1cba4716f93d93 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Fri, 6 Nov 2015 01:42:38 +0100 Subject: BIP141: Commitment structure and deployment Includes a fix by Suhas Daftuar and LongShao007 --- src/rpc/blockchain.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/rpc/blockchain.cpp') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 1bb365d36..dae283fb6 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -930,6 +930,7 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp) softforks.push_back(SoftForkDesc("bip66", 3, tip, consensusParams)); softforks.push_back(SoftForkDesc("bip65", 4, tip, consensusParams)); bip9_softforks.push_back(Pair("csv", BIP9SoftForkDesc(consensusParams, Consensus::DEPLOYMENT_CSV))); + bip9_softforks.push_back(Pair("segwit", BIP9SoftForkDesc(consensusParams, Consensus::DEPLOYMENT_SEGWIT))); obj.push_back(Pair("softforks", softforks)); obj.push_back(Pair("bip9_softforks", bip9_softforks)); -- cgit v1.2.3 From 7c4bf779e8b74e474551982a24f5acc265293abd Mon Sep 17 00:00:00 2001 From: Johnson Lau Date: Sat, 23 Jan 2016 01:46:11 +0800 Subject: [RPC] Return witness data in blockchain RPCs Includes RPC field name changes by Luke-jr. --- src/rpc/blockchain.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/rpc/blockchain.cpp') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index dae283fb6..f11af876f 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -99,6 +99,7 @@ UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool tx if (chainActive.Contains(blockindex)) confirmations = chainActive.Height() - blockindex->nHeight + 1; result.push_back(Pair("confirmations", confirmations)); + result.push_back(Pair("strippedsize", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS))); result.push_back(Pair("size", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION))); result.push_back(Pair("height", blockindex->nHeight)); result.push_back(Pair("version", block.nVersion)); @@ -558,6 +559,7 @@ UniValue getblock(const UniValue& params, bool fHelp) " \"hash\" : \"hash\", (string) the block hash (same as provided)\n" " \"confirmations\" : n, (numeric) The number of confirmations, or -1 if the block is not on the main chain\n" " \"size\" : n, (numeric) The block size\n" + " \"strippedsize\" : n, (numeric) The block size excluding witness data\n" " \"height\" : n, (numeric) The block height or index\n" " \"version\" : n, (numeric) The block version\n" " \"versionHex\" : \"00000000\", (string) The block version formatted in hexadecimal\n" -- cgit v1.2.3 From 2b1f6f9ccf36f1e0a2c9d99154e1642f796d7c2b Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Sun, 3 Jan 2016 18:54:50 +0100 Subject: BIP141: Other consensus critical limits, and BIP145 Includes changes by Suhas Daftuar, Luke-jr, and mruddy. --- src/rpc/blockchain.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/rpc/blockchain.cpp') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index f11af876f..43ba4edd7 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -101,6 +101,7 @@ UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool tx result.push_back(Pair("confirmations", confirmations)); result.push_back(Pair("strippedsize", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS))); result.push_back(Pair("size", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION))); + result.push_back(Pair("cost", (int)::GetBlockCost(block))); result.push_back(Pair("height", blockindex->nHeight)); result.push_back(Pair("version", block.nVersion)); result.push_back(Pair("versionHex", strprintf("%08x", block.nVersion))); @@ -560,6 +561,7 @@ UniValue getblock(const UniValue& params, bool fHelp) " \"confirmations\" : n, (numeric) The number of confirmations, or -1 if the block is not on the main chain\n" " \"size\" : n, (numeric) The block size\n" " \"strippedsize\" : n, (numeric) The block size excluding witness data\n" + " \"cost\" : n (numeric) The block cost\n" " \"height\" : n, (numeric) The block height or index\n" " \"version\" : n, (numeric) The block version\n" " \"versionHex\" : \"00000000\", (string) The block version formatted in hexadecimal\n" -- cgit v1.2.3 From 27f8126ff37ec590c266adc6228d216857606536 Mon Sep 17 00:00:00 2001 From: Daniel Cousens Date: Thu, 23 Jun 2016 12:44:53 +1000 Subject: remove unnecessary LOCK(cs_main) --- src/rpc/blockchain.cpp | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/rpc/blockchain.cpp') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 1bb365d36..e63232b48 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -289,8 +289,6 @@ UniValue getrawmempool(const UniValue& params, bool fHelp) + HelpExampleRpc("getrawmempool", "true") ); - LOCK(cs_main); - bool fVerbose = false; if (params.size() > 0) fVerbose = params[0].get_bool(); -- cgit v1.2.3 From 409f83322e9fe3257cf9f3f61813195ac1aaa20c Mon Sep 17 00:00:00 2001 From: jl2012 Date: Sat, 25 Jun 2016 00:55:07 +0800 Subject: RPC: Hide softfork if timeout is 0 --- src/rpc/blockchain.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'src/rpc/blockchain.cpp') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 43ba4edd7..60462b9f8 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -868,6 +868,15 @@ static UniValue BIP9SoftForkDesc(const Consensus::Params& consensusParams, Conse return rv; } +void BIP9SoftForkDescPushBack(UniValue& bip9_softforks, const std::string &name, const Consensus::Params& consensusParams, Consensus::DeploymentPos id) +{ + // Deployments with timeout value of 0 are hidden. + // A timeout value of 0 guarantees a softfork will never be activated. + // This is used when softfork codes are merged without specifying the deployment schedule. + if (consensusParams.vDeployments[id].nTimeout > 0) + bip9_softforks.push_back(Pair(name, BIP9SoftForkDesc(consensusParams, id))); +} + UniValue getblockchaininfo(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) @@ -901,7 +910,7 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp) " ],\n" " \"bip9_softforks\": { (object) status of BIP9 softforks in progress\n" " \"xxxx\" : { (string) name of the softfork\n" - " \"status\": \"xxxx\", (string) one of \"defined\", \"started\", \"lockedin\", \"active\", \"failed\"\n" + " \"status\": \"xxxx\", (string) one of \"defined\", \"started\", \"locked_in\", \"active\", \"failed\"\n" " \"bit\": xx, (numeric) the bit, 0-28, in the block version field used to signal this soft fork\n" " \"startTime\": xx, (numeric) the minimum median time past of a block at which the bit gains its meaning\n" " \"timeout\": xx (numeric) the median time past of a block at which the deployment is considered failed if not yet locked in\n" @@ -933,8 +942,8 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp) softforks.push_back(SoftForkDesc("bip34", 2, tip, consensusParams)); softforks.push_back(SoftForkDesc("bip66", 3, tip, consensusParams)); softforks.push_back(SoftForkDesc("bip65", 4, tip, consensusParams)); - bip9_softforks.push_back(Pair("csv", BIP9SoftForkDesc(consensusParams, Consensus::DEPLOYMENT_CSV))); - bip9_softforks.push_back(Pair("segwit", BIP9SoftForkDesc(consensusParams, Consensus::DEPLOYMENT_SEGWIT))); + BIP9SoftForkDescPushBack(bip9_softforks, "csv", consensusParams, Consensus::DEPLOYMENT_CSV); + BIP9SoftForkDescPushBack(bip9_softforks, "segwit", consensusParams, Consensus::DEPLOYMENT_SEGWIT); obj.push_back(Pair("softforks", softforks)); obj.push_back(Pair("bip9_softforks", bip9_softforks)); -- cgit v1.2.3 From 2129fcea69ee0cf71c5e082607d101c3680af84c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jan=C3=ADk?= Date: Sat, 25 Jun 2016 08:19:36 +0200 Subject: The bit field is shown only when status is "started" --- src/rpc/blockchain.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/rpc/blockchain.cpp') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 9d1d12a47..20eefa1c5 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -909,7 +909,7 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp) " \"bip9_softforks\": { (object) status of BIP9 softforks in progress\n" " \"xxxx\" : { (string) name of the softfork\n" " \"status\": \"xxxx\", (string) one of \"defined\", \"started\", \"locked_in\", \"active\", \"failed\"\n" - " \"bit\": xx, (numeric) the bit, 0-28, in the block version field used to signal this soft fork\n" + " \"bit\": xx, (numeric) the bit (0-28) in the block version field used to signal this softfork (only for \"started\" status)\n" " \"startTime\": xx, (numeric) the minimum median time past of a block at which the bit gains its meaning\n" " \"timeout\": xx (numeric) the median time past of a block at which the deployment is considered failed if not yet locked in\n" " }\n" -- cgit v1.2.3 From 2c06bae39edfaa9c0855d83377ad8fda09e4fa08 Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Mon, 18 Jul 2016 13:28:26 -0400 Subject: Rename "block cost" to "block weight" --- src/rpc/blockchain.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/rpc/blockchain.cpp') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 20eefa1c5..9dc896b7a 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -101,7 +101,7 @@ UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool tx result.push_back(Pair("confirmations", confirmations)); result.push_back(Pair("strippedsize", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS))); result.push_back(Pair("size", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION))); - result.push_back(Pair("cost", (int)::GetBlockCost(block))); + result.push_back(Pair("weight", (int)::GetBlockWeight(block))); result.push_back(Pair("height", blockindex->nHeight)); result.push_back(Pair("version", block.nVersion)); result.push_back(Pair("versionHex", strprintf("%08x", block.nVersion))); @@ -559,7 +559,7 @@ UniValue getblock(const UniValue& params, bool fHelp) " \"confirmations\" : n, (numeric) The number of confirmations, or -1 if the block is not on the main chain\n" " \"size\" : n, (numeric) The block size\n" " \"strippedsize\" : n, (numeric) The block size excluding witness data\n" - " \"cost\" : n (numeric) The block cost\n" + " \"weight\" : n (numeric) The block weight (BIP 141)\n" " \"height\" : n, (numeric) The block height or index\n" " \"version\" : n, (numeric) The block version\n" " \"versionHex\" : \"00000000\", (string) The block version formatted in hexadecimal\n" -- cgit v1.2.3 From 122786d0e0170c73536360b705af711e1338adbf Mon Sep 17 00:00:00 2001 From: NicolasDorier Date: Fri, 22 Jul 2016 08:27:55 +0900 Subject: Consensus: Remove ISM --- src/rpc/blockchain.cpp | 36 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 20 deletions(-) (limited to 'src/rpc/blockchain.cpp') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 9dc896b7a..e3c32d905 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -817,22 +817,23 @@ UniValue verifychain(const UniValue& params, bool fHelp) } /** Implementation of IsSuperMajority with better feedback */ -static UniValue SoftForkMajorityDesc(int minVersion, CBlockIndex* pindex, int nRequired, const Consensus::Params& consensusParams) +static UniValue SoftForkMajorityDesc(int version, CBlockIndex* pindex, const Consensus::Params& consensusParams) { - int nFound = 0; - CBlockIndex* pstart = pindex; - for (int i = 0; i < consensusParams.nMajorityWindow && pstart != NULL; i++) + UniValue rv(UniValue::VOBJ); + bool activated = false; + switch(version) { - if (pstart->nVersion >= minVersion) - ++nFound; - pstart = pstart->pprev; + case 2: + activated = pindex->nHeight >= consensusParams.BIP34Height; + break; + case 3: + activated = pindex->nHeight >= consensusParams.BIP66Height; + break; + case 4: + activated = pindex->nHeight >= consensusParams.BIP65Height; + break; } - - UniValue rv(UniValue::VOBJ); - rv.push_back(Pair("status", nFound >= nRequired)); - rv.push_back(Pair("found", nFound)); - rv.push_back(Pair("required", nRequired)); - rv.push_back(Pair("window", consensusParams.nMajorityWindow)); + rv.push_back(Pair("status", activated)); return rv; } @@ -841,8 +842,7 @@ static UniValue SoftForkDesc(const std::string &name, int version, CBlockIndex* UniValue rv(UniValue::VOBJ); rv.push_back(Pair("id", name)); rv.push_back(Pair("version", version)); - rv.push_back(Pair("enforce", SoftForkMajorityDesc(version, pindex, consensusParams.nMajorityEnforceBlockUpgrade, consensusParams))); - rv.push_back(Pair("reject", SoftForkMajorityDesc(version, pindex, consensusParams.nMajorityRejectBlockOutdated, consensusParams))); + rv.push_back(Pair("reject", SoftForkMajorityDesc(version, pindex, consensusParams))); return rv; } @@ -897,13 +897,9 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp) " {\n" " \"id\": \"xxxx\", (string) name of softfork\n" " \"version\": xx, (numeric) block version\n" - " \"enforce\": { (object) progress toward enforcing the softfork rules for new-version blocks\n" + " \"reject\": { (object) progress toward rejecting pre-softfork blocks\n" " \"status\": xx, (boolean) true if threshold reached\n" - " \"found\": xx, (numeric) number of blocks with the new version found\n" - " \"required\": xx, (numeric) number of blocks required to trigger\n" - " \"window\": xx, (numeric) maximum size of examined window of recent blocks\n" " },\n" - " \"reject\": { ... } (object) progress toward rejecting pre-softfork blocks (same fields as \"enforce\")\n" " }, ...\n" " ],\n" " \"bip9_softforks\": { (object) status of BIP9 softforks in progress\n" -- cgit v1.2.3 From de1bbe3b7876e311ebba5445b7b251782c0a7e0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jan=C3=ADk?= Date: Tue, 7 Jun 2016 18:42:42 +0200 Subject: Do not shadow global RPC table variable (tableRPC) --- src/rpc/blockchain.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/rpc/blockchain.cpp') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index e3c32d905..7f391da09 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -1205,8 +1205,8 @@ static const CRPCCommand commands[] = { "hidden", "reconsiderblock", &reconsiderblock, true }, }; -void RegisterBlockchainRPCCommands(CRPCTable &tableRPC) +void RegisterBlockchainRPCCommands(CRPCTable &t) { for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++) - tableRPC.appendCommand(commands[vcidx].name, &commands[vcidx]); + t.appendCommand(commands[vcidx].name, &commands[vcidx]); } -- cgit v1.2.3 From 5127c4f21ca3f092b3a853833631dfc7f9c9456b Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Fri, 26 Aug 2016 23:05:09 +0200 Subject: Add preciousblock RPC Includes a bugfix by Luke-Jr. --- src/rpc/blockchain.cpp | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) (limited to 'src/rpc/blockchain.cpp') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index e3c32d905..75f49e939 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -1105,6 +1105,44 @@ UniValue getmempoolinfo(const UniValue& params, bool fHelp) return mempoolInfoToJSON(); } +UniValue preciousblock(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() != 1) + throw runtime_error( + "preciousblock \"hash\"\n" + "\nTreats a block as if it were received before others with the same work.\n" + "\nA later preciousblock call can override the effect of an earlier one.\n" + "\nThe effects of preciousblock are not retained across restarts.\n" + "\nArguments:\n" + "1. hash (string, required) the hash of the block to mark as precious\n" + "\nResult:\n" + "\nExamples:\n" + + HelpExampleCli("preciousblock", "\"blockhash\"") + + HelpExampleRpc("preciousblock", "\"blockhash\"") + ); + + std::string strHash = params[0].get_str(); + uint256 hash(uint256S(strHash)); + CBlockIndex* pblockindex; + + { + LOCK(cs_main); + if (mapBlockIndex.count(hash) == 0) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); + + pblockindex = mapBlockIndex[hash]; + } + + CValidationState state; + PreciousBlock(state, Params(), pblockindex); + + if (!state.IsValid()) { + throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason()); + } + + return NullUniValue; +} + UniValue invalidateblock(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 1) @@ -1200,6 +1238,8 @@ static const CRPCCommand commands[] = { "blockchain", "gettxoutsetinfo", &gettxoutsetinfo, true }, { "blockchain", "verifychain", &verifychain, true }, + { "blockchain", "preciousblock", &preciousblock, true }, + /* Not shown in help */ { "hidden", "invalidateblock", &invalidateblock, true }, { "hidden", "reconsiderblock", &reconsiderblock, true }, -- cgit v1.2.3 From cdd79eb70fe163a92531a6f11c72bce6d228dac6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Tim=C3=B3n?= Date: Tue, 30 Aug 2016 22:41:56 +0200 Subject: C++11: s/boost::scoped_ptr/std::unique_ptr/ --- src/rpc/blockchain.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/rpc/blockchain.cpp') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index e3c32d905..0f3edde14 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -632,7 +632,7 @@ struct CCoinsStats //! Calculate statistics about the unspent transaction output set static bool GetUTXOStats(CCoinsView *view, CCoinsStats &stats) { - boost::scoped_ptr pcursor(view->Cursor()); + std::unique_ptr pcursor(view->Cursor()); CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION); stats.hashBlock = pcursor->GetBestBlock(); -- cgit v1.2.3 From d6a5dc4a2eaa0d7348804254ca09e75fc3a858ab Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Thu, 1 Sep 2016 21:55:21 -0400 Subject: add waitfornewblock/waitforblock/waitforblockheight rpcs and use them for tests waitfornewblock waits until a new block is received, or the timeout expires, then returns the current block height/hash. waitforblock waits for a specific blockhash, or until the timeout expires, then returns the current block height/hash. If the target blockhash is the current tip, it will return immediately. waitforblockheight waits until the tip has reached a certain height or higher, then returns the current height and hash. waitforblockheight is used to avoid polling in the rpc tests. --- src/rpc/blockchain.cpp | 147 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 147 insertions(+) (limited to 'src/rpc/blockchain.cpp') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index b90410017..dc7e4721b 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -26,8 +26,20 @@ #include // boost::thread::interrupt +#include +#include using namespace std; +struct CUpdatedBlock +{ + uint256 hash; + int height; +}; + +static std::mutex cs_blockchange; +static std::condition_variable cond_blockchange; +static CUpdatedBlock latestblock; + extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry); void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex); @@ -168,6 +180,138 @@ UniValue getbestblockhash(const UniValue& params, bool fHelp) return chainActive.Tip()->GetBlockHash().GetHex(); } +void RPCNotifyBlockChange(bool ibd, const CBlockIndex * pindex) +{ + if(pindex) { + std::lock_guard lock(cs_blockchange); + latestblock.hash = pindex->GetBlockHash(); + latestblock.height = pindex->nHeight; + } + cond_blockchange.notify_all(); +} + +UniValue waitfornewblock(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() > 1) + throw runtime_error( + "waitfornewblock\n" + "\nWaits for a specific new block and returns useful info about it.\n" + "\nReturns the current block on timeout or exit.\n" + "\nArguments:\n" + "1. timeout (milliseconds) (int, optional, default=false)\n" + "\nResult::\n" + "{ (json object)\n" + " \"hash\" : { (string) The blockhash\n" + " \"height\" : { (int) Block height\n" + "}\n" + "\nExamples\n" + + HelpExampleCli("waitfornewblock", "1000") + + HelpExampleRpc("waitfornewblock", "1000") + ); + int timeout = 0; + if (params.size() > 0) + timeout = params[0].get_int(); + + CUpdatedBlock block; + { + std::unique_lock lock(cs_blockchange); + block = latestblock; + if(timeout) + cond_blockchange.wait_for(lock, std::chrono::milliseconds(timeout), [&block]{return latestblock.height != block.height || latestblock.hash != block.hash || !IsRPCRunning(); }); + else + cond_blockchange.wait(lock, [&block]{return latestblock.height != block.height || latestblock.hash != block.hash || !IsRPCRunning(); }); + block = latestblock; + } + UniValue ret(UniValue::VOBJ); + ret.push_back(Pair("hash", block.hash.GetHex())); + ret.push_back(Pair("height", block.height)); + return ret; +} + +UniValue waitforblock(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() < 1 || params.size() > 2) + throw runtime_error( + "waitforblock\n" + "\nWaits for a specific new block and returns useful info about it.\n" + "\nReturns the current block on timeout or exit.\n" + "\nArguments:\n" + "1. blockhash to wait for (string)\n" + "2. timeout (milliseconds) (int, optional, default=false)\n" + "\nResult::\n" + "{ (json object)\n" + " \"hash\" : { (string) The blockhash\n" + " \"height\" : { (int) Block height\n" + "}\n" + "\nExamples\n" + + HelpExampleCli("waitforblock", "\"0000000000079f8ef3d2c688c244eb7a4570b24c9ed7b4a8c619eb02596f8862\", 1000") + + HelpExampleRpc("waitforblock", "\"0000000000079f8ef3d2c688c244eb7a4570b24c9ed7b4a8c619eb02596f8862\", 1000") + ); + int timeout = 0; + + uint256 hash = uint256S(params[0].get_str()); + + if (params.size() > 1) + timeout = params[1].get_int(); + + CUpdatedBlock block; + { + std::unique_lock lock(cs_blockchange); + if(timeout) + cond_blockchange.wait_for(lock, std::chrono::milliseconds(timeout), [&hash]{return latestblock.hash == hash || !IsRPCRunning();}); + else + cond_blockchange.wait(lock, [&hash]{return latestblock.hash == hash || !IsRPCRunning(); }); + block = latestblock; + } + + UniValue ret(UniValue::VOBJ); + ret.push_back(Pair("hash", block.hash.GetHex())); + ret.push_back(Pair("height", block.height)); + return ret; +} + +UniValue waitforblockheight(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() < 1 || params.size() > 2) + throw runtime_error( + "waitforblock\n" + "\nWaits for (at least) block height and returns the height and hash\n" + "\nof the current tip.\n" + "\nReturns the current block on timeout or exit.\n" + "\nArguments:\n" + "1. block height to wait for (int)\n" + "2. timeout (milliseconds) (int, optional, default=false)\n" + "\nResult::\n" + "{ (json object)\n" + " \"hash\" : { (string) The blockhash\n" + " \"height\" : { (int) Block height\n" + "}\n" + "\nExamples\n" + + HelpExampleCli("waitforblockheight", "\"100\", 1000") + + HelpExampleRpc("waitforblockheight", "\"100\", 1000") + ); + int timeout = 0; + + int height = params[0].get_int(); + + if (params.size() > 1) + timeout = params[1].get_int(); + + CUpdatedBlock block; + { + std::unique_lock lock(cs_blockchange); + if(timeout) + cond_blockchange.wait_for(lock, std::chrono::milliseconds(timeout), [&height]{return latestblock.height >= height || !IsRPCRunning();}); + else + cond_blockchange.wait(lock, [&height]{return latestblock.height >= height || !IsRPCRunning(); }); + block = latestblock; + } + UniValue ret(UniValue::VOBJ); + ret.push_back(Pair("hash", block.hash.GetHex())); + ret.push_back(Pair("height", block.height)); + return ret; +} + UniValue getdifficulty(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) @@ -1203,6 +1347,9 @@ static const CRPCCommand commands[] = /* Not shown in help */ { "hidden", "invalidateblock", &invalidateblock, true }, { "hidden", "reconsiderblock", &reconsiderblock, true }, + { "hidden", "waitfornewblock", &waitfornewblock, true }, + { "hidden", "waitforblock", &waitforblock, true }, + { "hidden", "waitforblockheight", &waitforblockheight, true }, }; void RegisterBlockchainRPCCommands(CRPCTable &t) -- cgit v1.2.3 From 8d58c4d81f18e9a51d11ee354434cf55d03a4add Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Thu, 26 May 2016 14:26:01 -0400 Subject: net: Pass CConnman around as needed --- src/rpc/blockchain.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/rpc/blockchain.cpp') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index b90410017..d600383c4 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -1133,7 +1133,7 @@ UniValue invalidateblock(const UniValue& params, bool fHelp) } if (state.IsValid()) { - ActivateBestChain(state, Params()); + ActivateBestChain(state, Params(), NULL, g_connman.get()); } if (!state.IsValid()) { @@ -1171,7 +1171,7 @@ UniValue reconsiderblock(const UniValue& params, bool fHelp) } CValidationState state; - ActivateBestChain(state, Params()); + ActivateBestChain(state, Params(), NULL, g_connman.get()); if (!state.IsValid()) { throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason()); -- cgit v1.2.3 From 4731cab8fbff51a8178c85d572e2482040278616 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jan=C3=ADk?= Date: Fri, 2 Sep 2016 18:19:01 +0200 Subject: Do not shadow variables --- src/rpc/blockchain.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/rpc/blockchain.cpp') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index f05f8ff35..91d3197cd 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -497,10 +497,10 @@ UniValue getmempoolancestors(const UniValue& params, bool fHelp) UniValue o(UniValue::VOBJ); BOOST_FOREACH(CTxMemPool::txiter ancestorIt, setAncestors) { const CTxMemPoolEntry &e = *ancestorIt; - const uint256& hash = e.GetTx().GetHash(); + const uint256& _hash = e.GetTx().GetHash(); UniValue info(UniValue::VOBJ); entryToJSON(info, e); - o.push_back(Pair(hash.ToString(), info)); + o.push_back(Pair(_hash.ToString(), info)); } return o; } @@ -561,10 +561,10 @@ UniValue getmempooldescendants(const UniValue& params, bool fHelp) UniValue o(UniValue::VOBJ); BOOST_FOREACH(CTxMemPool::txiter descendantIt, setDescendants) { const CTxMemPoolEntry &e = *descendantIt; - const uint256& hash = e.GetTx().GetHash(); + const uint256& _hash = e.GetTx().GetHash(); UniValue info(UniValue::VOBJ); entryToJSON(info, e); - o.push_back(Pair(hash.ToString(), info)); + o.push_back(Pair(_hash.ToString(), info)); } return o; } -- cgit v1.2.3 From fa05cfdf256f3bc13b89ea80231e342f4302d204 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Wed, 28 Sep 2016 21:05:11 +0200 Subject: [rpc] throw JSONRPCError when utxo set can not be read --- src/rpc/blockchain.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/rpc/blockchain.cpp') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 91d3197cd..41d862934 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -848,6 +848,8 @@ UniValue gettxoutsetinfo(const UniValue& params, bool fHelp) ret.push_back(Pair("bytes_serialized", (int64_t)stats.nSerializedSize)); ret.push_back(Pair("hash_serialized", stats.hashSerialized.GetHex())); ret.push_back(Pair("total_amount", ValueFromAmount(stats.nTotalAmount))); + } else { + throw JSONRPCError(RPC_INTERNAL_ERROR, "Unable to read UTXO set"); } return ret; } -- cgit v1.2.3 From f5efa283931ce1d52c59234b58988a221d42ecb4 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Fri, 30 Sep 2016 18:38:05 -0400 Subject: Remove CConnman parameter from ProcessNewBlock/ActivateBestChain --- src/rpc/blockchain.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/rpc/blockchain.cpp') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 41d862934..d85f6fed6 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -1279,7 +1279,7 @@ UniValue invalidateblock(const UniValue& params, bool fHelp) } if (state.IsValid()) { - ActivateBestChain(state, Params(), NULL, g_connman.get()); + ActivateBestChain(state, Params(), NULL); } if (!state.IsValid()) { @@ -1317,7 +1317,7 @@ UniValue reconsiderblock(const UniValue& params, bool fHelp) } CValidationState state; - ActivateBestChain(state, Params(), NULL, g_connman.get()); + ActivateBestChain(state, Params(), NULL); if (!state.IsValid()) { throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason()); -- cgit v1.2.3 From a78e5428acb862bfb47e6faff39f4889f5c73269 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Tue, 4 Oct 2016 22:20:07 +0000 Subject: Bugfix: Trivial: RPC: getblockchaininfo help: pruneheight is the lowest, not highest, block --- src/rpc/blockchain.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/rpc/blockchain.cpp') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 20eefa1c5..675d9ba90 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -892,7 +892,7 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp) " \"verificationprogress\": xxxx, (numeric) estimate of verification progress [0..1]\n" " \"chainwork\": \"xxxx\" (string) total amount of work in active chain, in hexadecimal\n" " \"pruned\": xx, (boolean) if the blocks are subject to pruning\n" - " \"pruneheight\": xxxxxx, (numeric) heighest block available\n" + " \"pruneheight\": xxxxxx, (numeric) lowest-height complete block stored\n" " \"softforks\": [ (array) status of softforks in progress\n" " {\n" " \"id\": \"xxxx\", (string) name of softfork\n" -- cgit v1.2.3 From 69d1c25768a8649bfc7eb8e9c35b8fe9874ac9fc Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Thu, 22 Sep 2016 09:46:41 +0200 Subject: [RPC] Give RPC commands more information about the RPC request --- src/rpc/blockchain.cpp | 158 ++++++++++++++++++++++++------------------------- 1 file changed, 79 insertions(+), 79 deletions(-) (limited to 'src/rpc/blockchain.cpp') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 5414ac9ff..0c827a1e3 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -146,9 +146,9 @@ UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool tx return result; } -UniValue getblockcount(const UniValue& params, bool fHelp) +UniValue getblockcount(const JSONRPCRequest& request) { - if (fHelp || params.size() != 0) + if (request.fHelp || request.params.size() != 0) throw runtime_error( "getblockcount\n" "\nReturns the number of blocks in the longest block chain.\n" @@ -163,9 +163,9 @@ UniValue getblockcount(const UniValue& params, bool fHelp) return chainActive.Height(); } -UniValue getbestblockhash(const UniValue& params, bool fHelp) +UniValue getbestblockhash(const JSONRPCRequest& request) { - if (fHelp || params.size() != 0) + if (request.fHelp || request.params.size() != 0) throw runtime_error( "getbestblockhash\n" "\nReturns the hash of the best (tip) block in the longest block chain.\n" @@ -190,9 +190,9 @@ void RPCNotifyBlockChange(bool ibd, const CBlockIndex * pindex) cond_blockchange.notify_all(); } -UniValue waitfornewblock(const UniValue& params, bool fHelp) +UniValue waitfornewblock(const JSONRPCRequest& request) { - if (fHelp || params.size() > 1) + if (request.fHelp || request.params.size() > 1) throw runtime_error( "waitfornewblock\n" "\nWaits for a specific new block and returns useful info about it.\n" @@ -209,8 +209,8 @@ UniValue waitfornewblock(const UniValue& params, bool fHelp) + HelpExampleRpc("waitfornewblock", "1000") ); int timeout = 0; - if (params.size() > 0) - timeout = params[0].get_int(); + if (request.params.size() > 0) + timeout = request.params[0].get_int(); CUpdatedBlock block; { @@ -228,9 +228,9 @@ UniValue waitfornewblock(const UniValue& params, bool fHelp) return ret; } -UniValue waitforblock(const UniValue& params, bool fHelp) +UniValue waitforblock(const JSONRPCRequest& request) { - if (fHelp || params.size() < 1 || params.size() > 2) + if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) throw runtime_error( "waitforblock\n" "\nWaits for a specific new block and returns useful info about it.\n" @@ -249,10 +249,10 @@ UniValue waitforblock(const UniValue& params, bool fHelp) ); int timeout = 0; - uint256 hash = uint256S(params[0].get_str()); + uint256 hash = uint256S(request.params[0].get_str()); - if (params.size() > 1) - timeout = params[1].get_int(); + if (request.params.size() > 1) + timeout = request.params[1].get_int(); CUpdatedBlock block; { @@ -270,9 +270,9 @@ UniValue waitforblock(const UniValue& params, bool fHelp) return ret; } -UniValue waitforblockheight(const UniValue& params, bool fHelp) +UniValue waitforblockheight(const JSONRPCRequest& request) { - if (fHelp || params.size() < 1 || params.size() > 2) + if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) throw runtime_error( "waitforblock\n" "\nWaits for (at least) block height and returns the height and hash\n" @@ -292,10 +292,10 @@ UniValue waitforblockheight(const UniValue& params, bool fHelp) ); int timeout = 0; - int height = params[0].get_int(); + int height = request.params[0].get_int(); - if (params.size() > 1) - timeout = params[1].get_int(); + if (request.params.size() > 1) + timeout = request.params[1].get_int(); CUpdatedBlock block; { @@ -312,9 +312,9 @@ UniValue waitforblockheight(const UniValue& params, bool fHelp) return ret; } -UniValue getdifficulty(const UniValue& params, bool fHelp) +UniValue getdifficulty(const JSONRPCRequest& request) { - if (fHelp || params.size() != 0) + if (request.fHelp || request.params.size() != 0) throw runtime_error( "getdifficulty\n" "\nReturns the proof-of-work difficulty as a multiple of the minimum difficulty.\n" @@ -411,9 +411,9 @@ UniValue mempoolToJSON(bool fVerbose = false) } } -UniValue getrawmempool(const UniValue& params, bool fHelp) +UniValue getrawmempool(const JSONRPCRequest& request) { - if (fHelp || params.size() > 1) + if (request.fHelp || request.params.size() > 1) throw runtime_error( "getrawmempool ( verbose )\n" "\nReturns all transaction ids in memory pool as a json array of string transaction ids.\n" @@ -436,15 +436,15 @@ UniValue getrawmempool(const UniValue& params, bool fHelp) ); bool fVerbose = false; - if (params.size() > 0) - fVerbose = params[0].get_bool(); + if (request.params.size() > 0) + fVerbose = request.params[0].get_bool(); return mempoolToJSON(fVerbose); } -UniValue getmempoolancestors(const UniValue& params, bool fHelp) +UniValue getmempoolancestors(const JSONRPCRequest& request) { - if (fHelp || params.size() < 1 || params.size() > 2) { + if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) { throw runtime_error( "getmempoolancestors txid (verbose)\n" "\nIf txid is in the mempool, returns all in-mempool ancestors.\n" @@ -469,10 +469,10 @@ UniValue getmempoolancestors(const UniValue& params, bool fHelp) } bool fVerbose = false; - if (params.size() > 1) - fVerbose = params[1].get_bool(); + if (request.params.size() > 1) + fVerbose = request.params[1].get_bool(); - uint256 hash = ParseHashV(params[0], "parameter 1"); + uint256 hash = ParseHashV(request.params[0], "parameter 1"); LOCK(mempool.cs); @@ -506,9 +506,9 @@ UniValue getmempoolancestors(const UniValue& params, bool fHelp) } } -UniValue getmempooldescendants(const UniValue& params, bool fHelp) +UniValue getmempooldescendants(const JSONRPCRequest& request) { - if (fHelp || params.size() < 1 || params.size() > 2) { + if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) { throw runtime_error( "getmempooldescendants txid (verbose)\n" "\nIf txid is in the mempool, returns all in-mempool descendants.\n" @@ -533,10 +533,10 @@ UniValue getmempooldescendants(const UniValue& params, bool fHelp) } bool fVerbose = false; - if (params.size() > 1) - fVerbose = params[1].get_bool(); + if (request.params.size() > 1) + fVerbose = request.params[1].get_bool(); - uint256 hash = ParseHashV(params[0], "parameter 1"); + uint256 hash = ParseHashV(request.params[0], "parameter 1"); LOCK(mempool.cs); @@ -570,9 +570,9 @@ UniValue getmempooldescendants(const UniValue& params, bool fHelp) } } -UniValue getmempoolentry(const UniValue& params, bool fHelp) +UniValue getmempoolentry(const JSONRPCRequest& request) { - if (fHelp || params.size() != 1) { + if (request.fHelp || request.params.size() != 1) { throw runtime_error( "getmempoolentry txid\n" "\nReturns mempool data for given transaction\n" @@ -588,7 +588,7 @@ UniValue getmempoolentry(const UniValue& params, bool fHelp) ); } - uint256 hash = ParseHashV(params[0], "parameter 1"); + uint256 hash = ParseHashV(request.params[0], "parameter 1"); LOCK(mempool.cs); @@ -603,9 +603,9 @@ UniValue getmempoolentry(const UniValue& params, bool fHelp) return info; } -UniValue getblockhash(const UniValue& params, bool fHelp) +UniValue getblockhash(const JSONRPCRequest& request) { - if (fHelp || params.size() != 1) + if (request.fHelp || request.params.size() != 1) throw runtime_error( "getblockhash index\n" "\nReturns hash of block in best-block-chain at index provided.\n" @@ -620,7 +620,7 @@ UniValue getblockhash(const UniValue& params, bool fHelp) LOCK(cs_main); - int nHeight = params[0].get_int(); + int nHeight = request.params[0].get_int(); if (nHeight < 0 || nHeight > chainActive.Height()) throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range"); @@ -628,9 +628,9 @@ UniValue getblockhash(const UniValue& params, bool fHelp) return pblockindex->GetBlockHash().GetHex(); } -UniValue getblockheader(const UniValue& params, bool fHelp) +UniValue getblockheader(const JSONRPCRequest& request) { - if (fHelp || params.size() < 1 || params.size() > 2) + if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) throw runtime_error( "getblockheader \"hash\" ( verbose )\n" "\nIf verbose is false, returns a string that is serialized, hex-encoded data for blockheader 'hash'.\n" @@ -664,12 +664,12 @@ UniValue getblockheader(const UniValue& params, bool fHelp) LOCK(cs_main); - std::string strHash = params[0].get_str(); + std::string strHash = request.params[0].get_str(); uint256 hash(uint256S(strHash)); bool fVerbose = true; - if (params.size() > 1) - fVerbose = params[1].get_bool(); + if (request.params.size() > 1) + fVerbose = request.params[1].get_bool(); if (mapBlockIndex.count(hash) == 0) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); @@ -687,9 +687,9 @@ UniValue getblockheader(const UniValue& params, bool fHelp) return blockheaderToJSON(pblockindex); } -UniValue getblock(const UniValue& params, bool fHelp) +UniValue getblock(const JSONRPCRequest& request) { - if (fHelp || params.size() < 1 || params.size() > 2) + if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) throw runtime_error( "getblock \"hash\" ( verbose )\n" "\nIf verbose is false, returns a string that is serialized, hex-encoded data for block 'hash'.\n" @@ -730,12 +730,12 @@ UniValue getblock(const UniValue& params, bool fHelp) LOCK(cs_main); - std::string strHash = params[0].get_str(); + std::string strHash = request.params[0].get_str(); uint256 hash(uint256S(strHash)); bool fVerbose = true; - if (params.size() > 1) - fVerbose = params[1].get_bool(); + if (request.params.size() > 1) + fVerbose = request.params[1].get_bool(); if (mapBlockIndex.count(hash) == 0) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); @@ -814,9 +814,9 @@ static bool GetUTXOStats(CCoinsView *view, CCoinsStats &stats) return true; } -UniValue gettxoutsetinfo(const UniValue& params, bool fHelp) +UniValue gettxoutsetinfo(const JSONRPCRequest& request) { - if (fHelp || params.size() != 0) + if (request.fHelp || request.params.size() != 0) throw runtime_error( "gettxoutsetinfo\n" "\nReturns statistics about the unspent transaction output set.\n" @@ -854,9 +854,9 @@ UniValue gettxoutsetinfo(const UniValue& params, bool fHelp) return ret; } -UniValue gettxout(const UniValue& params, bool fHelp) +UniValue gettxout(const JSONRPCRequest& request) { - if (fHelp || params.size() < 2 || params.size() > 3) + if (request.fHelp || request.params.size() < 2 || request.params.size() > 3) throw runtime_error( "gettxout \"txid\" n ( includemempool )\n" "\nReturns details about an unspent transaction output.\n" @@ -896,12 +896,12 @@ UniValue gettxout(const UniValue& params, bool fHelp) UniValue ret(UniValue::VOBJ); - std::string strHash = params[0].get_str(); + std::string strHash = request.params[0].get_str(); uint256 hash(uint256S(strHash)); - int n = params[1].get_int(); + int n = request.params[1].get_int(); bool fMempool = true; - if (params.size() > 2) - fMempool = params[2].get_bool(); + if (request.params.size() > 2) + fMempool = request.params[2].get_bool(); CCoins coins; if (fMempool) { @@ -934,11 +934,11 @@ UniValue gettxout(const UniValue& params, bool fHelp) return ret; } -UniValue verifychain(const UniValue& params, bool fHelp) +UniValue verifychain(const JSONRPCRequest& request) { int nCheckLevel = GetArg("-checklevel", DEFAULT_CHECKLEVEL); int nCheckDepth = GetArg("-checkblocks", DEFAULT_CHECKBLOCKS); - if (fHelp || params.size() > 2) + if (request.fHelp || request.params.size() > 2) throw runtime_error( "verifychain ( checklevel numblocks )\n" "\nVerifies blockchain database.\n" @@ -954,10 +954,10 @@ UniValue verifychain(const UniValue& params, bool fHelp) LOCK(cs_main); - if (params.size() > 0) - nCheckLevel = params[0].get_int(); - if (params.size() > 1) - nCheckDepth = params[1].get_int(); + if (request.params.size() > 0) + nCheckLevel = request.params[0].get_int(); + if (request.params.size() > 1) + nCheckDepth = request.params[1].get_int(); return CVerifyDB().VerifyDB(Params(), pcoinsTip, nCheckLevel, nCheckDepth); } @@ -1021,9 +1021,9 @@ void BIP9SoftForkDescPushBack(UniValue& bip9_softforks, const std::string &name, bip9_softforks.push_back(Pair(name, BIP9SoftForkDesc(consensusParams, id))); } -UniValue getblockchaininfo(const UniValue& params, bool fHelp) +UniValue getblockchaininfo(const JSONRPCRequest& request) { - if (fHelp || params.size() != 0) + if (request.fHelp || request.params.size() != 0) throw runtime_error( "getblockchaininfo\n" "Returns an object containing various state info regarding block chain processing.\n" @@ -1113,9 +1113,9 @@ struct CompareBlocksByHeight } }; -UniValue getchaintips(const UniValue& params, bool fHelp) +UniValue getchaintips(const JSONRPCRequest& request) { - if (fHelp || params.size() != 0) + if (request.fHelp || request.params.size() != 0) throw runtime_error( "getchaintips\n" "Return information about all known tips in the block tree," @@ -1229,9 +1229,9 @@ UniValue mempoolInfoToJSON() return ret; } -UniValue getmempoolinfo(const UniValue& params, bool fHelp) +UniValue getmempoolinfo(const JSONRPCRequest& request) { - if (fHelp || params.size() != 0) + if (request.fHelp || request.params.size() != 0) throw runtime_error( "getmempoolinfo\n" "\nReturns details on the active state of the TX memory pool.\n" @@ -1251,9 +1251,9 @@ UniValue getmempoolinfo(const UniValue& params, bool fHelp) return mempoolInfoToJSON(); } -UniValue preciousblock(const UniValue& params, bool fHelp) +UniValue preciousblock(const JSONRPCRequest& request) { - if (fHelp || params.size() != 1) + if (request.fHelp || request.params.size() != 1) throw runtime_error( "preciousblock \"hash\"\n" "\nTreats a block as if it were received before others with the same work.\n" @@ -1267,7 +1267,7 @@ UniValue preciousblock(const UniValue& params, bool fHelp) + HelpExampleRpc("preciousblock", "\"blockhash\"") ); - std::string strHash = params[0].get_str(); + std::string strHash = request.params[0].get_str(); uint256 hash(uint256S(strHash)); CBlockIndex* pblockindex; @@ -1289,9 +1289,9 @@ UniValue preciousblock(const UniValue& params, bool fHelp) return NullUniValue; } -UniValue invalidateblock(const UniValue& params, bool fHelp) +UniValue invalidateblock(const JSONRPCRequest& request) { - if (fHelp || params.size() != 1) + if (request.fHelp || request.params.size() != 1) throw runtime_error( "invalidateblock \"hash\"\n" "\nPermanently marks a block as invalid, as if it violated a consensus rule.\n" @@ -1303,7 +1303,7 @@ UniValue invalidateblock(const UniValue& params, bool fHelp) + HelpExampleRpc("invalidateblock", "\"blockhash\"") ); - std::string strHash = params[0].get_str(); + std::string strHash = request.params[0].get_str(); uint256 hash(uint256S(strHash)); CValidationState state; @@ -1327,9 +1327,9 @@ UniValue invalidateblock(const UniValue& params, bool fHelp) return NullUniValue; } -UniValue reconsiderblock(const UniValue& params, bool fHelp) +UniValue reconsiderblock(const JSONRPCRequest& request) { - if (fHelp || params.size() != 1) + if (request.fHelp || request.params.size() != 1) throw runtime_error( "reconsiderblock \"hash\"\n" "\nRemoves invalidity status of a block and its descendants, reconsider them for activation.\n" @@ -1342,7 +1342,7 @@ UniValue reconsiderblock(const UniValue& params, bool fHelp) + HelpExampleRpc("reconsiderblock", "\"blockhash\"") ); - std::string strHash = params[0].get_str(); + std::string strHash = request.params[0].get_str(); uint256 hash(uint256S(strHash)); { -- cgit v1.2.3 From fc146095d20452686efe1944b143452bec394343 Mon Sep 17 00:00:00 2001 From: mruddy Date: Fri, 6 May 2016 22:08:39 +0000 Subject: RPC: augment getblockchaininfo bip9_softforks data --- src/rpc/blockchain.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/rpc/blockchain.cpp') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 5414ac9ff..141ca87b6 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -1009,6 +1009,7 @@ static UniValue BIP9SoftForkDesc(const Consensus::Params& consensusParams, Conse } rv.push_back(Pair("startTime", consensusParams.vDeployments[id].nStartTime)); rv.push_back(Pair("timeout", consensusParams.vDeployments[id].nTimeout)); + rv.push_back(Pair("since", VersionBitsTipStateSinceHeight(consensusParams, id))); return rv; } @@ -1053,7 +1054,8 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp) " \"status\": \"xxxx\", (string) one of \"defined\", \"started\", \"locked_in\", \"active\", \"failed\"\n" " \"bit\": xx, (numeric) the bit (0-28) in the block version field used to signal this softfork (only for \"started\" status)\n" " \"startTime\": xx, (numeric) the minimum median time past of a block at which the bit gains its meaning\n" - " \"timeout\": xx (numeric) the median time past of a block at which the deployment is considered failed if not yet locked in\n" + " \"timeout\": xx, (numeric) the median time past of a block at which the deployment is considered failed if not yet locked in\n" + " \"since\": xx (numeric) height of the first block to which the status applies\n" " }\n" " }\n" "}\n" -- cgit v1.2.3 From 3a286abf8fe1ab1f4234c45de819fb1014141364 Mon Sep 17 00:00:00 2001 From: "S. Matthew English" Date: Thu, 20 Oct 2016 12:39:48 +0200 Subject: Eliminating Inconsistencies in Textual Output MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There were discrepancies between usage of "block chain" and "blockchain", I've changed them to the latter. The reason for this was that Wikipedia when describing this data structure writes "A blockchain — *originally block chain*", so it seemed the more appropriate term. --- src/rpc/blockchain.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/rpc/blockchain.cpp') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index f538ddcc0..7c128885d 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -151,7 +151,7 @@ UniValue getblockcount(const JSONRPCRequest& request) if (request.fHelp || request.params.size() != 0) throw runtime_error( "getblockcount\n" - "\nReturns the number of blocks in the longest block chain.\n" + "\nReturns the number of blocks in the longest blockchain.\n" "\nResult:\n" "n (numeric) The current block count\n" "\nExamples:\n" @@ -168,7 +168,7 @@ UniValue getbestblockhash(const JSONRPCRequest& request) if (request.fHelp || request.params.size() != 0) throw runtime_error( "getbestblockhash\n" - "\nReturns the hash of the best (tip) block in the longest block chain.\n" + "\nReturns the hash of the best (tip) block in the longest blockchain.\n" "\nResult\n" "\"hex\" (string) the block hash hex encoded\n" "\nExamples\n" @@ -1027,7 +1027,7 @@ UniValue getblockchaininfo(const JSONRPCRequest& request) if (request.fHelp || request.params.size() != 0) throw runtime_error( "getblockchaininfo\n" - "Returns an object containing various state info regarding block chain processing.\n" + "Returns an object containing various state info regarding blockchain processing.\n" "\nResult:\n" "{\n" " \"chain\": \"xxxx\", (string) current network name as defined in BIP70 (main, test, regtest)\n" -- cgit v1.2.3 From 1c3ecc70c8cd6c33cf3ff4e2099c8e7d8a8ca9d2 Mon Sep 17 00:00:00 2001 From: "S. Matthew English" Date: Thu, 27 Oct 2016 12:13:03 +0200 Subject: instance of 'mem pool' to 'mempool' there was only one instance of 'mem pool' and not 'mempool', so I changed it to conform to the others --- src/rpc/blockchain.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/rpc/blockchain.cpp') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 7c128885d..8caea14ad 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -863,7 +863,7 @@ UniValue gettxout(const JSONRPCRequest& request) "\nArguments:\n" "1. \"txid\" (string, required) The transaction id\n" "2. n (numeric, required) vout number\n" - "3. includemempool (boolean, optional) Whether to include the mem pool\n" + "3. includemempool (boolean, optional) Whether to include the mempool\n" "\nResult:\n" "{\n" " \"bestblock\" : \"hash\", (string) the block hash\n" -- cgit v1.2.3 From 1662b437b33b7ec5a1723f6ae6187d3bdd06f593 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Thu, 10 Nov 2016 17:26:00 -0800 Subject: Make CBlock::vtx a vector of shared_ptr --- src/rpc/blockchain.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/rpc/blockchain.cpp') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 8caea14ad..154107c0d 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -119,16 +119,16 @@ UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool tx result.push_back(Pair("versionHex", strprintf("%08x", block.nVersion))); result.push_back(Pair("merkleroot", block.hashMerkleRoot.GetHex())); UniValue txs(UniValue::VARR); - BOOST_FOREACH(const CTransaction&tx, block.vtx) + for(const auto& tx : block.vtx) { if(txDetails) { UniValue objTx(UniValue::VOBJ); - TxToJSON(tx, uint256(), objTx); + TxToJSON(*tx, uint256(), objTx); txs.push_back(objTx); } else - txs.push_back(tx.GetHash().GetHex()); + txs.push_back(tx->GetHash().GetHex()); } result.push_back(Pair("tx", txs)); result.push_back(Pair("time", block.GetBlockTime())); -- cgit v1.2.3 From e3c4f7e18246f0872c816358d4013d229261bbcf Mon Sep 17 00:00:00 2001 From: fanquake Date: Sat, 12 Nov 2016 20:27:36 +0800 Subject: Correct help output for waitfor RPC commands --- src/rpc/blockchain.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'src/rpc/blockchain.cpp') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 154107c0d..733d14d24 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -194,12 +194,12 @@ UniValue waitfornewblock(const JSONRPCRequest& request) { if (request.fHelp || request.params.size() > 1) throw runtime_error( - "waitfornewblock\n" + "waitfornewblock (timeout)\n" "\nWaits for a specific new block and returns useful info about it.\n" "\nReturns the current block on timeout or exit.\n" "\nArguments:\n" - "1. timeout (milliseconds) (int, optional, default=false)\n" - "\nResult::\n" + "1. timeout (int, optional, default=0) Time in milliseconds to wait for a response. 0 indicates no timeout.\n" + "\nResult:\n" "{ (json object)\n" " \"hash\" : { (string) The blockhash\n" " \"height\" : { (int) Block height\n" @@ -232,13 +232,13 @@ UniValue waitforblock(const JSONRPCRequest& request) { if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) throw runtime_error( - "waitforblock\n" + "waitforblock (timeout)\n" "\nWaits for a specific new block and returns useful info about it.\n" "\nReturns the current block on timeout or exit.\n" "\nArguments:\n" "1. blockhash to wait for (string)\n" - "2. timeout (milliseconds) (int, optional, default=false)\n" - "\nResult::\n" + "2. timeout (int, optional, default=0) Time in milliseconds to wait for a response. 0 indicates no timeout.\n" + "\nResult:\n" "{ (json object)\n" " \"hash\" : { (string) The blockhash\n" " \"height\" : { (int) Block height\n" @@ -274,14 +274,14 @@ UniValue waitforblockheight(const JSONRPCRequest& request) { if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) throw runtime_error( - "waitforblock\n" + "waitforblockheight (timeout)\n" "\nWaits for (at least) block height and returns the height and hash\n" - "\nof the current tip.\n" + "of the current tip.\n" "\nReturns the current block on timeout or exit.\n" "\nArguments:\n" "1. block height to wait for (int)\n" - "2. timeout (milliseconds) (int, optional, default=false)\n" - "\nResult::\n" + "2. timeout (int, optional, default=0) Time in milliseconds to wait for a response. 0 indicates no timeout.\n" + "\nResult:\n" "{ (json object)\n" " \"hash\" : { (string) The blockhash\n" " \"height\" : { (int) Block height\n" -- cgit v1.2.3 From 76faa3cdfedbd3fc91be4ecfff77fc6dc18134fb Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Thu, 1 Dec 2016 16:06:41 -0800 Subject: Rename the remaining main.{h,cpp} to validation.{h,cpp} --- src/rpc/blockchain.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/rpc/blockchain.cpp') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 733d14d24..b9b68fc10 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -9,7 +9,7 @@ #include "checkpoints.h" #include "coins.h" #include "consensus/validation.h" -#include "main.h" +#include "validation.h" #include "policy/policy.h" #include "primitives/transaction.h" #include "rpc/server.h" -- cgit v1.2.3 From 2736c44c8edea5ce6a502a04269926fecda27301 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Sat, 15 Oct 2016 14:01:31 -0400 Subject: Make the optional pblock in ActivateBestChain a shared_ptr --- src/rpc/blockchain.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/rpc/blockchain.cpp') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index b9b68fc10..e6d80f06a 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -1319,7 +1319,7 @@ UniValue invalidateblock(const JSONRPCRequest& request) } if (state.IsValid()) { - ActivateBestChain(state, Params(), NULL); + ActivateBestChain(state, Params()); } if (!state.IsValid()) { @@ -1357,7 +1357,7 @@ UniValue reconsiderblock(const JSONRPCRequest& request) } CValidationState state; - ActivateBestChain(state, Params(), NULL); + ActivateBestChain(state, Params()); if (!state.IsValid()) { throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason()); -- cgit v1.2.3 From bc7ff8db99dbc28f8b2d7a22f4650fa5349cb23b Mon Sep 17 00:00:00 2001 From: Gregory Sanders Date: Sun, 20 Nov 2016 09:54:51 -0500 Subject: Add option to return non-segwit serialization via rpc --- src/rpc/blockchain.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/rpc/blockchain.cpp') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index e6d80f06a..1139c2aa5 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -751,7 +751,7 @@ UniValue getblock(const JSONRPCRequest& request) if (!fVerbose) { - CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION); + CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION | RPCSerializationFlags()); ssBlock << block; std::string strHex = HexStr(ssBlock.begin(), ssBlock.end()); return strHex; -- cgit v1.2.3 From d29505db22892548a5eca5567bf8acf4e950efea Mon Sep 17 00:00:00 2001 From: jonnynewbs Date: Thu, 15 Sep 2016 10:46:01 -0400 Subject: Fix transaction size comments. Size now refers to virtual size as defined in BIP141. --- src/rpc/blockchain.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/rpc/blockchain.cpp') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 154107c0d..a6f92ea20 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -331,7 +331,7 @@ UniValue getdifficulty(const JSONRPCRequest& request) std::string EntryDescriptionString() { - return " \"size\" : n, (numeric) transaction size in bytes\n" + return " \"size\" : n, (numeric) virtual transaction size as defined in BIP 141. This is different from actual serialized size for witness transactions as witness data is discounted.\n" " \"fee\" : n, (numeric) transaction fee in " + CURRENCY_UNIT + "\n" " \"modifiedfee\" : n, (numeric) transaction fee with fee deltas used for mining priority\n" " \"time\" : n, (numeric) local time transaction entered pool in seconds since 1 Jan 1970 GMT\n" @@ -339,10 +339,10 @@ std::string EntryDescriptionString() " \"startingpriority\" : n, (numeric) priority when transaction entered pool\n" " \"currentpriority\" : n, (numeric) transaction priority now\n" " \"descendantcount\" : n, (numeric) number of in-mempool descendant transactions (including this one)\n" - " \"descendantsize\" : n, (numeric) size of in-mempool descendants (including this one)\n" + " \"descendantsize\" : n, (numeric) virtual transaction size of in-mempool descendants (including this one)\n" " \"descendantfees\" : n, (numeric) modified fees (see above) of in-mempool descendants (including this one)\n" " \"ancestorcount\" : n, (numeric) number of in-mempool ancestor transactions (including this one)\n" - " \"ancestorsize\" : n, (numeric) size of in-mempool ancestors (including this one)\n" + " \"ancestorsize\" : n, (numeric) virtual transaction size of in-mempool ancestors (including this one)\n" " \"ancestorfees\" : n, (numeric) modified fees (see above) of in-mempool ancestors (including this one)\n" " \"depends\" : [ (array) unconfirmed transactions used as inputs for this transaction\n" " \"transactionid\", (string) parent transaction id\n" @@ -703,7 +703,7 @@ UniValue getblock(const JSONRPCRequest& request) " \"confirmations\" : n, (numeric) The number of confirmations, or -1 if the block is not on the main chain\n" " \"size\" : n, (numeric) The block size\n" " \"strippedsize\" : n, (numeric) The block size excluding witness data\n" - " \"weight\" : n (numeric) The block weight (BIP 141)\n" + " \"weight\" : n (numeric) The block weight as defined in BIP 141\n" " \"height\" : n, (numeric) The block height or index\n" " \"version\" : n, (numeric) The block version\n" " \"versionHex\" : \"00000000\", (string) The block version formatted in hexadecimal\n" @@ -1240,7 +1240,7 @@ UniValue getmempoolinfo(const JSONRPCRequest& request) "\nResult:\n" "{\n" " \"size\": xxxxx, (numeric) Current tx count\n" - " \"bytes\": xxxxx, (numeric) Sum of all tx sizes\n" + " \"bytes\": xxxxx, (numeric) Sum of all virtual transaction sizes as defined in BIP 141. Differs from actual serialized size because witness data is discounted\n" " \"usage\": xxxxx, (numeric) Total memory usage for the mempool\n" " \"maxmempool\": xxxxx, (numeric) Maximum memory usage for the mempool\n" " \"mempoolminfee\": xxxxx (numeric) Minimum fee for tx to be accepted\n" -- cgit v1.2.3 From afe5b3f553e1d67b78fee83a18b83c322471ed00 Mon Sep 17 00:00:00 2001 From: Anditto Heristyo Date: Thu, 22 Dec 2016 13:26:03 +0900 Subject: Added missing colons in when running help command --- src/rpc/blockchain.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'src/rpc/blockchain.cpp') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 1139c2aa5..9ebe48530 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -169,9 +169,9 @@ UniValue getbestblockhash(const JSONRPCRequest& request) throw runtime_error( "getbestblockhash\n" "\nReturns the hash of the best (tip) block in the longest blockchain.\n" - "\nResult\n" + "\nResult:\n" "\"hex\" (string) the block hash hex encoded\n" - "\nExamples\n" + "\nExamples:\n" + HelpExampleCli("getbestblockhash", "") + HelpExampleRpc("getbestblockhash", "") ); @@ -204,7 +204,7 @@ UniValue waitfornewblock(const JSONRPCRequest& request) " \"hash\" : { (string) The blockhash\n" " \"height\" : { (int) Block height\n" "}\n" - "\nExamples\n" + "\nExamples:\n" + HelpExampleCli("waitfornewblock", "1000") + HelpExampleRpc("waitfornewblock", "1000") ); @@ -243,7 +243,7 @@ UniValue waitforblock(const JSONRPCRequest& request) " \"hash\" : { (string) The blockhash\n" " \"height\" : { (int) Block height\n" "}\n" - "\nExamples\n" + "\nExamples:\n" + HelpExampleCli("waitforblock", "\"0000000000079f8ef3d2c688c244eb7a4570b24c9ed7b4a8c619eb02596f8862\", 1000") + HelpExampleRpc("waitforblock", "\"0000000000079f8ef3d2c688c244eb7a4570b24c9ed7b4a8c619eb02596f8862\", 1000") ); @@ -286,7 +286,7 @@ UniValue waitforblockheight(const JSONRPCRequest& request) " \"hash\" : { (string) The blockhash\n" " \"height\" : { (int) Block height\n" "}\n" - "\nExamples\n" + "\nExamples:\n" + HelpExampleCli("waitforblockheight", "\"100\", 1000") + HelpExampleRpc("waitforblockheight", "\"100\", 1000") ); @@ -430,7 +430,7 @@ UniValue getrawmempool(const JSONRPCRequest& request) + EntryDescriptionString() + " }, ...\n" "}\n" - "\nExamples\n" + "\nExamples:\n" + HelpExampleCli("getrawmempool", "true") + HelpExampleRpc("getrawmempool", "true") ); @@ -462,7 +462,7 @@ UniValue getmempoolancestors(const JSONRPCRequest& request) + EntryDescriptionString() + " }, ...\n" "}\n" - "\nExamples\n" + "\nExamples:\n" + HelpExampleCli("getmempoolancestors", "\"mytxid\"") + HelpExampleRpc("getmempoolancestors", "\"mytxid\"") ); @@ -526,7 +526,7 @@ UniValue getmempooldescendants(const JSONRPCRequest& request) + EntryDescriptionString() + " }, ...\n" "}\n" - "\nExamples\n" + "\nExamples:\n" + HelpExampleCli("getmempooldescendants", "\"mytxid\"") + HelpExampleRpc("getmempooldescendants", "\"mytxid\"") ); @@ -582,7 +582,7 @@ UniValue getmempoolentry(const JSONRPCRequest& request) "{ (json object)\n" + EntryDescriptionString() + "}\n" - "\nExamples\n" + "\nExamples:\n" + HelpExampleCli("getmempoolentry", "\"mytxid\"") + HelpExampleRpc("getmempoolentry", "\"mytxid\"") ); -- cgit v1.2.3 From 27765b6403cece54320374b37afb01a0cfe571c3 Mon Sep 17 00:00:00 2001 From: isle2983 Date: Sat, 31 Dec 2016 11:01:21 -0700 Subject: Increment MIT Licence copyright header year on files modified in 2016 Edited via: $ contrib/devtools/copyright_header.py update . --- src/rpc/blockchain.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/rpc/blockchain.cpp') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 9ebe48530..a127f10b8 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2015 The Bitcoin Core developers +// Copyright (c) 2009-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -- cgit v1.2.3 From a4bac66cca62a5514579a15d198f3baa80683172 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Wed, 4 Jan 2017 07:09:02 -0800 Subject: [MOVEONLY] Move progress estimation out of checkpoints --- src/rpc/blockchain.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/rpc/blockchain.cpp') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index a127f10b8..a3954d81f 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -1073,7 +1073,7 @@ UniValue getblockchaininfo(const JSONRPCRequest& request) obj.push_back(Pair("bestblockhash", chainActive.Tip()->GetBlockHash().GetHex())); obj.push_back(Pair("difficulty", (double)GetDifficulty())); obj.push_back(Pair("mediantime", (int64_t)chainActive.Tip()->GetMedianTimePast())); - obj.push_back(Pair("verificationprogress", Checkpoints::GuessVerificationProgress(Params().Checkpoints(), chainActive.Tip()))); + obj.push_back(Pair("verificationprogress", GuessVerificationProgress(Params().Checkpoints(), chainActive.Tip()))); obj.push_back(Pair("chainwork", chainActive.Tip()->nChainWork.GetHex())); obj.push_back(Pair("pruned", fPruneMode)); -- cgit v1.2.3 From 3641141c8f9bdc68fcc0792ce8842a8e33ea7320 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Wed, 4 Jan 2017 07:31:56 -0800 Subject: Move tx estimation data out of CCheckPointData --- src/rpc/blockchain.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/rpc/blockchain.cpp') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index a3954d81f..09671ea20 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -1073,7 +1073,7 @@ UniValue getblockchaininfo(const JSONRPCRequest& request) obj.push_back(Pair("bestblockhash", chainActive.Tip()->GetBlockHash().GetHex())); obj.push_back(Pair("difficulty", (double)GetDifficulty())); obj.push_back(Pair("mediantime", (int64_t)chainActive.Tip()->GetMedianTimePast())); - obj.push_back(Pair("verificationprogress", GuessVerificationProgress(Params().Checkpoints(), chainActive.Tip()))); + obj.push_back(Pair("verificationprogress", GuessVerificationProgress(Params().TxData(), chainActive.Tip()))); obj.push_back(Pair("chainwork", chainActive.Tip()->nChainWork.GetHex())); obj.push_back(Pair("pruned", fPruneMode)); -- cgit v1.2.3 From 495eb44a4f8461c799d2b1ad70e54d087a0b3098 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Sun, 25 Sep 2016 20:44:06 +0200 Subject: rpc: Named arguments for blockchain calls --- src/rpc/blockchain.cpp | 62 +++++++++++++++++++++++++------------------------- 1 file changed, 31 insertions(+), 31 deletions(-) (limited to 'src/rpc/blockchain.cpp') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index a127f10b8..e38636aa7 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -232,11 +232,11 @@ UniValue waitforblock(const JSONRPCRequest& request) { if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) throw runtime_error( - "waitforblock (timeout)\n" + "waitforblock (timeout)\n" "\nWaits for a specific new block and returns useful info about it.\n" "\nReturns the current block on timeout or exit.\n" "\nArguments:\n" - "1. blockhash to wait for (string)\n" + "1. hash (string) Block hash to wait for.\n" "2. timeout (int, optional, default=0) Time in milliseconds to wait for a response. 0 indicates no timeout.\n" "\nResult:\n" "{ (json object)\n" @@ -858,12 +858,12 @@ UniValue gettxout(const JSONRPCRequest& request) { if (request.fHelp || request.params.size() < 2 || request.params.size() > 3) throw runtime_error( - "gettxout \"txid\" n ( includemempool )\n" + "gettxout \"txid\" n ( include_mempool )\n" "\nReturns details about an unspent transaction output.\n" "\nArguments:\n" "1. \"txid\" (string, required) The transaction id\n" "2. n (numeric, required) vout number\n" - "3. includemempool (boolean, optional) Whether to include the mempool\n" + "3. include_mempool (boolean, optional) Whether to include the mempool\n" "\nResult:\n" "{\n" " \"bestblock\" : \"hash\", (string) the block hash\n" @@ -940,11 +940,11 @@ UniValue verifychain(const JSONRPCRequest& request) int nCheckDepth = GetArg("-checkblocks", DEFAULT_CHECKBLOCKS); if (request.fHelp || request.params.size() > 2) throw runtime_error( - "verifychain ( checklevel numblocks )\n" + "verifychain ( checklevel nblocks )\n" "\nVerifies blockchain database.\n" "\nArguments:\n" "1. checklevel (numeric, optional, 0-4, default=" + strprintf("%d", nCheckLevel) + ") How thorough the block verification is.\n" - "2. numblocks (numeric, optional, default=" + strprintf("%d", nCheckDepth) + ", 0=all) The number of blocks to check.\n" + "2. nblocks (numeric, optional, default=" + strprintf("%d", nCheckDepth) + ", 0=all) The number of blocks to check.\n" "\nResult:\n" "true|false (boolean) Verified or not\n" "\nExamples:\n" @@ -1367,33 +1367,33 @@ UniValue reconsiderblock(const JSONRPCRequest& request) } static const CRPCCommand commands[] = -{ // category name actor (function) okSafeMode - // --------------------- ------------------------ ----------------------- ---------- - { "blockchain", "getblockchaininfo", &getblockchaininfo, true }, - { "blockchain", "getbestblockhash", &getbestblockhash, true }, - { "blockchain", "getblockcount", &getblockcount, true }, - { "blockchain", "getblock", &getblock, true }, - { "blockchain", "getblockhash", &getblockhash, true }, - { "blockchain", "getblockheader", &getblockheader, true }, - { "blockchain", "getchaintips", &getchaintips, true }, - { "blockchain", "getdifficulty", &getdifficulty, true }, - { "blockchain", "getmempoolancestors", &getmempoolancestors, true }, - { "blockchain", "getmempooldescendants", &getmempooldescendants, true }, - { "blockchain", "getmempoolentry", &getmempoolentry, true }, - { "blockchain", "getmempoolinfo", &getmempoolinfo, true }, - { "blockchain", "getrawmempool", &getrawmempool, true }, - { "blockchain", "gettxout", &gettxout, true }, - { "blockchain", "gettxoutsetinfo", &gettxoutsetinfo, true }, - { "blockchain", "verifychain", &verifychain, true }, - - { "blockchain", "preciousblock", &preciousblock, true }, +{ // category name actor (function) okSafe argNames + // --------------------- ------------------------ ----------------------- ------ ---------- + { "blockchain", "getblockchaininfo", &getblockchaininfo, true, {} }, + { "blockchain", "getbestblockhash", &getbestblockhash, true, {} }, + { "blockchain", "getblockcount", &getblockcount, true, {} }, + { "blockchain", "getblock", &getblock, true, {"hash","verbose"} }, + { "blockchain", "getblockhash", &getblockhash, true, {"index"} }, + { "blockchain", "getblockheader", &getblockheader, true, {"hash","verbose"} }, + { "blockchain", "getchaintips", &getchaintips, true, {} }, + { "blockchain", "getdifficulty", &getdifficulty, true, {} }, + { "blockchain", "getmempoolancestors", &getmempoolancestors, true, {"txid","verbose"} }, + { "blockchain", "getmempooldescendants", &getmempooldescendants, true, {"txid","verbose"} }, + { "blockchain", "getmempoolentry", &getmempoolentry, true, {"txid"} }, + { "blockchain", "getmempoolinfo", &getmempoolinfo, true, {} }, + { "blockchain", "getrawmempool", &getrawmempool, true, {"verbose"} }, + { "blockchain", "gettxout", &gettxout, true, {"txid","n","include_mempool"} }, + { "blockchain", "gettxoutsetinfo", &gettxoutsetinfo, true, {} }, + { "blockchain", "verifychain", &verifychain, true, {"checklevel","nblocks"} }, + + { "blockchain", "preciousblock", &preciousblock, true, {"hash"} }, /* Not shown in help */ - { "hidden", "invalidateblock", &invalidateblock, true }, - { "hidden", "reconsiderblock", &reconsiderblock, true }, - { "hidden", "waitfornewblock", &waitfornewblock, true }, - { "hidden", "waitforblock", &waitforblock, true }, - { "hidden", "waitforblockheight", &waitforblockheight, true }, + { "hidden", "invalidateblock", &invalidateblock, true, {"hash"} }, + { "hidden", "reconsiderblock", &reconsiderblock, true, {"hash"} }, + { "hidden", "waitfornewblock", &waitfornewblock, true, {"timeout"} }, + { "hidden", "waitforblock", &waitforblock, true, {"hash","timeout"} }, + { "hidden", "waitforblockheight", &waitforblockheight, true, {"height","timeout"} }, }; void RegisterBlockchainRPCCommands(CRPCTable &t) -- cgit v1.2.3 From 9adb4e1a59d54788e204895aaff5d6cbefd1b97a Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 21 Nov 2016 14:39:58 +0100 Subject: rpc: Argument name consistency The meaning is clear from the context, and we're inconsistent here. Also save typing when using named arguments. - `bitcoinaddress` -> `address` - `bitcoinprivkey` -> `privkey` - `bitcoinpubkey` -> `pubkey` --- src/rpc/blockchain.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/rpc/blockchain.cpp') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index e38636aa7..77eb4190a 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -875,7 +875,7 @@ UniValue gettxout(const JSONRPCRequest& request) " \"reqSigs\" : n, (numeric) Number of required signatures\n" " \"type\" : \"pubkeyhash\", (string) The type, eg pubkeyhash\n" " \"addresses\" : [ (array of string) array of bitcoin addresses\n" - " \"bitcoinaddress\" (string) bitcoin address\n" + " \"address\" (string) bitcoin address\n" " ,...\n" " ]\n" " },\n" -- cgit v1.2.3 From 4e7e2e16e4530be31bfc696a08bd3d1265e6f235 Mon Sep 17 00:00:00 2001 From: John Newbery Date: Fri, 9 Dec 2016 17:06:42 +0000 Subject: Update RPC argument names --- src/rpc/blockchain.cpp | 58 +++++++++++++++++++++++++------------------------- 1 file changed, 29 insertions(+), 29 deletions(-) (limited to 'src/rpc/blockchain.cpp') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 77eb4190a..5b529d7f2 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -232,12 +232,12 @@ UniValue waitforblock(const JSONRPCRequest& request) { if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) throw runtime_error( - "waitforblock (timeout)\n" + "waitforblock (timeout)\n" "\nWaits for a specific new block and returns useful info about it.\n" "\nReturns the current block on timeout or exit.\n" "\nArguments:\n" - "1. hash (string) Block hash to wait for.\n" - "2. timeout (int, optional, default=0) Time in milliseconds to wait for a response. 0 indicates no timeout.\n" + "1. \"blockhash\" (required, string) Block hash to wait for.\n" + "2. timeout (int, optional, default=0) Time in milliseconds to wait for a response. 0 indicates no timeout.\n" "\nResult:\n" "{ (json object)\n" " \"hash\" : { (string) The blockhash\n" @@ -274,12 +274,12 @@ UniValue waitforblockheight(const JSONRPCRequest& request) { if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) throw runtime_error( - "waitforblockheight (timeout)\n" + "waitforblockheight (timeout)\n" "\nWaits for (at least) block height and returns the height and hash\n" "of the current tip.\n" "\nReturns the current block on timeout or exit.\n" "\nArguments:\n" - "1. block height to wait for (int)\n" + "1. height (required, int) Block height to wait for (int)\n" "2. timeout (int, optional, default=0) Time in milliseconds to wait for a response. 0 indicates no timeout.\n" "\nResult:\n" "{ (json object)\n" @@ -418,7 +418,7 @@ UniValue getrawmempool(const JSONRPCRequest& request) "getrawmempool ( verbose )\n" "\nReturns all transaction ids in memory pool as a json array of string transaction ids.\n" "\nArguments:\n" - "1. verbose (boolean, optional, default=false) true for a json object, false for array of transaction ids\n" + "1. verbose (boolean, optional, default=false) True for a json object, false for array of transaction ids\n" "\nResult: (for verbose = false):\n" "[ (json array of string)\n" " \"transactionid\" (string) The transaction id\n" @@ -449,8 +449,8 @@ UniValue getmempoolancestors(const JSONRPCRequest& request) "getmempoolancestors txid (verbose)\n" "\nIf txid is in the mempool, returns all in-mempool ancestors.\n" "\nArguments:\n" - "1. \"txid\" (string, required) The transaction id (must be in mempool)\n" - "2. verbose (boolean, optional, default=false) true for a json object, false for array of transaction ids\n" + "1. \"txid\" (string, required) The transaction id (must be in mempool)\n" + "2. verbose (boolean, optional, default=false) True for a json object, false for array of transaction ids\n" "\nResult (for verbose=false):\n" "[ (json array of strings)\n" " \"transactionid\" (string) The transaction id of an in-mempool ancestor transaction\n" @@ -513,8 +513,8 @@ UniValue getmempooldescendants(const JSONRPCRequest& request) "getmempooldescendants txid (verbose)\n" "\nIf txid is in the mempool, returns all in-mempool descendants.\n" "\nArguments:\n" - "1. \"txid\" (string, required) The transaction id (must be in mempool)\n" - "2. verbose (boolean, optional, default=false) true for a json object, false for array of transaction ids\n" + "1. \"txid\" (string, required) The transaction id (must be in mempool)\n" + "2. verbose (boolean, optional, default=false) True for a json object, false for array of transaction ids\n" "\nResult (for verbose=false):\n" "[ (json array of strings)\n" " \"transactionid\" (string) The transaction id of an in-mempool descendant transaction\n" @@ -607,10 +607,10 @@ UniValue getblockhash(const JSONRPCRequest& request) { if (request.fHelp || request.params.size() != 1) throw runtime_error( - "getblockhash index\n" - "\nReturns hash of block in best-block-chain at index provided.\n" + "getblockhash height\n" + "\nReturns hash of block in best-block-chain at height provided.\n" "\nArguments:\n" - "1. index (numeric, required) The block index\n" + "1. height (numeric, required) The height index\n" "\nResult:\n" "\"hash\" (string) The block hash\n" "\nExamples:\n" @@ -691,12 +691,12 @@ UniValue getblock(const JSONRPCRequest& request) { if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) throw runtime_error( - "getblock \"hash\" ( verbose )\n" + "getblock \"blockhash\" ( verbose )\n" "\nIf verbose is false, returns a string that is serialized, hex-encoded data for block 'hash'.\n" "If verbose is true, returns an Object with information about block .\n" "\nArguments:\n" - "1. \"hash\" (string, required) The block hash\n" - "2. verbose (boolean, optional, default=true) true for a json object, false for the hex encoded data\n" + "1. \"blockhash\" (string, required) The block hash\n" + "2. verbose (boolean, optional, default=true) true for a json object, false for the hex encoded data\n" "\nResult (for verbose = true):\n" "{\n" " \"hash\" : \"hash\", (string) the block hash (same as provided)\n" @@ -1257,12 +1257,12 @@ UniValue preciousblock(const JSONRPCRequest& request) { if (request.fHelp || request.params.size() != 1) throw runtime_error( - "preciousblock \"hash\"\n" + "preciousblock \"blockhash\"\n" "\nTreats a block as if it were received before others with the same work.\n" "\nA later preciousblock call can override the effect of an earlier one.\n" "\nThe effects of preciousblock are not retained across restarts.\n" "\nArguments:\n" - "1. hash (string, required) the hash of the block to mark as precious\n" + "1. \"blockhash\" (string, required) the hash of the block to mark as precious\n" "\nResult:\n" "\nExamples:\n" + HelpExampleCli("preciousblock", "\"blockhash\"") @@ -1295,10 +1295,10 @@ UniValue invalidateblock(const JSONRPCRequest& request) { if (request.fHelp || request.params.size() != 1) throw runtime_error( - "invalidateblock \"hash\"\n" + "invalidateblock \"blockhash\"\n" "\nPermanently marks a block as invalid, as if it violated a consensus rule.\n" "\nArguments:\n" - "1. hash (string, required) the hash of the block to mark as invalid\n" + "1. \"blockhash\" (string, required) the hash of the block to mark as invalid\n" "\nResult:\n" "\nExamples:\n" + HelpExampleCli("invalidateblock", "\"blockhash\"") @@ -1333,11 +1333,11 @@ UniValue reconsiderblock(const JSONRPCRequest& request) { if (request.fHelp || request.params.size() != 1) throw runtime_error( - "reconsiderblock \"hash\"\n" + "reconsiderblock \"blockhash\"\n" "\nRemoves invalidity status of a block and its descendants, reconsider them for activation.\n" "This can be used to undo the effects of invalidateblock.\n" "\nArguments:\n" - "1. hash (string, required) the hash of the block to reconsider\n" + "1. \"blockhash\" (string, required) the hash of the block to reconsider\n" "\nResult:\n" "\nExamples:\n" + HelpExampleCli("reconsiderblock", "\"blockhash\"") @@ -1372,9 +1372,9 @@ static const CRPCCommand commands[] = { "blockchain", "getblockchaininfo", &getblockchaininfo, true, {} }, { "blockchain", "getbestblockhash", &getbestblockhash, true, {} }, { "blockchain", "getblockcount", &getblockcount, true, {} }, - { "blockchain", "getblock", &getblock, true, {"hash","verbose"} }, - { "blockchain", "getblockhash", &getblockhash, true, {"index"} }, - { "blockchain", "getblockheader", &getblockheader, true, {"hash","verbose"} }, + { "blockchain", "getblock", &getblock, true, {"blockhash","verbose"} }, + { "blockchain", "getblockhash", &getblockhash, true, {"height"} }, + { "blockchain", "getblockheader", &getblockheader, true, {"blockhash","verbose"} }, { "blockchain", "getchaintips", &getchaintips, true, {} }, { "blockchain", "getdifficulty", &getdifficulty, true, {} }, { "blockchain", "getmempoolancestors", &getmempoolancestors, true, {"txid","verbose"} }, @@ -1386,13 +1386,13 @@ static const CRPCCommand commands[] = { "blockchain", "gettxoutsetinfo", &gettxoutsetinfo, true, {} }, { "blockchain", "verifychain", &verifychain, true, {"checklevel","nblocks"} }, - { "blockchain", "preciousblock", &preciousblock, true, {"hash"} }, + { "blockchain", "preciousblock", &preciousblock, true, {"blockhash"} }, /* Not shown in help */ - { "hidden", "invalidateblock", &invalidateblock, true, {"hash"} }, - { "hidden", "reconsiderblock", &reconsiderblock, true, {"hash"} }, + { "hidden", "invalidateblock", &invalidateblock, true, {"blockhash"} }, + { "hidden", "reconsiderblock", &reconsiderblock, true, {"blockhash"} }, { "hidden", "waitfornewblock", &waitfornewblock, true, {"timeout"} }, - { "hidden", "waitforblock", &waitforblock, true, {"hash","timeout"} }, + { "hidden", "waitforblock", &waitforblock, true, {"blockhash","timeout"} }, { "hidden", "waitforblockheight", &waitforblockheight, true, {"height","timeout"} }, }; -- cgit v1.2.3 From 1fc4ec7bf224748d3d6271bffa23d121f015cbf3 Mon Sep 17 00:00:00 2001 From: mrbandrews Date: Tue, 29 Nov 2016 12:39:19 -0500 Subject: Add pruneblockchain RPC to enable manual block file pruning. --- src/rpc/blockchain.cpp | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'src/rpc/blockchain.cpp') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 0b42c1d62..f49a33327 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -814,6 +814,36 @@ static bool GetUTXOStats(CCoinsView *view, CCoinsStats &stats) return true; } +UniValue pruneblockchain(const JSONRPCRequest& request) +{ + if (request.fHelp || request.params.size() != 1) + throw runtime_error( + "pruneblockchain\n" + "\nArguments:\n" + "1. \"height\" (int, required) The block height to prune up to.\n"); + + if (!fPruneMode) + throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Cannot prune blocks because node is not in prune mode."); + + LOCK(cs_main); + + int heightParam = request.params[0].get_int(); + if (heightParam < 0) + throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative block height."); + + unsigned int height = (unsigned int) heightParam; + unsigned int chainHeight = (unsigned int) chainActive.Height(); + if (chainHeight < Params().PruneAfterHeight()) + throw JSONRPCError(RPC_INTERNAL_ERROR, "Blockchain is too short for pruning."); + else if (height > chainHeight) + throw JSONRPCError(RPC_INVALID_PARAMETER, "Blockchain is shorter than the attempted prune height."); + else if (height > chainHeight - MIN_BLOCKS_TO_KEEP) + LogPrint("rpc", "Attempt to prune blocks close to the tip. Retaining the minimum number of blocks."); + + PruneBlockFilesManual(height); + return NullUniValue; +} + UniValue gettxoutsetinfo(const JSONRPCRequest& request) { if (request.fHelp || request.params.size() != 0) @@ -1384,6 +1414,7 @@ static const CRPCCommand commands[] = { "blockchain", "getrawmempool", &getrawmempool, true, {"verbose"} }, { "blockchain", "gettxout", &gettxout, true, {"txid","n","include_mempool"} }, { "blockchain", "gettxoutsetinfo", &gettxoutsetinfo, true, {} }, + { "blockchain", "pruneblockchain", &pruneblockchain, true, {"height"} }, { "blockchain", "verifychain", &verifychain, true, {"checklevel","nblocks"} }, { "blockchain", "preciousblock", &preciousblock, true, {"blockhash"} }, -- cgit v1.2.3 From afffeea7d98ba358acd54a89bc0e7ae1c4d54023 Mon Sep 17 00:00:00 2001 From: Russell Yanofsky Date: Mon, 9 Jan 2017 13:35:12 -0500 Subject: fixup! Add pruneblockchain RPC to enable manual block file pruning. Extend pruneblockchain RPC to accept block timestamps as well as block indices. --- src/rpc/blockchain.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'src/rpc/blockchain.cpp') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index f49a33327..e828618a8 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -820,7 +820,7 @@ UniValue pruneblockchain(const JSONRPCRequest& request) throw runtime_error( "pruneblockchain\n" "\nArguments:\n" - "1. \"height\" (int, required) The block height to prune up to.\n"); + "1. \"height\" (numeric, required) The block height to prune up to. May be set to a discrete height, or to a unix timestamp to prune based on block time.\n"); if (!fPruneMode) throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Cannot prune blocks because node is not in prune mode."); @@ -831,6 +831,16 @@ UniValue pruneblockchain(const JSONRPCRequest& request) if (heightParam < 0) throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative block height."); + // Height value more than a billion is too high to be a block height, and + // too low to be a block time (corresponds to timestamp from Sep 2001). + if (heightParam > 1000000000) { + CBlockIndex* pindex = chainActive.FindLatestBefore(heightParam); + if (!pindex) { + throw JSONRPCError(RPC_INTERNAL_ERROR, "Could not find block before specified timestamp."); + } + heightParam = pindex->nHeight; + } + unsigned int height = (unsigned int) heightParam; unsigned int chainHeight = (unsigned int) chainActive.Height(); if (chainHeight < Params().PruneAfterHeight()) -- cgit v1.2.3 From 918d1fb86b687693b4f248c14238676300872749 Mon Sep 17 00:00:00 2001 From: Russell Yanofsky Date: Wed, 11 Jan 2017 14:25:32 -0500 Subject: Return height of last block pruned by pruneblockchain RPC Change suggested by Jonas Schnelli in https://github.com/bitcoin/bitcoin/pull/7871#discussion_r95577623 --- src/rpc/blockchain.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'src/rpc/blockchain.cpp') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index e828618a8..8a912ff3d 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -820,7 +820,12 @@ UniValue pruneblockchain(const JSONRPCRequest& request) throw runtime_error( "pruneblockchain\n" "\nArguments:\n" - "1. \"height\" (numeric, required) The block height to prune up to. May be set to a discrete height, or to a unix timestamp to prune based on block time.\n"); + "1. \"height\" (numeric, required) The block height to prune up to. May be set to a discrete height, or to a unix timestamp to prune based on block time.\n" + "\nResult:\n" + "n (numeric) Height of the last block pruned.\n" + "\nExamples:\n" + + HelpExampleCli("pruneblockchain", "1000") + + HelpExampleRpc("pruneblockchain", "1000")); if (!fPruneMode) throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Cannot prune blocks because node is not in prune mode."); @@ -847,11 +852,13 @@ UniValue pruneblockchain(const JSONRPCRequest& request) throw JSONRPCError(RPC_INTERNAL_ERROR, "Blockchain is too short for pruning."); else if (height > chainHeight) throw JSONRPCError(RPC_INVALID_PARAMETER, "Blockchain is shorter than the attempted prune height."); - else if (height > chainHeight - MIN_BLOCKS_TO_KEEP) + else if (height > chainHeight - MIN_BLOCKS_TO_KEEP) { LogPrint("rpc", "Attempt to prune blocks close to the tip. Retaining the minimum number of blocks."); + height = chainHeight - MIN_BLOCKS_TO_KEEP; + } PruneBlockFilesManual(height); - return NullUniValue; + return uint64_t(height); } UniValue gettxoutsetinfo(const JSONRPCRequest& request) -- cgit v1.2.3 From 54ee3fcb8f2d21ded2efd236aa0b974050f685ba Mon Sep 17 00:00:00 2001 From: Michael Rotarius Date: Wed, 11 Jan 2017 14:29:46 +0100 Subject: RPC help updated --- src/rpc/blockchain.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/rpc/blockchain.cpp') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 0b42c1d62..59748dd20 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -336,8 +336,8 @@ std::string EntryDescriptionString() " \"modifiedfee\" : n, (numeric) transaction fee with fee deltas used for mining priority\n" " \"time\" : n, (numeric) local time transaction entered pool in seconds since 1 Jan 1970 GMT\n" " \"height\" : n, (numeric) block height when transaction entered pool\n" - " \"startingpriority\" : n, (numeric) priority when transaction entered pool\n" - " \"currentpriority\" : n, (numeric) transaction priority now\n" + " \"startingpriority\" : n, (numeric) DEPRECATED. Priority when transaction entered pool\n" + " \"currentpriority\" : n, (numeric) DEPRECATED. Transaction priority now\n" " \"descendantcount\" : n, (numeric) number of in-mempool descendant transactions (including this one)\n" " \"descendantsize\" : n, (numeric) virtual transaction size of in-mempool descendants (including this one)\n" " \"descendantfees\" : n, (numeric) modified fees (see above) of in-mempool descendants (including this one)\n" @@ -651,9 +651,9 @@ UniValue getblockheader(const JSONRPCRequest& request) " \"nonce\" : n, (numeric) The nonce\n" " \"bits\" : \"1d00ffff\", (string) The bits\n" " \"difficulty\" : x.xxx, (numeric) The difficulty\n" + " \"chainwork\" : \"0000...1f3\" (string) Expected number of hashes required to produce the current chain (in hex)\n" " \"previousblockhash\" : \"hash\", (string) The hash of the previous block\n" " \"nextblockhash\" : \"hash\", (string) The hash of the next block\n" - " \"chainwork\" : \"0000...1f3\" (string) Expected number of hashes required to produce the current chain (in hex)\n" "}\n" "\nResult (for verbose=false):\n" "\"data\" (string) A string that is serialized, hex-encoded data for block 'hash'.\n" -- cgit v1.2.3 From 997a98a674df70a2192e8d8b91c631e5c241509d Mon Sep 17 00:00:00 2001 From: Gregory Maxwell Date: Sun, 8 Jan 2017 04:05:14 +0000 Subject: Replace FindLatestBefore used by importmuti with FindEarliestAtLeast. In spite of the name FindLatestBefore used std::lower_bound to try to find the earliest block with a nTime greater or equal to the the requested value. But lower_bound uses bisection and requires the input to be ordered with respect to the comparison operation. Block times are not well ordered. I don't know what lower_bound is permitted to do when the data is not sufficiently ordered, but it's probably not good. (I could construct an implementation which would infinite loop...) To resolve the issue this commit introduces a maximum-so-far to the block indexes and searches that. For clarity the function is renamed to reflect what it actually does. An issue that remains is that there is no grace period in importmulti: If a address is created at time T and a send is immediately broadcast and included by a miner with a slow clock there may not yet have been any block with at least time T. The normal rescan has a grace period of 7200 seconds, but importmulti does not. --- src/rpc/blockchain.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/rpc/blockchain.cpp') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index bbcbde71c..368654bfa 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -839,9 +839,9 @@ UniValue pruneblockchain(const JSONRPCRequest& request) // Height value more than a billion is too high to be a block height, and // too low to be a block time (corresponds to timestamp from Sep 2001). if (heightParam > 1000000000) { - CBlockIndex* pindex = chainActive.FindLatestBefore(heightParam); + CBlockIndex* pindex = chainActive.FindEarliestAtLeast(heightParam); if (!pindex) { - throw JSONRPCError(RPC_INTERNAL_ERROR, "Could not find block before specified timestamp."); + throw JSONRPCError(RPC_INTERNAL_ERROR, "Could not find block with at least the specified timestamp."); } heightParam = pindex->nHeight; } -- cgit v1.2.3 From 91fb506e0a156d5b4f2e9ca76ee8de0b591b2ee0 Mon Sep 17 00:00:00 2001 From: Alex Morcos Date: Thu, 16 Feb 2017 11:07:15 -0500 Subject: Add two hour buffer to manual pruning --- src/rpc/blockchain.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/rpc/blockchain.cpp') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 368654bfa..7b69c81ff 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -820,7 +820,8 @@ UniValue pruneblockchain(const JSONRPCRequest& request) throw runtime_error( "pruneblockchain\n" "\nArguments:\n" - "1. \"height\" (numeric, required) The block height to prune up to. May be set to a discrete height, or to a unix timestamp to prune based on block time.\n" + "1. \"height\" (numeric, required) The block height to prune up to. May be set to a discrete height, or a unix timestamp\n" + " to prune blocks whose block time is at least 2 hours older than the provided timestamp.\n" "\nResult:\n" "n (numeric) Height of the last block pruned.\n" "\nExamples:\n" @@ -839,7 +840,8 @@ UniValue pruneblockchain(const JSONRPCRequest& request) // Height value more than a billion is too high to be a block height, and // too low to be a block time (corresponds to timestamp from Sep 2001). if (heightParam > 1000000000) { - CBlockIndex* pindex = chainActive.FindEarliestAtLeast(heightParam); + // Add a 2 hour buffer to include blocks which might have had old timestamps + CBlockIndex* pindex = chainActive.FindEarliestAtLeast(heightParam - 7200); if (!pindex) { throw JSONRPCError(RPC_INTERNAL_ERROR, "Could not find block with at least the specified timestamp."); } -- cgit v1.2.3 From fe51c8924e62bf146a722f632324c99c2f97bc75 Mon Sep 17 00:00:00 2001 From: John Newbery Date: Thu, 9 Feb 2017 16:39:18 -0500 Subject: Return correct error codes in blockchain.cpp. RPCs in blockchain.cpp were returning misleading or incorrect error codes (for example getblock() returning RPC_INTERNAL_ERROR when the block had been pruned). This commit fixes those error codes: - RPC_INTERNAL_ERROR should not be returned for application-level errors, only for genuine internal errors such as corrupted data. - RPC_METHOD_NOT_FOUND should not be returned in response to a JSON request for an existing method. Those error codes have been replaced with RPC_MISC_ERROR or RPC_INVALID_PARAMETER as appropriate. Github-Pull: #9853 Rebased-From: c1190963b388590dc0a346bf625c7e84f69cee8d --- src/rpc/blockchain.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'src/rpc/blockchain.cpp') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 7b69c81ff..6080650f8 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -744,10 +744,15 @@ UniValue getblock(const JSONRPCRequest& request) CBlockIndex* pblockindex = mapBlockIndex[hash]; if (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0) - throw JSONRPCError(RPC_INTERNAL_ERROR, "Block not available (pruned data)"); + throw JSONRPCError(RPC_MISC_ERROR, "Block not available (pruned data)"); - if(!ReadBlockFromDisk(block, pblockindex, Params().GetConsensus())) - throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk"); + if (!ReadBlockFromDisk(block, pblockindex, Params().GetConsensus())) + // Block not found on disk. This could be because we have the block + // header in our index but don't have the block (for example if a + // non-whitelisted node sends us an unrequested long chain of valid + // blocks, we add the headers to our index, but don't accept the + // block). + throw JSONRPCError(RPC_MISC_ERROR, "Block not found on disk"); if (!fVerbose) { @@ -829,7 +834,7 @@ UniValue pruneblockchain(const JSONRPCRequest& request) + HelpExampleRpc("pruneblockchain", "1000")); if (!fPruneMode) - throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Cannot prune blocks because node is not in prune mode."); + throw JSONRPCError(RPC_MISC_ERROR, "Cannot prune blocks because node is not in prune mode."); LOCK(cs_main); @@ -843,7 +848,7 @@ UniValue pruneblockchain(const JSONRPCRequest& request) // Add a 2 hour buffer to include blocks which might have had old timestamps CBlockIndex* pindex = chainActive.FindEarliestAtLeast(heightParam - 7200); if (!pindex) { - throw JSONRPCError(RPC_INTERNAL_ERROR, "Could not find block with at least the specified timestamp."); + throw JSONRPCError(RPC_INVALID_PARAMETER, "Could not find block with at least the specified timestamp."); } heightParam = pindex->nHeight; } @@ -851,7 +856,7 @@ UniValue pruneblockchain(const JSONRPCRequest& request) unsigned int height = (unsigned int) heightParam; unsigned int chainHeight = (unsigned int) chainActive.Height(); if (chainHeight < Params().PruneAfterHeight()) - throw JSONRPCError(RPC_INTERNAL_ERROR, "Blockchain is too short for pruning."); + throw JSONRPCError(RPC_MISC_ERROR, "Blockchain is too short for pruning."); else if (height > chainHeight) throw JSONRPCError(RPC_INVALID_PARAMETER, "Blockchain is shorter than the attempted prune height."); else if (height > chainHeight - MIN_BLOCKS_TO_KEEP) { -- cgit v1.2.3 From ff274d3b00737d9f93c85c0bcff51f1f548354b6 Mon Sep 17 00:00:00 2001 From: Karl-Johan Alm Date: Sat, 6 May 2017 12:51:01 +0900 Subject: [doc] Add hint about getmempoolentry to getrawmempool help. Github-Pull: #10310 Rebased-From: 3a0a5bc2341ea6a453306f6fe1c065b937294cfb --- src/rpc/blockchain.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/rpc/blockchain.cpp') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 6080650f8..fd8f52a5c 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -417,6 +417,7 @@ UniValue getrawmempool(const JSONRPCRequest& request) throw runtime_error( "getrawmempool ( verbose )\n" "\nReturns all transaction ids in memory pool as a json array of string transaction ids.\n" + "\nHint: use getmempoolentry to fetch a specific transaction from the mempool.\n" "\nArguments:\n" "1. verbose (boolean, optional, default=false) True for a json object, false for array of transaction ids\n" "\nResult: (for verbose = false):\n" -- cgit v1.2.3 From bc8cca48968dfa3f60b5eae6a2b92bdd2870eee3 Mon Sep 17 00:00:00 2001 From: Ross Nicoll Date: Sun, 13 Aug 2017 13:31:12 +0100 Subject: Merge AuxPoW support from Namecore Changes are as below: Wrap CBlockHeader::nVersion into a new class (CBlockVersion). This allows to take care of interpreting the field into a base version, auxpow flag and the chain ID. Update getauxblock.py for new 'generate' RPC call. Add 'auxpow' to block JSON. Accept auxpow as PoW verification. Add unit tests for auxpow verification. Add check for memory-layout of CBlockVersion. Weaken auxpow chain ID checks for the testnet. Allow Params() to overrule when to check the auxpow chain ID and for legacy blocks. Use this to disable the checks on testnet. Introduce CPureBlockHeader. Split the block header part that is used by auxpow and the "real" block header (that uses auxpow) to resolve the cyclic dependency between the two. Differentiate between uint256 and arith_uint256. This change was done upstream, modify the auxpow code. Add missing lock in auxpow_tests. Fix REST header check for auxpow headers. Those can be longer, thus take that into account. Also perform the check actually on an auxpow header. Correctly set the coinbase for getauxblock results. Call IncrementExtraNonce in getauxblock so that the coinbase is actually initialised with the stuff it should be. (BIP30 block height and COINBASE_FLAGS.) Implement getauxblock plus regression test. Turn auxpow test into FIXTURE test. This allows using of the Params() calls. Move CMerkleTx code to auxpow.cpp. Otherwise we get linker errors when building without wallet. Fix rebase with BIP66. Update the code to handle BIP66's nVersion=3. Enforce that auxpow parent blocks have no auxpow block version. This is for compatibility with namecoind. See also https://github.com/namecoin/namecoin/pull/199. Move auxpow-related parameters to Consensus::Params. --- src/rpc/blockchain.cpp | 42 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) (limited to 'src/rpc/blockchain.cpp') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index fd8f52a5c..92601a5ec 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -9,6 +9,7 @@ #include "checkpoints.h" #include "coins.h" #include "consensus/validation.h" +#include "core_io.h" #include "validation.h" #include "policy/policy.h" #include "primitives/transaction.h" @@ -74,6 +75,42 @@ double GetDifficulty(const CBlockIndex* blockindex) return dDiff; } +UniValue AuxpowToJSON(const CAuxPow& auxpow) +{ + UniValue result(UniValue::VOBJ); + + { + UniValue tx(UniValue::VOBJ); + tx.push_back(Pair("hex", EncodeHexTx(auxpow))); + TxToJSON(auxpow, auxpow.parentBlock.GetHash(), tx); + result.push_back(Pair("tx", tx)); + } + + result.push_back(Pair("index", auxpow.nIndex)); + result.push_back(Pair("chainindex", auxpow.nChainIndex)); + + { + UniValue branch(UniValue::VARR); + BOOST_FOREACH(const uint256& node, auxpow.vMerkleBranch) + branch.push_back(node.GetHex()); + result.push_back(Pair("merklebranch", branch)); + } + + { + UniValue branch(UniValue::VARR); + BOOST_FOREACH(const uint256& node, auxpow.vChainMerkleBranch) + branch.push_back(node.GetHex()); + result.push_back(Pair("chainmerklebranch", branch)); + } + + CDataStream ssParent(SER_NETWORK, PROTOCOL_VERSION); + ssParent << auxpow.parentBlock; + const std::string strHex = HexStr(ssParent.begin(), ssParent.end()); + result.push_back(Pair("parentblock", strHex)); + + return result; +} + UniValue blockheaderToJSON(const CBlockIndex* blockindex) { UniValue result(UniValue::VOBJ); @@ -138,6 +175,9 @@ UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool tx result.push_back(Pair("difficulty", GetDifficulty(blockindex))); result.push_back(Pair("chainwork", blockindex->nChainWork.GetHex())); + if (block.auxpow) + result.push_back(Pair("auxpow", AuxpowToJSON(*block.auxpow))); + if (blockindex->pprev) result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex())); CBlockIndex *pnext = chainActive.Next(blockindex); @@ -680,7 +720,7 @@ UniValue getblockheader(const JSONRPCRequest& request) if (!fVerbose) { CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION); - ssBlock << pblockindex->GetBlockHeader(); + ssBlock << pblockindex->GetBlockHeader(Params().GetConsensus()); std::string strHex = HexStr(ssBlock.begin(), ssBlock.end()); return strHex; } -- cgit v1.2.3 From a89d54c4b228c02a62e21039f318f5225aad2cf9 Mon Sep 17 00:00:00 2001 From: Ross Nicoll Date: Wed, 27 Dec 2017 21:11:14 +0000 Subject: Change BIP65/66 enforcement to match Dogecoin (#1403) * Introduce first estimates at BIP lock-in blocks * Introduce Dogecoin BIP parameters * Re-introduce supermajority rules for BIP65 * Add BIP65 supermajority rules * Tighten v3 block constraints * Don't enforce coinbase in v2 blocks * Correct testnet majority params * Change to using base version when checking supermajority --- src/rpc/blockchain.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'src/rpc/blockchain.cpp') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 92601a5ec..d06c00cbc 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -1071,7 +1071,20 @@ static UniValue SoftForkMajorityDesc(int version, CBlockIndex* pindex, const Con activated = pindex->nHeight >= consensusParams.BIP66Height; break; case 4: - activated = pindex->nHeight >= consensusParams.BIP65Height; + int nFound = 0; + int nRequired = consensusParams.nMajorityRejectBlockOutdated; + CBlockIndex* pstart = pindex; + for (int i = 0; i < consensusParams.nMajorityWindow && pstart != NULL; i++) + { + if (pstart->nVersion >= version) + ++nFound; + pstart = pstart->pprev; + } + + activated = nFound >= nRequired; + rv.push_back(Pair("found", nFound)); + rv.push_back(Pair("required", nRequired)); + rv.push_back(Pair("window", consensusParams.nMajorityWindow)); break; } rv.push_back(Pair("status", activated)); -- cgit v1.2.3 From 1be681a1b97b686f838af90682a57f2030d26015 Mon Sep 17 00:00:00 2001 From: Ross Nicoll Date: Thu, 28 Dec 2017 15:04:08 +0000 Subject: Modify chain consensus parameters to be height aware (#1396) * Modify chain consensus parameters to be height aware * Correct implementation of simplified rewards in parameters * Correct max money * Use base block version in IsSuperMajority() instead of full version * Correct mining of blocks in AuxPoW tests * Add in missing pre-AuxPoW consensus checks --- src/rpc/blockchain.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/rpc/blockchain.cpp') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index d06c00cbc..6fb45a515 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -720,7 +720,7 @@ UniValue getblockheader(const JSONRPCRequest& request) if (!fVerbose) { CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION); - ssBlock << pblockindex->GetBlockHeader(Params().GetConsensus()); + ssBlock << pblockindex->GetBlockHeader(Params().GetConsensus(pblockindex->nHeight)); std::string strHex = HexStr(ssBlock.begin(), ssBlock.end()); return strHex; } @@ -787,7 +787,7 @@ UniValue getblock(const JSONRPCRequest& request) if (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0) throw JSONRPCError(RPC_MISC_ERROR, "Block not available (pruned data)"); - if (!ReadBlockFromDisk(block, pblockindex, Params().GetConsensus())) + if (!ReadBlockFromDisk(block, pblockindex, Params().GetConsensus(pblockindex->nHeight))) // Block not found on disk. This could be because we have the block // header in our index but don't have the block (for example if a // non-whitelisted node sends us an unrequested long chain of valid @@ -1185,7 +1185,7 @@ UniValue getblockchaininfo(const JSONRPCRequest& request) obj.push_back(Pair("chainwork", chainActive.Tip()->nChainWork.GetHex())); obj.push_back(Pair("pruned", fPruneMode)); - const Consensus::Params& consensusParams = Params().GetConsensus(); + const Consensus::Params& consensusParams = Params().GetConsensus(0); CBlockIndex* tip = chainActive.Tip(); UniValue softforks(UniValue::VARR); UniValue bip9_softforks(UniValue::VOBJ); -- cgit v1.2.3 From c6eeab75a1c70b6ad63854e036e5843b7f104d31 Mon Sep 17 00:00:00 2001 From: Ross Nicoll Date: Mon, 1 Jan 2018 16:24:14 +0000 Subject: Change count type used by `gettxoutsetinfo` (#1415) changing CAmount (is a int64_t) to arith_uint256 for nTotalAmount in CCoinsStats to prevent overflow --- src/rpc/blockchain.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/rpc/blockchain.cpp') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 6fb45a515..a005cde44 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -814,7 +814,7 @@ struct CCoinsStats uint64_t nTransactionOutputs; uint64_t nSerializedSize; uint256 hashSerialized; - CAmount nTotalAmount; + arith_uint256 nTotalAmount; CCoinsStats() : nHeight(0), nTransactions(0), nTransactionOutputs(0), nSerializedSize(0), nTotalAmount(0) {} }; @@ -831,7 +831,7 @@ static bool GetUTXOStats(CCoinsView *view, CCoinsStats &stats) stats.nHeight = mapBlockIndex.find(stats.hashBlock)->second->nHeight; } ss << stats.hashBlock; - CAmount nTotalAmount = 0; + arith_uint256 nTotalAmount = 0; while (pcursor->Valid()) { boost::this_thread::interruption_point(); uint256 key; -- cgit v1.2.3 From 148a2aca05fe98031bcf857fa186d792c507090c Mon Sep 17 00:00:00 2001 From: Ross Nicoll Date: Mon, 27 Jul 2015 16:35:30 +0100 Subject: Introduce basic Dogecoin branding --- src/rpc/blockchain.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/rpc/blockchain.cpp') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index a005cde44..43a802e9b 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -969,8 +969,8 @@ UniValue gettxout(const JSONRPCRequest& request) " \"hex\" : \"hex\", (string) \n" " \"reqSigs\" : n, (numeric) Number of required signatures\n" " \"type\" : \"pubkeyhash\", (string) The type, eg pubkeyhash\n" - " \"addresses\" : [ (array of string) array of bitcoin addresses\n" - " \"address\" (string) bitcoin address\n" + " \"addresses\" : [ (array of string) array of dogecoin addresses\n" + " \"address\" (string) dogecoin address\n" " ,...\n" " ]\n" " },\n" -- cgit v1.2.3 From c4b8fbf57ff6de22112275555de62f9b51c29752 Mon Sep 17 00:00:00 2001 From: John Newbery Date: Mon, 31 Dec 2018 10:43:02 -0800 Subject: [rpc] Add initialblockdownload to getblockchaininfo --- src/rpc/blockchain.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/rpc/blockchain.cpp') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 43a802e9b..e1119495f 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -1145,6 +1145,7 @@ UniValue getblockchaininfo(const JSONRPCRequest& request) " \"difficulty\": xxxxxx, (numeric) the current difficulty\n" " \"mediantime\": xxxxxx, (numeric) median time for the current best block\n" " \"verificationprogress\": xxxx, (numeric) estimate of verification progress [0..1]\n" + " \"initialblockdownload\": xxxx, (bool) (debug information) estimate of whether this node is in Initial Block Download mode.\n" " \"chainwork\": \"xxxx\" (string) total amount of work in active chain, in hexadecimal\n" " \"pruned\": xx, (boolean) if the blocks are subject to pruning\n" " \"pruneheight\": xxxxxx, (numeric) lowest-height complete block stored\n" @@ -1182,6 +1183,7 @@ UniValue getblockchaininfo(const JSONRPCRequest& request) obj.push_back(Pair("difficulty", (double)GetDifficulty())); obj.push_back(Pair("mediantime", (int64_t)chainActive.Tip()->GetMedianTimePast())); obj.push_back(Pair("verificationprogress", GuessVerificationProgress(Params().TxData(), chainActive.Tip()))); + obj.push_back(Pair("initialblockdownload", IsInitialBlockDownload())); obj.push_back(Pair("chainwork", chainActive.Tip()->nChainWork.GetHex())); obj.push_back(Pair("pruned", fPruneMode)); -- cgit v1.2.3