test: add function to convert to json for height_or_hash params

This is necessary for bitcoin-cli because a string without quotes
is not a valid json.
This commit is contained in:
Martin Zumsande committed 2025-06-23 17:42:56 -04:00
1 parent 54d28722ba
commit 6530d0015b
5 files changed
+18 -14

No files matched your search

+1 -1
View File
@@ -481,7 +481,7 @@ class AssumeutxoTest(BitcoinTestFramework):
# Use a hash instead of a height # Use a hash instead of a height
prev_snap_hash = n0.getblockhash(prev_snap_height) prev_snap_hash = n0.getblockhash(prev_snap_height)
dump_output5 = n0.dumptxoutset('utxos5.dat', rollback=prev_snap_hash) dump_output5 = n0.dumptxoutset('utxos5.dat', rollback=self.convert_to_json_for_cli(prev_snap_hash))
assert_equal(sha256sum_file(dump_output4['path']), sha256sum_file(dump_output5['path'])) assert_equal(sha256sum_file(dump_output4['path']), sha256sum_file(dump_output5['path']))
# Ensure n0 is back at the tip # Ensure n0 is back at the tip
+3 -4
View File
@@ -41,7 +41,6 @@ class CoinStatsIndexTest(BitcoinTestFramework):
def set_test_params(self): def set_test_params(self):
self.setup_clean_chain = True self.setup_clean_chain = True
self.num_nodes = 2 self.num_nodes = 2
self.supports_cli = False
self.extra_args = [ self.extra_args = [
[], [],
["-coinstatsindex"] ["-coinstatsindex"]
@@ -104,7 +103,7 @@ class CoinStatsIndexTest(BitcoinTestFramework):
assert_equal(res0, res2) assert_equal(res0, res2)
# Fetch old stats by hash # Fetch old stats by hash
res3 = index_node.gettxoutsetinfo(hash_option, res0['bestblock']) res3 = index_node.gettxoutsetinfo(hash_option, self.convert_to_json_for_cli(res0['bestblock']))
del res3['block_info'], res3['total_unspendable_amount'] del res3['block_info'], res3['total_unspendable_amount']
res3.pop('muhash', None) res3.pop('muhash', None)
assert_equal(res0, res3) assert_equal(res0, res3)
@@ -243,7 +242,7 @@ class CoinStatsIndexTest(BitcoinTestFramework):
assert_equal(res12, res10) assert_equal(res12, res10)
self.log.info("Test obtaining info for a non-existent block hash") self.log.info("Test obtaining info for a non-existent block hash")
assert_raises_rpc_error(-5, "Block not found", index_node.gettxoutsetinfo, hash_type="none", hash_or_height="ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", use_index=True) assert_raises_rpc_error(-5, "Block not found", index_node.gettxoutsetinfo, hash_type="none", hash_or_height=self.convert_to_json_for_cli("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), use_index=True)
def _test_use_index_option(self): def _test_use_index_option(self):
self.log.info("Test use_index option for nodes running the index") self.log.info("Test use_index option for nodes running the index")
@@ -278,7 +277,7 @@ class CoinStatsIndexTest(BitcoinTestFramework):
assert_not_equal(res["muhash"], res_invalid["muhash"]) assert_not_equal(res["muhash"], res_invalid["muhash"])
# Test that requesting reorged out block by hash is still returning correct results # Test that requesting reorged out block by hash is still returning correct results
res_invalid2 = index_node.gettxoutsetinfo(hash_type='muhash', hash_or_height=reorg_block) res_invalid2 = index_node.gettxoutsetinfo(hash_type='muhash', hash_or_height=self.convert_to_json_for_cli(reorg_block))
assert_equal(res_invalid2["muhash"], res_invalid["muhash"]) assert_equal(res_invalid2["muhash"], res_invalid["muhash"])
assert_not_equal(res["muhash"], res_invalid2["muhash"]) assert_not_equal(res["muhash"], res_invalid2["muhash"])
+4 -4
View File
@@ -67,7 +67,7 @@ class FeatureIndexPruneTest(BitcoinTestFramework):
for node in filter_nodes: for node in filter_nodes:
assert_greater_than(len(node.getblockfilter(tip)['filter']), 0) assert_greater_than(len(node.getblockfilter(tip)['filter']), 0)
for node in stats_nodes: for node in stats_nodes:
assert node.gettxoutsetinfo(hash_type="muhash", hash_or_height=tip)['muhash'] assert node.gettxoutsetinfo(hash_type="muhash", hash_or_height=self.convert_to_json_for_cli(tip))['muhash']
self.generate(self.nodes[0], 500) self.generate(self.nodes[0], 500)
self.sync_index(height=700) self.sync_index(height=700)
@@ -85,14 +85,14 @@ class FeatureIndexPruneTest(BitcoinTestFramework):
for node in filter_nodes: for node in filter_nodes:
assert_greater_than(len(node.getblockfilter(tip)['filter']), 0) assert_greater_than(len(node.getblockfilter(tip)['filter']), 0)
for node in stats_nodes: for node in stats_nodes:
assert node.gettxoutsetinfo(hash_type="muhash", hash_or_height=tip)['muhash'] assert node.gettxoutsetinfo(hash_type="muhash", hash_or_height=self.convert_to_json_for_cli(tip))['muhash']
self.log.info("check if we can access the blockfilter and coinstats of a pruned block") self.log.info("check if we can access the blockfilter and coinstats of a pruned block")
height_hash = self.nodes[0].getblockhash(2) height_hash = self.nodes[0].getblockhash(2)
for node in filter_nodes: for node in filter_nodes:
assert_greater_than(len(node.getblockfilter(height_hash)['filter']), 0) assert_greater_than(len(node.getblockfilter(height_hash)['filter']), 0)
for node in stats_nodes: for node in stats_nodes:
assert node.gettxoutsetinfo(hash_type="muhash", hash_or_height=height_hash)['muhash'] assert node.gettxoutsetinfo(hash_type="muhash", hash_or_height=self.convert_to_json_for_cli(height_hash))['muhash']
# mine and sync index up to a height that will later be the pruneheight # mine and sync index up to a height that will later be the pruneheight
self.generate(self.nodes[0], 51) self.generate(self.nodes[0], 51)
@@ -106,7 +106,7 @@ class FeatureIndexPruneTest(BitcoinTestFramework):
assert_raises_rpc_error(-1, msg, node.getblockfilter, height_hash) assert_raises_rpc_error(-1, msg, node.getblockfilter, height_hash)
for node in stats_nodes: for node in stats_nodes:
msg = "Querying specific block heights requires coinstatsindex" msg = "Querying specific block heights requires coinstatsindex"
assert_raises_rpc_error(-8, msg, node.gettxoutsetinfo, "muhash", height_hash) assert_raises_rpc_error(-8, msg, node.gettxoutsetinfo, "muhash", self.convert_to_json_for_cli(height_hash))
self.generate(self.nodes[0], 749) self.generate(self.nodes[0], 749)
+4 -5
View File
@@ -36,7 +36,6 @@ class GetblockstatsTest(BitcoinTestFramework):
def set_test_params(self): def set_test_params(self):
self.num_nodes = 1 self.num_nodes = 1
self.setup_clean_chain = True self.setup_clean_chain = True
self.supports_cli = False
def get_stats(self): def get_stats(self):
return [self.nodes[0].getblockstats(hash_or_height=self.start_height + i) for i in range(self.max_stat_pos+1)] return [self.nodes[0].getblockstats(hash_or_height=self.start_height + i) for i in range(self.max_stat_pos+1)]
@@ -120,7 +119,7 @@ class GetblockstatsTest(BitcoinTestFramework):
# Check selecting block by hash too # Check selecting block by hash too
blockhash = self.expected_stats[i]['blockhash'] blockhash = self.expected_stats[i]['blockhash']
stats_by_hash = self.nodes[0].getblockstats(hash_or_height=blockhash) stats_by_hash = self.nodes[0].getblockstats(hash_or_height=self.convert_to_json_for_cli(blockhash))
assert_equal(stats_by_hash, self.expected_stats[i]) assert_equal(stats_by_hash, self.expected_stats[i])
# Make sure each stat can be queried on its own # Make sure each stat can be queried on its own
@@ -162,10 +161,10 @@ class GetblockstatsTest(BitcoinTestFramework):
self.nodes[0].getblockstats, hash_or_height=1, stats=['minfee', f'aaa{inv_sel_stat}']) self.nodes[0].getblockstats, hash_or_height=1, stats=['minfee', f'aaa{inv_sel_stat}'])
# Mainchain's genesis block shouldn't be found on regtest # Mainchain's genesis block shouldn't be found on regtest
assert_raises_rpc_error(-5, 'Block not found', self.nodes[0].getblockstats, assert_raises_rpc_error(-5, 'Block not found', self.nodes[0].getblockstats,
hash_or_height='000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f') hash_or_height=self.convert_to_json_for_cli('000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f'))
# Invalid number of args # Invalid number of args
assert_raises_rpc_error(-1, 'getblockstats hash_or_height ( stats )', self.nodes[0].getblockstats, '00', 1, 2) assert_raises_rpc_error(-1, 'getblockstats hash_or_height ( stats )', self.nodes[0].getblockstats, self.convert_to_json_for_cli('00'), 1, 2)
assert_raises_rpc_error(-1, 'getblockstats hash_or_height ( stats )', self.nodes[0].getblockstats) assert_raises_rpc_error(-1, 'getblockstats hash_or_height ( stats )', self.nodes[0].getblockstats)
self.log.info('Test block height 0') self.log.info('Test block height 0')
@@ -186,7 +185,7 @@ class GetblockstatsTest(BitcoinTestFramework):
self.log.info("Test when only header is known") self.log.info("Test when only header is known")
block = self.generateblock(self.nodes[0], output="raw(55)", transactions=[], submit=False) block = self.generateblock(self.nodes[0], output="raw(55)", transactions=[], submit=False)
self.nodes[0].submitheader(block["hex"]) self.nodes[0].submitheader(block["hex"])
assert_raises_rpc_error(-1, "Block not available (not fully downloaded)", lambda: self.nodes[0].getblockstats(block['hash'])) assert_raises_rpc_error(-1, "Block not available (not fully downloaded)", lambda: self.nodes[0].getblockstats(self.convert_to_json_for_cli(block['hash'])))
self.log.info('Test when block is missing') self.log.info('Test when block is missing')
(self.nodes[0].blocks_path / 'blk00000.dat').rename(self.nodes[0].blocks_path / 'blk00000.dat.backup') (self.nodes[0].blocks_path / 'blk00000.dat').rename(self.nodes[0].blocks_path / 'blk00000.dat.backup')
@@ -8,6 +8,7 @@ import configparser
from enum import Enum from enum import Enum
import argparse import argparse
from datetime import datetime, timezone from datetime import datetime, timezone
import json
import logging import logging
import os import os
import platform import platform
@@ -1072,3 +1073,8 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
def has_blockfile(self, node, filenum: str): def has_blockfile(self, node, filenum: str):
return (node.blocks_path/ f"blk{filenum}.dat").is_file() return (node.blocks_path/ f"blk{filenum}.dat").is_file()
def convert_to_json_for_cli(self, text):
if self.options.usecli:
return json.dumps(text)
return text