aboutsummaryrefslogtreecommitdiff
path: root/src/rpc
diff options
context:
space:
mode:
Diffstat (limited to 'src/rpc')
-rw-r--r--src/rpc/blockchain.cpp67
-rw-r--r--src/rpc/mining.cpp18
-rw-r--r--src/rpc/misc.cpp3
-rw-r--r--src/rpc/net.cpp4
-rw-r--r--src/rpc/rawtransaction.cpp19
-rw-r--r--src/rpc/util.cpp10
6 files changed, 68 insertions, 53 deletions
diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp
index 03f28239ba..c4a89c9772 100644
--- a/src/rpc/blockchain.cpp
+++ b/src/rpc/blockchain.cpp
@@ -10,8 +10,11 @@
#include <chain.h>
#include <chainparams.h>
#include <coins.h>
+#include <consensus/params.h>
#include <consensus/validation.h>
#include <core_io.h>
+#include <deploymentinfo.h>
+#include <deploymentstatus.h>
#include <hash.h>
#include <index/blockfilterindex.h>
#include <index/coinstatsindex.h>
@@ -37,6 +40,7 @@
#include <util/translation.h>
#include <validation.h>
#include <validationinterface.h>
+#include <versionbits.h>
#include <warnings.h>
#include <stdint.h>
@@ -84,7 +88,6 @@ ChainstateManager& EnsureChainman(const NodeContext& node)
if (!node.chainman) {
throw JSONRPCError(RPC_INTERNAL_ERROR, "Node chainman not found");
}
- WITH_LOCK(::cs_main, CHECK_NONFATAL(std::addressof(g_chainman) == std::addressof(*node.chainman)));
return *node.chainman;
}
@@ -1196,7 +1199,7 @@ static RPCHelpMan gettxoutsetinfo()
CCoinsStats prev_stats{hash_type};
if (pindex->nHeight > 0) {
- GetUTXOStats(coins_view, WITH_LOCK(::cs_main, return std::ref(g_chainman.m_blockman)), prev_stats, node.rpc_interruption_point, pindex->pprev);
+ GetUTXOStats(coins_view, *blockman, prev_stats, node.rpc_interruption_point, pindex->pprev);
}
UniValue block_info(UniValue::VOBJ);
@@ -1344,32 +1347,29 @@ static RPCHelpMan verifychain()
};
}
-static void BuriedForkDescPushBack(UniValue& softforks, const std::string &name, int softfork_height, int tip_height) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
+static void SoftForkDescPushBack(const CBlockIndex* active_chain_tip, UniValue& softforks, const Consensus::Params& params, Consensus::BuriedDeployment dep)
{
// For buried deployments.
- // A buried deployment is one where the height of the activation has been hardcoded into
- // the client implementation long after the consensus change has activated. See BIP 90.
- // Buried deployments with activation height value of
- // std::numeric_limits<int>::max() are disabled and thus hidden.
- if (softfork_height == std::numeric_limits<int>::max()) return;
+
+ if (!DeploymentEnabled(params, dep)) return;
UniValue rv(UniValue::VOBJ);
rv.pushKV("type", "buried");
// getblockchaininfo reports the softfork as active from when the chain height is
// one below the activation height
- rv.pushKV("active", tip_height + 1 >= softfork_height);
- rv.pushKV("height", softfork_height);
- softforks.pushKV(name, rv);
+ rv.pushKV("active", DeploymentActiveAfter(active_chain_tip, params, dep));
+ rv.pushKV("height", params.DeploymentHeight(dep));
+ softforks.pushKV(DeploymentName(dep), rv);
}
-static void BIP9SoftForkDescPushBack(const CBlockIndex* active_chain_tip, UniValue& softforks, const std::string &name, const Consensus::Params& consensusParams, Consensus::DeploymentPos id) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
+static void SoftForkDescPushBack(const CBlockIndex* active_chain_tip, UniValue& softforks, const Consensus::Params& consensusParams, Consensus::DeploymentPos id)
{
// For BIP9 deployments.
- // Deployments that are never active are hidden.
- if (consensusParams.vDeployments[id].nStartTime == Consensus::BIP9Deployment::NEVER_ACTIVE) return;
+
+ if (!DeploymentEnabled(consensusParams, id)) return;
UniValue bip9(UniValue::VOBJ);
- const ThresholdState thresholdState = VersionBitsState(active_chain_tip, consensusParams, id, versionbitscache);
+ const ThresholdState thresholdState = g_versionbitscache.State(active_chain_tip, consensusParams, id);
switch (thresholdState) {
case ThresholdState::DEFINED: bip9.pushKV("status", "defined"); break;
case ThresholdState::STARTED: bip9.pushKV("status", "started"); break;
@@ -1383,12 +1383,12 @@ static void BIP9SoftForkDescPushBack(const CBlockIndex* active_chain_tip, UniVal
}
bip9.pushKV("start_time", consensusParams.vDeployments[id].nStartTime);
bip9.pushKV("timeout", consensusParams.vDeployments[id].nTimeout);
- int64_t since_height = VersionBitsStateSinceHeight(active_chain_tip, consensusParams, id, versionbitscache);
+ int64_t since_height = g_versionbitscache.StateSinceHeight(active_chain_tip, consensusParams, id);
bip9.pushKV("since", since_height);
if (ThresholdState::STARTED == thresholdState)
{
UniValue statsUV(UniValue::VOBJ);
- BIP9Stats statsStruct = VersionBitsStatistics(active_chain_tip, consensusParams, id);
+ BIP9Stats statsStruct = g_versionbitscache.Statistics(active_chain_tip, consensusParams, id);
statsUV.pushKV("period", statsStruct.period);
statsUV.pushKV("threshold", statsStruct.threshold);
statsUV.pushKV("elapsed", statsStruct.elapsed);
@@ -1406,7 +1406,7 @@ static void BIP9SoftForkDescPushBack(const CBlockIndex* active_chain_tip, UniVal
}
rv.pushKV("active", ThresholdState::ACTIVE == thresholdState);
- softforks.pushKV(name, rv);
+ softforks.pushKV(DeploymentName(id), rv);
}
RPCHelpMan getblockchaininfo()
@@ -1503,14 +1503,14 @@ RPCHelpMan getblockchaininfo()
const Consensus::Params& consensusParams = Params().GetConsensus();
UniValue softforks(UniValue::VOBJ);
- BuriedForkDescPushBack(softforks, "bip34", consensusParams.BIP34Height, height);
- BuriedForkDescPushBack(softforks, "bip66", consensusParams.BIP66Height, height);
- BuriedForkDescPushBack(softforks, "bip65", consensusParams.BIP65Height, height);
- BuriedForkDescPushBack(softforks, "csv", consensusParams.CSVHeight, height);
- BuriedForkDescPushBack(softforks, "segwit", consensusParams.SegwitHeight, height);
- BIP9SoftForkDescPushBack(tip, softforks, "testdummy", consensusParams, Consensus::DEPLOYMENT_TESTDUMMY);
- BIP9SoftForkDescPushBack(tip, softforks, "taproot", consensusParams, Consensus::DEPLOYMENT_TAPROOT);
- obj.pushKV("softforks", softforks);
+ SoftForkDescPushBack(tip, softforks, consensusParams, Consensus::DEPLOYMENT_HEIGHTINCB);
+ SoftForkDescPushBack(tip, softforks, consensusParams, Consensus::DEPLOYMENT_DERSIG);
+ SoftForkDescPushBack(tip, softforks, consensusParams, Consensus::DEPLOYMENT_CLTV);
+ SoftForkDescPushBack(tip, softforks, consensusParams, Consensus::DEPLOYMENT_CSV);
+ SoftForkDescPushBack(tip, softforks, consensusParams, Consensus::DEPLOYMENT_SEGWIT);
+ SoftForkDescPushBack(tip, softforks, consensusParams, Consensus::DEPLOYMENT_TESTDUMMY);
+ SoftForkDescPushBack(tip, softforks, consensusParams, Consensus::DEPLOYMENT_TAPROOT);
+ obj.pushKV("softforks", softforks);
obj.pushKV("warnings", GetWarnings(false).original);
return obj;
@@ -1707,7 +1707,7 @@ static RPCHelpMan preciousblock()
}
BlockValidationState state;
- chainman.ActiveChainstate().PreciousBlock(state, Params(), pblockindex);
+ chainman.ActiveChainstate().PreciousBlock(state, pblockindex);
if (!state.IsValid()) {
throw JSONRPCError(RPC_DATABASE_ERROR, state.ToString());
@@ -1744,10 +1744,10 @@ static RPCHelpMan invalidateblock()
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
}
}
- chainman.ActiveChainstate().InvalidateBlock(state, Params(), pblockindex);
+ chainman.ActiveChainstate().InvalidateBlock(state, pblockindex);
if (state.IsValid()) {
- chainman.ActiveChainstate().ActivateBestChain(state, Params());
+ chainman.ActiveChainstate().ActivateBestChain(state);
}
if (!state.IsValid()) {
@@ -1788,7 +1788,7 @@ static RPCHelpMan reconsiderblock()
}
BlockValidationState state;
- chainman.ActiveChainstate().ActivateBestChain(state, Params());
+ chainman.ActiveChainstate().ActivateBestChain(state);
if (!state.IsValid()) {
throw JSONRPCError(RPC_DATABASE_ERROR, state.ToString());
@@ -2259,6 +2259,7 @@ public:
if (g_scan_in_progress.exchange(true)) {
return false;
}
+ CHECK_NONFATAL(g_scan_progress == 0);
m_could_reserve = true;
return true;
}
@@ -2266,6 +2267,7 @@ public:
~CoinsViewScanReserver() {
if (m_could_reserve) {
g_scan_in_progress = false;
+ g_scan_progress = 0;
}
}
};
@@ -2382,7 +2384,6 @@ static RPCHelpMan scantxoutset()
std::vector<CTxOut> input_txos;
std::map<COutPoint, Coin> coins;
g_should_abort_scan = false;
- g_scan_progress = 0;
int64_t count = 0;
std::unique_ptr<CCoinsViewCursor> pcursor;
CBlockIndex* tip;
@@ -2392,7 +2393,7 @@ static RPCHelpMan scantxoutset()
LOCK(cs_main);
CChainState& active_chainstate = chainman.ActiveChainstate();
active_chainstate.ForceFlushStateToDisk();
- pcursor = std::unique_ptr<CCoinsViewCursor>(active_chainstate.CoinsDB().Cursor());
+ pcursor = active_chainstate.CoinsDB().Cursor();
CHECK_NONFATAL(pcursor);
tip = active_chainstate.m_chain.Tip();
CHECK_NONFATAL(tip);
@@ -2591,7 +2592,7 @@ UniValue CreateUTXOSnapshot(NodeContext& node, CChainState& chainstate, CAutoFil
throw JSONRPCError(RPC_INTERNAL_ERROR, "Unable to read UTXO set");
}
- pcursor = std::unique_ptr<CCoinsViewCursor>(chainstate.CoinsDB().Cursor());
+ pcursor = chainstate.CoinsDB().Cursor();
tip = chainstate.m_blockman.LookupBlockIndex(stats.hashBlock);
CHECK_NONFATAL(tip);
}
diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp
index 8190a2f006..692096367c 100644
--- a/src/rpc/mining.cpp
+++ b/src/rpc/mining.cpp
@@ -10,6 +10,8 @@
#include <consensus/params.h>
#include <consensus/validation.h>
#include <core_io.h>
+#include <deploymentinfo.h>
+#include <deploymentstatus.h>
#include <key_io.h>
#include <miner.h>
#include <net.h>
@@ -34,7 +36,6 @@
#include <util/translation.h>
#include <validation.h>
#include <validationinterface.h>
-#include <versionbitsinfo.h>
#include <warnings.h>
#include <memory>
@@ -114,7 +115,6 @@ static bool GenerateBlock(ChainstateManager& chainman, CBlock& block, uint64_t&
{
LOCK(cs_main);
- CHECK_NONFATAL(std::addressof(::ChainActive()) == std::addressof(chainman.ActiveChain()));
IncrementExtraNonce(&block, chainman.ActiveChain().Tip(), extra_nonce);
}
@@ -147,7 +147,6 @@ static UniValue generateBlocks(ChainstateManager& chainman, const CTxMemPool& me
{ // Don't keep cs_main locked
LOCK(cs_main);
- CHECK_NONFATAL(std::addressof(::ChainActive()) == std::addressof(chainman.ActiveChain()));
nHeight = chainman.ActiveChain().Height();
nHeightEnd = nHeight+nGenerate;
}
@@ -378,8 +377,7 @@ static RPCHelpMan generateblock()
// Add transactions
block.vtx.insert(block.vtx.end(), txs.begin(), txs.end());
- CBlockIndex* prev_block = WITH_LOCK(::cs_main, return chainman.m_blockman.LookupBlockIndex(block.hashPrevBlock));
- RegenerateCommitments(block, prev_block);
+ RegenerateCommitments(block, chainman);
{
LOCK(cs_main);
@@ -777,7 +775,7 @@ static RPCHelpMan getblocktemplate()
pblock->nNonce = 0;
// NOTE: If at some point we support pre-segwit miners post-segwit-activation, this needs to take segwit support into consideration
- const bool fPreSegWit = (pindexPrev->nHeight + 1 < consensusParams.SegwitHeight);
+ const bool fPreSegWit = !DeploymentActiveAfter(pindexPrev, consensusParams, Consensus::DEPLOYMENT_SEGWIT);
UniValue aCaps(UniValue::VARR); aCaps.push_back("proposal");
@@ -843,7 +841,7 @@ static RPCHelpMan getblocktemplate()
UniValue vbavailable(UniValue::VOBJ);
for (int j = 0; j < (int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; ++j) {
Consensus::DeploymentPos pos = Consensus::DeploymentPos(j);
- ThresholdState state = VersionBitsState(pindexPrev, consensusParams, pos, versionbitscache);
+ ThresholdState state = g_versionbitscache.State(pindexPrev, consensusParams, pos);
switch (state) {
case ThresholdState::DEFINED:
case ThresholdState::FAILED:
@@ -851,8 +849,8 @@ static RPCHelpMan getblocktemplate()
break;
case ThresholdState::LOCKED_IN:
// Ensure bit is set in block version
- pblock->nVersion |= VersionBitsMask(consensusParams, pos);
- // FALL THROUGH to get vbavailable set...
+ pblock->nVersion |= g_versionbitscache.Mask(consensusParams, pos);
+ [[fallthrough]];
case ThresholdState::STARTED:
{
const struct VBDeploymentInfo& vbinfo = VersionBitsDeploymentInfo[pos];
@@ -860,7 +858,7 @@ static RPCHelpMan getblocktemplate()
if (setClientRules.find(vbinfo.name) == setClientRules.end()) {
if (!vbinfo.gbt_force) {
// If the client doesn't support this, don't indicate it in the [default] version
- pblock->nVersion &= ~VersionBitsMask(consensusParams, pos);
+ pblock->nVersion &= ~g_versionbitscache.Mask(consensusParams, pos);
}
}
break;
diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp
index ab239fe79c..5178ce60e8 100644
--- a/src/rpc/misc.cpp
+++ b/src/rpc/misc.cpp
@@ -131,6 +131,9 @@ static RPCHelpMan createmultisig()
if (!ParseOutputType(request.params[2].get_str(), output_type)) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Unknown address type '%s'", request.params[2].get_str()));
}
+ if (output_type == OutputType::BECH32M) {
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "createmultisig cannot create bech32m multisig addresses");
+ }
}
// Construct using pay-to-script-hash:
diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp
index 50280915c3..dba0f971b2 100644
--- a/src/rpc/net.cpp
+++ b/src/rpc/net.cpp
@@ -242,6 +242,8 @@ static RPCHelpMan getpeerinfo()
heights.push_back(height);
}
obj.pushKV("inflight", heights);
+ obj.pushKV("addr_processed", statestats.m_addr_processed);
+ obj.pushKV("addr_rate_limited", statestats.m_addr_rate_limited);
}
UniValue permissions(UniValue::VARR);
for (const auto& permission : NetPermissions::ToStrings(stats.m_permissionFlags)) {
@@ -941,7 +943,7 @@ static RPCHelpMan addpeeraddress()
bool success{false};
if (LookupHost(addr_string, net_addr, false)) {
- CAddress address{CAddress({net_addr, port}, ServiceFlags(NODE_NETWORK | NODE_WITNESS))};
+ CAddress address{{net_addr, port}, ServiceFlags{NODE_NETWORK | NODE_WITNESS}};
address.nTime = GetAdjustedTime();
// The source address is set equal to the address. This is equivalent to the peer
// announcing itself.
diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp
index 339d711ac9..617dfec98f 100644
--- a/src/rpc/rawtransaction.cpp
+++ b/src/rpc/rawtransaction.cpp
@@ -753,7 +753,8 @@ static RPCHelpMan signrawtransactionwithkey()
},
},
},
- {"sighashtype", RPCArg::Type::STR, RPCArg::Default{"ALL"}, "The signature hash type. Must be one of:\n"
+ {"sighashtype", RPCArg::Type::STR, RPCArg::Default{"DEFAULT"}, "The signature hash type. Must be one of:\n"
+ " \"DEFAULT\"\n"
" \"ALL\"\n"
" \"NONE\"\n"
" \"SINGLE\"\n"
@@ -889,12 +890,11 @@ static RPCHelpMan testmempoolaccept()
"\nReturns result of mempool acceptance tests indicating if raw transaction(s) (serialized, hex-encoded) would be accepted by mempool.\n"
"\nIf multiple transactions are passed in, parents must come before children and package policies apply: the transactions cannot conflict with any mempool transactions or each other.\n"
"\nIf one transaction fails, other transactions may not be fully validated (the 'allowed' key will be blank).\n"
- "\nThe maximum number of transactions allowed is 25 (MAX_PACKAGE_COUNT)\n"
+ "\nThe maximum number of transactions allowed is " + ToString(MAX_PACKAGE_COUNT) + ".\n"
"\nThis checks if transactions violate the consensus or policy rules.\n"
"\nSee sendrawtransaction call.\n",
{
- {"rawtxs", RPCArg::Type::ARR, RPCArg::Optional::NO, "An array of hex strings of raw transactions.\n"
- " Length must be one for now.",
+ {"rawtxs", RPCArg::Type::ARR, RPCArg::Optional::NO, "An array of hex strings of raw transactions.",
{
{"rawtx", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, ""},
},
@@ -905,7 +905,7 @@ static RPCHelpMan testmempoolaccept()
RPCResult{
RPCResult::Type::ARR, "", "The result of the mempool acceptance test for each raw transaction in the input array.\n"
"Returns results for each transaction in the same order they were passed in.\n"
- "It is possible for transactions to not be fully validated ('allowed' unset) if an earlier transaction failed.\n",
+ "It is possible for transactions to not be fully validated ('allowed' unset) if another transaction failed.\n",
{
{RPCResult::Type::OBJ, "", "",
{
@@ -939,7 +939,6 @@ static RPCHelpMan testmempoolaccept()
UniValue::VARR,
UniValueType(), // VNUM or VSTR, checked inside AmountFromValue()
});
-
const UniValue raw_transactions = request.params[0].get_array();
if (raw_transactions.size() < 1 || raw_transactions.size() > MAX_PACKAGE_COUNT) {
throw JSONRPCError(RPC_INVALID_PARAMETER,
@@ -951,6 +950,7 @@ static RPCHelpMan testmempoolaccept()
CFeeRate(AmountFromValue(request.params[1]));
std::vector<CTransactionRef> txns;
+ txns.reserve(raw_transactions.size());
for (const auto& rawtx : raw_transactions.getValues()) {
CMutableTransaction mtx;
if (!DecodeHexTx(mtx, rawtx.get_str())) {
@@ -971,8 +971,8 @@ static RPCHelpMan testmempoolaccept()
}();
UniValue rpc_result(UniValue::VARR);
- // We will check transaction fees we iterate through txns in order. If any transaction fee
- // exceeds maxfeerate, we will keave the rest of the validation results blank, because it
+ // We will check transaction fees while we iterate through txns in order. If any transaction fee
+ // exceeds maxfeerate, we will leave the rest of the validation results blank, because it
// doesn't make sense to return a validation result for a transaction if its ancestor(s) would
// not be submitted.
bool exit_early{false};
@@ -1655,6 +1655,7 @@ static RPCHelpMan utxoupdatepsbt()
}
// Fill the inputs
+ const PrecomputedTransactionData txdata = PrecomputePSBTData(psbtx);
for (unsigned int i = 0; i < psbtx.tx->vin.size(); ++i) {
PSBTInput& input = psbtx.inputs.at(i);
@@ -1671,7 +1672,7 @@ static RPCHelpMan utxoupdatepsbt()
// Update script/keypath information using descriptor data.
// Note that SignPSBTInput does a lot more than just constructing ECDSA signatures
// we don't actually care about those here, in fact.
- SignPSBTInput(public_provider, psbtx, i, /* sighash_type */ 1);
+ SignPSBTInput(public_provider, psbtx, i, &txdata, /* sighash_type */ 1);
}
// Update script/keypath information using descriptor data.
diff --git a/src/rpc/util.cpp b/src/rpc/util.cpp
index 7cf25e0c82..2059628b54 100644
--- a/src/rpc/util.cpp
+++ b/src/rpc/util.cpp
@@ -301,6 +301,16 @@ public:
return obj;
}
+ UniValue operator()(const WitnessV1Taproot& tap) const
+ {
+ UniValue obj(UniValue::VOBJ);
+ obj.pushKV("isscript", true);
+ obj.pushKV("iswitness", true);
+ obj.pushKV("witness_version", 1);
+ obj.pushKV("witness_program", HexStr(tap));
+ return obj;
+ }
+
UniValue operator()(const WitnessUnknown& id) const
{
UniValue obj(UniValue::VOBJ);