Skip to content

Instantly share code, notes, and snippets.

@l0rinc
Created August 26, 2024 14:32
Show Gist options
  • Save l0rinc/3da714613283763e9464cb0011a9f732 to your computer and use it in GitHub Desktop.
Save l0rinc/3da714613283763e9464cb0011a9f732 to your computer and use it in GitHub Desktop.
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