Inside Bitcoin
Opening the selected file…
Inside Bitcoin
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
1#!/usr/bin/env python32# Copyright (c) 2026 The Bitcoin Core developers3# Distributed under the MIT software license, see the accompanying4# file COPYING or http://www.opensource.org/licenses/mit-license.php.5"""Check that getopenrpcinfo RPC is callable and serializable as valid json."""7import json9from test_framework.test_framework import BitcoinTestFramework10from test_framework.util import assert_equal13def find_method(openrpc, name):14return next(method for method in openrpc["methods"] if method["name"] == name)17def find_param(method, name):18return next(param for param in method["params"] if param["name"] == name)21class OpenRPCDocTest(BitcoinTestFramework):22def set_test_params(self):23self.num_nodes = 125def run_test(self):26self.log.info("Calling getopenrpcinfo")27openrpc = self.nodes[0].getopenrpcinfo()28json.dumps(openrpc)29assert_equal(openrpc["openrpc"], "1.4.1")30assert_equal(type(openrpc["openrpc"]).__name__, "str")31assert_equal(type(openrpc["info"]).__name__, "dict")32assert_equal(type(openrpc["methods"]).__name__, "list")34self.log.info("Calling rpc.discover")35if self.options.usecli:36discovered = self.nodes[0].cli("rpc.discover").send_cli()37else:38discovered = self.nodes[0].rpc.discover()39assert_equal(discovered, openrpc)40rpc_discover = find_method(discovered, "rpc.discover")41assert_equal(rpc_discover["params"], [])43stop = find_method(openrpc, "stop")44assert "wait" not in [param["name"] for param in stop["params"]]46self.log.info("Calling getopenrpcinfo with hidden commands")47openrpc_with_hidden = self.nodes[0].getopenrpcinfo(True)48stop_with_hidden = find_method(openrpc_with_hidden, "stop")49wait = find_param(stop_with_hidden, "wait")50assert_equal(wait["schema"]["type"], "number")52self.log.info("Checking type_str override schemas")53getblockstats = find_method(openrpc, "getblockstats")54hash_or_height = find_param(getblockstats, "hash_or_height")55assert_equal(hash_or_height["schema"], {"oneOf": [{"type": "integer"}, {"type": "string"}]})57self.log.info("Checking fixed-length array schemas")58deriveaddresses = find_method(openrpc, "deriveaddresses")59range_array = find_param(deriveaddresses, "range")["schema"]["oneOf"][1]60assert_equal(range_array, {61"type": "array",62"items": [{"type": "number"}, {"type": "number"}],63"additionalItems": False,64"minItems": 2,65"maxItems": 2,66})68feerate_percentiles = getblockstats["result"]["schema"]["properties"]["feerate_percentiles"]69assert_equal(feerate_percentiles["type"], "array")70assert_equal(feerate_percentiles["items"], [{"type": "number"}] * 5)71assert_equal(feerate_percentiles["additionalItems"], False)72assert_equal(feerate_percentiles["minItems"], 5)73assert_equal(feerate_percentiles["maxItems"], 5)75self.log.info("Checking relaxed schemas for unchecked RPC types")76createrawtransaction = find_method(openrpc, "createrawtransaction")77outputs = find_param(createrawtransaction, "outputs")78address_description = "A key-value pair. The key (string) is the bitcoin address, the value (float or string) is the amount in BTC"79address_obj = {"type": "object", "additionalProperties": {"oneOf": [{"type": "number"},{"type": "string"}]}, "description": address_description}80data_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"81data_obj = {"type": "object", "properties": { "data": {"type": "string", "pattern": "^([0-9a-fA-F]{2})*$", "description": data_description}}, "additionalProperties": False, "required": ["data"]}82assert_equal(outputs["schema"], {"oneOf": [{"type": "array", "items": {"anyOf": [address_obj, data_obj]}}, {"type": "object"}]})84getdescriptoractivity = find_method(openrpc, "getdescriptoractivity")85activity = getdescriptoractivity["result"]["schema"]["properties"]["activity"]86assert_equal(activity["type"], "array")88if "getwalletinfo" in [method["name"] for method in openrpc["methods"]]:89getwalletinfo = find_method(openrpc, "getwalletinfo")90scanning = getwalletinfo["result"]["schema"]["properties"]["scanning"]91assert_equal(scanning["oneOf"][0]["type"], "object")92assert_equal(scanning["oneOf"][1], {"const": False})94self.log.info("Checking argument fallback annotations")95getblock = find_method(openrpc, "getblock")96verbosity = find_param(getblock, "verbosity")97assert_equal(verbosity["schema"]["default"], 1)98stats = find_param(getblockstats, "stats")99assert_equal(stats["schema"]["x-bitcoin-default-hint"], "all values")101self.log.info("Checking numeric amount result annotations")102analyzepsbt = find_method(openrpc, "analyzepsbt")103result_schema = analyzepsbt["result"]["schema"]104estimated_feerate = result_schema["properties"]["estimated_feerate"]105assert_equal(estimated_feerate["type"], "number")106assert_equal(estimated_feerate["x-bitcoin-unit"], "amount")109if __name__ == "__main__":110OpenRPCDocTest(__file__).main()
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.