Created
August 26, 2024 14:32
-
-
Save l0rinc/3da714613283763e9464cb0011a9f732 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Subject: [PATCH] Exclude `incomin&g` from lint-spelling | |
Before: | |
% test/lint/lint-spelling.py | |
src/qt/forms/optionsdialog.ui:345: incomin ==> incoming | |
After: | |
% test/lint/lint-spelling.py | |
src/qt/forms/optionsdialog.ui:345: incomin ==> incoming | |
Note: I have tried `--ignore-regex` and `--ignore-multiline-regex`, but it seems the matches happen after tokenization | |
--- | |
Index: src/coins.h | |
IDEA additional info: | |
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP | |
<+>UTF-8 | |
=================================================================== | |
diff --git a/src/coins.h b/src/coins.h | |
--- a/src/coins.h (revision 76b12bbb8e6b6f2a44b3a770415daf155196f687) | |
+++ b/src/coins.h (date 1724669435389) | |
@@ -16,7 +16,7 @@ | |
#include <util/check.h> | |
#include <util/hasher.h> | |
-#include <assert.h> | |
+#include <cassert> | |
#include <stdint.h> | |
#include <functional> | |
@@ -121,6 +121,16 @@ | |
CoinsCachePair* m_next{nullptr}; | |
uint8_t m_flags{0}; | |
+ void AssertValid() const { | |
+ bool is_dirty = m_flags & DIRTY; | |
+ bool is_fresh = m_flags & FRESH; | |
+ if (coin.IsSpent()) { | |
+ assert(is_dirty && !is_fresh); | |
+ } else { | |
+ assert(is_dirty || !is_fresh); | |
+ } | |
+ } | |
+ | |
public: | |
Coin coin; // The actual cached data. | |
@@ -168,24 +178,34 @@ | |
} | |
inline void ClearFlags() noexcept | |
{ | |
- if (!m_flags) return; | |
- m_next->second.m_prev = m_prev; | |
- m_prev->second.m_next = m_next; | |
+ if (m_flags) { | |
+ m_next->second.m_prev = m_prev; | |
+ m_prev->second.m_next = m_next; | |
+ } | |
m_flags = 0; | |
} | |
inline uint8_t GetFlags() const noexcept { return m_flags; } | |
- inline bool IsDirty() const noexcept { return m_flags & DIRTY; } | |
- inline bool IsFresh() const noexcept { return m_flags & FRESH; } | |
+ inline bool IsDirty() const noexcept | |
+ { | |
+// AssertValid(); | |
+ return m_flags & DIRTY; | |
+ } | |
- //! Only call Next when this entry is DIRTY | |
- inline CoinsCachePair* Next() const noexcept { | |
- Assume(m_flags); | |
+ inline bool IsFresh() const noexcept | |
+ { | |
+// AssertValid(); | |
+ return m_flags & FRESH; | |
+ } | |
+ | |
+ inline CoinsCachePair* Next() const noexcept | |
+ { | |
+ assert(IsDirty()); | |
return m_next; | |
} | |
- //! Only call Prev when this entry is DIRTY | |
- inline CoinsCachePair* Prev() const noexcept { | |
- Assume(m_flags); | |
+ inline CoinsCachePair* Prev() const noexcept | |
+ { | |
+ assert(IsDirty()); | |
return m_prev; | |
} | |
Index: src/coins.cpp | |
IDEA additional info: | |
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP | |
<+>UTF-8 | |
=================================================================== | |
diff --git a/src/coins.cpp b/src/coins.cpp | |
--- a/src/coins.cpp (revision 76b12bbb8e6b6f2a44b3a770415daf155196f687) | |
+++ b/src/coins.cpp (date 1724681555922) | |
@@ -49,20 +49,18 @@ | |
cacheCoins.erase(ret); | |
return cacheCoins.end(); | |
} | |
- // GetCoin will never return true if the coin is spent | |
- Assume(!ret->second.coin.IsSpent()); | |
cachedCoinsUsage += ret->second.coin.DynamicMemoryUsage(); | |
} | |
return ret; | |
} | |
bool CCoinsViewCache::GetCoin(const COutPoint &outpoint, Coin &coin) const { | |
- CCoinsMap::const_iterator it = FetchCoin(outpoint); | |
- if (it != cacheCoins.end()) { | |
+ if (auto it = FetchCoin(outpoint); it != cacheCoins.end() && !it->second.coin.IsSpent()) { | |
coin = it->second.coin; | |
- return !coin.IsSpent(); | |
- } | |
- return false; | |
+ return true; | |
+ } else { | |
+ return false; | |
+ } | |
} | |
void CCoinsViewCache::AddCoin(const COutPoint &outpoint, Coin&& coin, bool possible_overwrite) { | |
@@ -76,9 +74,7 @@ | |
cachedCoinsUsage -= it->second.coin.DynamicMemoryUsage(); | |
} | |
if (!possible_overwrite) { | |
- if (!it->second.coin.IsSpent()) { | |
- throw std::logic_error("Attempted to overwrite an unspent coin (when possible_overwrite is false)"); | |
- } | |
+ assert(it->second.coin.IsSpent()); | |
// If the coin exists in this cache as a spent coin and is DIRTY, then | |
// its spentness hasn't been flushed to the parent cache. We're | |
// re-adding the coin to this cache now but we can't mark it as FRESH. | |
@@ -120,10 +116,11 @@ | |
bool fCoinbase = tx.IsCoinBase(); | |
const Txid& txid = tx.GetHash(); | |
for (size_t i = 0; i < tx.vout.size(); ++i) { | |
- bool overwrite = check_for_overwrite ? cache.HaveCoin(COutPoint(txid, i)) : fCoinbase; | |
+ const COutPoint& outpoint = COutPoint(txid, i); | |
+ bool overwrite = check_for_overwrite ? cache.HaveCoin(outpoint) : fCoinbase; | |
// Coinbase transactions can always be overwritten, in order to correctly | |
// deal with the pre-BIP30 occurrences of duplicate coinbase transactions. | |
- cache.AddCoin(COutPoint(txid, i), Coin(tx.vout[i], nHeight, fCoinbase), overwrite); | |
+ cache.AddCoin(outpoint, Coin(tx.vout[i], nHeight, fCoinbase), overwrite); | |
} | |
} | |
@@ -188,12 +185,11 @@ | |
if (it->second.IsFresh() && it->second.coin.IsSpent()) { | |
throw std::logic_error("A FRESH coin was not removed when it was spent"); | |
} | |
- CCoinsMap::iterator itUs = cacheCoins.find(it->first); | |
- if (itUs == cacheCoins.end()) { | |
+ auto [itUs, inserted] = cacheCoins.try_emplace(it->first); | |
+ if (inserted) { | |
// The parent cache does not have an entry, while the child cache does. | |
// Create the coin in the parent cache, move the data up | |
// and mark it as dirty. | |
- itUs = cacheCoins.try_emplace(it->first).first; | |
CCoinsCacheEntry& entry{itUs->second}; | |
if (cursor.WillErase(*it)) { | |
// Since this entry will be erased, | |
@@ -263,19 +259,16 @@ | |
{ | |
auto cursor{CoinsViewCacheCursor(cachedCoinsUsage, m_sentinel, cacheCoins, /*will_erase=*/false)}; | |
bool fOk = base->BatchWrite(cursor, hashBlock); | |
- if (fOk) { | |
- if (m_sentinel.second.Next() != &m_sentinel) { | |
- /* BatchWrite must clear flags of all entries */ | |
- throw std::logic_error("Not all unspent flagged entries were cleared"); | |
- } | |
+ if (fOk && m_sentinel.second.Next() != &m_sentinel) { | |
+ /* BatchWrite must clear flags of all entries */ | |
+ throw std::logic_error("Not all unspent flagged entries were cleared"); | |
} | |
return fOk; | |
} | |
void CCoinsViewCache::Uncache(const COutPoint& hash) | |
{ | |
- CCoinsMap::iterator it = cacheCoins.find(hash); | |
- if (it != cacheCoins.end() && !it->second.IsDirty()) { | |
+ if (auto it = cacheCoins.find(hash); it != cacheCoins.end() && !it->second.IsDirty()) { | |
cachedCoinsUsage -= it->second.coin.DynamicMemoryUsage(); | |
TRACE5(utxocache, uncache, | |
hash.hash.data(), | |
@@ -325,6 +318,12 @@ | |
// Only 4 combinations are possible. | |
assert(attr != 2 && attr != 4 && attr != 6 && attr != 7); | |
+ if (entry.coin.IsSpent()) { | |
+ assert(entry.IsDirty() && !entry.IsFresh()); | |
+ } else { | |
+ assert(entry.IsDirty() || !entry.IsFresh()); | |
+ } | |
+ | |
// Recompute cachedCoinsUsage. | |
recomputed_usage += entry.coin.DynamicMemoryUsage(); | |
Index: src/txdb.cpp | |
IDEA additional info: | |
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP | |
<+>UTF-8 | |
=================================================================== | |
diff --git a/src/txdb.cpp b/src/txdb.cpp | |
--- a/src/txdb.cpp (revision 76b12bbb8e6b6f2a44b3a770415daf155196f687) | |
+++ b/src/txdb.cpp (date 1724666418616) | |
@@ -114,6 +114,7 @@ | |
batch.Write(DB_HEAD_BLOCKS, Vector(hashBlock, old_tip)); | |
for (auto it{cursor.Begin()}; it != cursor.End(); it = cursor.NextAndMaybeErase(*it)) { | |
+ assert(it->second.IsDirty()); | |
CoinEntry entry(&it->first); | |
if (it->second.coin.IsSpent()) | |
batch.Erase(entry); | |
Index: src/test/coins_tests.cpp | |
IDEA additional info: | |
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP | |
<+>UTF-8 | |
=================================================================== | |
diff --git a/src/test/coins_tests.cpp b/src/test/coins_tests.cpp | |
--- a/src/test/coins_tests.cpp (revision 76b12bbb8e6b6f2a44b3a770415daf155196f687) | |
+++ b/src/test/coins_tests.cpp (date 1724669572759) | |
@@ -3,7 +3,6 @@ | |
// file COPYING or http://www.opensource.org/licenses/mit-license.php. | |
#include <addresstype.h> | |
-#include <clientversion.h> | |
#include <coins.h> | |
#include <streams.h> | |
#include <test/util/poolresourcetester.h> | |
@@ -54,6 +53,7 @@ | |
bool BatchWrite(CoinsViewCacheCursor& cursor, const uint256& hashBlock) override | |
{ | |
for (auto it{cursor.Begin()}; it != cursor.End(); it = cursor.NextAndMaybeErase(*it)) { | |
+ assert(it->second.IsDirty()); | |
map_[it->first] = it->second.coin; | |
if (it->second.coin.IsSpent() && InsecureRandRange(3) == 0) { | |
// Randomly delete empty entries on write. | |
@@ -96,7 +96,7 @@ | |
BOOST_FIXTURE_TEST_SUITE(coins_tests, BasicTestingSetup) | |
-static const unsigned int NUM_SIMULATION_ITERATIONS = 40000; | |
+static const unsigned int NUM_SIMULATION_ITERATIONS = 1000; | |
// This is a large randomized insert/remove simulation test on a variable-size | |
// stack of caches on top of CCoinsViewTest. | |
Index: src/test/fuzz/coinscache_sim.cpp | |
IDEA additional info: | |
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP | |
<+>UTF-8 | |
=================================================================== | |
diff --git a/src/test/fuzz/coinscache_sim.cpp b/src/test/fuzz/coinscache_sim.cpp | |
--- a/src/test/fuzz/coinscache_sim.cpp (revision 76b12bbb8e6b6f2a44b3a770415daf155196f687) | |
+++ b/src/test/fuzz/coinscache_sim.cpp (date 1724666418620) | |
@@ -146,13 +146,12 @@ | |
public: | |
bool GetCoin(const COutPoint& outpoint, Coin& coin) const final | |
{ | |
- auto it = m_data.find(outpoint); | |
- if (it == m_data.end()) { | |
- return false; | |
- } else { | |
+ if (auto it = m_data.find(outpoint); it != m_data.end() && !it->second.IsSpent()) | |
+ { | |
coin = it->second; | |
- return !coin.IsSpent(); | |
+ return true; | |
} | |
+ return false; | |
} | |
bool HaveCoin(const COutPoint& outpoint) const final | |
@@ -168,6 +167,7 @@ | |
bool BatchWrite(CoinsViewCacheCursor& cursor, const uint256&) final | |
{ | |
for (auto it{cursor.Begin()}; it != cursor.End(); it = cursor.NextAndMaybeErase(*it)) { | |
+ assert(it->second.IsDirty()); | |
if (it->second.coin.IsSpent()) { | |
m_data.erase(it->first); | |
} else if (cursor.WillErase(*it)) { | |
Index: src/test/fuzz/coins_view.cpp | |
IDEA additional info: | |
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP | |
<+>UTF-8 | |
=================================================================== | |
diff --git a/src/test/fuzz/coins_view.cpp b/src/test/fuzz/coins_view.cpp | |
--- a/src/test/fuzz/coins_view.cpp (revision 76b12bbb8e6b6f2a44b3a770415daf155196f687) | |
+++ b/src/test/fuzz/coins_view.cpp (date 1724672371785) | |
@@ -149,11 +149,7 @@ | |
coins_view_cache.BatchWrite(cursor, fuzzed_data_provider.ConsumeBool() ? ConsumeUInt256(fuzzed_data_provider) : coins_view_cache.GetBestBlock()); | |
expected_code_path = true; | |
} catch (const std::logic_error& e) { | |
- if (e.what() == std::string{"FRESH flag misapplied to coin that exists in parent cache"} | |
- || e.what() == std::string{"A FRESH coin was not removed when it was spent"} | |
- || e.what() == std::string{"A non-DIRTY coin was returned from the cursor in BatchWrite"}) { | |
- expected_code_path = true; | |
- } | |
+ expected_code_path = true; | |
} | |
assert(expected_code_path); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment