Skip to content

Commit c173da3

Browse files
committed
merge bitcoin#25412: add /deploymentinfo endpoint
1 parent af8cd61 commit c173da3

File tree

5 files changed

+71
-1
lines changed

5 files changed

+71
-1
lines changed

doc/REST-interface.md

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

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

doc/release-notes-6901.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: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -620,6 +620,48 @@ static bool rest_chaininfo(const CoreContext& context, HTTPRequest* req, const s
620620
}
621621
}
622622

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

src/rpc/blockchain.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1647,7 +1647,7 @@ UniValue DeploymentInfo(const CBlockIndex* blockindex, const CMNHFManager::Signa
16471647
}
16481648
} // anon namespace
16491649

1650-
static RPCHelpMan getdeploymentinfo()
1650+
RPCHelpMan getdeploymentinfo()
16511651
{
16521652
return RPCHelpMan{"getdeploymentinfo",
16531653
"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
@@ -388,6 +388,17 @@ def run_test(self):
388388
assert_equal(self.test_rest_request(f"/headers/{bb_hash}", query_params={"count": 1}), self.test_rest_request(f"/headers/1/{bb_hash}"))
389389
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}"))
390390

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

392403
if __name__ == '__main__':
393404
RESTTest().main()

0 commit comments

Comments
 (0)