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.
502self.test_rest_request(f"/block/{blockhash}", status=200, req_type=ReqType.BIN, ret_type=RetType.OBJ)503self.test_rest_request(f"/blockpart/{blockhash}", query_params={"offset": 0, "size": 1}, status=200, req_type=ReqType.BIN, ret_type=RetType.OBJ)504blk_files = list(self.nodes[0].blocks_path.glob("blk*.dat"))505for blk_file in blk_files:506blk_file.rename(blk_file.with_suffix('.bkp'))507self.test_rest_request(f"/block/{blockhash}", status=500, req_type=ReqType.BIN, ret_type=RetType.OBJ)508self.test_rest_request(f"/blockpart/{blockhash}", query_params={"offset": 0, "size": 1}, status=500, req_type=ReqType.BIN, ret_type=RetType.OBJ)509for blk_file in blk_files:510blk_file.with_suffix('.bkp').rename(blk_file)512self.log.info("Test the /deploymentinfo URI")514deployment_info = self.nodes[0].getdeploymentinfo()515assert_equal(deployment_info, self.test_rest_request('/deploymentinfo'))517previous_bb_hash = self.nodes[0].getblockhash(self.nodes[0].getblockcount() - 1)518deployment_info = self.nodes[0].getdeploymentinfo(previous_bb_hash)519assert_equal(deployment_info, self.test_rest_request(f"/deploymentinfo/{previous_bb_hash}"))521non_existing_blockhash = '42759cde25462784395a337460bde75f58e73d3f08bd31fdc3507cbac856a2c4'522resp = self.test_rest_request(f'/deploymentinfo/{non_existing_blockhash}', ret_type=RetType.OBJ, status=400)523assert_equal(resp.read().decode('utf-8').rstrip(), "Block not found")525resp = self.test_rest_request(f"/deploymentinfo/{INVALID_PARAM}", ret_type=RetType.OBJ, status=400)526assert_equal(resp.read().decode('utf-8').rstrip(), f"Invalid hash: {INVALID_PARAM}")528self.log.info("Test Cache-Control headers on REST responses")530blockhash = self.nodes[0].getbestblockhash()531height = self.nodes[0].getblockcount()532immutable = "public, immutable, max-age=86400"533no_store = "no-store"535def assert_cache_control(536uri: str,537expected: str,538*,539req_type: typing.Optional[ReqType] = ReqType.JSON,540status: int = 200,541query_params: typing.Union[dict[str, typing.Any], str, None] = None,542) -> bytes:543"""Assert `uri` has expected Cache-Control and return the response body."""544response = self.test_rest_request(545uri,546req_type=req_type,547status=status,548ret_type=RetType.OBJ,549query_params=query_params,550)551assert isinstance(response, http.client.HTTPResponse)552assert_equal(response.getheader("Cache-Control"), expected)553return response.read()555# Immutable endpoints556immutable_block = assert_cache_control(f"/block/{blockhash}", immutable, req_type=ReqType.BIN)557immutable_spenttxouts = assert_cache_control(f"/spenttxouts/{blockhash}", immutable)558assert_cache_control(f"/spenttxouts/{blockhash}", immutable, req_type=ReqType.BIN)559assert_cache_control(f"/spenttxouts/{blockhash}", immutable, req_type=ReqType.HEX)560immutable_blockfilter = assert_cache_control(561f"/blockfilter/basic/{blockhash}", immutable, req_type=ReqType.JSON562)563assert_cache_control(f"/blockfilter/basic/{blockhash}", immutable, req_type=ReqType.BIN)564assert_cache_control(f"/blockfilter/basic/{blockhash}", immutable, req_type=ReqType.HEX)566# Mutable endpoints are not stored until validator support is available.567mutable_block = assert_cache_control(f"/block/{blockhash}", no_store)568assert_cache_control(f"/block/notxdetails/{blockhash}", no_store)569mutable_headers = assert_cache_control(570f"/headers/{blockhash}", no_store, req_type=ReqType.JSON, query_params={"count": 2}571)572assert_cache_control(f"/headers/{blockhash}", no_store, req_type=ReqType.BIN, query_params={"count": 1})573assert_cache_control(f"/headers/{blockhash}", no_store, req_type=ReqType.HEX, query_params={"count": 1})574assert_cache_control(f"/blockfilterheaders/basic/{blockhash}", no_store, req_type=ReqType.JSON, query_params={"count": 1})575assert_cache_control(f"/blockfilterheaders/basic/{blockhash}", no_store, req_type=ReqType.BIN, query_params={"count": 1})576assert_cache_control(f"/blockfilterheaders/basic/{blockhash}", no_store, req_type=ReqType.HEX, query_params={"count": 1})577assert_cache_control(f"/blockhashbyheight/{height}", no_store)578assert_cache_control(f"/blockhashbyheight/{height}", no_store, req_type=ReqType.BIN)579assert_cache_control(f"/blockhashbyheight/{height}", no_store, req_type=ReqType.HEX)581# Dynamic endpoints582mutable_chaininfo = assert_cache_control("/chaininfo", no_store)583assert_cache_control("/mempool/info", no_store)584mutable_deploymentinfo = assert_cache_control("/deploymentinfo", no_store)585immutable_deploymentinfo = assert_cache_control(f"/deploymentinfo/{blockhash}", immutable)587cache_tx = self.wallet.send_self_transfer(from_node=self.nodes[0])588mempool_txid = cache_tx["txid"]589cache_utxo = cache_tx["new_utxo"]590cache_utxo_path = f"/getutxos/{mempool_txid}-{cache_utxo['vout']}"592mempool_tx_response = assert_cache_control(f"/tx/{mempool_txid}", no_store, req_type=ReqType.JSON)593mempool_tx = json.loads(mempool_tx_response, parse_float=Decimal)594assert "blockhash" not in mempool_tx595assert_cache_control(f"/tx/{mempool_txid}", no_store, req_type=ReqType.BIN)596assert_cache_control(f"/tx/{mempool_txid}", no_store, req_type=ReqType.HEX)598self.generate(self.nodes[0], 1)599sync_txindex(self, self.nodes[0])601self.log.info("Test Cache-Control response behavior across a newly mined block")602assert_equal(immutable_block, assert_cache_control(f"/block/{blockhash}", immutable, req_type=ReqType.BIN))603assert_equal(immutable_spenttxouts, assert_cache_control(f"/spenttxouts/{blockhash}", immutable))604assert_equal(605immutable_blockfilter,606assert_cache_control(f"/blockfilter/basic/{blockhash}", immutable, req_type=ReqType.JSON),607)608assert_equal(immutable_deploymentinfo, assert_cache_control(f"/deploymentinfo/{blockhash}", immutable))610# no-store responses need not change after every block. Only compare responses611# that are guaranteed to incorporate this active chain extension.612assert_not_equal(mutable_block, assert_cache_control(f"/block/{blockhash}", no_store))613assert_not_equal(614mutable_headers,615assert_cache_control(f"/headers/{blockhash}", no_store, req_type=ReqType.JSON, query_params={"count": 2}),616)617assert_not_equal(mutable_chaininfo, assert_cache_control("/chaininfo", no_store))618assert_not_equal(mutable_deploymentinfo, assert_cache_control("/deploymentinfo", no_store))620confirmed_tx_response = assert_cache_control(f"/tx/{mempool_txid}", no_store, req_type=ReqType.JSON)621assert_not_equal(mempool_tx_response, confirmed_tx_response)622confirmed_tx = json.loads(confirmed_tx_response, parse_float=Decimal)623assert_equal(confirmed_tx["txid"], mempool_txid)624assert "blockhash" in confirmed_tx625assert_cache_control(f"/tx/{mempool_txid}", no_store, req_type=ReqType.BIN)626assert_cache_control(f"/tx/{mempool_txid}", no_store, req_type=ReqType.HEX)627assert_cache_control(cache_utxo_path, no_store, req_type=ReqType.JSON)628assert_cache_control(cache_utxo_path, no_store, req_type=ReqType.BIN)629assert_cache_control(cache_utxo_path, no_store, req_type=ReqType.HEX)631self.log.info("Test Cache-Control headers on REST error responses")632assert_cache_control(f"/block/{blockhash}.invalid", no_store, status=400, req_type=None)633assert_cache_control(f"/tx/{INVALID_PARAM}", no_store, status=400)634assert_cache_control(f"/deploymentinfo/{INVALID_PARAM}", no_store, status=400)635assert_cache_control("/blockhashbyheight/999999999", no_store, status=404)636assert_cache_control(f"/block/{UNKNOWN_PARAM}", no_store, status=404)637assert_cache_control(f"/tx/{'f' * 64}", no_store, status=404)638assert_cache_control("", no_store, status=404, query_params={"x": 1}, req_type=None)639assert_cache_control("/tx", no_store, status=404, req_type=None)640assert_cache_control("/does-not-exist", no_store, status=404, req_type=None)641assert_cache_control("/mempool/not-a-valid-path", no_store, status=400)642assert_cache_control(f"/deploymentinfo/{non_existing_blockhash}", no_store, status=400)644if __name__ == '__main__':645RESTTest(__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.