Add getspecialtxes rpc (#2668)
* Add getspecialtxes rpc Returns an array of special transactions found in the specified block * small help text tweak * add comments
This commit is contained in:
parent
34dee23386
commit
23eb70cb77
@ -9,6 +9,7 @@
|
||||
#include "chainparams.h"
|
||||
#include "checkpoints.h"
|
||||
#include "coins.h"
|
||||
#include "core_io.h"
|
||||
#include "consensus/validation.h"
|
||||
#include "instantx.h"
|
||||
#include "validation.h"
|
||||
@ -1620,6 +1621,113 @@ UniValue reconsiderblock(const JSONRPCRequest& request)
|
||||
return NullUniValue;
|
||||
}
|
||||
|
||||
UniValue getspecialtxes(const JSONRPCRequest& request)
|
||||
{
|
||||
if (request.fHelp || request.params.size() < 1 || request.params.size() > 5)
|
||||
throw std::runtime_error(
|
||||
"getspecialtxes \"blockhash\" ( type count skip verbosity ) \n"
|
||||
"Returns an array of special transactions found in the specified block\n"
|
||||
"\nIf verbosity is 0, returns tx hash for each transaction.\n"
|
||||
"If verbosity is 1, returns hex-encoded data for each transaction.\n"
|
||||
"If verbosity is 2, returns an Object with information for each transaction.\n"
|
||||
"\nArguments:\n"
|
||||
"1. \"blockhash\" (string, required) The block hash\n"
|
||||
"2. type (numeric, optional, default=-1) Filter special txes by type, -1 means all types\n"
|
||||
"3. count (numeric, optional, default=10) The number of transactions to return\n"
|
||||
"4. skip (numeric, optional, default=0) The number of transactions to skip\n"
|
||||
"5. verbosity (numeric, optional, default=0) 0 for hashes, 1 for hex-encoded data, and 2 for json object\n"
|
||||
"\nResult (for verbosity = 0):\n"
|
||||
"[\n"
|
||||
" \"txid\" : \"xxxx\", (string) The transaction id\n"
|
||||
"]\n"
|
||||
"\nResult (for verbosity = 1):\n"
|
||||
"[\n"
|
||||
" \"data\", (string) A string that is serialized, hex-encoded data for the transaction\n"
|
||||
"]\n"
|
||||
"\nResult (for verbosity = 2):\n"
|
||||
"[ (array of Objects) The transactions in the format of the getrawtransaction RPC.\n"
|
||||
" ...,\n"
|
||||
"]\n"
|
||||
"\nExamples:\n"
|
||||
+ HelpExampleCli("getspecialtxes", "\"00000000000fd08c2fb661d2fcb0d49abb3a91e5f27082ce64feed3b4dede2e2\"")
|
||||
+ HelpExampleRpc("getspecialtxes", "\"00000000000fd08c2fb661d2fcb0d49abb3a91e5f27082ce64feed3b4dede2e2\"")
|
||||
);
|
||||
|
||||
LOCK(cs_main);
|
||||
|
||||
std::string strHash = request.params[0].get_str();
|
||||
uint256 hash(uint256S(strHash));
|
||||
|
||||
int nTxType = -1;
|
||||
if (request.params.size() > 1) {
|
||||
nTxType = request.params[1].get_int();
|
||||
}
|
||||
|
||||
int nCount = 10;
|
||||
if (request.params.size() > 2) {
|
||||
nCount = request.params[2].get_int();
|
||||
if (nCount < 0)
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative count");
|
||||
}
|
||||
|
||||
int nSkip = 0;
|
||||
if (request.params.size() > 3) {
|
||||
nSkip = request.params[3].get_int();
|
||||
if (nSkip < 0)
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative skip");
|
||||
}
|
||||
|
||||
int nVerbosity = 0;
|
||||
if (request.params.size() > 4) {
|
||||
nVerbosity = request.params[4].get_int();
|
||||
if (nVerbosity < 0 || nVerbosity > 2) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Verbosity must be in range 0..2");
|
||||
}
|
||||
}
|
||||
|
||||
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");
|
||||
|
||||
int nTxNum = 0;
|
||||
UniValue result(UniValue::VARR);
|
||||
for(const auto& tx : block.vtx)
|
||||
{
|
||||
if (tx->nVersion != 3 || tx->nType == TRANSACTION_NORMAL // ensure it's in fact a special tx
|
||||
|| (nTxType != -1 && tx->nType != nTxType)) { // ensure special tx type matches filter, if given
|
||||
continue;
|
||||
}
|
||||
|
||||
nTxNum++;
|
||||
if (nTxNum <= nSkip) continue;
|
||||
if (nTxNum > nSkip + nCount) break;
|
||||
|
||||
switch (nVerbosity)
|
||||
{
|
||||
case 0 : result.push_back(tx->GetHash().GetHex()); break;
|
||||
case 1 : result.push_back(EncodeHexTx(*tx)); break;
|
||||
case 2 :
|
||||
{
|
||||
UniValue objTx(UniValue::VOBJ);
|
||||
TxToJSON(*tx, uint256(), objTx);
|
||||
result.push_back(objTx);
|
||||
break;
|
||||
}
|
||||
default : throw JSONRPCError(RPC_INTERNAL_ERROR, "Unsupported verbosity");
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static const CRPCCommand commands[] =
|
||||
{ // category name actor (function) okSafe argNames
|
||||
// --------------------- ------------------------ ----------------------- ------ ----------
|
||||
@ -1638,6 +1746,7 @@ static const CRPCCommand commands[] =
|
||||
{ "blockchain", "getmempoolentry", &getmempoolentry, true, {"txid"} },
|
||||
{ "blockchain", "getmempoolinfo", &getmempoolinfo, true, {} },
|
||||
{ "blockchain", "getrawmempool", &getrawmempool, true, {"verbose"} },
|
||||
{ "blockchain", "getspecialtxes", &getspecialtxes, true, {"blockhash", "type", "count", "skip", "verbosity"} },
|
||||
{ "blockchain", "gettxout", &gettxout, true, {"txid","n","include_mempool"} },
|
||||
{ "blockchain", "gettxoutsetinfo", &gettxoutsetinfo, true, {} },
|
||||
{ "blockchain", "pruneblockchain", &pruneblockchain, true, {"height"} },
|
||||
|
@ -154,6 +154,10 @@ static const CRPCConvertParam vRPCConvertParams[] =
|
||||
{ "getaddressdeltas", 0, "addresses" },
|
||||
{ "getaddressutxos", 0, "addresses" },
|
||||
{ "getaddressmempool", 0, "addresses" },
|
||||
{ "getspecialtxes", 1, "type" },
|
||||
{ "getspecialtxes", 2, "count" },
|
||||
{ "getspecialtxes", 3, "skip" },
|
||||
{ "getspecialtxes", 4, "verbosity" },
|
||||
// Echo with conversion (For testing only)
|
||||
{ "echojson", 0, "arg0" },
|
||||
{ "echojson", 1, "arg1" },
|
||||
|
Loading…
Reference in New Issue
Block a user