Skip to content

Commit

Permalink
refactor: pcoinsTip -> CChainState::CoinsTip()
Browse files Browse the repository at this point in the history
This aliasing makes subsequent commits easier to review; eventually CoinsTip()
will return the CCoinsViewCache managed by CChainState.
  • Loading branch information
jamesob committed Aug 6, 2019
1 parent e5fdda6 commit fae6ab6
Show file tree
Hide file tree
Showing 13 changed files with 70 additions and 58 deletions.
2 changes: 1 addition & 1 deletion src/interfaces/node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ class NodeImpl : public Node
bool getUnspentOutput(const COutPoint& output, Coin& coin) override
{
LOCK(::cs_main);
return ::pcoinsTip->GetCoin(output, coin);
return ::ChainstateActive().CoinsTip().GetCoin(output, coin);
}
std::string getWalletDir() override
{
Expand Down
9 changes: 5 additions & 4 deletions src/net_processing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1291,11 +1291,12 @@ bool static AlreadyHave(const CInv& inv) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
LOCK(g_cs_orphans);
if (mapOrphanTransactions.count(inv.hash)) return true;
}
const CCoinsViewCache& coins_cache = ::ChainstateActive().CoinsTip();

return recentRejects->contains(inv.hash) ||
mempool.exists(inv.hash) ||
pcoinsTip->HaveCoinInCache(COutPoint(inv.hash, 0)) || // Best effort: only try output 0 and 1
pcoinsTip->HaveCoinInCache(COutPoint(inv.hash, 1));
coins_cache.HaveCoinInCache(COutPoint(inv.hash, 0)) || // Best effort: only try output 0 and 1
coins_cache.HaveCoinInCache(COutPoint(inv.hash, 1));
}
case MSG_BLOCK:
case MSG_WITNESS_BLOCK:
Expand Down Expand Up @@ -1844,7 +1845,7 @@ void static ProcessOrphanTx(CConnman* connman, std::set<uint256>& orphan_work_se
EraseOrphanTx(orphanHash);
done = true;
}
mempool.check(pcoinsTip.get());
mempool.check(&::ChainstateActive().CoinsTip());
}
}

Expand Down Expand Up @@ -2497,7 +2498,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr

if (!AlreadyHave(inv) &&
AcceptToMemoryPool(mempool, state, ptx, &fMissingInputs, &lRemovedTxn, false /* bypass_limits */, 0 /* nAbsurdFee */)) {
mempool.check(pcoinsTip.get());
mempool.check(&::ChainstateActive().CoinsTip());
RelayTransaction(tx.GetHash(), *connman);
for (unsigned int i = 0; i < tx.vout.size(); i++) {
auto it_by_prev = mapOrphanTransactionsByPrev.find(COutPoint(inv.hash, i));
Expand Down
3 changes: 1 addition & 2 deletions src/node/coin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@
void FindCoins(std::map<COutPoint, Coin>& coins)
{
LOCK2(cs_main, ::mempool.cs);
assert(pcoinsTip);
CCoinsViewCache& chain_view = *::pcoinsTip;
CCoinsViewCache& chain_view = ::ChainstateActive().CoinsTip();
CCoinsViewMemPool mempool_view(&chain_view, ::mempool);
for (auto& coin : coins) {
if (!mempool_view.GetCoin(coin.first, coin.second)) {
Expand Down
2 changes: 1 addition & 1 deletion src/node/transaction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ TransactionError BroadcastTransaction(const CTransactionRef tx, std::string& err
LOCK(cs_main);
// If the transaction is already confirmed in the chain, don't do anything
// and return early.
CCoinsViewCache &view = *pcoinsTip;
CCoinsViewCache &view = ::ChainstateActive().CoinsTip();
for (size_t o = 0; o < tx->vout.size(); o++) {
const Coin& existingCoin = view.AccessCoin(COutPoint(hashTx, o));
// IsSpent doesnt mean the coin is spent, it means the output doesnt' exist.
Expand Down
4 changes: 2 additions & 2 deletions src/rest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -503,12 +503,12 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart)
if (fCheckMemPool) {
// use db+mempool as cache backend in case user likes to query mempool
LOCK2(cs_main, mempool.cs);
CCoinsViewCache& viewChain = *pcoinsTip;
CCoinsViewCache& viewChain = ::ChainstateActive().CoinsTip();
CCoinsViewMemPool viewMempool(&viewChain, mempool);
process_utxos(viewMempool, mempool);
} else {
LOCK(cs_main); // no need to lock mempool!
process_utxos(*pcoinsTip, CTxMemPool());
process_utxos(::ChainstateActive().CoinsTip(), CTxMemPool());
}

for (size_t i = 0; i < hits.size(); ++i) {
Expand Down
11 changes: 7 additions & 4 deletions src/rpc/blockchain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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 */
Expand Down
6 changes: 3 additions & 3 deletions src/rpc/rawtransaction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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

Expand Down
6 changes: 3 additions & 3 deletions src/test/miner_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
CBlockIndex* prev = ::ChainActive().Tip();
CBlockIndex* next = new CBlockIndex();
next->phashBlock = new uint256(InsecureRand256());
pcoinsTip->SetBestBlock(next->GetBlockHash());
::ChainstateActive().CoinsTip().SetBestBlock(next->GetBlockHash());
next->pprev = prev;
next->nHeight = prev->nHeight + 1;
next->BuildSkip();
Expand All @@ -384,7 +384,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
CBlockIndex* prev = ::ChainActive().Tip();
CBlockIndex* next = new CBlockIndex();
next->phashBlock = new uint256(InsecureRand256());
pcoinsTip->SetBestBlock(next->GetBlockHash());
::ChainstateActive().CoinsTip().SetBestBlock(next->GetBlockHash());
next->pprev = prev;
next->nHeight = prev->nHeight + 1;
next->BuildSkip();
Expand Down Expand Up @@ -414,7 +414,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
while (::ChainActive().Tip()->nHeight > nHeight) {
CBlockIndex* del = ::ChainActive().Tip();
::ChainActive().SetTip(del->pprev);
pcoinsTip->SetBestBlock(del->pprev->GetBlockHash());
::ChainstateActive().CoinsTip().SetBestBlock(del->pprev->GetBlockHash());
delete del->phashBlock;
delete del;
}
Expand Down
22 changes: 11 additions & 11 deletions src/test/txvalidationcache_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ BOOST_FIXTURE_TEST_CASE(tx_mempool_block_doublespend, TestChain100Setup)
BOOST_CHECK_EQUAL(mempool.size(), 0U);
}

// Run CheckInputs (using pcoinsTip) on the given transaction, for all script
// Run CheckInputs (using CoinsTip()) on the given transaction, for all script
// flags. Test that CheckInputs passes for all flags that don't overlap with
// the failing_flags argument, but otherwise fails.
// CHECKLOCKTIMEVERIFY and CHECKSEQUENCEVERIFY (and future NOP codes that may
Expand Down Expand Up @@ -125,7 +125,7 @@ static void ValidateCheckInputsForAllFlags(const CTransaction &tx, uint32_t fail
// WITNESS requires P2SH
test_flags |= SCRIPT_VERIFY_P2SH;
}
bool ret = CheckInputs(tx, state, pcoinsTip.get(), true, test_flags, true, add_to_cache, txdata, nullptr);
bool ret = CheckInputs(tx, state, &::ChainstateActive().CoinsTip(), true, test_flags, true, add_to_cache, txdata, nullptr);
// CheckInputs should succeed iff test_flags doesn't intersect with
// failing_flags
bool expected_return_value = !(test_flags & failing_flags);
Expand All @@ -135,13 +135,13 @@ static void ValidateCheckInputsForAllFlags(const CTransaction &tx, uint32_t fail
if (ret && add_to_cache) {
// Check that we get a cache hit if the tx was valid
std::vector<CScriptCheck> scriptchecks;
BOOST_CHECK(CheckInputs(tx, state, pcoinsTip.get(), true, test_flags, true, add_to_cache, txdata, &scriptchecks));
BOOST_CHECK(CheckInputs(tx, state, &::ChainstateActive().CoinsTip(), true, test_flags, true, add_to_cache, txdata, &scriptchecks));
BOOST_CHECK(scriptchecks.empty());
} else {
// Check that we get script executions to check, if the transaction
// was invalid, or we didn't add to cache.
std::vector<CScriptCheck> scriptchecks;
BOOST_CHECK(CheckInputs(tx, state, pcoinsTip.get(), true, test_flags, true, add_to_cache, txdata, &scriptchecks));
BOOST_CHECK(CheckInputs(tx, state, &::ChainstateActive().CoinsTip(), true, test_flags, true, add_to_cache, txdata, &scriptchecks));
BOOST_CHECK_EQUAL(scriptchecks.size(), tx.vin.size());
}
}
Expand Down Expand Up @@ -204,13 +204,13 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup)
CValidationState state;
PrecomputedTransactionData ptd_spend_tx(spend_tx);

BOOST_CHECK(!CheckInputs(CTransaction(spend_tx), state, pcoinsTip.get(), true, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_DERSIG, true, true, ptd_spend_tx, nullptr));
BOOST_CHECK(!CheckInputs(CTransaction(spend_tx), state, &::ChainstateActive().CoinsTip(), true, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_DERSIG, true, true, ptd_spend_tx, nullptr));

// If we call again asking for scriptchecks (as happens in
// ConnectBlock), we should add a script check object for this -- we're
// not caching invalidity (if that changes, delete this test case).
std::vector<CScriptCheck> scriptchecks;
BOOST_CHECK(CheckInputs(CTransaction(spend_tx), state, pcoinsTip.get(), true, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_DERSIG, true, true, ptd_spend_tx, &scriptchecks));
BOOST_CHECK(CheckInputs(CTransaction(spend_tx), state, &::ChainstateActive().CoinsTip(), true, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_DERSIG, true, true, ptd_spend_tx, &scriptchecks));
BOOST_CHECK_EQUAL(scriptchecks.size(), 1U);

// Test that CheckInputs returns true iff DERSIG-enforcing flags are
Expand All @@ -227,7 +227,7 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup)
block = CreateAndProcessBlock({spend_tx}, p2pk_scriptPubKey);
LOCK(cs_main);
BOOST_CHECK(::ChainActive().Tip()->GetBlockHash() == block.GetHash());
BOOST_CHECK(pcoinsTip->GetBestBlock() == block.GetHash());
BOOST_CHECK(::ChainstateActive().CoinsTip().GetBestBlock() == block.GetHash());

// Test P2SH: construct a transaction that is valid without P2SH, and
// then test validity with P2SH.
Expand Down Expand Up @@ -272,7 +272,7 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup)
invalid_with_cltv_tx.vin[0].scriptSig = CScript() << vchSig << 100;
CValidationState state;
PrecomputedTransactionData txdata(invalid_with_cltv_tx);
BOOST_CHECK(CheckInputs(CTransaction(invalid_with_cltv_tx), state, pcoinsTip.get(), true, SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY, true, true, txdata, nullptr));
BOOST_CHECK(CheckInputs(CTransaction(invalid_with_cltv_tx), state, ::ChainstateActive().CoinsTip(), true, SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY, true, true, txdata, nullptr));
}

// TEST CHECKSEQUENCEVERIFY
Expand Down Expand Up @@ -300,7 +300,7 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup)
invalid_with_csv_tx.vin[0].scriptSig = CScript() << vchSig << 100;
CValidationState state;
PrecomputedTransactionData txdata(invalid_with_csv_tx);
BOOST_CHECK(CheckInputs(CTransaction(invalid_with_csv_tx), state, pcoinsTip.get(), true, SCRIPT_VERIFY_CHECKSEQUENCEVERIFY, true, true, txdata, nullptr));
BOOST_CHECK(CheckInputs(CTransaction(invalid_with_csv_tx), state, &::ChainstateActive().CoinsTip(), true, SCRIPT_VERIFY_CHECKSEQUENCEVERIFY, true, true, txdata, nullptr));
}

// TODO: add tests for remaining script flags
Expand Down Expand Up @@ -362,12 +362,12 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup)
CValidationState state;
PrecomputedTransactionData txdata(tx);
// This transaction is now invalid under segwit, because of the second input.
BOOST_CHECK(!CheckInputs(CTransaction(tx), state, pcoinsTip.get(), true, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, true, true, txdata, nullptr));
BOOST_CHECK(!CheckInputs(CTransaction(tx), state, &::ChainstateActive().CoinsTip(), true, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, true, true, txdata, nullptr));

std::vector<CScriptCheck> scriptchecks;
// Make sure this transaction was not cached (ie because the first
// input was valid)
BOOST_CHECK(CheckInputs(CTransaction(tx), state, pcoinsTip.get(), true, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, true, true, txdata, &scriptchecks));
BOOST_CHECK(CheckInputs(CTransaction(tx), state, &::ChainstateActive().CoinsTip(), true, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, true, true, txdata, &scriptchecks));
// Should get 2 script checks back -- caching is on a whole-transaction basis.
BOOST_CHECK_EQUAL(scriptchecks.size(), 2U);
}
Expand Down
2 changes: 1 addition & 1 deletion src/txmempool.h
Original file line number Diff line number Diff line change
Expand Up @@ -497,7 +497,7 @@ class CTxMemPool
*
* 1. Locking both `cs_main` and `mempool.cs` will give a view of mempool
* that is consistent with current chain tip (`::ChainActive()` and
* `pcoinsTip`) and is fully populated. Fully populated means that if the
* `CoinsTip()`) and is fully populated. Fully populated means that if the
* current active chain is missing transactions that were present in a
* previously active chain, all the missing transactions will have been
* re-added to the mempool and should be present if they meet size and
Expand Down
Loading

0 comments on commit fae6ab6

Please sign in to comment.