rpc: move softfork info from getblockchaininfo to getdeploymentinfo

This commit is contained in:
Anthony Towns 2021-12-01 17:46:21 +10:00
parent 7908772244
commit fd826130a0
7 changed files with 95 additions and 36 deletions

View file

@ -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, },

View file

@ -120,6 +120,7 @@ const std::vector<std::string> RPC_COMMANDS_SAFE_FOR_FUZZING{
"getchaintips",
"getchaintxstats",
"getconnectioncount",
"getdeploymentinfo",
"getdescriptorinfo",
"getdifficulty",
"getindexinfo",

View file

@ -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",

View file

@ -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,

View file

@ -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):

View file

@ -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])

View file

@ -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):