Skip to content

Commit 9964cbe

Browse files
kwvgPastaPastaPasta
authored andcommitted
merge bitcoin#23411: Avoid integer overflow in ApplyStats when activating snapshot
1 parent a2dcf74 commit 9964cbe

File tree

14 files changed

+95
-27
lines changed

14 files changed

+95
-27
lines changed

src/Makefile.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,7 @@ BITCOIN_CORE_H = \
323323
util/macros.h \
324324
util/message.h \
325325
util/moneystr.h \
326+
util/overflow.h \
326327
util/ranges.h \
327328
util/readwritefile.h \
328329
util/underlying.h \

src/index/coinstatsindex.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@ bool CoinStatsIndex::LookUpStats(const CBlockIndex* block_index, CCoinsStats& co
321321
coins_stats.hashSerialized = entry.muhash;
322322
coins_stats.nTransactionOutputs = entry.transaction_output_count;
323323
coins_stats.nBogoSize = entry.bogo_size;
324-
coins_stats.nTotalAmount = entry.total_amount;
324+
coins_stats.total_amount = entry.total_amount;
325325
coins_stats.total_subsidy = entry.total_subsidy;
326326
coins_stats.total_unspendable_amount = entry.total_unspendable_amount;
327327
coins_stats.total_prevout_spent_amount = entry.total_prevout_spent_amount;

src/init.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -885,7 +885,9 @@ static void PeriodicStats(ArgsManager& args, const CTxMemPool& mempool)
885885
statsClient.gauge("utxoset.txOutputs", stats.nTransactionOutputs, 1.0f);
886886
statsClient.gauge("utxoset.dbSizeBytes", stats.nDiskSize, 1.0f);
887887
statsClient.gauge("utxoset.blockHeight", stats.nHeight, 1.0f);
888-
statsClient.gauge("utxoset.totalAmount", (double)stats.nTotalAmount / (double)COIN, 1.0f);
888+
if (stats.total_amount.has_value()) {
889+
statsClient.gauge("utxoset.totalAmount", (double)stats.total_amount.value() / (double)COIN, 1.0f);
890+
}
889891
} else {
890892
// something went wrong
891893
LogPrintf("%s: GetUTXOStats failed\n", __func__);

src/node/coinstats.cpp

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111
#include <index/coinstatsindex.h>
1212
#include <serialize.h>
1313
#include <uint256.h>
14-
// #include <util/system.h>
1514
#include <util/check.h>
15+
#include <util/overflow.h>
1616
#include <util/system.h>
1717
#include <validation.h>
1818

@@ -83,7 +83,9 @@ static void ApplyStats(CCoinsStats& stats, const uint256& hash, const std::map<u
8383
stats.nTransactions++;
8484
for (auto it = outputs.begin(); it != outputs.end(); ++it) {
8585
stats.nTransactionOutputs++;
86-
stats.nTotalAmount += it->second.out.nValue;
86+
if (stats.total_amount.has_value()) {
87+
stats.total_amount = CheckedAdd(*stats.total_amount, it->second.out.nValue);
88+
}
8789
stats.nBogoSize += GetBogoSize(it->second.out.scriptPubKey);
8890
}
8991
}
@@ -94,7 +96,9 @@ static void ApplyStats(CCoinsStats& stats, std::nullptr_t, const uint256& hash,
9496
stats.nTransactions++;
9597
for (const auto& output : outputs) {
9698
stats.nTransactionOutputs++;
97-
stats.nTotalAmount += output.second.out.nValue;
99+
if (stats.total_amount.has_value()) {
100+
stats.total_amount = CheckedAdd(*stats.total_amount, output.second.out.nValue);
101+
}
98102
stats.nBogoSize += GetBogoSize(output.second.out.scriptPubKey);
99103
}
100104
}
@@ -107,11 +111,9 @@ static bool GetUTXOStats(CCoinsView* view, BlockManager& blockman, CCoinsStats&
107111
assert(pcursor);
108112

109113
if (!pindex) {
110-
{
111-
LOCK(cs_main);
112-
assert(std::addressof(g_chainman.m_blockman) == std::addressof(blockman));
113-
pindex = blockman.LookupBlockIndex(view->GetBestBlock());
114-
}
114+
LOCK(cs_main);
115+
assert(std::addressof(g_chainman.m_blockman) == std::addressof(blockman));
116+
pindex = blockman.LookupBlockIndex(view->GetBestBlock());
115117
}
116118
stats.nHeight = Assert(pindex)->nHeight;
117119
stats.hashBlock = pindex->GetBlockHash();

src/node/coinstats.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,19 @@ enum class CoinStatsHashType {
2424
NONE,
2525
};
2626

27-
struct CCoinsStats
28-
{
29-
CoinStatsHashType m_hash_type;
27+
struct CCoinsStats {
28+
//! Which hash type to use
29+
const CoinStatsHashType m_hash_type;
30+
3031
int nHeight{0};
3132
uint256 hashBlock{};
3233
uint64_t nTransactions{0};
3334
uint64_t nTransactionOutputs{0};
3435
uint64_t nBogoSize{0};
3536
uint256 hashSerialized{};
3637
uint64_t nDiskSize{0};
37-
CAmount nTotalAmount{0};
38+
//! The total amount, or nullopt if an overflow occurred calculating it
39+
std::optional<CAmount> total_amount{0};
3840

3941
//! The number of coins contained.
4042
uint64_t coins_count{0};

src/rpc/blockchain.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1423,9 +1423,10 @@ static UniValue gettxoutsetinfo(const JSONRPCRequest& request)
14231423
ret.pushKV("hash_serialized_2", stats.hashSerialized.GetHex());
14241424
}
14251425
if (hash_type == CoinStatsHashType::MUHASH) {
1426-
ret.pushKV("muhash", stats.hashSerialized.GetHex());
1426+
ret.pushKV("muhash", stats.hashSerialized.GetHex());
14271427
}
1428-
ret.pushKV("total_amount", ValueFromAmount(stats.nTotalAmount));
1428+
CHECK_NONFATAL(stats.total_amount.has_value());
1429+
ret.pushKV("total_amount", ValueFromAmount(stats.total_amount.value()));
14291430
if (!stats.index_used) {
14301431
ret.pushKV("transactions", static_cast<int64_t>(stats.nTransactions));
14311432
ret.pushKV("disk_size", stats.nDiskSize);

src/test/fuzz/addition_overflow.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <test/fuzz/FuzzedDataProvider.h>
66
#include <test/fuzz/fuzz.h>
77
#include <test/fuzz/util.h>
8+
#include <util/overflow.h>
89

910
#include <cstdint>
1011
#include <string>

src/test/fuzz/crypto_chacha20_poly1305_aead.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <test/fuzz/FuzzedDataProvider.h>
88
#include <test/fuzz/fuzz.h>
99
#include <test/fuzz/util.h>
10+
#include <util/overflow.h>
1011

1112
#include <cassert>
1213
#include <cstdint>

src/test/fuzz/integer.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include <uint256.h>
2828
#include <util/check.h>
2929
#include <util/moneystr.h>
30+
#include <util/overflow.h>
3031
#include <util/strencodings.h>
3132
#include <util/string.h>
3233
#include <util/system.h>

src/test/fuzz/pow.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <test/fuzz/FuzzedDataProvider.h>
1010
#include <test/fuzz/fuzz.h>
1111
#include <test/fuzz/util.h>
12+
#include <util/overflow.h>
1213

1314
#include <cstdint>
1415
#include <optional>

0 commit comments

Comments
 (0)