coins: avoid moving `COutPoint` values
What changed, and why it matters
This is a small code cleanup change. It changes one internal function so it accepts a constant reference to an outpoint instead of taking ownership by moving it. Since COutPoint is a tiny, cheap-to-copy object, moving it was unnecessary and forced callers to write extra std::move() calls. The behavior of the program is unchanged; there is no security fix here.
No security action needed. Treat as normal code-quality refactor.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The patch refactors CCoinsViewCache::EmplaceCoinInternalDANGER to take const COutPoint& rather than COutPoint&&. COutPoint is a trivially copyable 36-byte struct, so moving it offers no performance benefit and only complicates the API. All call sites are updated to pass the outpoint directly instead of via std::move() or temporary copies. The coin itself is still moved. This is a pure maintainability/style change with no functional or security impact.
Changed components
src/coins.cppsrc/coins.hsrc/validation.cpptest files onlyInspect captured patch +10 / −10
diff --git a/src/coins.cpp b/src/coins.cpp
index c403e006..a532573b 100644
--- a/src/coins.cpp
+++ b/src/coins.cpp
@@ -108,9 +108,9 @@ void CCoinsViewCache::AddCoin(const COutPoint &outpoint, Coin&& coin, bool possi
(bool)it->second.coin.IsCoinBase());
}
-void CCoinsViewCache::EmplaceCoinInternalDANGER(COutPoint&& outpoint, Coin&& coin) {
+void CCoinsViewCache::EmplaceCoinInternalDANGER(const COutPoint& outpoint, Coin&& coin) {
const auto mem_usage{coin.DynamicMemoryUsage()};
- auto [it, inserted] = cacheCoins.try_emplace(std::move(outpoint), std::move(coin));
+ auto [it, inserted] = cacheCoins.try_emplace(outpoint, std::move(coin));
if (inserted) {
CCoinsCacheEntry::SetDirty(*it, m_sentinel);
++m_dirty_count;
diff --git a/src/coins.h b/src/coins.h
index ae7f34f4..48b68d08 100644
--- a/src/coins.h
+++ b/src/coins.h
@@ -471,7 +471,7 @@ public:
* NOT FOR GENERAL USE. Used only when loading coins from a UTXO snapshot.
* @sa ChainstateManager::PopulateAndValidateSnapshot()
*/
- void EmplaceCoinInternalDANGER(COutPoint&& outpoint, Coin&& coin);
+ void EmplaceCoinInternalDANGER(const COutPoint& outpoint, Coin&& coin);
/**
* Spend a coin. Pass moveto in order to get the deleted data.
diff --git a/src/test/coins_tests.cpp b/src/test/coins_tests.cpp
index 14ccb1c4..9d728536 100644
--- a/src/test/coins_tests.cpp
+++ b/src/test/coins_tests.cpp
@@ -193,7 +193,7 @@ void SimulationTest(CCoinsView* base, bool fake_best_block)
coin = newcoin;
}
if (COutPoint op(txid, 0); !stack.back()->map().contains(op) && !newcoin.out.scriptPubKey.IsUnspendable() && m_rng.randbool()) {
- stack.back()->EmplaceCoinInternalDANGER(std::move(op), std::move(newcoin));
+ stack.back()->EmplaceCoinInternalDANGER(op, std::move(newcoin));
} else {
stack.back()->AddCoin(op, std::move(newcoin), /*possible_overwrite=*/!coin.IsSpent() || m_rng.randbool());
}
@@ -1109,11 +1109,11 @@ BOOST_AUTO_TEST_CASE(ccoins_emplace_duplicate_keeps_usage_balanced)
const COutPoint outpoint{Txid::FromUint256(m_rng.rand256()), m_rng.rand32()};
const Coin coin1{CTxOut{m_rng.randrange(10), CScript{} << m_rng.randbytes(CScriptBase::STATIC_SIZE + 1)}, 1, false};
- cache.EmplaceCoinInternalDANGER(COutPoint{outpoint}, Coin{coin1});
+ cache.EmplaceCoinInternalDANGER(outpoint, Coin{coin1});
cache.SelfTest();
const Coin coin2{CTxOut{m_rng.randrange(20), CScript{} << m_rng.randbytes(CScriptBase::STATIC_SIZE + 2)}, 2, false};
- cache.EmplaceCoinInternalDANGER(COutPoint{outpoint}, Coin{coin2});
+ cache.EmplaceCoinInternalDANGER(outpoint, Coin{coin2});
cache.SelfTest();
BOOST_CHECK(cache.AccessCoin(outpoint) == coin1);
@@ -1132,7 +1132,7 @@ BOOST_AUTO_TEST_CASE(ccoins_reset_guard)
const COutPoint outpoint{Txid::FromUint256(m_rng.rand256()), m_rng.rand32()};
const Coin coin{CTxOut{m_rng.randrange(10), CScript{} << m_rng.randbytes(CScriptBase::STATIC_SIZE + 1)}, 1, false};
- cache.EmplaceCoinInternalDANGER(COutPoint{outpoint}, Coin{coin});
+ cache.EmplaceCoinInternalDANGER(outpoint, Coin{coin});
BOOST_CHECK_EQUAL(cache.GetDirtyCount(), 1U);
uint256 cache_best_block{m_rng.rand256()};
diff --git a/src/test/coinsviewoverlay_tests.cpp b/src/test/coinsviewoverlay_tests.cpp
index 6b20b312..6f75dc82 100644
--- a/src/test/coinsviewoverlay_tests.cpp
+++ b/src/test/coinsviewoverlay_tests.cpp
@@ -48,7 +48,7 @@ void PopulateView(const CBlock& block, CCoinsView& view, bool spent = false)
for (const auto& in : tx->vin) {
Coin coin{};
if (!spent) coin.out.nValue = 1;
- cache.EmplaceCoinInternalDANGER(COutPoint{in.prevout}, std::move(coin));
+ cache.EmplaceCoinInternalDANGER(in.prevout, std::move(coin));
}
}
diff --git a/src/test/fuzz/coins_view.cpp b/src/test/fuzz/coins_view.cpp
index c11581d2..a8f79bef 100644
--- a/src/test/fuzz/coins_view.cpp
+++ b/src/test/fuzz/coins_view.cpp
@@ -115,7 +115,7 @@ void TestCoinsView(FuzzedDataProvider& fuzzed_data_provider, CCoinsViewCache& co
const bool possible_overwrite{coins_view_cache.PeekCoin(outpoint) || fuzzed_data_provider.ConsumeBool()};
coins_view_cache.AddCoin(outpoint, std::move(coin), possible_overwrite);
} else {
- coins_view_cache.EmplaceCoinInternalDANGER(std::move(outpoint), std::move(coin));
+ coins_view_cache.EmplaceCoinInternalDANGER(outpoint, std::move(coin));
}
},
[&] {
diff --git a/src/validation.cpp b/src/validation.cpp
index 7dd1b2b6..45032c2b 100644
--- a/src/validation.cpp
+++ b/src/validation.cpp
@@ -5812,7 +5812,7 @@ util::Result<void> ChainstateManager::PopulateAndValidateSnapshot(
return util::Error{Untranslated(strprintf("Bad snapshot data after deserializing %d coins - bad tx out value",
coins_count - coins_left))};
}
- coins_cache.EmplaceCoinInternalDANGER(std::move(outpoint), std::move(coin));
+ coins_cache.EmplaceCoinInternalDANGER(outpoint, std::move(coin));
--coins_left;
++coins_processed;
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.