From fae6ab6aed3b9fdc9201bb19a307dfc3d9b89891 Mon Sep 17 00:00:00 2001 From: James O'Beirne Date: Wed, 24 Jul 2019 11:45:04 -0400 Subject: refactor: pcoinsTip -> CChainState::CoinsTip() This aliasing makes subsequent commits easier to review; eventually CoinsTip() will return the CCoinsViewCache managed by CChainState. --- src/rpc/blockchain.cpp | 11 +++++++---- src/rpc/rawtransaction.cpp | 6 +++--- 2 files changed, 10 insertions(+), 7 deletions(-) (limited to 'src/rpc') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index b7dcd59c6d..c35c478f33 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -1126,19 +1126,21 @@ UniValue gettxout(const JSONRPCRequest& request) fMempool = request.params[2].get_bool(); Coin coin; + CCoinsViewCache* coins_view = &::ChainstateActive().CoinsTip(); + if (fMempool) { LOCK(mempool.cs); - CCoinsViewMemPool view(pcoinsTip.get(), mempool); + CCoinsViewMemPool view(coins_view, mempool); if (!view.GetCoin(out, coin) || mempool.isSpent(out)) { return NullUniValue; } } else { - if (!pcoinsTip->GetCoin(out, coin)) { + if (!coins_view->GetCoin(out, coin)) { return NullUniValue; } } - const CBlockIndex* pindex = LookupBlockIndex(pcoinsTip->GetBestBlock()); + const CBlockIndex* pindex = LookupBlockIndex(coins_view->GetBestBlock()); ret.pushKV("bestblock", pindex->GetBlockHash().GetHex()); if (coin.nHeight == MEMPOOL_HEIGHT) { ret.pushKV("confirmations", 0); @@ -1180,7 +1182,8 @@ static UniValue verifychain(const JSONRPCRequest& request) if (!request.params[1].isNull()) nCheckDepth = request.params[1].get_int(); - return CVerifyDB().VerifyDB(Params(), pcoinsTip.get(), nCheckLevel, nCheckDepth); + return CVerifyDB().VerifyDB( + Params(), &::ChainstateActive().CoinsTip(), nCheckLevel, nCheckDepth); } /** Implementation of IsSuperMajority with better feedback */ diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index 966c159f0f..ffbad45714 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -259,7 +259,7 @@ static UniValue gettxoutproof(const JSONRPCRequest& request) // Loop through txids and try to find which block they're in. Exit loop once a block is found. for (const auto& tx : setTxids) { - const Coin& coin = AccessByTxid(*pcoinsTip, tx); + const Coin& coin = AccessByTxid(::ChainstateActive().CoinsTip(), tx); if (!coin.IsSpent()) { pblockindex = ::ChainActive()[coin.nHeight]; break; @@ -636,7 +636,7 @@ static UniValue combinerawtransaction(const JSONRPCRequest& request) { LOCK(cs_main); LOCK(mempool.cs); - CCoinsViewCache &viewChain = *pcoinsTip; + CCoinsViewCache &viewChain = ::ChainstateActive().CoinsTip(); CCoinsViewMemPool viewMempool(&viewChain, mempool); view.SetBackend(viewMempool); // temporarily switch cache backend to db+mempool view @@ -1505,7 +1505,7 @@ UniValue utxoupdatepsbt(const JSONRPCRequest& request) CCoinsViewCache view(&viewDummy); { LOCK2(cs_main, mempool.cs); - CCoinsViewCache &viewChain = *pcoinsTip; + CCoinsViewCache &viewChain = ::ChainstateActive().CoinsTip(); CCoinsViewMemPool viewMempool(&viewChain, mempool); view.SetBackend(viewMempool); // temporarily switch cache backend to db+mempool view -- cgit v1.2.3 From 569353068568444a25b301bbd6513bb510157dc9 Mon Sep 17 00:00:00 2001 From: James O'Beirne Date: Wed, 24 Jul 2019 13:23:48 -0400 Subject: refactor: have CCoins* data managed under CChainState This change encapsulates UTXO set data within CChainState instances, removing global data `pcoinsTip` and `pcoinsviewdb`. This is necessary if we want to maintain multiple chainstates with their own rendering of the UTXO set. We introduce a class CoinsViews which consolidates the construction of a CCoins* hierarchy. Construction of its various pieces (db, coinscatcher, in-memory cache) is split up so that we avoid flushing bad state to disk if startup is interrupted. We also introduce `CChainState::CanFlushToDisk()` which tells us when it is safe to flush the chainstate based on this partial construction. This commit could be broken into smaller pieces, but it would require more ephemeral diffs to, e.g., temporarily change CCoinsViewDB's constructor invocations. Other changes: - A parameter has been added to the CCoinsViewDB constructor that allows the name of the corresponding leveldb directory to be specified. Thanks to Russell Yanofsky and Marco Falke for helpful feedback. --- src/rpc/blockchain.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/rpc') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index c35c478f33..8061939a26 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -1062,7 +1062,7 @@ static UniValue gettxoutsetinfo(const JSONRPCRequest& request) CCoinsStats stats; ::ChainstateActive().ForceFlushStateToDisk(); - if (GetUTXOStats(pcoinsdbview.get(), stats)) { + if (GetUTXOStats(&::ChainstateActive().CoinsDB(), stats)) { ret.pushKV("height", (int64_t)stats.nHeight); ret.pushKV("bestblock", stats.hashBlock.GetHex()); ret.pushKV("transactions", (int64_t)stats.nTransactions); @@ -2206,7 +2206,7 @@ UniValue scantxoutset(const JSONRPCRequest& request) { LOCK(cs_main); ::ChainstateActive().ForceFlushStateToDisk(); - pcursor = std::unique_ptr(pcoinsdbview->Cursor()); + pcursor = std::unique_ptr(::ChainstateActive().CoinsDB().Cursor()); assert(pcursor); } bool res = FindScriptPubKey(g_scan_progress, g_should_abort_scan, count, pcursor.get(), needles, coins); -- cgit v1.2.3 From 582d2cd74754d6b9a2394616a9c82a89d2d71976 Mon Sep 17 00:00:00 2001 From: James O'Beirne Date: Wed, 24 Jul 2019 13:39:42 -0400 Subject: 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 --- src/rpc/blockchain.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/rpc') 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); -- cgit v1.2.3