aboutsummaryrefslogtreecommitdiff
path: root/src/rpc
diff options
context:
space:
mode:
Diffstat (limited to 'src/rpc')
-rw-r--r--src/rpc/blockchain.cpp90
-rw-r--r--src/rpc/client.cpp11
-rw-r--r--src/rpc/mining.cpp40
-rw-r--r--src/rpc/misc.cpp45
-rw-r--r--src/rpc/net.cpp36
-rw-r--r--src/rpc/protocol.h1
-rw-r--r--src/rpc/rawtransaction.cpp67
-rw-r--r--src/rpc/server.cpp31
-rw-r--r--src/rpc/server.h8
-rw-r--r--src/rpc/util.cpp18
-rw-r--r--src/rpc/util.h2
11 files changed, 195 insertions, 154 deletions
diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp
index c454ba6963..ea92dc11a4 100644
--- a/src/rpc/blockchain.cpp
+++ b/src/rpc/blockchain.cpp
@@ -843,7 +843,7 @@ static RPCHelpMan getblockheader()
const CBlockIndex* tip;
{
LOCK(cs_main);
- pblockindex = LookupBlockIndex(hash);
+ pblockindex = g_chainman.m_blockman.LookupBlockIndex(hash);
tip = ::ChainActive().Tip();
}
@@ -967,7 +967,7 @@ static RPCHelpMan getblock()
const CBlockIndex* tip;
{
LOCK(cs_main);
- pblockindex = LookupBlockIndex(hash);
+ pblockindex = g_chainman.m_blockman.LookupBlockIndex(hash);
tip = ::ChainActive().Tip();
if (!pblockindex) {
@@ -1164,7 +1164,7 @@ static RPCHelpMan gettxout()
}
}
- const CBlockIndex* pindex = LookupBlockIndex(coins_view->GetBestBlock());
+ const CBlockIndex* pindex = g_chainman.m_blockman.LookupBlockIndex(coins_view->GetBestBlock());
ret.pushKV("bestblock", pindex->GetBlockHash().GetHex());
if (coin.nHeight == MEMPOOL_HEIGHT) {
ret.pushKV("confirmations", 0);
@@ -1559,7 +1559,7 @@ static RPCHelpMan preciousblock()
{
LOCK(cs_main);
- pblockindex = LookupBlockIndex(hash);
+ pblockindex = g_chainman.m_blockman.LookupBlockIndex(hash);
if (!pblockindex) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
}
@@ -1597,7 +1597,7 @@ static RPCHelpMan invalidateblock()
CBlockIndex* pblockindex;
{
LOCK(cs_main);
- pblockindex = LookupBlockIndex(hash);
+ pblockindex = g_chainman.m_blockman.LookupBlockIndex(hash);
if (!pblockindex) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
}
@@ -1605,7 +1605,7 @@ static RPCHelpMan invalidateblock()
InvalidateBlock(state, Params(), pblockindex);
if (state.IsValid()) {
- ActivateBestChain(state, Params());
+ ::ChainstateActive().ActivateBestChain(state, Params());
}
if (!state.IsValid()) {
@@ -1636,7 +1636,7 @@ static RPCHelpMan reconsiderblock()
{
LOCK(cs_main);
- CBlockIndex* pblockindex = LookupBlockIndex(hash);
+ CBlockIndex* pblockindex = g_chainman.m_blockman.LookupBlockIndex(hash);
if (!pblockindex) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
}
@@ -1645,7 +1645,7 @@ static RPCHelpMan reconsiderblock()
}
BlockValidationState state;
- ActivateBestChain(state, Params());
+ ::ChainstateActive().ActivateBestChain(state, Params());
if (!state.IsValid()) {
throw JSONRPCError(RPC_DATABASE_ERROR, state.ToString());
@@ -1691,7 +1691,7 @@ static RPCHelpMan getchaintxstats()
} else {
uint256 hash(ParseHashV(request.params[1], "blockhash"));
LOCK(cs_main);
- pindex = LookupBlockIndex(hash);
+ pindex = g_chainman.m_blockman.LookupBlockIndex(hash);
if (!pindex) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
}
@@ -1869,7 +1869,7 @@ static RPCHelpMan getblockstats()
pindex = ::ChainActive()[height];
} else {
const uint256 hash(ParseHashV(request.params[0], "hash_or_height"));
- pindex = LookupBlockIndex(hash);
+ pindex = g_chainman.m_blockman.LookupBlockIndex(hash);
if (!pindex) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
}
@@ -2332,7 +2332,7 @@ static RPCHelpMan getblockfilter()
bool block_was_connected;
{
LOCK(cs_main);
- block_index = LookupBlockIndex(block_hash);
+ block_index = g_chainman.m_blockman.LookupBlockIndex(block_hash);
if (!block_index) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
}
@@ -2442,7 +2442,7 @@ static RPCHelpMan dumptxoutset()
}
pcursor = std::unique_ptr<CCoinsViewCursor>(::ChainstateActive().CoinsDB().Cursor());
- tip = LookupBlockIndex(stats.hashBlock);
+ tip = g_chainman.m_blockman.LookupBlockIndex(stats.hashBlock);
CHECK_NONFATAL(tip);
}
@@ -2482,41 +2482,41 @@ void RegisterBlockchainRPCCommands(CRPCTable &t)
{
// clang-format off
static const CRPCCommand commands[] =
-{ // category name actor (function) argNames
- // --------------------- ------------------------ ----------------------- ----------
- { "blockchain", "getblockchaininfo", &getblockchaininfo, {} },
- { "blockchain", "getchaintxstats", &getchaintxstats, {"nblocks", "blockhash"} },
- { "blockchain", "getblockstats", &getblockstats, {"hash_or_height", "stats"} },
- { "blockchain", "getbestblockhash", &getbestblockhash, {} },
- { "blockchain", "getblockcount", &getblockcount, {} },
- { "blockchain", "getblock", &getblock, {"blockhash","verbosity|verbose"} },
- { "blockchain", "getblockhash", &getblockhash, {"height"} },
- { "blockchain", "getblockheader", &getblockheader, {"blockhash","verbose"} },
- { "blockchain", "getchaintips", &getchaintips, {} },
- { "blockchain", "getdifficulty", &getdifficulty, {} },
- { "blockchain", "getmempoolancestors", &getmempoolancestors, {"txid","verbose"} },
- { "blockchain", "getmempooldescendants", &getmempooldescendants, {"txid","verbose"} },
- { "blockchain", "getmempoolentry", &getmempoolentry, {"txid"} },
- { "blockchain", "getmempoolinfo", &getmempoolinfo, {} },
- { "blockchain", "getrawmempool", &getrawmempool, {"verbose", "mempool_sequence"} },
- { "blockchain", "gettxout", &gettxout, {"txid","n","include_mempool"} },
- { "blockchain", "gettxoutsetinfo", &gettxoutsetinfo, {"hash_type"} },
- { "blockchain", "pruneblockchain", &pruneblockchain, {"height"} },
- { "blockchain", "savemempool", &savemempool, {} },
- { "blockchain", "verifychain", &verifychain, {"checklevel","nblocks"} },
-
- { "blockchain", "preciousblock", &preciousblock, {"blockhash"} },
- { "blockchain", "scantxoutset", &scantxoutset, {"action", "scanobjects"} },
- { "blockchain", "getblockfilter", &getblockfilter, {"blockhash", "filtertype"} },
+{ // category actor (function)
+ // --------------------- ------------------------
+ { "blockchain", &getblockchaininfo, },
+ { "blockchain", &getchaintxstats, },
+ { "blockchain", &getblockstats, },
+ { "blockchain", &getbestblockhash, },
+ { "blockchain", &getblockcount, },
+ { "blockchain", &getblock, },
+ { "blockchain", &getblockhash, },
+ { "blockchain", &getblockheader, },
+ { "blockchain", &getchaintips, },
+ { "blockchain", &getdifficulty, },
+ { "blockchain", &getmempoolancestors, },
+ { "blockchain", &getmempooldescendants, },
+ { "blockchain", &getmempoolentry, },
+ { "blockchain", &getmempoolinfo, },
+ { "blockchain", &getrawmempool, },
+ { "blockchain", &gettxout, },
+ { "blockchain", &gettxoutsetinfo, },
+ { "blockchain", &pruneblockchain, },
+ { "blockchain", &savemempool, },
+ { "blockchain", &verifychain, },
+
+ { "blockchain", &preciousblock, },
+ { "blockchain", &scantxoutset, },
+ { "blockchain", &getblockfilter, },
/* Not shown in help */
- { "hidden", "invalidateblock", &invalidateblock, {"blockhash"} },
- { "hidden", "reconsiderblock", &reconsiderblock, {"blockhash"} },
- { "hidden", "waitfornewblock", &waitfornewblock, {"timeout"} },
- { "hidden", "waitforblock", &waitforblock, {"blockhash","timeout"} },
- { "hidden", "waitforblockheight", &waitforblockheight, {"height","timeout"} },
- { "hidden", "syncwithvalidationinterfacequeue", &syncwithvalidationinterfacequeue, {} },
- { "hidden", "dumptxoutset", &dumptxoutset, {"path"} },
+ { "hidden", &invalidateblock, },
+ { "hidden", &reconsiderblock, },
+ { "hidden", &waitfornewblock, },
+ { "hidden", &waitforblock, },
+ { "hidden", &waitforblockheight, },
+ { "hidden", &syncwithvalidationinterfacequeue, },
+ { "hidden", &dumptxoutset, },
};
// clang-format on
for (const auto& c : commands) {
diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp
index 042005b9a6..d1eb849b7e 100644
--- a/src/rpc/client.cpp
+++ b/src/rpc/client.cpp
@@ -210,14 +210,9 @@ public:
CRPCConvertTable::CRPCConvertTable()
{
- const unsigned int n_elem =
- (sizeof(vRPCConvertParams) / sizeof(vRPCConvertParams[0]));
-
- for (unsigned int i = 0; i < n_elem; i++) {
- members.insert(std::make_pair(vRPCConvertParams[i].methodName,
- vRPCConvertParams[i].paramIdx));
- membersByName.insert(std::make_pair(vRPCConvertParams[i].methodName,
- vRPCConvertParams[i].paramName));
+ for (const auto& cp : vRPCConvertParams) {
+ members.emplace(cp.methodName, cp.paramIdx);
+ membersByName.emplace(cp.methodName, cp.paramName);
}
}
diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp
index 0e96beb6db..50987a735b 100644
--- a/src/rpc/mining.cpp
+++ b/src/rpc/mining.cpp
@@ -375,7 +375,7 @@ static RPCHelpMan generateblock()
LOCK(cs_main);
BlockValidationState state;
- if (!TestBlockValidity(state, chainparams, block, LookupBlockIndex(block.hashPrevBlock), false, false)) {
+ if (!TestBlockValidity(state, chainparams, ::ChainstateActive(), block, g_chainman.m_blockman.LookupBlockIndex(block.hashPrevBlock), false, false)) {
throw JSONRPCError(RPC_VERIFY_ERROR, strprintf("TestBlockValidity failed: %s", state.ToString()));
}
}
@@ -618,7 +618,7 @@ static RPCHelpMan getblocktemplate()
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block decode failed");
uint256 hash = block.GetHash();
- const CBlockIndex* pindex = LookupBlockIndex(hash);
+ const CBlockIndex* pindex = g_chainman.m_blockman.LookupBlockIndex(hash);
if (pindex) {
if (pindex->IsValid(BLOCK_VALID_SCRIPTS))
return "duplicate";
@@ -632,7 +632,7 @@ static RPCHelpMan getblocktemplate()
if (block.hashPrevBlock != pindexPrev->GetBlockHash())
return "inconclusive-not-best-prevblk";
BlockValidationState state;
- TestBlockValidity(state, Params(), block, pindexPrev, false, true);
+ TestBlockValidity(state, Params(), ::ChainstateActive(), block, pindexPrev, false, true);
return BIP22ValidationResult(state);
}
@@ -966,7 +966,7 @@ static RPCHelpMan submitblock()
uint256 hash = block.GetHash();
{
LOCK(cs_main);
- const CBlockIndex* pindex = LookupBlockIndex(hash);
+ const CBlockIndex* pindex = g_chainman.m_blockman.LookupBlockIndex(hash);
if (pindex) {
if (pindex->IsValid(BLOCK_VALID_SCRIPTS)) {
return "duplicate";
@@ -979,7 +979,7 @@ static RPCHelpMan submitblock()
{
LOCK(cs_main);
- const CBlockIndex* pindex = LookupBlockIndex(block.hashPrevBlock);
+ const CBlockIndex* pindex = g_chainman.m_blockman.LookupBlockIndex(block.hashPrevBlock);
if (pindex) {
UpdateUncommittedBlockStructures(block, pindex, Params().GetConsensus());
}
@@ -1023,7 +1023,7 @@ static RPCHelpMan submitheader()
}
{
LOCK(cs_main);
- if (!LookupBlockIndex(h.hashPrevBlock)) {
+ if (!g_chainman.m_blockman.LookupBlockIndex(h.hashPrevBlock)) {
throw JSONRPCError(RPC_VERIFY_ERROR, "Must submit previous header (" + h.hashPrevBlock.GetHex() + ") first");
}
}
@@ -1232,24 +1232,24 @@ void RegisterMiningRPCCommands(CRPCTable &t)
{
// clang-format off
static const CRPCCommand commands[] =
-{ // category name actor (function) argNames
- // --------------------- ------------------------ ----------------------- ----------
- { "mining", "getnetworkhashps", &getnetworkhashps, {"nblocks","height"} },
- { "mining", "getmininginfo", &getmininginfo, {} },
- { "mining", "prioritisetransaction", &prioritisetransaction, {"txid","dummy","fee_delta"} },
- { "mining", "getblocktemplate", &getblocktemplate, {"template_request"} },
- { "mining", "submitblock", &submitblock, {"hexdata","dummy"} },
- { "mining", "submitheader", &submitheader, {"hexdata"} },
+{ // category actor (function)
+ // --------------------- -----------------------
+ { "mining", &getnetworkhashps, },
+ { "mining", &getmininginfo, },
+ { "mining", &prioritisetransaction, },
+ { "mining", &getblocktemplate, },
+ { "mining", &submitblock, },
+ { "mining", &submitheader, },
- { "generating", "generatetoaddress", &generatetoaddress, {"nblocks","address","maxtries"} },
- { "generating", "generatetodescriptor", &generatetodescriptor, {"num_blocks","descriptor","maxtries"} },
- { "generating", "generateblock", &generateblock, {"output","transactions"} },
+ { "generating", &generatetoaddress, },
+ { "generating", &generatetodescriptor, },
+ { "generating", &generateblock, },
- { "util", "estimatesmartfee", &estimatesmartfee, {"conf_target", "estimate_mode"} },
+ { "util", &estimatesmartfee, },
- { "hidden", "estimaterawfee", &estimaterawfee, {"conf_target", "threshold"} },
- { "hidden", "generate", &generate, {} },
+ { "hidden", &estimaterawfee, },
+ { "hidden", &generate, },
};
// clang-format on
for (const auto& c : commands) {
diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp
index b3102a236d..b75a7b8d26 100644
--- a/src/rpc/misc.cpp
+++ b/src/rpc/misc.cpp
@@ -39,13 +39,14 @@ static RPCHelpMan validateaddress()
RPCResult{
RPCResult::Type::OBJ, "", "",
{
- {RPCResult::Type::BOOL, "isvalid", "If the address is valid or not. If not, this is the only property returned."},
+ {RPCResult::Type::BOOL, "isvalid", "If the address is valid or not"},
{RPCResult::Type::STR, "address", "The bitcoin address validated"},
{RPCResult::Type::STR_HEX, "scriptPubKey", "The hex-encoded scriptPubKey generated by the address"},
{RPCResult::Type::BOOL, "isscript", "If the key is a script"},
{RPCResult::Type::BOOL, "iswitness", "If the address is a witness address"},
{RPCResult::Type::NUM, "witness_version", /* optional */ true, "The version number of the witness program"},
{RPCResult::Type::STR_HEX, "witness_program", /* optional */ true, "The hex value of the witness program"},
+ {RPCResult::Type::STR, "error", /* optional */ true, "Error message, if any"},
}
},
RPCExamples{
@@ -54,13 +55,14 @@ static RPCHelpMan validateaddress()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
- CTxDestination dest = DecodeDestination(request.params[0].get_str());
- bool isValid = IsValidDestination(dest);
+ std::string error_msg;
+ CTxDestination dest = DecodeDestination(request.params[0].get_str(), error_msg);
+ const bool isValid = IsValidDestination(dest);
+ CHECK_NONFATAL(isValid == error_msg.empty());
UniValue ret(UniValue::VOBJ);
ret.pushKV("isvalid", isValid);
- if (isValid)
- {
+ if (isValid) {
std::string currentAddress = EncodeDestination(dest);
ret.pushKV("address", currentAddress);
@@ -69,7 +71,10 @@ static RPCHelpMan validateaddress()
UniValue detail = DescribeAddress(dest);
ret.pushKVs(detail);
+ } else {
+ ret.pushKV("error", error_msg);
}
+
return ret;
},
};
@@ -694,23 +699,23 @@ void RegisterMiscRPCCommands(CRPCTable &t)
{
// clang-format off
static const CRPCCommand commands[] =
-{ // category name actor (function) argNames
- // --------------------- ------------------------ ----------------------- ----------
- { "control", "getmemoryinfo", &getmemoryinfo, {"mode"} },
- { "control", "logging", &logging, {"include", "exclude"}},
- { "util", "validateaddress", &validateaddress, {"address"} },
- { "util", "createmultisig", &createmultisig, {"nrequired","keys","address_type"} },
- { "util", "deriveaddresses", &deriveaddresses, {"descriptor", "range"} },
- { "util", "getdescriptorinfo", &getdescriptorinfo, {"descriptor"} },
- { "util", "verifymessage", &verifymessage, {"address","signature","message"} },
- { "util", "signmessagewithprivkey", &signmessagewithprivkey, {"privkey","message"} },
- { "util", "getindexinfo", &getindexinfo, {"index_name"} },
+{ // category actor (function)
+ // --------------------- ------------------------
+ { "control", &getmemoryinfo, },
+ { "control", &logging, },
+ { "util", &validateaddress, },
+ { "util", &createmultisig, },
+ { "util", &deriveaddresses, },
+ { "util", &getdescriptorinfo, },
+ { "util", &verifymessage, },
+ { "util", &signmessagewithprivkey, },
+ { "util", &getindexinfo, },
/* Not shown in help */
- { "hidden", "setmocktime", &setmocktime, {"timestamp"}},
- { "hidden", "mockscheduler", &mockscheduler, {"delta_time"}},
- { "hidden", "echo", &echo, {"arg0","arg1","arg2","arg3","arg4","arg5","arg6","arg7","arg8","arg9"}},
- { "hidden", "echojson", &echojson, {"arg0","arg1","arg2","arg3","arg4","arg5","arg6","arg7","arg8","arg9"}},
+ { "hidden", &setmocktime, },
+ { "hidden", &mockscheduler, },
+ { "hidden", &echo, },
+ { "hidden", &echojson, },
};
// clang-format on
for (const auto& c : commands) {
diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp
index cfca8b4ad4..47d77b341a 100644
--- a/src/rpc/net.cpp
+++ b/src/rpc/net.cpp
@@ -941,24 +941,24 @@ void RegisterNetRPCCommands(CRPCTable &t)
{
// clang-format off
static const CRPCCommand commands[] =
-{ // category name actor (function) argNames
- // --------------------- ------------------------ ----------------------- ----------
- { "network", "getconnectioncount", &getconnectioncount, {} },
- { "network", "ping", &ping, {} },
- { "network", "getpeerinfo", &getpeerinfo, {} },
- { "network", "addnode", &addnode, {"node","command"} },
- { "network", "disconnectnode", &disconnectnode, {"address", "nodeid"} },
- { "network", "getaddednodeinfo", &getaddednodeinfo, {"node"} },
- { "network", "getnettotals", &getnettotals, {} },
- { "network", "getnetworkinfo", &getnetworkinfo, {} },
- { "network", "setban", &setban, {"subnet", "command", "bantime", "absolute"} },
- { "network", "listbanned", &listbanned, {} },
- { "network", "clearbanned", &clearbanned, {} },
- { "network", "setnetworkactive", &setnetworkactive, {"state"} },
- { "network", "getnodeaddresses", &getnodeaddresses, {"count"} },
-
- { "hidden", "addconnection", &addconnection, {"address", "connection_type"} },
- { "hidden", "addpeeraddress", &addpeeraddress, {"address", "port"} },
+{ // category actor
+ // --------------------- -----------------------
+ { "network", &getconnectioncount, },
+ { "network", &ping, },
+ { "network", &getpeerinfo, },
+ { "network", &addnode, },
+ { "network", &disconnectnode, },
+ { "network", &getaddednodeinfo, },
+ { "network", &getnettotals, },
+ { "network", &getnetworkinfo, },
+ { "network", &setban, },
+ { "network", &listbanned, },
+ { "network", &clearbanned, },
+ { "network", &setnetworkactive, },
+ { "network", &getnodeaddresses, },
+
+ { "hidden", &addconnection, },
+ { "hidden", &addpeeraddress, },
};
// clang-format on
for (const auto& c : commands) {
diff --git a/src/rpc/protocol.h b/src/rpc/protocol.h
index c8ceb2c186..fc00a1efad 100644
--- a/src/rpc/protocol.h
+++ b/src/rpc/protocol.h
@@ -79,6 +79,7 @@ enum RPCErrorCode
RPC_WALLET_ALREADY_UNLOCKED = -17, //!< Wallet is already unlocked
RPC_WALLET_NOT_FOUND = -18, //!< Invalid wallet specified
RPC_WALLET_NOT_SPECIFIED = -19, //!< No wallet specified (error when there are multiple wallets loaded)
+ RPC_WALLET_ALREADY_LOADED = -35, //!< This same wallet is already loaded
//! Backwards compatible aliases
RPC_WALLET_INVALID_ACCOUNT_NAME = RPC_WALLET_INVALID_LABEL_NAME,
diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp
index e94d554e3c..ac42404470 100644
--- a/src/rpc/rawtransaction.cpp
+++ b/src/rpc/rawtransaction.cpp
@@ -54,7 +54,7 @@ static void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue&
LOCK(cs_main);
entry.pushKV("blockhash", hashBlock.GetHex());
- CBlockIndex* pindex = LookupBlockIndex(hashBlock);
+ CBlockIndex* pindex = g_chainman.m_blockman.LookupBlockIndex(hashBlock);
if (pindex) {
if (::ChainActive().Contains(pindex)) {
entry.pushKV("confirmations", 1 + ::ChainActive().Height() - pindex->nHeight);
@@ -178,7 +178,7 @@ static RPCHelpMan getrawtransaction()
LOCK(cs_main);
uint256 blockhash = ParseHashV(request.params[2], "parameter 3");
- blockindex = LookupBlockIndex(blockhash);
+ blockindex = g_chainman.m_blockman.LookupBlockIndex(blockhash);
if (!blockindex) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block hash not found");
}
@@ -260,7 +260,7 @@ static RPCHelpMan gettxoutproof()
if (!request.params[1].isNull()) {
LOCK(cs_main);
hashBlock = ParseHashV(request.params[1], "blockhash");
- pblockindex = LookupBlockIndex(hashBlock);
+ pblockindex = g_chainman.m_blockman.LookupBlockIndex(hashBlock);
if (!pblockindex) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
}
@@ -290,7 +290,7 @@ static RPCHelpMan gettxoutproof()
if (!tx || hashBlock.IsNull()) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not yet in block");
}
- pblockindex = LookupBlockIndex(hashBlock);
+ pblockindex = g_chainman.m_blockman.LookupBlockIndex(hashBlock);
if (!pblockindex) {
throw JSONRPCError(RPC_INTERNAL_ERROR, "Transaction index corrupt");
}
@@ -350,7 +350,7 @@ static RPCHelpMan verifytxoutproof()
LOCK(cs_main);
- const CBlockIndex* pindex = LookupBlockIndex(merkleBlock.header.GetHash());
+ const CBlockIndex* pindex = g_chainman.m_blockman.LookupBlockIndex(merkleBlock.header.GetHash());
if (!pindex || !::ChainActive().Contains(pindex) || pindex->nTx == 0) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found in chain");
}
@@ -816,10 +816,11 @@ static RPCHelpMan sendrawtransaction()
{
return RPCHelpMan{"sendrawtransaction",
"\nSubmit a raw transaction (serialized, hex-encoded) to local node and network.\n"
- "\nNote that the transaction will be sent unconditionally to all peers, so using this\n"
+ "\nThe transaction will be sent unconditionally to all peers, so using sendrawtransaction\n"
"for manual rebroadcast may degrade privacy by leaking the transaction's origin, as\n"
"nodes will normally not rebroadcast non-wallet transactions already in their mempool.\n"
- "\nAlso see createrawtransaction and signrawtransactionwithkey calls.\n",
+ "\nA specific exception, RPC_TRANSACTION_ALREADY_IN_CHAIN, may throw if the transaction cannot be added to the mempool.\n"
+ "\nRelated RPCs: createrawtransaction, signrawtransactionwithkey\n",
{
{"hexstring", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The hex string of the raw transaction"},
{"maxfeerate", RPCArg::Type::AMOUNT, /* default */ FormatMoney(DEFAULT_MAX_RAW_TX_FEE_RATE.GetFeePerK()),
@@ -1344,7 +1345,7 @@ static RPCHelpMan combinepsbt()
CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
ssTx << merged_psbt;
- return EncodeBase64(MakeUCharSpan(ssTx));
+ return EncodeBase64(ssTx);
},
};
}
@@ -1483,7 +1484,7 @@ static RPCHelpMan createpsbt()
CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
ssTx << psbtx;
- return EncodeBase64(MakeUCharSpan(ssTx));
+ return EncodeBase64(ssTx);
},
};
}
@@ -1552,7 +1553,7 @@ static RPCHelpMan converttopsbt()
CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
ssTx << psbtx;
- return EncodeBase64(MakeUCharSpan(ssTx));
+ return EncodeBase64(ssTx);
},
};
}
@@ -1643,7 +1644,7 @@ static RPCHelpMan utxoupdatepsbt()
CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
ssTx << psbtx;
- return EncodeBase64(MakeUCharSpan(ssTx));
+ return EncodeBase64(ssTx);
},
};
}
@@ -1739,7 +1740,7 @@ static RPCHelpMan joinpsbts()
CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
ssTx << shuffled_psbt;
- return EncodeBase64(MakeUCharSpan(ssTx));
+ return EncodeBase64(ssTx);
},
};
}
@@ -1859,27 +1860,27 @@ void RegisterRawTransactionRPCCommands(CRPCTable &t)
{
// clang-format off
static const CRPCCommand commands[] =
-{ // category name actor (function) argNames
- // --------------------- ------------------------ ----------------------- ----------
- { "rawtransactions", "getrawtransaction", &getrawtransaction, {"txid","verbose","blockhash"} },
- { "rawtransactions", "createrawtransaction", &createrawtransaction, {"inputs","outputs","locktime","replaceable"} },
- { "rawtransactions", "decoderawtransaction", &decoderawtransaction, {"hexstring","iswitness"} },
- { "rawtransactions", "decodescript", &decodescript, {"hexstring"} },
- { "rawtransactions", "sendrawtransaction", &sendrawtransaction, {"hexstring","maxfeerate"} },
- { "rawtransactions", "combinerawtransaction", &combinerawtransaction, {"txs"} },
- { "rawtransactions", "signrawtransactionwithkey", &signrawtransactionwithkey, {"hexstring","privkeys","prevtxs","sighashtype"} },
- { "rawtransactions", "testmempoolaccept", &testmempoolaccept, {"rawtxs","maxfeerate"} },
- { "rawtransactions", "decodepsbt", &decodepsbt, {"psbt"} },
- { "rawtransactions", "combinepsbt", &combinepsbt, {"txs"} },
- { "rawtransactions", "finalizepsbt", &finalizepsbt, {"psbt", "extract"} },
- { "rawtransactions", "createpsbt", &createpsbt, {"inputs","outputs","locktime","replaceable"} },
- { "rawtransactions", "converttopsbt", &converttopsbt, {"hexstring","permitsigdata","iswitness"} },
- { "rawtransactions", "utxoupdatepsbt", &utxoupdatepsbt, {"psbt", "descriptors"} },
- { "rawtransactions", "joinpsbts", &joinpsbts, {"txs"} },
- { "rawtransactions", "analyzepsbt", &analyzepsbt, {"psbt"} },
-
- { "blockchain", "gettxoutproof", &gettxoutproof, {"txids", "blockhash"} },
- { "blockchain", "verifytxoutproof", &verifytxoutproof, {"proof"} },
+{ // category actor (function)
+ // --------------------- -----------------------
+ { "rawtransactions", &getrawtransaction, },
+ { "rawtransactions", &createrawtransaction, },
+ { "rawtransactions", &decoderawtransaction, },
+ { "rawtransactions", &decodescript, },
+ { "rawtransactions", &sendrawtransaction, },
+ { "rawtransactions", &combinerawtransaction, },
+ { "rawtransactions", &signrawtransactionwithkey, },
+ { "rawtransactions", &testmempoolaccept, },
+ { "rawtransactions", &decodepsbt, },
+ { "rawtransactions", &combinepsbt, },
+ { "rawtransactions", &finalizepsbt, },
+ { "rawtransactions", &createpsbt, },
+ { "rawtransactions", &converttopsbt, },
+ { "rawtransactions", &utxoupdatepsbt, },
+ { "rawtransactions", &joinpsbts, },
+ { "rawtransactions", &analyzepsbt, },
+
+ { "blockchain", &gettxoutproof, },
+ { "blockchain", &verifytxoutproof, },
};
// clang-format on
for (const auto& c : commands) {
diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp
index f32d9abac6..9a9b3713f3 100644
--- a/src/rpc/server.cpp
+++ b/src/rpc/server.cpp
@@ -144,8 +144,13 @@ static RPCHelpMan help()
[&](const RPCHelpMan& self, const JSONRPCRequest& jsonRequest) -> UniValue
{
std::string strCommand;
- if (jsonRequest.params.size() > 0)
+ if (jsonRequest.params.size() > 0) {
strCommand = jsonRequest.params[0].get_str();
+ }
+ if (strCommand == "dump_all_command_conversions") {
+ // Used for testing only, undocumented
+ return tableRPC.dumpArgMap();
+ }
return tableRPC.help(strCommand, jsonRequest);
},
@@ -244,13 +249,13 @@ static RPCHelpMan getrpcinfo()
// clang-format off
static const CRPCCommand vRPCCommands[] =
-{ // category name actor (function) argNames
- // --------------------- ------------------------ ----------------------- ----------
+{ // category actor (function)
+ // --------------------- -----------------------
/* Overall control/query calls */
- { "control", "getrpcinfo", &getrpcinfo, {} },
- { "control", "help", &help, {"command"} },
- { "control", "stop", &stop, {"wait"} },
- { "control", "uptime", &uptime, {} },
+ { "control", &getrpcinfo, },
+ { "control", &help, },
+ { "control", &stop, },
+ { "control", &uptime, },
};
// clang-format on
@@ -479,6 +484,18 @@ std::vector<std::string> CRPCTable::listCommands() const
return commandList;
}
+UniValue CRPCTable::dumpArgMap() const
+{
+ UniValue ret{UniValue::VARR};
+ for (const auto& cmd : mapCommands) {
+ for (const auto& c : cmd.second) {
+ const auto help = RpcMethodFnType(c->unique_id)();
+ help.AppendArgMap(ret);
+ }
+ }
+ return ret;
+}
+
void RPCSetTimerInterfaceIfUnset(RPCTimerInterface *iface)
{
if (!timerInterface)
diff --git a/src/rpc/server.h b/src/rpc/server.h
index 040192b455..fe5a791e1e 100644
--- a/src/rpc/server.h
+++ b/src/rpc/server.h
@@ -103,7 +103,7 @@ public:
}
//! Simplified constructor taking plain RpcMethodFnType function pointer.
- CRPCCommand(std::string category, std::string name_in, RpcMethodFnType fn, std::vector<std::string> args_in)
+ CRPCCommand(std::string category, RpcMethodFnType fn)
: CRPCCommand(
category,
fn().m_name,
@@ -111,8 +111,6 @@ public:
fn().GetArgNames(),
intptr_t(fn))
{
- CHECK_NONFATAL(fn().m_name == name_in);
- CHECK_NONFATAL(fn().GetArgNames() == args_in);
}
std::string category;
@@ -147,6 +145,10 @@ public:
*/
std::vector<std::string> listCommands() const;
+ /**
+ * Return all named arguments that need to be converted by the client from string to another JSON type
+ */
+ UniValue dumpArgMap() const;
/**
* Appends a CRPCCommand to the dispatch table.
diff --git a/src/rpc/util.cpp b/src/rpc/util.cpp
index 31072114da..bfdba5253c 100644
--- a/src/rpc/util.cpp
+++ b/src/rpc/util.cpp
@@ -549,6 +549,24 @@ std::string RPCHelpMan::ToString() const
return ret;
}
+void RPCHelpMan::AppendArgMap(UniValue& arr) const
+{
+ for (int i{0}; i < int(m_args.size()); ++i) {
+ const auto& arg = m_args.at(i);
+ std::vector<std::string> arg_names;
+ boost::split(arg_names, arg.m_names, boost::is_any_of("|"));
+ for (const auto& arg_name : arg_names) {
+ UniValue map{UniValue::VARR};
+ map.push_back(m_name);
+ map.push_back(i);
+ map.push_back(arg_name);
+ map.push_back(arg.m_type == RPCArg::Type::STR ||
+ arg.m_type == RPCArg::Type::STR_HEX);
+ arr.push_back(map);
+ }
+ }
+}
+
std::string RPCArg::GetFirstName() const
{
return m_names.substr(0, m_names.find("|"));
diff --git a/src/rpc/util.h b/src/rpc/util.h
index 942c243718..444a013ca1 100644
--- a/src/rpc/util.h
+++ b/src/rpc/util.h
@@ -336,6 +336,8 @@ public:
RPCHelpMan(std::string name, std::string description, std::vector<RPCArg> args, RPCResults results, RPCExamples examples, RPCMethodImpl fun);
std::string ToString() const;
+ /** Append the named args that need to be converted from string to another JSON type */
+ void AppendArgMap(UniValue& arr) const;
UniValue HandleRequest(const JSONRPCRequest& request)
{
Check(request);