mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-21 14:34:49 +01:00
Merge bitcoin/bitcoin#25412: rest: add /deploymentinfo
endpoint
a8250e30f1
doc: add release note about `/rest/deploymentinfo` (brunoerg)5c96020024
doc: add `/deploymentinfo` in REST-interface (brunoerg)3e44bee08e
test: add coverage for `/rest/deploymentinfo` (brunoerg)91497031cb
rest: add `/deploymentinfo` (brunoerg) Pull request description: #23508 added a new RPC named `getdeploymentinfo`, it moved the softfork section from `getblockchaininfo` into this new one. In the REST interface, we have an endpoint named`/rest/chaininfo.json` (which refers to `getblockchaininfo`), so, this PR adds a new REST endpoint named `/deploymentinfo` which refers to `getdeploymentinfo`. You can use it by passing a block hash, e.g: '/rest/deploymentinfo/<BLOCKHASH>.json' or you can use it without passing a block hash to get the 'deploymentinfo' for the last block. ACKs for top commit: jonatack: re-ACKa8250e30f1
rebase-only since my last review at c65f82bb achow101: ACKa8250e30f1
stickies-v: re-ACKa8250e30f1
Tree-SHA512: 0735183b6828d51a72ed0e2be5a09b314ac4693f548982c6e9adaa0ef07a55aa428d3b2d1b1de70b83169811a663a8624b686166e5797f624dcc00178b9796e6
This commit is contained in:
commit
92be831847
5 changed files with 70 additions and 1 deletions
|
@ -86,6 +86,15 @@ Returns various state info regarding block chain processing.
|
||||||
Only supports JSON as output format.
|
Only supports JSON as output format.
|
||||||
Refer to the `getblockchaininfo` RPC help for details.
|
Refer to the `getblockchaininfo` RPC help for details.
|
||||||
|
|
||||||
|
#### Deployment info
|
||||||
|
`GET /rest/deploymentinfo.json`
|
||||||
|
`GET /rest/deploymentinfo/<BLOCKHASH>.json`
|
||||||
|
|
||||||
|
Returns an object containing various state info regarding deployments of
|
||||||
|
consensus changes at the current chain tip, or at <BLOCKHASH> if provided.
|
||||||
|
Only supports JSON as output format.
|
||||||
|
Refer to the `getdeploymentinfo` RPC help for details.
|
||||||
|
|
||||||
#### Query UTXO set
|
#### Query UTXO set
|
||||||
- `GET /rest/getutxos/<TXID>-<N>/<TXID>-<N>/.../<TXID>-<N>.<bin|hex|json>`
|
- `GET /rest/getutxos/<TXID>-<N>/<TXID>-<N>/.../<TXID>-<N>.<bin|hex|json>`
|
||||||
- `GET /rest/getutxos/checkmempool/<TXID>-<N>/<TXID>-<N>/.../<TXID>-<N>.<bin|hex|json>`
|
- `GET /rest/getutxos/checkmempool/<TXID>-<N>/<TXID>-<N>/.../<TXID>-<N>.<bin|hex|json>`
|
||||||
|
|
5
doc/release-notes-25412.md
Normal file
5
doc/release-notes-25412.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
New REST endpoint
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
- A new `/rest/deploymentinfo` endpoint has been added for fetching various
|
||||||
|
state info regarding deployments of consensus changes. (#25412)
|
44
src/rest.cpp
44
src/rest.cpp
|
@ -590,6 +590,48 @@ static bool rest_chaininfo(const std::any& context, HTTPRequest* req, const std:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
RPCHelpMan getdeploymentinfo();
|
||||||
|
|
||||||
|
static bool rest_deploymentinfo(const std::any& context, HTTPRequest* req, const std::string& str_uri_part)
|
||||||
|
{
|
||||||
|
if (!CheckWarmup(req)) return false;
|
||||||
|
|
||||||
|
std::string hash_str;
|
||||||
|
const RESTResponseFormat rf = ParseDataFormat(hash_str, str_uri_part);
|
||||||
|
|
||||||
|
switch (rf) {
|
||||||
|
case RESTResponseFormat::JSON: {
|
||||||
|
JSONRPCRequest jsonRequest;
|
||||||
|
jsonRequest.context = context;
|
||||||
|
jsonRequest.params = UniValue(UniValue::VARR);
|
||||||
|
|
||||||
|
if (!hash_str.empty()) {
|
||||||
|
uint256 hash;
|
||||||
|
if (!ParseHashStr(hash_str, hash)) {
|
||||||
|
return RESTERR(req, HTTP_BAD_REQUEST, "Invalid hash: " + hash_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
const ChainstateManager* chainman = GetChainman(context, req);
|
||||||
|
if (!chainman) return false;
|
||||||
|
if (!WITH_LOCK(::cs_main, return chainman->m_blockman.LookupBlockIndex(ParseHashV(hash_str, "blockhash")))) {
|
||||||
|
return RESTERR(req, HTTP_BAD_REQUEST, "Block not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
jsonRequest.params.pushKV("blockhash", hash_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
req->WriteHeader("Content-Type", "application/json");
|
||||||
|
req->WriteReply(HTTP_OK, getdeploymentinfo().HandleRequest(jsonRequest).write() + "\n");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
return RESTERR(req, HTTP_NOT_FOUND, "output format not found (available: json)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
static bool rest_mempool(const std::any& context, HTTPRequest* req, const std::string& str_uri_part)
|
static bool rest_mempool(const std::any& context, HTTPRequest* req, const std::string& str_uri_part)
|
||||||
{
|
{
|
||||||
if (!CheckWarmup(req))
|
if (!CheckWarmup(req))
|
||||||
|
@ -939,6 +981,8 @@ static const struct {
|
||||||
{"/rest/mempool/", rest_mempool},
|
{"/rest/mempool/", rest_mempool},
|
||||||
{"/rest/headers/", rest_headers},
|
{"/rest/headers/", rest_headers},
|
||||||
{"/rest/getutxos", rest_getutxos},
|
{"/rest/getutxos", rest_getutxos},
|
||||||
|
{"/rest/deploymentinfo/", rest_deploymentinfo},
|
||||||
|
{"/rest/deploymentinfo", rest_deploymentinfo},
|
||||||
{"/rest/blockhashbyheight/", rest_blockhash_by_height},
|
{"/rest/blockhashbyheight/", rest_blockhash_by_height},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1307,7 +1307,7 @@ UniValue DeploymentInfo(const CBlockIndex* blockindex, const ChainstateManager&
|
||||||
}
|
}
|
||||||
} // anon namespace
|
} // anon namespace
|
||||||
|
|
||||||
static RPCHelpMan getdeploymentinfo()
|
RPCHelpMan getdeploymentinfo()
|
||||||
{
|
{
|
||||||
return RPCHelpMan{"getdeploymentinfo",
|
return RPCHelpMan{"getdeploymentinfo",
|
||||||
"Returns an object containing various state info regarding deployments of consensus changes.",
|
"Returns an object containing various state info regarding deployments of consensus changes.",
|
||||||
|
|
|
@ -387,6 +387,17 @@ class RESTTest (BitcoinTestFramework):
|
||||||
assert_equal(self.test_rest_request(f"/headers/{bb_hash}", query_params={"count": 1}), self.test_rest_request(f"/headers/1/{bb_hash}"))
|
assert_equal(self.test_rest_request(f"/headers/{bb_hash}", query_params={"count": 1}), self.test_rest_request(f"/headers/1/{bb_hash}"))
|
||||||
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}"))
|
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}"))
|
||||||
|
|
||||||
|
self.log.info("Test the /deploymentinfo URI")
|
||||||
|
|
||||||
|
deployment_info = self.nodes[0].getdeploymentinfo()
|
||||||
|
assert_equal(deployment_info, self.test_rest_request('/deploymentinfo'))
|
||||||
|
|
||||||
|
non_existing_blockhash = '42759cde25462784395a337460bde75f58e73d3f08bd31fdc3507cbac856a2c4'
|
||||||
|
resp = self.test_rest_request(f'/deploymentinfo/{non_existing_blockhash}', ret_type=RetType.OBJ, status=400)
|
||||||
|
assert_equal(resp.read().decode('utf-8').rstrip(), "Block not found")
|
||||||
|
|
||||||
|
resp = self.test_rest_request(f"/deploymentinfo/{INVALID_PARAM}", ret_type=RetType.OBJ, status=400)
|
||||||
|
assert_equal(resp.read().decode('utf-8').rstrip(), f"Invalid hash: {INVALID_PARAM}")
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
RESTTest().main()
|
RESTTest().main()
|
||||||
|
|
Loading…
Add table
Reference in a new issue