Skip to content

Commit fa2dada

Browse files
author
MarcoFalke
committed
rpc: Avoid getchaintxstats invalid results
1 parent 0bd2bd1 commit fa2dada

File tree

3 files changed

+23
-13
lines changed

3 files changed

+23
-13
lines changed

src/rpc/blockchain.cpp

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1645,13 +1645,19 @@ static RPCHelpMan getchaintxstats()
16451645
RPCResult::Type::OBJ, "", "",
16461646
{
16471647
{RPCResult::Type::NUM_TIME, "time", "The timestamp for the final block in the window, expressed in " + UNIX_EPOCH_TIME},
1648-
{RPCResult::Type::NUM, "txcount", "The total number of transactions in the chain up to that point"},
1648+
{RPCResult::Type::NUM, "txcount", /*optional=*/true,
1649+
"The total number of transactions in the chain up to that point, if known. "
1650+
"It may be unknown when using assumeutxo."},
16491651
{RPCResult::Type::STR_HEX, "window_final_block_hash", "The hash of the final block in the window"},
16501652
{RPCResult::Type::NUM, "window_final_block_height", "The height of the final block in the window."},
16511653
{RPCResult::Type::NUM, "window_block_count", "Size of the window in number of blocks"},
1652-
{RPCResult::Type::NUM, "window_tx_count", /*optional=*/true, "The number of transactions in the window. Only returned if \"window_block_count\" is > 0"},
1654+
{RPCResult::Type::NUM, "window_tx_count", /*optional=*/true,
1655+
"The number of transactions in the window. "
1656+
"Only returned if \"window_block_count\" is > 0 and if txcount exists for the start and end of the window."},
16531657
{RPCResult::Type::NUM, "window_interval", /*optional=*/true, "The elapsed time in the window in seconds. Only returned if \"window_block_count\" is > 0"},
1654-
{RPCResult::Type::NUM, "txrate", /*optional=*/true, "The average rate of transactions per second in the window. Only returned if \"window_interval\" is > 0"},
1658+
{RPCResult::Type::NUM, "txrate", /*optional=*/true,
1659+
"The average rate of transactions per second in the window. "
1660+
"Only returned if \"window_interval\" is > 0 and if window_tx_count exists."},
16551661
}},
16561662
RPCExamples{
16571663
HelpExampleCli("getchaintxstats", "")
@@ -1692,19 +1698,25 @@ static RPCHelpMan getchaintxstats()
16921698

16931699
const CBlockIndex& past_block{*CHECK_NONFATAL(pindex->GetAncestor(pindex->nHeight - blockcount))};
16941700
const int64_t nTimeDiff{pindex->GetMedianTimePast() - past_block.GetMedianTimePast()};
1695-
const int nTxDiff = pindex->nChainTx - past_block.nChainTx;
1701+
const auto window_tx_count{
1702+
(pindex->nChainTx != 0 && past_block.nChainTx != 0) ? std::optional{pindex->nChainTx - past_block.nChainTx} : std::nullopt,
1703+
};
16961704

16971705
UniValue ret(UniValue::VOBJ);
16981706
ret.pushKV("time", (int64_t)pindex->nTime);
1699-
ret.pushKV("txcount", (int64_t)pindex->nChainTx);
1707+
if (pindex->nChainTx) {
1708+
ret.pushKV("txcount", pindex->nChainTx);
1709+
}
17001710
ret.pushKV("window_final_block_hash", pindex->GetBlockHash().GetHex());
17011711
ret.pushKV("window_final_block_height", pindex->nHeight);
17021712
ret.pushKV("window_block_count", blockcount);
17031713
if (blockcount > 0) {
1704-
ret.pushKV("window_tx_count", nTxDiff);
1714+
if (window_tx_count) {
1715+
ret.pushKV("window_tx_count", *window_tx_count);
1716+
}
17051717
ret.pushKV("window_interval", nTimeDiff);
1706-
if (nTimeDiff > 0) {
1707-
ret.pushKV("txrate", ((double)nTxDiff) / nTimeDiff);
1718+
if (nTimeDiff > 0 && window_tx_count) {
1719+
ret.pushKV("txrate", double(*window_tx_count) / nTimeDiff);
17081720
}
17091721
}
17101722

test/functional/feature_assumeutxo.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ def check_tx_counts(final: bool) -> None:
301301
the snapshot, and final values after the snapshot is validated."""
302302
for height, block in blocks.items():
303303
tx = n1.getblockheader(block.hash)["nTx"]
304-
chain_tx = n1.getchaintxstats(nblocks=1, blockhash=block.hash)["txcount"]
304+
chain_tx = n1.getchaintxstats(nblocks=1, blockhash=block.hash).get("txcount", None)
305305

306306
# Intermediate nTx of the starting block should be set, but nTx of
307307
# later blocks should be 0 before they are downloaded.
@@ -311,11 +311,11 @@ def check_tx_counts(final: bool) -> None:
311311
assert_equal(tx, 0)
312312

313313
# Intermediate nChainTx of the starting block and snapshot block
314-
# should be set, but others should be 0 until they are downloaded.
314+
# should be set, but others should be None until they are downloaded.
315315
if final or height in (START_HEIGHT, SNAPSHOT_BASE_HEIGHT):
316316
assert_equal(chain_tx, block.chain_tx)
317317
else:
318-
assert_equal(chain_tx, 0)
318+
assert_equal(chain_tx, None)
319319

320320
check_tx_counts(final=False)
321321

test/sanitizer_suppressions/ubsan

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ unsigned-integer-overflow:CCoinsViewCache::Uncache
5151
unsigned-integer-overflow:CompressAmount
5252
unsigned-integer-overflow:DecompressAmount
5353
unsigned-integer-overflow:crypto/
54-
unsigned-integer-overflow:getchaintxstats*
5554
unsigned-integer-overflow:MurmurHash3
5655
unsigned-integer-overflow:CBlockPolicyEstimator::processBlockTx
5756
unsigned-integer-overflow:TxConfirmStats::EstimateMedianVal
@@ -63,7 +62,6 @@ implicit-integer-sign-change:CBlockPolicyEstimator::processBlockTx
6362
implicit-integer-sign-change:SetStdinEcho
6463
implicit-integer-sign-change:compressor.h
6564
implicit-integer-sign-change:crypto/
66-
implicit-integer-sign-change:getchaintxstats*
6765
implicit-integer-sign-change:TxConfirmStats::removeTx
6866
implicit-integer-sign-change:prevector.h
6967
implicit-integer-sign-change:verify_flags

0 commit comments

Comments
 (0)