aboutsummaryrefslogtreecommitdiff
path: root/src/rpc
diff options
context:
space:
mode:
Diffstat (limited to 'src/rpc')
-rw-r--r--src/rpc/blockchain.cpp57
-rw-r--r--src/rpc/client.cpp2
-rw-r--r--src/rpc/mining.cpp20
-rw-r--r--src/rpc/mining.h11
-rw-r--r--src/rpc/misc.cpp4
-rw-r--r--src/rpc/net.cpp17
-rw-r--r--src/rpc/rawtransaction.cpp33
-rw-r--r--src/rpc/rawtransaction_util.cpp4
-rw-r--r--src/rpc/server.cpp14
-rw-r--r--src/rpc/util.cpp21
-rw-r--r--src/rpc/util.h3
11 files changed, 113 insertions, 73 deletions
diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp
index 8252af3ee6..c6c78a983a 100644
--- a/src/rpc/blockchain.cpp
+++ b/src/rpc/blockchain.cpp
@@ -75,7 +75,10 @@ CTxMemPool& EnsureMemPool(const util::Ref& context)
ChainstateManager& EnsureChainman(const util::Ref& context)
{
NodeContext& node = EnsureNodeContext(context);
- return EnsureChainman(node);
+ if (!node.chainman) {
+ throw JSONRPCError(RPC_INTERNAL_ERROR, "Node chainman not found");
+ }
+ return *node.chainman;
}
/* Calculate the difficulty for a given block index.
@@ -779,7 +782,7 @@ static UniValue getblockheader(const JSONRPCRequest& request)
{
CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION);
ssBlock << pblockindex->GetBlockHeader();
- std::string strHex = HexStr(ssBlock.begin(), ssBlock.end());
+ std::string strHex = HexStr(ssBlock);
return strHex;
}
@@ -795,10 +798,8 @@ static CBlock GetBlockChecked(const CBlockIndex* pblockindex)
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).
+ // header in our index but not yet have the block or did not accept the
+ // block.
throw JSONRPCError(RPC_MISC_ERROR, "Block not found on disk");
}
@@ -905,7 +906,7 @@ static UniValue getblock(const JSONRPCRequest& request)
{
CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION | RPCSerializationFlags());
ssBlock << block;
- std::string strHex = HexStr(ssBlock.begin(), ssBlock.end());
+ std::string strHex = HexStr(ssBlock);
return strHex;
}
@@ -972,7 +973,9 @@ static UniValue gettxoutsetinfo(const JSONRPCRequest& request)
RPCHelpMan{"gettxoutsetinfo",
"\nReturns statistics about the unspent transaction output set.\n"
"Note this call may take some time.\n",
- {},
+ {
+ {"hash_type", RPCArg::Type::STR, /* default */ "hash_serialized_2", "Which UTXO set hash should be calculated. Options: 'hash_serialized_2' (the legacy algorithm), 'none'."},
+ },
RPCResult{
RPCResult::Type::OBJ, "", "",
{
@@ -981,7 +984,7 @@ static UniValue gettxoutsetinfo(const JSONRPCRequest& request)
{RPCResult::Type::NUM, "transactions", "The number of transactions with unspent outputs"},
{RPCResult::Type::NUM, "txouts", "The number of unspent transaction outputs"},
{RPCResult::Type::NUM, "bogosize", "A meaningless metric for UTXO set size"},
- {RPCResult::Type::STR_HEX, "hash_serialized_2", "The serialized hash"},
+ {RPCResult::Type::STR_HEX, "hash_serialized_2", "The serialized hash (only present if 'hash_serialized_2' hash_type is chosen)"},
{RPCResult::Type::NUM, "disk_size", "The estimated size of the chainstate on disk"},
{RPCResult::Type::STR_AMOUNT, "total_amount", "The total amount"},
}},
@@ -996,14 +999,18 @@ static UniValue gettxoutsetinfo(const JSONRPCRequest& request)
CCoinsStats stats;
::ChainstateActive().ForceFlushStateToDisk();
+ const CoinStatsHashType hash_type = ParseHashType(request.params[0], CoinStatsHashType::HASH_SERIALIZED);
+
CCoinsView* coins_view = WITH_LOCK(cs_main, return &ChainstateActive().CoinsDB());
- if (GetUTXOStats(coins_view, stats, RpcInterruptionPoint)) {
+ if (GetUTXOStats(coins_view, stats, hash_type, RpcInterruptionPoint)) {
ret.pushKV("height", (int64_t)stats.nHeight);
ret.pushKV("bestblock", stats.hashBlock.GetHex());
ret.pushKV("transactions", (int64_t)stats.nTransactions);
ret.pushKV("txouts", (int64_t)stats.nTransactionOutputs);
ret.pushKV("bogosize", (int64_t)stats.nBogoSize);
- ret.pushKV("hash_serialized_2", stats.hashSerialized.GetHex());
+ if (hash_type == CoinStatsHashType::HASH_SERIALIZED) {
+ ret.pushKV("hash_serialized_2", stats.hashSerialized.GetHex());
+ }
ret.pushKV("disk_size", stats.nDiskSize);
ret.pushKV("total_amount", ValueFromAmount(stats.nTotalAmount));
} else {
@@ -1325,50 +1332,48 @@ static UniValue getchaintips(const JSONRPCRequest& request)
},
}.Check(request);
+ ChainstateManager& chainman = EnsureChainman(request.context);
LOCK(cs_main);
/*
- * Idea: the set of chain tips is ::ChainActive().tip, plus orphan blocks which do not have another orphan building off of them.
+ * Idea: The set of chain tips is the active chain tip, plus orphan blocks which do not have another orphan building off of them.
* Algorithm:
* - Make one pass through BlockIndex(), 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()
+ * - Add the active chain tip
*/
std::set<const CBlockIndex*, CompareBlocksByHeight> setTips;
std::set<const CBlockIndex*> setOrphans;
std::set<const CBlockIndex*> setPrevs;
- for (const std::pair<const uint256, CBlockIndex*>& item : ::BlockIndex())
- {
- if (!::ChainActive().Contains(item.second)) {
+ for (const std::pair<const uint256, CBlockIndex*>& item : chainman.BlockIndex()) {
+ if (!chainman.ActiveChain().Contains(item.second)) {
setOrphans.insert(item.second);
setPrevs.insert(item.second->pprev);
}
}
- for (std::set<const CBlockIndex*>::iterator it = setOrphans.begin(); it != setOrphans.end(); ++it)
- {
+ for (std::set<const CBlockIndex*>::iterator it = setOrphans.begin(); it != setOrphans.end(); ++it) {
if (setPrevs.erase(*it) == 0) {
setTips.insert(*it);
}
}
// Always report the currently active tip.
- setTips.insert(::ChainActive().Tip());
+ setTips.insert(chainman.ActiveChain().Tip());
/* Construct the output array. */
UniValue res(UniValue::VARR);
- for (const CBlockIndex* block : setTips)
- {
+ for (const CBlockIndex* block : setTips) {
UniValue obj(UniValue::VOBJ);
obj.pushKV("height", block->nHeight);
obj.pushKV("hash", block->phashBlock->GetHex());
- const int branchLen = block->nHeight - ::ChainActive().FindFork(block)->nHeight;
+ const int branchLen = block->nHeight - chainman.ActiveChain().FindFork(block)->nHeight;
obj.pushKV("branchlen", branchLen);
std::string status;
- if (::ChainActive().Contains(block)) {
+ if (chainman.ActiveChain().Contains(block)) {
// This block is part of the currently active chain.
status = "active";
} else if (block->nStatus & BLOCK_FAILED_MASK) {
@@ -2159,7 +2164,7 @@ UniValue scantxoutset(const JSONRPCRequest& request)
UniValue unspent(UniValue::VOBJ);
unspent.pushKV("txid", outpoint.hash.GetHex());
unspent.pushKV("vout", (int32_t)outpoint.n);
- unspent.pushKV("scriptPubKey", HexStr(txo.scriptPubKey.begin(), txo.scriptPubKey.end()));
+ unspent.pushKV("scriptPubKey", HexStr(txo.scriptPubKey));
unspent.pushKV("desc", descriptors[txo.scriptPubKey]);
unspent.pushKV("amount", ValueFromAmount(txo.nValue));
unspent.pushKV("height", (int32_t)coin.nHeight);
@@ -2316,7 +2321,7 @@ UniValue dumptxoutset(const JSONRPCRequest& request)
::ChainstateActive().ForceFlushStateToDisk();
- if (!GetUTXOStats(&::ChainstateActive().CoinsDB(), stats, RpcInterruptionPoint)) {
+ if (!GetUTXOStats(&::ChainstateActive().CoinsDB(), stats, CoinStatsHashType::NONE, RpcInterruptionPoint)) {
throw JSONRPCError(RPC_INTERNAL_ERROR, "Unable to read UTXO set");
}
@@ -2377,7 +2382,7 @@ static const CRPCCommand commands[] =
{ "blockchain", "getmempoolinfo", &getmempoolinfo, {} },
{ "blockchain", "getrawmempool", &getrawmempool, {"verbose"} },
{ "blockchain", "gettxout", &gettxout, {"txid","n","include_mempool"} },
- { "blockchain", "gettxoutsetinfo", &gettxoutsetinfo, {} },
+ { "blockchain", "gettxoutsetinfo", &gettxoutsetinfo, {"hash_type"} },
{ "blockchain", "pruneblockchain", &pruneblockchain, {"height"} },
{ "blockchain", "savemempool", &savemempool, {} },
{ "blockchain", "verifychain", &verifychain, {"checklevel","nblocks"} },
diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp
index 3045a74d7a..66ace7263a 100644
--- a/src/rpc/client.cpp
+++ b/src/rpc/client.cpp
@@ -217,7 +217,7 @@ UniValue ParseNonRFCJSONValue(const std::string& strVal)
UniValue jVal;
if (!jVal.read(std::string("[")+strVal+std::string("]")) ||
!jVal.isArray() || jVal.size()!=1)
- throw std::runtime_error(std::string("Error parsing JSON:")+strVal);
+ throw std::runtime_error(std::string("Error parsing JSON: ") + strVal);
return jVal[0];
}
diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp
index d5fc3f57bb..fee6a893eb 100644
--- a/src/rpc/mining.cpp
+++ b/src/rpc/mining.cpp
@@ -17,6 +17,7 @@
#include <policy/fees.h>
#include <pow.h>
#include <rpc/blockchain.h>
+#include <rpc/mining.h>
#include <rpc/server.h>
#include <rpc/util.h>
#include <script/descriptor.h>
@@ -207,7 +208,7 @@ static UniValue generatetodescriptor(const JSONRPCRequest& request)
{
{"num_blocks", RPCArg::Type::NUM, RPCArg::Optional::NO, "How many blocks are generated immediately."},
{"descriptor", RPCArg::Type::STR, RPCArg::Optional::NO, "The descriptor to send the newly generated bitcoin to."},
- {"maxtries", RPCArg::Type::NUM, /* default */ "1000000", "How many iterations to try."},
+ {"maxtries", RPCArg::Type::NUM, /* default */ ToString(DEFAULT_MAX_TRIES), "How many iterations to try."},
},
RPCResult{
RPCResult::Type::ARR, "", "hashes of blocks generated",
@@ -221,7 +222,7 @@ static UniValue generatetodescriptor(const JSONRPCRequest& request)
.Check(request);
const int num_blocks{request.params[0].get_int()};
- const int64_t max_tries{request.params[2].isNull() ? 1000000 : request.params[2].get_int()};
+ const uint64_t max_tries{request.params[2].isNull() ? DEFAULT_MAX_TRIES : request.params[2].get_int()};
CScript coinbase_script;
std::string error;
@@ -242,7 +243,7 @@ static UniValue generatetoaddress(const JSONRPCRequest& request)
{
{"nblocks", RPCArg::Type::NUM, RPCArg::Optional::NO, "How many blocks are generated immediately."},
{"address", RPCArg::Type::STR, RPCArg::Optional::NO, "The address to send the newly generated bitcoin to."},
- {"maxtries", RPCArg::Type::NUM, /* default */ "1000000", "How many iterations to try."},
+ {"maxtries", RPCArg::Type::NUM, /* default */ ToString(DEFAULT_MAX_TRIES), "How many iterations to try."},
},
RPCResult{
RPCResult::Type::ARR, "", "hashes of blocks generated",
@@ -257,11 +258,8 @@ static UniValue generatetoaddress(const JSONRPCRequest& request)
},
}.Check(request);
- int nGenerate = request.params[0].get_int();
- uint64_t nMaxTries = 1000000;
- if (!request.params[2].isNull()) {
- nMaxTries = request.params[2].get_int();
- }
+ const int num_blocks{request.params[0].get_int()};
+ const uint64_t max_tries{request.params[2].isNull() ? DEFAULT_MAX_TRIES : request.params[2].get_int()};
CTxDestination destination = DecodeDestination(request.params[1].get_str());
if (!IsValidDestination(destination)) {
@@ -273,7 +271,7 @@ static UniValue generatetoaddress(const JSONRPCRequest& request)
CScript coinbase_script = GetScriptForDestination(destination);
- return generateBlocks(chainman, mempool, coinbase_script, nGenerate, nMaxTries);
+ return generateBlocks(chainman, mempool, coinbase_script, num_blocks, max_tries);
}
static UniValue generateblock(const JSONRPCRequest& request)
@@ -371,7 +369,7 @@ static UniValue generateblock(const JSONRPCRequest& request)
}
uint256 block_hash;
- uint64_t max_tries{1000000};
+ uint64_t max_tries{DEFAULT_MAX_TRIES};
unsigned int extra_nonce{0};
if (!GenerateBlock(EnsureChainman(request.context), block, max_tries, extra_nonce, block_hash) || block_hash.IsNull()) {
@@ -875,7 +873,7 @@ static UniValue getblocktemplate(const JSONRPCRequest& request)
result.pushKV("height", (int64_t)(pindexPrev->nHeight+1));
if (!pblocktemplate->vchCoinbaseCommitment.empty()) {
- result.pushKV("default_witness_commitment", HexStr(pblocktemplate->vchCoinbaseCommitment.begin(), pblocktemplate->vchCoinbaseCommitment.end()));
+ result.pushKV("default_witness_commitment", HexStr(pblocktemplate->vchCoinbaseCommitment));
}
return result;
diff --git a/src/rpc/mining.h b/src/rpc/mining.h
new file mode 100644
index 0000000000..acc74e1dcc
--- /dev/null
+++ b/src/rpc/mining.h
@@ -0,0 +1,11 @@
+// Copyright (c) 2020 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_RPC_MINING_H
+#define BITCOIN_RPC_MINING_H
+
+/** Default max iterations to try in RPC generatetodescriptor, generatetoaddress, and generateblock. */
+static const uint64_t DEFAULT_MAX_TRIES{1000000};
+
+#endif // BITCOIN_RPC_MINING_H
diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp
index ce98a7c937..53d38f4e11 100644
--- a/src/rpc/misc.cpp
+++ b/src/rpc/misc.cpp
@@ -63,7 +63,7 @@ static UniValue validateaddress(const JSONRPCRequest& request)
ret.pushKV("address", currentAddress);
CScript scriptPubKey = GetScriptForDestination(dest);
- ret.pushKV("scriptPubKey", HexStr(scriptPubKey.begin(), scriptPubKey.end()));
+ ret.pushKV("scriptPubKey", HexStr(scriptPubKey));
UniValue detail = DescribeAddress(dest);
ret.pushKVs(detail);
@@ -131,7 +131,7 @@ static UniValue createmultisig(const JSONRPCRequest& request)
UniValue result(UniValue::VOBJ);
result.pushKV("address", EncodeDestination(dest));
- result.pushKV("redeemScript", HexStr(inner.begin(), inner.end()));
+ result.pushKV("redeemScript", HexStr(inner));
result.pushKV("descriptor", descriptor->ToString());
return result;
diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp
index df1e0fe623..9981ea35df 100644
--- a/src/rpc/net.cpp
+++ b/src/rpc/net.cpp
@@ -112,7 +112,7 @@ static UniValue getpeerinfo(const JSONRPCRequest& request)
{RPCResult::Type::BOOL, "inbound", "Inbound (true) or Outbound (false)"},
{RPCResult::Type::BOOL, "addnode", "Whether connection was due to addnode/-connect or if it was an automatic/inbound connection"},
{RPCResult::Type::NUM, "startingheight", "The starting height (block) of the peer"},
- {RPCResult::Type::NUM, "banscore", "The ban score"},
+ {RPCResult::Type::NUM, "banscore", "The ban score (DEPRECATED, returned only if config option -deprecatedrpc=banscore is passed)"},
{RPCResult::Type::NUM, "synced_headers", "The last header we have in common with this peer"},
{RPCResult::Type::NUM, "synced_blocks", "The last block we have in common with this peer"},
{RPCResult::Type::ARR, "inflight", "",
@@ -191,7 +191,10 @@ static UniValue getpeerinfo(const JSONRPCRequest& request)
obj.pushKV("addnode", stats.m_manual_connection);
obj.pushKV("startingheight", stats.nStartingHeight);
if (fStateStats) {
- obj.pushKV("banscore", statestats.nMisbehavior);
+ if (IsDeprecatedRPCEnabled("banscore")) {
+ // banscore is deprecated in v0.21 for removal in v0.22
+ obj.pushKV("banscore", statestats.nMisbehavior);
+ }
obj.pushKV("synced_headers", statestats.nSyncHeight);
obj.pushKV("synced_blocks", statestats.nCommonHeight);
UniValue heights(UniValue::VARR);
@@ -614,12 +617,12 @@ static UniValue setban(const JSONRPCRequest& request)
absolute = true;
if (isSubnet) {
- node.banman->Ban(subNet, BanReasonManuallyAdded, banTime, absolute);
+ node.banman->Ban(subNet, banTime, absolute);
if (node.connman) {
node.connman->DisconnectNode(subNet);
}
} else {
- node.banman->Ban(netAddr, BanReasonManuallyAdded, banTime, absolute);
+ node.banman->Ban(netAddr, banTime, absolute);
if (node.connman) {
node.connman->DisconnectNode(netAddr);
}
@@ -628,7 +631,7 @@ static UniValue setban(const JSONRPCRequest& request)
else if(strCommand == "remove")
{
if (!( isSubnet ? node.banman->Unban(subNet) : node.banman->Unban(netAddr) )) {
- throw JSONRPCError(RPC_CLIENT_INVALID_IP_OR_SUBNET, "Error: Unban failed. Requested address/subnet was not previously banned.");
+ throw JSONRPCError(RPC_CLIENT_INVALID_IP_OR_SUBNET, "Error: Unban failed. Requested address/subnet was not previously manually banned.");
}
}
return NullUniValue;
@@ -637,7 +640,7 @@ static UniValue setban(const JSONRPCRequest& request)
static UniValue listbanned(const JSONRPCRequest& request)
{
RPCHelpMan{"listbanned",
- "\nList all banned IPs/Subnets.\n",
+ "\nList all manually banned IPs/Subnets.\n",
{},
RPCResult{RPCResult::Type::ARR, "", "",
{
@@ -646,7 +649,6 @@ static UniValue listbanned(const JSONRPCRequest& request)
{RPCResult::Type::STR, "address", ""},
{RPCResult::Type::NUM_TIME, "banned_until", ""},
{RPCResult::Type::NUM_TIME, "ban_created", ""},
- {RPCResult::Type::STR, "ban_reason", ""},
}},
}},
RPCExamples{
@@ -671,7 +673,6 @@ static UniValue listbanned(const JSONRPCRequest& request)
rec.pushKV("address", entry.first.ToString());
rec.pushKV("banned_until", banEntry.nBanUntil);
rec.pushKV("ban_created", banEntry.nCreateTime);
- rec.pushKV("ban_reason", banEntry.banReasonToString());
bannedAddresses.push_back(rec);
}
diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp
index e14217c307..5f8c02df65 100644
--- a/src/rpc/rawtransaction.cpp
+++ b/src/rpc/rawtransaction.cpp
@@ -305,7 +305,7 @@ static UniValue gettxoutproof(const JSONRPCRequest& request)
CDataStream ssMB(SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS);
CMerkleBlock mb(block, setTxids);
ssMB << mb;
- std::string strHex = HexStr(ssMB.begin(), ssMB.end());
+ std::string strHex = HexStr(ssMB);
return strHex;
}
@@ -511,12 +511,12 @@ static UniValue decoderawtransaction(const JSONRPCRequest& request)
static std::string GetAllOutputTypes()
{
- std::string ret;
- for (int i = TX_NONSTANDARD; i <= TX_WITNESS_UNKNOWN; ++i) {
- if (i != TX_NONSTANDARD) ret += ", ";
- ret += GetTxnOutputType(static_cast<txnouttype>(i));
+ std::vector<std::string> ret;
+ using U = std::underlying_type<TxoutType>::type;
+ for (U i = (U)TxoutType::NONSTANDARD; i <= (U)TxoutType::WITNESS_UNKNOWN; ++i) {
+ ret.emplace_back(GetTxnOutputType(static_cast<TxoutType>(i)));
}
- return ret;
+ return Join(ret, ", ");
}
static UniValue decodescript(const JSONRPCRequest& request)
@@ -580,10 +580,10 @@ static UniValue decodescript(const JSONRPCRequest& request)
// is a witness program, don't return addresses for a segwit programs.
if (type.get_str() == "pubkey" || type.get_str() == "pubkeyhash" || type.get_str() == "multisig" || type.get_str() == "nonstandard") {
std::vector<std::vector<unsigned char>> solutions_data;
- txnouttype which_type = Solver(script, solutions_data);
+ TxoutType which_type = Solver(script, solutions_data);
// Uncompressed pubkeys cannot be used with segwit checksigs.
// If the script contains an uncompressed pubkey, skip encoding of a segwit program.
- if ((which_type == TX_PUBKEY) || (which_type == TX_MULTISIG)) {
+ if ((which_type == TxoutType::PUBKEY) || (which_type == TxoutType::MULTISIG)) {
for (const auto& solution : solutions_data) {
if ((solution.size() != 1) && !CPubKey(solution).IsCompressed()) {
return r;
@@ -592,10 +592,10 @@ static UniValue decodescript(const JSONRPCRequest& request)
}
UniValue sr(UniValue::VOBJ);
CScript segwitScr;
- if (which_type == TX_PUBKEY) {
+ if (which_type == TxoutType::PUBKEY) {
segwitScr = GetScriptForDestination(WitnessV0KeyHash(Hash160(solutions_data[0].begin(), solutions_data[0].end())));
- } else if (which_type == TX_PUBKEYHASH) {
- segwitScr = GetScriptForDestination(WitnessV0KeyHash(solutions_data[0]));
+ } else if (which_type == TxoutType::PUBKEYHASH) {
+ segwitScr = GetScriptForDestination(WitnessV0KeyHash(uint160{solutions_data[0]}));
} else {
// Scripts that are not fit for P2WPKH are encoded as P2WSH.
// Newer segwit program versions should be considered when then become available.
@@ -1104,6 +1104,7 @@ UniValue decodepsbt(const JSONRPCRequest& request)
const PSBTInput& input = psbtx.inputs[i];
UniValue in(UniValue::VOBJ);
// UTXOs
+ bool have_a_utxo = false;
if (!input.witness_utxo.IsNull()) {
const CTxOut& txout = input.witness_utxo;
@@ -1121,7 +1122,9 @@ UniValue decodepsbt(const JSONRPCRequest& request)
ScriptToUniv(txout.scriptPubKey, o, true);
out.pushKV("scriptPubKey", o);
in.pushKV("witness_utxo", out);
- } else if (input.non_witness_utxo) {
+ have_a_utxo = true;
+ }
+ if (input.non_witness_utxo) {
UniValue non_wit(UniValue::VOBJ);
TxToUniv(*input.non_witness_utxo, uint256(), non_wit, false);
in.pushKV("non_witness_utxo", non_wit);
@@ -1132,7 +1135,9 @@ UniValue decodepsbt(const JSONRPCRequest& request)
// Hack to just not show fee later
have_all_utxos = false;
}
- } else {
+ have_a_utxo = true;
+ }
+ if (!have_a_utxo) {
have_all_utxos = false;
}
@@ -1186,7 +1191,7 @@ UniValue decodepsbt(const JSONRPCRequest& request)
if (!input.final_script_witness.IsNull()) {
UniValue txinwitness(UniValue::VARR);
for (const auto& item : input.final_script_witness.stack) {
- txinwitness.push_back(HexStr(item.begin(), item.end()));
+ txinwitness.push_back(HexStr(item));
}
in.pushKV("final_scriptwitness", txinwitness);
}
diff --git a/src/rpc/rawtransaction_util.cpp b/src/rpc/rawtransaction_util.cpp
index bd82773bf2..1031716b4a 100644
--- a/src/rpc/rawtransaction_util.cpp
+++ b/src/rpc/rawtransaction_util.cpp
@@ -138,10 +138,10 @@ static void TxInErrorToJSON(const CTxIn& txin, UniValue& vErrorsRet, const std::
entry.pushKV("vout", (uint64_t)txin.prevout.n);
UniValue witness(UniValue::VARR);
for (unsigned int i = 0; i < txin.scriptWitness.stack.size(); i++) {
- witness.push_back(HexStr(txin.scriptWitness.stack[i].begin(), txin.scriptWitness.stack[i].end()));
+ witness.push_back(HexStr(txin.scriptWitness.stack[i]));
}
entry.pushKV("witness", witness);
- entry.pushKV("scriptSig", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()));
+ entry.pushKV("scriptSig", HexStr(txin.scriptSig));
entry.pushKV("sequence", (uint64_t)txin.nSequence);
entry.pushKV("error", strMessage);
vErrorsRet.push_back(entry);
diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp
index 844f62cbc6..de8791a935 100644
--- a/src/rpc/server.cpp
+++ b/src/rpc/server.cpp
@@ -20,10 +20,10 @@
#include <mutex>
#include <unordered_map>
-static RecursiveMutex cs_rpcWarmup;
+static Mutex g_rpc_warmup_mutex;
static std::atomic<bool> g_rpc_running{false};
-static bool fRPCInWarmup GUARDED_BY(cs_rpcWarmup) = true;
-static std::string rpcWarmupStatus GUARDED_BY(cs_rpcWarmup) = "RPC server started";
+static bool fRPCInWarmup GUARDED_BY(g_rpc_warmup_mutex) = true;
+static std::string rpcWarmupStatus GUARDED_BY(g_rpc_warmup_mutex) = "RPC server started";
/* Timer-creating functions */
static RPCTimerInterface* timerInterface = nullptr;
/* Map of name to timer. */
@@ -327,20 +327,20 @@ void RpcInterruptionPoint()
void SetRPCWarmupStatus(const std::string& newStatus)
{
- LOCK(cs_rpcWarmup);
+ LOCK(g_rpc_warmup_mutex);
rpcWarmupStatus = newStatus;
}
void SetRPCWarmupFinished()
{
- LOCK(cs_rpcWarmup);
+ LOCK(g_rpc_warmup_mutex);
assert(fRPCInWarmup);
fRPCInWarmup = false;
}
bool RPCIsInWarmup(std::string *outStatus)
{
- LOCK(cs_rpcWarmup);
+ LOCK(g_rpc_warmup_mutex);
if (outStatus)
*outStatus = rpcWarmupStatus;
return fRPCInWarmup;
@@ -439,7 +439,7 @@ UniValue CRPCTable::execute(const JSONRPCRequest &request) const
{
// Return immediately if in warmup
{
- LOCK(cs_rpcWarmup);
+ LOCK(g_rpc_warmup_mutex);
if (fRPCInWarmup)
throw JSONRPCError(RPC_IN_WARMUP, rpcWarmupStatus);
}
diff --git a/src/rpc/util.cpp b/src/rpc/util.cpp
index e7afef4cac..ca73c699c9 100644
--- a/src/rpc/util.cpp
+++ b/src/rpc/util.cpp
@@ -113,6 +113,23 @@ std::vector<unsigned char> ParseHexO(const UniValue& o, std::string strKey)
return ParseHexV(find_value(o, strKey), strKey);
}
+CoinStatsHashType ParseHashType(const UniValue& param, const CoinStatsHashType default_type)
+{
+ if (param.isNull()) {
+ return default_type;
+ } else {
+ std::string hash_type_input = param.get_str();
+
+ if (hash_type_input == "hash_serialized_2") {
+ return CoinStatsHashType::HASH_SERIALIZED;
+ } else if (hash_type_input == "none") {
+ return CoinStatsHashType::NONE;
+ } else {
+ throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("%d is not a valid hash_type", hash_type_input));
+ }
+ }
+}
+
std::string HelpExampleCli(const std::string& methodname, const std::string& args)
{
return "> bitcoin-cli " + methodname + " " + args + "\n";
@@ -224,7 +241,7 @@ public:
obj.pushKV("isscript", false);
obj.pushKV("iswitness", true);
obj.pushKV("witness_version", 0);
- obj.pushKV("witness_program", HexStr(id.begin(), id.end()));
+ obj.pushKV("witness_program", HexStr(id));
return obj;
}
@@ -234,7 +251,7 @@ public:
obj.pushKV("isscript", true);
obj.pushKV("iswitness", true);
obj.pushKV("witness_version", 0);
- obj.pushKV("witness_program", HexStr(id.begin(), id.end()));
+ obj.pushKV("witness_program", HexStr(id));
return obj;
}
diff --git a/src/rpc/util.h b/src/rpc/util.h
index 53dce2c397..96dd1ea74a 100644
--- a/src/rpc/util.h
+++ b/src/rpc/util.h
@@ -5,6 +5,7 @@
#ifndef BITCOIN_RPC_UTIL_H
#define BITCOIN_RPC_UTIL_H
+#include <node/coinstats.h>
#include <node/transaction.h>
#include <outputtype.h>
#include <protocol.h>
@@ -77,6 +78,8 @@ extern uint256 ParseHashO(const UniValue& o, std::string strKey);
extern std::vector<unsigned char> ParseHexV(const UniValue& v, std::string strName);
extern std::vector<unsigned char> ParseHexO(const UniValue& o, std::string strKey);
+CoinStatsHashType ParseHashType(const UniValue& param, const CoinStatsHashType default_type);
+
extern CAmount AmountFromValue(const UniValue& value);
extern std::string HelpExampleCli(const std::string& methodname, const std::string& args);
extern std::string HelpExampleRpc(const std::string& methodname, const std::string& args);