mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-09-11 21:20:39 +02:00
This should be an integer, not a numeric, as already enforced by the RPC code and described in the mapping just above the changed line.
111 lines
5.3 KiB
Python
Executable File
111 lines
5.3 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
# Copyright (c) 2026 The Bitcoin Core developers
|
|
# Distributed under the MIT software license, see the accompanying
|
|
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
"""Check that getopenrpcinfo RPC is callable and serializable as valid json."""
|
|
|
|
import json
|
|
|
|
from test_framework.test_framework import BitcoinTestFramework
|
|
from test_framework.util import assert_equal
|
|
|
|
|
|
def find_method(openrpc, name):
|
|
return next(method for method in openrpc["methods"] if method["name"] == name)
|
|
|
|
|
|
def find_param(method, name):
|
|
return next(param for param in method["params"] if param["name"] == name)
|
|
|
|
|
|
class OpenRPCDocTest(BitcoinTestFramework):
|
|
def set_test_params(self):
|
|
self.num_nodes = 1
|
|
|
|
def run_test(self):
|
|
self.log.info("Calling getopenrpcinfo")
|
|
openrpc = self.nodes[0].getopenrpcinfo()
|
|
json.dumps(openrpc)
|
|
assert_equal(openrpc["openrpc"], "1.4.1")
|
|
assert_equal(type(openrpc["openrpc"]).__name__, "str")
|
|
assert_equal(type(openrpc["info"]).__name__, "dict")
|
|
assert_equal(type(openrpc["methods"]).__name__, "list")
|
|
|
|
self.log.info("Calling rpc.discover")
|
|
if self.options.usecli:
|
|
discovered = self.nodes[0].cli("rpc.discover").send_cli()
|
|
else:
|
|
discovered = self.nodes[0].rpc.discover()
|
|
assert_equal(discovered, openrpc)
|
|
rpc_discover = find_method(discovered, "rpc.discover")
|
|
assert_equal(rpc_discover["params"], [])
|
|
|
|
stop = find_method(openrpc, "stop")
|
|
assert "wait" not in [param["name"] for param in stop["params"]]
|
|
|
|
self.log.info("Calling getopenrpcinfo with hidden commands")
|
|
openrpc_with_hidden = self.nodes[0].getopenrpcinfo(True)
|
|
stop_with_hidden = find_method(openrpc_with_hidden, "stop")
|
|
wait = find_param(stop_with_hidden, "wait")
|
|
assert_equal(wait["schema"]["type"], "number")
|
|
|
|
self.log.info("Checking type_str override schemas")
|
|
getblockstats = find_method(openrpc, "getblockstats")
|
|
hash_or_height = find_param(getblockstats, "hash_or_height")
|
|
assert_equal(hash_or_height["schema"], {"oneOf": [{"type": "integer"}, {"type": "string"}]})
|
|
|
|
self.log.info("Checking fixed-length array schemas")
|
|
deriveaddresses = find_method(openrpc, "deriveaddresses")
|
|
range_array = find_param(deriveaddresses, "range")["schema"]["oneOf"][1]
|
|
assert_equal(range_array, {
|
|
"type": "array",
|
|
"items": [{"type": "number"}, {"type": "number"}],
|
|
"additionalItems": False,
|
|
"minItems": 2,
|
|
"maxItems": 2,
|
|
})
|
|
|
|
feerate_percentiles = getblockstats["result"]["schema"]["properties"]["feerate_percentiles"]
|
|
assert_equal(feerate_percentiles["type"], "array")
|
|
assert_equal(feerate_percentiles["items"], [{"type": "number"}] * 5)
|
|
assert_equal(feerate_percentiles["additionalItems"], False)
|
|
assert_equal(feerate_percentiles["minItems"], 5)
|
|
assert_equal(feerate_percentiles["maxItems"], 5)
|
|
|
|
self.log.info("Checking relaxed schemas for unchecked RPC types")
|
|
createrawtransaction = find_method(openrpc, "createrawtransaction")
|
|
outputs = find_param(createrawtransaction, "outputs")
|
|
address_description = "A key-value pair. The key (string) is the bitcoin address, the value (float or string) is the amount in BTC"
|
|
address_obj = {"type": "object", "additionalProperties": {"oneOf": [{"type": "number"},{"type": "string"}]}, "description": address_description}
|
|
data_description = "A key-value pair. The key must be \"data\", the value is hex-encoded data that becomes a part of an OP_RETURN output"
|
|
data_obj = {"type": "object", "properties": { "data": {"type": "string", "pattern": "^[0-9a-fA-F]+$", "description": data_description}}, "additionalProperties": False, "required": ["data"]}
|
|
assert_equal(outputs["schema"], {"oneOf": [{"type": "array", "items": {"anyOf": [address_obj, data_obj]}}, {"type": "object"}]})
|
|
|
|
getdescriptoractivity = find_method(openrpc, "getdescriptoractivity")
|
|
activity = getdescriptoractivity["result"]["schema"]["properties"]["activity"]
|
|
assert_equal(activity["type"], "array")
|
|
|
|
if "getwalletinfo" in [method["name"] for method in openrpc["methods"]]:
|
|
getwalletinfo = find_method(openrpc, "getwalletinfo")
|
|
scanning = getwalletinfo["result"]["schema"]["properties"]["scanning"]
|
|
assert_equal(scanning["oneOf"][0]["type"], "object")
|
|
assert_equal(scanning["oneOf"][1], {"const": False})
|
|
|
|
self.log.info("Checking argument fallback annotations")
|
|
getblock = find_method(openrpc, "getblock")
|
|
verbosity = find_param(getblock, "verbosity")
|
|
assert_equal(verbosity["schema"]["default"], 1)
|
|
stats = find_param(getblockstats, "stats")
|
|
assert_equal(stats["schema"]["x-bitcoin-default-hint"], "all values")
|
|
|
|
self.log.info("Checking numeric amount result annotations")
|
|
analyzepsbt = find_method(openrpc, "analyzepsbt")
|
|
result_schema = analyzepsbt["result"]["schema"]
|
|
estimated_feerate = result_schema["properties"]["estimated_feerate"]
|
|
assert_equal(estimated_feerate["type"], "number")
|
|
assert_equal(estimated_feerate["x-bitcoin-unit"], "amount")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
OpenRPCDocTest(__file__).main()
|