aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJames O'Beirne <james.obeirne@gmail.com>2019-07-24 13:39:42 -0400
committerJames O'Beirne <james.obeirne@gmail.com>2019-08-15 11:19:40 -0400
commit582d2cd74754d6b9a2394616a9c82a89d2d71976 (patch)
tree6aca21d9b8481b465a74811fb9c2b97ddc9576c4 /src
parent569353068568444a25b301bbd6513bb510157dc9 (diff)
downloadbitcoin-582d2cd74754d6b9a2394616a9c82a89d2d71976.tar.xz
Cover UTXO set access with lock annotations
i.e. any CoinsViews members. Adds a lock acquisition to `gettxoutsetinfo` RPC to comply with added annotations. Co-authored-by: Russell Yanofsky <russ@yanofsky.org>
Diffstat (limited to 'src')
-rw-r--r--src/init.cpp7
-rw-r--r--src/rpc/blockchain.cpp4
-rw-r--r--src/validation.cpp7
-rw-r--r--src/validation.h18
4 files changed, 22 insertions, 14 deletions
diff --git a/src/init.cpp b/src/init.cpp
index 50ae0c6252..97be4637a6 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -235,8 +235,11 @@ void Shutdown(InitInterfaces& interfaces)
//
// g_chainstate is referenced here directly (instead of ::ChainstateActive()) because it
// may not have been initialized yet.
- if (g_chainstate && g_chainstate->CanFlushToDisk()) {
- g_chainstate->ForceFlushStateToDisk();
+ {
+ LOCK(cs_main);
+ if (g_chainstate && g_chainstate->CanFlushToDisk()) {
+ g_chainstate->ForceFlushStateToDisk();
+ }
}
// After there are no more peers/RPC left to give us new data which may generate
diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp
index 8061939a26..e3d5394a2c 100644
--- a/src/rpc/blockchain.cpp
+++ b/src/rpc/blockchain.cpp
@@ -1062,7 +1062,9 @@ static UniValue gettxoutsetinfo(const JSONRPCRequest& request)
CCoinsStats stats;
::ChainstateActive().ForceFlushStateToDisk();
- if (GetUTXOStats(&::ChainstateActive().CoinsDB(), stats)) {
+
+ CCoinsView* coins_view = WITH_LOCK(cs_main, return &ChainstateActive().CoinsDB());
+ if (GetUTXOStats(coins_view, stats)) {
ret.pushKV("height", (int64_t)stats.nHeight);
ret.pushKV("bestblock", stats.hashBlock.GetHex());
ret.pushKV("transactions", (int64_t)stats.nTransactions);
diff --git a/src/validation.cpp b/src/validation.cpp
index 0f24321aaf..8f44e2565a 100644
--- a/src/validation.cpp
+++ b/src/validation.cpp
@@ -314,7 +314,8 @@ bool CheckSequenceLocks(const CTxMemPool& pool, const CTransaction& tx, int flag
// Returns the script flags which should be checked for a given block
static unsigned int GetBlockScriptFlags(const CBlockIndex* pindex, const Consensus::Params& chainparams);
-static void LimitMempoolSize(CTxMemPool& pool, size_t limit, unsigned long age) EXCLUSIVE_LOCKS_REQUIRED(pool.cs)
+static void LimitMempoolSize(CTxMemPool& pool, size_t limit, unsigned long age)
+ EXCLUSIVE_LOCKS_REQUIRED(pool.cs, ::cs_main)
{
int expired = pool.Expire(GetTime() - age);
if (expired != 0) {
@@ -2160,7 +2161,9 @@ static void AppendWarning(std::string& res, const std::string& warn)
}
/** Check warning conditions and do some notifications on new chain tip set. */
-void static UpdateTip(const CBlockIndex *pindexNew, const CChainParams& chainParams) {
+void static UpdateTip(const CBlockIndex* pindexNew, const CChainParams& chainParams)
+ EXCLUSIVE_LOCKS_REQUIRED(::cs_main)
+{
// New best block
mempool.AddTransactionsUpdated(1);
diff --git a/src/validation.h b/src/validation.h
index 2a268d8cab..65f86e3070 100644
--- a/src/validation.h
+++ b/src/validation.h
@@ -519,14 +519,14 @@ class CoinsViews {
public:
//! The lowest level of the CoinsViews cache hierarchy sits in a leveldb database on disk.
//! All unspent coins reside in this store.
- CCoinsViewDB m_dbview;
+ CCoinsViewDB m_dbview GUARDED_BY(cs_main);
//! This view wraps access to the leveldb instance and handles read errors gracefully.
- CCoinsViewErrorCatcher m_catcherview;
+ CCoinsViewErrorCatcher m_catcherview GUARDED_BY(cs_main);
//! This is the top layer of the cache hierarchy - it keeps as many coins in memory as
//! can fit per the dbcache setting.
- std::unique_ptr<CCoinsViewCache> m_cacheview;
+ std::unique_ptr<CCoinsViewCache> m_cacheview GUARDED_BY(cs_main);
//! This constructor initializes CCoinsViewDB and CCoinsViewErrorCatcher instances, but it
//! *does not* create a CCoinsViewCache instance by default. This is done separately because the
@@ -537,7 +537,7 @@ public:
CoinsViews(std::string ldb_name, size_t cache_size_bytes, bool in_memory, bool should_wipe);
//! Initialize the CCoinsViewCache member.
- void InitCache();
+ void InitCache() EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
};
/**
@@ -609,11 +609,11 @@ public:
//! Initialize the in-memory coins cache (to be done after the health of the on-disk database
//! is verified).
- void InitCoinsCache();
+ void InitCoinsCache() EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
//! @returns whether or not the CoinsViews object has been fully initialized and we can
//! safely flush this object to disk.
- bool CanFlushToDisk() {
+ bool CanFlushToDisk() EXCLUSIVE_LOCKS_REQUIRED(cs_main) {
return m_coins_views && m_coins_views->m_cacheview;
}
@@ -629,21 +629,21 @@ public:
std::set<CBlockIndex*, CBlockIndexWorkComparator> setBlockIndexCandidates;
//! @returns A reference to the in-memory cache of the UTXO set.
- CCoinsViewCache& CoinsTip()
+ CCoinsViewCache& CoinsTip() EXCLUSIVE_LOCKS_REQUIRED(cs_main)
{
assert(m_coins_views->m_cacheview);
return *m_coins_views->m_cacheview.get();
}
//! @returns A reference to the on-disk UTXO set database.
- CCoinsViewDB& CoinsDB()
+ CCoinsViewDB& CoinsDB() EXCLUSIVE_LOCKS_REQUIRED(cs_main)
{
return m_coins_views->m_dbview;
}
//! @returns A reference to a wrapped view of the in-memory UTXO set that
//! handles disk read errors gracefully.
- CCoinsViewErrorCatcher& CoinsErrorCatcher()
+ CCoinsViewErrorCatcher& CoinsErrorCatcher() EXCLUSIVE_LOCKS_REQUIRED(cs_main)
{
return m_coins_views->m_catcherview;
}