mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-02 09:46:52 -05:00
rpc: Block until synced if coinstatsindex is used in gettxoutsetinfo
During initial sync after startup the gettxoutsetinfo RPC will still return an error while catching up. However, after the initial sync the index will not error immediately anymore when it's in the process of syncing to the tip while being called. Instead it will block until synced and then return the response.
This commit is contained in:
parent
a5f6791139
commit
d4356d4e48
2 changed files with 13 additions and 20 deletions
|
@ -1175,6 +1175,18 @@ static RPCHelpMan gettxoutsetinfo()
|
|||
pindex = ParseHashOrHeight(request.params[1], chainman);
|
||||
}
|
||||
|
||||
if (stats.index_requested && g_coin_stats_index) {
|
||||
if (!g_coin_stats_index->BlockUntilSyncedToCurrentChain()) {
|
||||
const IndexSummary summary{g_coin_stats_index->GetSummary()};
|
||||
|
||||
// If a specific block was requested and the index has already synced past that height, we can return the
|
||||
// data already even though the index is not fully synced yet.
|
||||
if (pindex->nHeight > summary.best_block_height) {
|
||||
throw JSONRPCError(RPC_INTERNAL_ERROR, strprintf("Unable to get data because coinstatsindex is still syncing. Current height: %d", summary.best_block_height));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (GetUTXOStats(coins_view, *blockman, stats, node.rpc_interruption_point, pindex)) {
|
||||
ret.pushKV("height", (int64_t)stats.nHeight);
|
||||
ret.pushKV("bestblock", stats.hashBlock.GetHex());
|
||||
|
@ -1215,13 +1227,6 @@ static RPCHelpMan gettxoutsetinfo()
|
|||
ret.pushKV("block_info", block_info);
|
||||
}
|
||||
} else {
|
||||
if (g_coin_stats_index) {
|
||||
const IndexSummary summary{g_coin_stats_index->GetSummary()};
|
||||
|
||||
if (!summary.synced) {
|
||||
throw JSONRPCError(RPC_INTERNAL_ERROR, strprintf("Unable to read UTXO set because coinstatsindex is still syncing. Current height: %d", summary.best_block_height));
|
||||
}
|
||||
}
|
||||
throw JSONRPCError(RPC_INTERNAL_ERROR, "Unable to read UTXO set");
|
||||
}
|
||||
return ret;
|
||||
|
|
|
@ -32,7 +32,6 @@ from test_framework.test_framework import BitcoinTestFramework
|
|||
from test_framework.util import (
|
||||
assert_equal,
|
||||
assert_raises_rpc_error,
|
||||
try_rpc,
|
||||
)
|
||||
|
||||
class CoinStatsIndexTest(BitcoinTestFramework):
|
||||
|
@ -76,13 +75,11 @@ class CoinStatsIndexTest(BitcoinTestFramework):
|
|||
self.sync_blocks(timeout=120)
|
||||
|
||||
self.log.info("Test that gettxoutsetinfo() output is consistent with or without coinstatsindex option")
|
||||
self.wait_until(lambda: not try_rpc(-32603, "Unable to read UTXO set", node.gettxoutsetinfo))
|
||||
res0 = node.gettxoutsetinfo('none')
|
||||
|
||||
# The fields 'disk_size' and 'transactions' do not exist on the index
|
||||
del res0['disk_size'], res0['transactions']
|
||||
|
||||
self.wait_until(lambda: not try_rpc(-32603, "Unable to read UTXO set", index_node.gettxoutsetinfo, 'muhash'))
|
||||
for hash_option in index_hash_options:
|
||||
res1 = index_node.gettxoutsetinfo(hash_option)
|
||||
# The fields 'block_info' and 'total_unspendable_amount' only exist on the index
|
||||
|
@ -97,7 +94,6 @@ class CoinStatsIndexTest(BitcoinTestFramework):
|
|||
# Generate a new tip
|
||||
node.generate(5)
|
||||
|
||||
self.wait_until(lambda: not try_rpc(-32603, "Unable to read UTXO set", index_node.gettxoutsetinfo, 'muhash'))
|
||||
for hash_option in index_hash_options:
|
||||
# Fetch old stats by height
|
||||
res2 = index_node.gettxoutsetinfo(hash_option, 102)
|
||||
|
@ -176,7 +172,6 @@ class CoinStatsIndexTest(BitcoinTestFramework):
|
|||
self.nodes[0].generate(1)
|
||||
self.sync_all()
|
||||
|
||||
self.wait_until(lambda: not try_rpc(-32603, "Unable to read UTXO set", index_node.gettxoutsetinfo, 'muhash'))
|
||||
for hash_option in index_hash_options:
|
||||
# Check all amounts were registered correctly
|
||||
res6 = index_node.gettxoutsetinfo(hash_option, 108)
|
||||
|
@ -209,7 +204,6 @@ class CoinStatsIndexTest(BitcoinTestFramework):
|
|||
self.nodes[0].submitblock(ToHex(block))
|
||||
self.sync_all()
|
||||
|
||||
self.wait_until(lambda: not try_rpc(-32603, "Unable to read UTXO set", index_node.gettxoutsetinfo, 'muhash'))
|
||||
for hash_option in index_hash_options:
|
||||
res7 = index_node.gettxoutsetinfo(hash_option, 109)
|
||||
assert_equal(res7['total_unspendable_amount'], Decimal('80.98999999'))
|
||||
|
@ -235,7 +229,6 @@ class CoinStatsIndexTest(BitcoinTestFramework):
|
|||
assert_equal(res8, res9)
|
||||
|
||||
index_node.generate(1)
|
||||
self.wait_until(lambda: not try_rpc(-32603, "Unable to read UTXO set", index_node.gettxoutsetinfo, 'muhash'))
|
||||
res10 = index_node.gettxoutsetinfo('muhash')
|
||||
assert(res8['txouts'] < res10['txouts'])
|
||||
|
||||
|
@ -256,14 +249,12 @@ class CoinStatsIndexTest(BitcoinTestFramework):
|
|||
index_node = self.nodes[1]
|
||||
reorg_blocks = index_node.generatetoaddress(2, index_node.getnewaddress())
|
||||
reorg_block = reorg_blocks[1]
|
||||
self.wait_until(lambda: not try_rpc(-32603, "Unable to read UTXO set", index_node.gettxoutsetinfo, 'muhash'))
|
||||
res_invalid = index_node.gettxoutsetinfo('muhash')
|
||||
index_node.invalidateblock(reorg_blocks[0])
|
||||
assert_equal(index_node.gettxoutsetinfo('muhash')['height'], 110)
|
||||
|
||||
# Add two new blocks
|
||||
block = index_node.generate(2)[1]
|
||||
self.wait_until(lambda: not try_rpc(-32603, "Unable to read UTXO set", index_node.gettxoutsetinfo, 'muhash'))
|
||||
res = index_node.gettxoutsetinfo(hash_type='muhash', hash_or_height=None, use_index=False)
|
||||
|
||||
# Test that the result of the reorged block is not returned for its old block height
|
||||
|
@ -284,9 +275,7 @@ class CoinStatsIndexTest(BitcoinTestFramework):
|
|||
# Ensure that removing and re-adding blocks yields consistent results
|
||||
block = index_node.getblockhash(99)
|
||||
index_node.invalidateblock(block)
|
||||
self.wait_until(lambda: not try_rpc(-32603, "Unable to read UTXO set", index_node.gettxoutsetinfo, 'muhash'))
|
||||
index_node.reconsiderblock(block)
|
||||
self.wait_until(lambda: not try_rpc(-32603, "Unable to read UTXO set", index_node.gettxoutsetinfo, 'muhash'))
|
||||
res3 = index_node.gettxoutsetinfo(hash_type='muhash', hash_or_height=112)
|
||||
assert_equal(res2, res3)
|
||||
|
||||
|
@ -296,8 +285,7 @@ class CoinStatsIndexTest(BitcoinTestFramework):
|
|||
node.getblock(reorg_block)
|
||||
|
||||
self.restart_node(0, ["-coinstatsindex"])
|
||||
self.wait_until(lambda: not try_rpc(-32603, "Unable to read UTXO set", node.gettxoutsetinfo, 'muhash'))
|
||||
assert_raises_rpc_error(-32603, "Unable to read UTXO set", node.gettxoutsetinfo, 'muhash', reorg_block)
|
||||
assert_raises_rpc_error(-32603, "Unable to get data because coinstatsindex is still syncing.", node.gettxoutsetinfo, 'muhash', reorg_block)
|
||||
|
||||
def _test_index_rejects_hash_serialized(self):
|
||||
self.log.info("Test that the rpc raises if the legacy hash is passed with the index")
|
||||
|
|
Loading…
Add table
Reference in a new issue