Skip to content

Commit a352e11

Browse files
committed
merge bitcoin#25412: add /deploymentinfo endpoint
1 parent 71f20cf commit a352e11

File tree

5 files changed

+69
-1
lines changed

5 files changed

+69
-1
lines changed

doc/REST-interface.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,15 @@ Returns various state info regarding block chain processing.
8686
Only supports JSON as output format.
8787
Refer to the `getblockchaininfo` RPC help for details.
8888

89+
#### Deployment info
90+
`GET /rest/deploymentinfo.json`
91+
`GET /rest/deploymentinfo/<BLOCKHASH>.json`
92+
93+
Returns an object containing various state info regarding deployments of
94+
consensus changes at the current chain tip, or at <BLOCKHASH> if provided.
95+
Only supports JSON as output format.
96+
Refer to the `getdeploymentinfo` RPC help for details.
97+
8998
#### Query UTXO set
9099
- `GET /rest/getutxos/<TXID>-<N>/<TXID>-<N>/.../<TXID>-<N>.<bin|hex|json>`
91100
- `GET /rest/getutxos/checkmempool/<TXID>-<N>/<TXID>-<N>/.../<TXID>-<N>.<bin|hex|json>`

doc/release-notes-6888.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,9 @@ Updated RPCs
99
a future release. Note that in either case, the `status` field
1010
now reflects the status of the current block rather than the next
1111
block.
12+
13+
New REST endpoint
14+
-----------------
15+
16+
- A new `/rest/deploymentinfo` endpoint has been added for fetching various
17+
state info regarding deployments of consensus changes.

src/rest.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -620,6 +620,46 @@ static bool rest_chaininfo(const CoreContext& context, HTTPRequest* req, const s
620620
}
621621
}
622622

623+
RPCHelpMan getdeploymentinfo();
624+
625+
static bool rest_deploymentinfo(const CoreContext& context, HTTPRequest* req, const std::string& str_uri_part)
626+
{
627+
if (!CheckWarmup(req)) return false;
628+
629+
std::string hash_str;
630+
const RESTResponseFormat rf = ParseDataFormat(hash_str, str_uri_part);
631+
632+
switch (rf) {
633+
case RESTResponseFormat::JSON: {
634+
JSONRPCRequest jsonRequest;
635+
jsonRequest.context = context;
636+
jsonRequest.params = UniValue(UniValue::VARR);
637+
638+
if (!hash_str.empty()) {
639+
uint256 hash;
640+
if (!ParseHashStr(hash_str, hash)) {
641+
return RESTERR(req, HTTP_BAD_REQUEST, "Invalid hash: " + hash_str);
642+
}
643+
644+
const ChainstateManager* chainman = GetChainman(context, req);
645+
if (!chainman) return false;
646+
if (!WITH_LOCK(::cs_main, return chainman->m_blockman.LookupBlockIndex(ParseHashV(hash_str, "blockhash")))) {
647+
return RESTERR(req, HTTP_BAD_REQUEST, "Block not found");
648+
}
649+
650+
jsonRequest.params.pushKV("blockhash", hash_str);
651+
}
652+
653+
req->WriteHeader("Content-Type", "application/json");
654+
req->WriteReply(HTTP_OK, getdeploymentinfo().HandleRequest(jsonRequest).write() + "\n");
655+
return true;
656+
}
657+
default: {
658+
return RESTERR(req, HTTP_NOT_FOUND, "output format not found (available: json)");
659+
}
660+
}
661+
}
662+
623663
static bool rest_mempool(const CoreContext& context, HTTPRequest* req, const std::string& str_uri_part)
624664
{
625665
if (!CheckWarmup(req))
@@ -968,6 +1008,8 @@ static const struct {
9681008
{"/rest/mempool/", rest_mempool},
9691009
{"/rest/headers/", rest_headers},
9701010
{"/rest/getutxos", rest_getutxos},
1011+
{"/rest/deploymentinfo/", rest_deploymentinfo},
1012+
{"/rest/deploymentinfo", rest_deploymentinfo},
9711013
{"/rest/blockhashbyheight/", rest_blockhash_by_height},
9721014
};
9731015

src/rpc/blockchain.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1657,7 +1657,7 @@ UniValue DeploymentInfo(const CBlockIndex* blockindex, const CMNHFManager::Signa
16571657
}
16581658
} // anon namespace
16591659

1660-
static RPCHelpMan getdeploymentinfo()
1660+
RPCHelpMan getdeploymentinfo()
16611661
{
16621662
return RPCHelpMan{"getdeploymentinfo",
16631663
"Returns an object containing various state info regarding deployments of consensus changes.",

test/functional/interface_rest.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,17 @@ def run_test(self):
391391
assert_equal(self.test_rest_request(f"/headers/{bb_hash}", query_params={"count": 1}), self.test_rest_request(f"/headers/1/{bb_hash}"))
392392
assert_equal(self.test_rest_request(f"/blockfilterheaders/basic/{bb_hash}", query_params={"count": 1}), self.test_rest_request(f"/blockfilterheaders/basic/5/{bb_hash}"))
393393

394+
self.log.info("Test the /deploymentinfo URI")
395+
396+
deployment_info = self.nodes[0].getdeploymentinfo()
397+
assert_equal(deployment_info, self.test_rest_request('/deploymentinfo'))
398+
399+
non_existing_blockhash = '42759cde25462784395a337460bde75f58e73d3f08bd31fdc3507cbac856a2c4'
400+
resp = self.test_rest_request(f'/deploymentinfo/{non_existing_blockhash}', ret_type=RetType.OBJ, status=400)
401+
assert_equal(resp.read().decode('utf-8').rstrip(), "Block not found")
402+
403+
resp = self.test_rest_request(f"/deploymentinfo/{INVALID_PARAM}", ret_type=RetType.OBJ, status=400)
404+
assert_equal(resp.read().decode('utf-8').rstrip(), f"Invalid hash: {INVALID_PARAM}")
394405

395406
if __name__ == '__main__':
396407
RESTTest().main()

0 commit comments

Comments
 (0)