aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/rpc/blockchain.cpp109
-rw-r--r--src/test/fuzz/rpc.cpp1
-rwxr-xr-xtest/functional/feature_cltv.py2
-rwxr-xr-xtest/functional/feature_dersig.py2
-rwxr-xr-xtest/functional/rpc_blockchain.py11
-rwxr-xr-xtest/functional/rpc_signrawtransaction.py4
-rw-r--r--test/functional/test_framework/util.py2
7 files changed, 95 insertions, 36 deletions
diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp
index 827b3a7da3..303fd2d70d 100644
--- a/src/rpc/blockchain.cpp
+++ b/src/rpc/blockchain.cpp
@@ -1400,7 +1400,7 @@ static void SoftForkDescPushBack(const CBlockIndex* active_chain_tip, UniValue&
UniValue rv(UniValue::VOBJ);
rv.pushKV("type", "buried");
- // getblockchaininfo reports the softfork as active from when the chain height is
+ // getdeploymentinfo reports the softfork as active from when the chain height is
// one below the activation height
rv.pushKV("active", DeploymentActiveAfter(active_chain_tip, params, dep));
rv.pushKV("height", params.DeploymentHeight(dep));
@@ -1455,8 +1455,16 @@ static void SoftForkDescPushBack(const CBlockIndex* active_chain_tip, UniValue&
softforks.pushKV(DeploymentName(id), rv);
}
+namespace {
+/* TODO: when -dprecatedrpc=softforks is removed, drop these */
+UniValue DeploymentInfo(const CBlockIndex* tip, const Consensus::Params& consensusParams);
+extern const std::vector<RPCResult> RPCHelpForDeployment;
+}
+
+// used by rest.cpp:rest_chaininfo, so cannot be static
RPCHelpMan getblockchaininfo()
{
+ /* TODO: from v24, remove -deprecatedrpc=softforks */
return RPCHelpMan{"getblockchaininfo",
"Returns an object containing various state info regarding blockchain processing.\n",
{},
@@ -1478,31 +1486,11 @@ RPCHelpMan getblockchaininfo()
{RPCResult::Type::NUM, "pruneheight", /*optional=*/true, "lowest-height complete block stored (only present if pruning is enabled)"},
{RPCResult::Type::BOOL, "automatic_pruning", /*optional=*/true, "whether automatic pruning is enabled (only present if pruning is enabled)"},
{RPCResult::Type::NUM, "prune_target_size", /*optional=*/true, "the target size used by pruning (only present if automatic pruning is enabled)"},
- {RPCResult::Type::OBJ_DYN, "softforks", "status of softforks",
+ {RPCResult::Type::OBJ_DYN, "softforks", "(DEPRECATED, returned only if config option -deprecatedrpc=softforks is passed) status of softforks",
{
{RPCResult::Type::OBJ, "xxxx", "name of the softfork",
- {
- {RPCResult::Type::STR, "type", "one of \"buried\", \"bip9\""},
- {RPCResult::Type::OBJ, "bip9", /*optional=*/true, "status of bip9 softforks (only for \"bip9\" type)",
- {
- {RPCResult::Type::STR, "status", "one of \"defined\", \"started\", \"locked_in\", \"active\", \"failed\""},
- {RPCResult::Type::NUM, "bit", /*optional=*/true, "the bit (0-28) in the block version field used to signal this softfork (only for \"started\" and \"locked_in\" status)"},
- {RPCResult::Type::NUM_TIME, "start_time", "the minimum median time past of a block at which the bit gains its meaning"},
- {RPCResult::Type::NUM_TIME, "timeout", "the median time past of a block at which the deployment is considered failed if not yet locked in"},
- {RPCResult::Type::NUM, "since", "height of the first block to which the status applies"},
- {RPCResult::Type::NUM, "min_activation_height", "minimum height of blocks for which the rules may be enforced"},
- {RPCResult::Type::OBJ, "statistics", /*optional=*/true, "numeric statistics about signalling for a softfork (only for \"started\" and \"locked_in\" status)",
- {
- {RPCResult::Type::NUM, "period", "the length in blocks of the signalling period"},
- {RPCResult::Type::NUM, "threshold", /*optional=*/true, "the number of blocks with the version bit set required to activate the feature (only for \"started\" status)"},
- {RPCResult::Type::NUM, "elapsed", "the number of blocks elapsed since the beginning of the current period"},
- {RPCResult::Type::NUM, "count", "the number of blocks with the version bit set in the current period"},
- {RPCResult::Type::BOOL, "possible", /*optional=*/true, "returns false if there are not enough blocks left in this period to pass activation threshold (only for \"started\" status)"},
- }},
- }},
- {RPCResult::Type::NUM, "height", /*optional=*/true, "height of the first block which the rules are or will be enforced (only for \"buried\" type, or \"bip9\" type with \"active\" status)"},
- {RPCResult::Type::BOOL, "active", "true if the rules are enforced for the mempool and the next block"},
- }},
+ RPCHelpForDeployment
+ },
}},
{RPCResult::Type::STR, "warnings", "any network and blockchain warnings"},
}},
@@ -1549,7 +1537,43 @@ RPCHelpMan getblockchaininfo()
}
}
- const Consensus::Params& consensusParams = Params().GetConsensus();
+ if (IsDeprecatedRPCEnabled("softforks")) {
+ const Consensus::Params& consensusParams = Params().GetConsensus();
+ obj.pushKV("softforks", DeploymentInfo(tip, consensusParams));
+ }
+
+ obj.pushKV("warnings", GetWarnings(false).original);
+ return obj;
+},
+ };
+}
+
+namespace {
+const std::vector<RPCResult> RPCHelpForDeployment{
+ {RPCResult::Type::STR, "type", "one of \"buried\", \"bip9\""},
+ {RPCResult::Type::OBJ, "bip9", /*optional=*/true, "status of bip9 softforks (only for \"bip9\" type)",
+ {
+ {RPCResult::Type::STR, "status", "one of \"defined\", \"started\", \"locked_in\", \"active\", \"failed\""},
+ {RPCResult::Type::NUM, "bit", /*optional=*/true, "the bit (0-28) in the block version field used to signal this softfork (only for \"started\" and \"locked_in\" status)"},
+ {RPCResult::Type::NUM_TIME, "start_time", "the minimum median time past of a block at which the bit gains its meaning"},
+ {RPCResult::Type::NUM_TIME, "timeout", "the median time past of a block at which the deployment is considered failed if not yet locked in"},
+ {RPCResult::Type::NUM, "since", "height of the first block to which the status applies"},
+ {RPCResult::Type::NUM, "min_activation_height", "minimum height of blocks for which the rules may be enforced"},
+ {RPCResult::Type::OBJ, "statistics", /*optional=*/true, "numeric statistics about signalling for a softfork (only for \"started\" and \"locked_in\" status)",
+ {
+ {RPCResult::Type::NUM, "period", "the length in blocks of the signalling period"},
+ {RPCResult::Type::NUM, "threshold", /*optional=*/true, "the number of blocks with the version bit set required to activate the feature (only for \"started\" status)"},
+ {RPCResult::Type::NUM, "elapsed", "the number of blocks elapsed since the beginning of the current period"},
+ {RPCResult::Type::NUM, "count", "the number of blocks with the version bit set in the current period"},
+ {RPCResult::Type::BOOL, "possible", /*optional=*/true, "returns false if there are not enough blocks left in this period to pass activation threshold (only for \"started\" status)"},
+ }},
+ }},
+ {RPCResult::Type::NUM, "height", /*optional=*/true, "height of the first block which the rules are or will be enforced (only for \"buried\" type, or \"bip9\" type with \"active\" status)"},
+ {RPCResult::Type::BOOL, "active", "true if the rules are enforced for the mempool and the next block"},
+};
+
+UniValue DeploymentInfo(const CBlockIndex* tip, const Consensus::Params& consensusParams)
+{
UniValue softforks(UniValue::VOBJ);
SoftForkDescPushBack(tip, softforks, consensusParams, Consensus::DEPLOYMENT_HEIGHTINCB);
SoftForkDescPushBack(tip, softforks, consensusParams, Consensus::DEPLOYMENT_DERSIG);
@@ -1558,11 +1582,37 @@ RPCHelpMan getblockchaininfo()
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);
+ return softforks;
+}
+} // anon namespace
- obj.pushKV("warnings", GetWarnings(false).original);
- return obj;
-},
+static RPCHelpMan getdeploymentinfo()
+{
+ return RPCHelpMan{"getdeploymentinfo",
+ "Returns an object containing various state info regarding soft-forks.",
+ {},
+ RPCResult{
+ RPCResult::Type::OBJ, "", "", {
+ {RPCResult::Type::OBJ, "deployments", "", {
+ {RPCResult::Type::OBJ, "xxxx", "name of the deployment", RPCHelpForDeployment}
+ }},
+ }
+ },
+ RPCExamples{ HelpExampleCli("getdeploymentinfo", "") + HelpExampleRpc("getdeploymentinfo", "") },
+ [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
+ {
+ ChainstateManager& chainman = EnsureAnyChainman(request.context);
+ LOCK(cs_main);
+ CChainState& active_chainstate = chainman.ActiveChainstate();
+
+ const CBlockIndex* tip = active_chainstate.m_chain.Tip();
+ CHECK_NONFATAL(tip);
+ const Consensus::Params& consensusParams = Params().GetConsensus();
+
+ UniValue deploymentinfo(UniValue::VOBJ);
+ deploymentinfo.pushKV("deployments", DeploymentInfo(tip, consensusParams));
+ return deploymentinfo;
+ },
};
}
@@ -2716,6 +2766,7 @@ static const CRPCCommand commands[] =
{ "blockchain", &getblockheader, },
{ "blockchain", &getchaintips, },
{ "blockchain", &getdifficulty, },
+ { "blockchain", &getdeploymentinfo, },
{ "blockchain", &getmempoolancestors, },
{ "blockchain", &getmempooldescendants, },
{ "blockchain", &getmempoolentry, },
diff --git a/src/test/fuzz/rpc.cpp b/src/test/fuzz/rpc.cpp
index b6ecf1c492..e1d371b7f8 100644
--- a/src/test/fuzz/rpc.cpp
+++ b/src/test/fuzz/rpc.cpp
@@ -120,6 +120,7 @@ const std::vector<std::string> RPC_COMMANDS_SAFE_FOR_FUZZING{
"getchaintips",
"getchaintxstats",
"getconnectioncount",
+ "getdeploymentinfo",
"getdescriptorinfo",
"getdifficulty",
"getindexinfo",
diff --git a/test/functional/feature_cltv.py b/test/functional/feature_cltv.py
index eb90b2c598..77e8545260 100755
--- a/test/functional/feature_cltv.py
+++ b/test/functional/feature_cltv.py
@@ -91,7 +91,7 @@ class BIP65Test(BitcoinTestFramework):
self.rpc_timeout = 480
def test_cltv_info(self, *, is_active):
- assert_equal(self.nodes[0].getblockchaininfo()['softforks']['bip65'], {
+ assert_equal(self.nodes[0].getdeploymentinfo()['deployments']['bip65'], {
"active": is_active,
"height": CLTV_HEIGHT,
"type": "buried",
diff --git a/test/functional/feature_dersig.py b/test/functional/feature_dersig.py
index b7cb32c842..1f57b15077 100755
--- a/test/functional/feature_dersig.py
+++ b/test/functional/feature_dersig.py
@@ -60,7 +60,7 @@ class BIP66Test(BitcoinTestFramework):
return self.miniwallet.create_self_transfer(from_node=self.nodes[0], utxo_to_spend=utxo_to_spend)['tx']
def test_dersig_info(self, *, is_active):
- assert_equal(self.nodes[0].getblockchaininfo()['softforks']['bip66'],
+ assert_equal(self.nodes[0].getdeploymentinfo()['deployments']['bip66'],
{
"active": is_active,
"height": DERSIG_HEIGHT,
diff --git a/test/functional/rpc_blockchain.py b/test/functional/rpc_blockchain.py
index 8f7d5114fa..9b9f989b04 100755
--- a/test/functional/rpc_blockchain.py
+++ b/test/functional/rpc_blockchain.py
@@ -6,6 +6,7 @@
Test the following RPCs:
- getblockchaininfo
+ - getdeploymentinfo
- getchaintxstats
- gettxoutsetinfo
- getblockheader
@@ -71,6 +72,7 @@ class BlockchainTest(BitcoinTestFramework):
self.restart_node(0, extra_args=['-stopatheight=207', '-prune=1']) # Set extra args with pruning after rescan is complete
self._test_getblockchaininfo()
+ self._test_getdeploymentinfo()
self._test_getchaintxstats()
self._test_gettxoutsetinfo()
self._test_getblockheader()
@@ -115,7 +117,6 @@ class BlockchainTest(BitcoinTestFramework):
'mediantime',
'pruned',
'size_on_disk',
- 'softforks',
'time',
'verificationprogress',
'warnings',
@@ -177,7 +178,12 @@ class BlockchainTest(BitcoinTestFramework):
assert_equal(res['prune_target_size'], 576716800)
assert_greater_than(res['size_on_disk'], 0)
- assert_equal(res['softforks'], {
+ def _test_getdeploymentinfo(self):
+ self.log.info("Test getdeploymentinfo")
+
+ res = self.nodes[0].getdeploymentinfo()
+ assert_equal(res, {
+ "deployments": {
'bip34': {'type': 'buried', 'active': True, 'height': 2},
'bip66': {'type': 'buried', 'active': True, 'height': 3},
'bip65': {'type': 'buried', 'active': True, 'height': 4},
@@ -214,6 +220,7 @@ class BlockchainTest(BitcoinTestFramework):
'height': 0,
'active': True
}
+ }
})
def _test_getchaintxstats(self):
diff --git a/test/functional/rpc_signrawtransaction.py b/test/functional/rpc_signrawtransaction.py
index e648040278..a2091b4ece 100755
--- a/test/functional/rpc_signrawtransaction.py
+++ b/test/functional/rpc_signrawtransaction.py
@@ -270,7 +270,7 @@ class SignRawTransactionsTest(BitcoinTestFramework):
getcontext().prec = 8
# Make sure CSV is active
- assert self.nodes[0].getblockchaininfo()['softforks']['csv']['active']
+ assert self.nodes[0].getdeploymentinfo()['deployments']['csv']['active']
# Create a P2WSH script with CSV
script = CScript([1, OP_CHECKSEQUENCEVERIFY, OP_DROP])
@@ -305,7 +305,7 @@ class SignRawTransactionsTest(BitcoinTestFramework):
getcontext().prec = 8
# Make sure CLTV is active
- assert self.nodes[0].getblockchaininfo()['softforks']['bip65']['active']
+ assert self.nodes[0].getdeploymentinfo()['deployments']['bip65']['active']
# Create a P2WSH script with CLTV
script = CScript([100, OP_CHECKLOCKTIMEVERIFY, OP_DROP])
diff --git a/test/functional/test_framework/util.py b/test/functional/test_framework/util.py
index c3a9029d55..059d3c3526 100644
--- a/test/functional/test_framework/util.py
+++ b/test/functional/test_framework/util.py
@@ -438,7 +438,7 @@ def delete_cookie_file(datadir, chain):
def softfork_active(node, key):
"""Return whether a softfork is active."""
- return node.getblockchaininfo()['softforks'][key]['active']
+ return node.getdeploymentinfo()['deployments'][key]['active']
def set_node_times(nodes, t):