From fa996c58e8a31ebe610d186cef408b6dd3b385a8 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Mon, 1 Nov 2021 17:03:09 +0100 Subject: [PATCH] refactor: Avoid integer overflow in ApplyStats when activating snapshot --- src/index/coinstatsindex.cpp | 2 +- src/node/coinstats.cpp | 5 ++++- src/node/coinstats.h | 3 ++- src/rpc/blockchain.cpp | 3 ++- 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/index/coinstatsindex.cpp b/src/index/coinstatsindex.cpp index 9ab9209ca41..e4ee0e674b7 100644 --- a/src/index/coinstatsindex.cpp +++ b/src/index/coinstatsindex.cpp @@ -321,7 +321,7 @@ bool CoinStatsIndex::LookUpStats(const CBlockIndex* block_index, CCoinsStats& co coins_stats.hashSerialized = entry.muhash; coins_stats.nTransactionOutputs = entry.transaction_output_count; coins_stats.nBogoSize = entry.bogo_size; - coins_stats.nTotalAmount = entry.total_amount; + coins_stats.total_amount = entry.total_amount; coins_stats.total_subsidy = entry.total_subsidy; coins_stats.total_unspendable_amount = entry.total_unspendable_amount; coins_stats.total_prevout_spent_amount = entry.total_prevout_spent_amount; diff --git a/src/node/coinstats.cpp b/src/node/coinstats.cpp index 639a5791728..eb21bbdba85 100644 --- a/src/node/coinstats.cpp +++ b/src/node/coinstats.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -82,7 +83,9 @@ static void ApplyStats(CCoinsStats& stats, const uint256& hash, const std::mapsecond.out.nValue; + if (stats.total_amount.has_value()) { + stats.total_amount = CheckedAdd(*stats.total_amount, it->second.out.nValue); + } stats.nBogoSize += GetBogoSize(it->second.out.scriptPubKey); } } diff --git a/src/node/coinstats.h b/src/node/coinstats.h index 1d95417d4fd..2a8fbf5bc64 100644 --- a/src/node/coinstats.h +++ b/src/node/coinstats.h @@ -35,7 +35,8 @@ struct CCoinsStats { uint64_t nBogoSize{0}; uint256 hashSerialized{}; uint64_t nDiskSize{0}; - CAmount nTotalAmount{0}; + //! The total amount, or nullopt if an overflow occurred calculating it + std::optional total_amount{0}; //! The number of coins contained. uint64_t coins_count{0}; diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 689c8751f33..f6112e78e07 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -1244,7 +1244,8 @@ static RPCHelpMan gettxoutsetinfo() if (hash_type == CoinStatsHashType::MUHASH) { ret.pushKV("muhash", stats.hashSerialized.GetHex()); } - ret.pushKV("total_amount", ValueFromAmount(stats.nTotalAmount)); + CHECK_NONFATAL(stats.total_amount.has_value()); + ret.pushKV("total_amount", ValueFromAmount(stats.total_amount.value())); if (!stats.index_used) { ret.pushKV("transactions", static_cast(stats.nTransactions)); ret.pushKV("disk_size", stats.nDiskSize);