tree-wide: De-globalize ChainstateManager #20158

pull dongcarl wants to merge 70 commits into bitcoin:master from dongcarl:2020-06-libbitcoinruntime changing 40 files +668 −660
  1. dongcarl commented at 6:28 pm on October 15, 2020: member

    Prelude

    Note to reviewers: Currently looking Code Review on Sub-PRs (see below)

    Originally: #20049

    Sub-PRs

    Last updated May 9th, 2020

    • #20323 | tests: Create or use existing properly initialized NodeContexts
    • #20946 | fuzz: Consolidate fuzzing TestingSetup initialization
    • #20972 | locks: Annotate CTxMemPool::check to require cs_main
    • #20749 | [Bundle 1/n] Prune g_chainman usage related to ::LookupBlockIndex
    • #20750 | [Bundle 2/n] Prune g_chainman usage in mempool-related validation functions
    • #21055 | [Bundle 3/n] Prune remaining g_chainman usage in validation functions
    • #21270 | [Bundle 4/n] Prune g_chainman usage in validation-adjacent modules
    • #21391 | [Bundle 5/n] Prune g_chainman usage in RPC modules
    • #21767 | [Bundle 6/n] Prune g_chainman usage in auxiliary modules
    • #21866 | [Bundle 7/n] Farewell, global Chainstate!

    Todo List

    Last updated Feb 1st, 2020

    Motivation

    Modularizing our consensus engine

    Excerpt from #20049

    From my reading of past conversations and from a few offline chats, it seems that modularizing our consensus engine is a worthwhile first step towards a more complete isolation of said engine from non-consensus code.

    Modularizing our consensus engine means that:

    1. We get clearer visibility into what currently lies in consensus codepaths and what depends on our consensus engine
    2. We can coalesce duplicate consensus initialization codepaths, mitigating against bugs that arise out of test/non-test initialization inconsistencies

    De-globalizing g_chainman

    Excerpt from #20049

    In order to modularize our consensus engine, we need to first de-globalize the global ChainstateManager – namely g_chainman – as it and its dependencies are what makes up the bulk of our consensus engine. A few direct references to g_chainman have already been removed in #19927, however, its indirect uses (mainly via ::Chain(state|)Active()) are numerous in our codebase and often used to cheat avoid obtaining a ChainstateManager reference.

    Description

    This changeset moves the global ChainstateManger to NodeContext and removes ::Chain{state,}Active() as a first step towards better modularization of our consensus engine.

    The commits are ordered as such:

    1. Fixes to our existing codebase crucial to subsequent changes in this changeset https://github.com/bitcoin/bitcoin/compare/master...dongcarl:2020-10-chainman-fixes
    2. Remove all references to g_chainman, ::Chain{state,}Active()
      1. In src/validation.{cpp,h}
        1. In a bundle of functions related to ::LookupBlockIndex in the call graph https://github.com/dongcarl/bitcoin/compare/2020-10-chainman-fixes...dongcarl:2020-09-libbitcoinruntime-v4
        2. In a bundle of functions that are mempool-related https://github.com/dongcarl/bitcoin/compare/dongcarl:2020-09-libbitcoinruntime-v4...2020-09-reduce-validation-mempool-ccsactiveglobal-usage
        3. In a bundle of functions which do not belong in previous bundles https://github.com/dongcarl/bitcoin/compare/2020-09-reduce-validation-mempool-ccsactiveglobal-usage...dongcarl:2020-09-reduce-validation-ccsactiveglobal-usage
      2. In “validation-adjacent” modules of the codebase https://github.com/dongcarl/bitcoin/compare/dongcarl:2020-09-reduce-validation-ccsactiveglobal-usage...2020-09-libbitcoinruntime-v6
        1. In src/txmempool.cpp
        2. In src/miner.cpp
        3. In src/node
        4. In src/net_processing.cpp
      3. In RPC modules of the codebase https://github.com/dongcarl/bitcoin/compare/2020-09-libbitcoinruntime-v6...dongcarl:2020-10-libbitcoinruntime-v7
        1. In src/rpc
        2. In src/rest.cpp
      4. In auxiliary modules of the codebase https://github.com/dongcarl/bitcoin/compare/dongcarl:2020-10-libbitcoinruntime-v7...2020-10-libbitcoinruntime-v8
        1. In src/bench
        2. In src/index
      5. In initialization codepaths and tests https://github.com/dongcarl/bitcoin/compare/2020-10-libbitcoinruntime-v8...dongcarl:2020-06-libbitcoinruntime
        1. In src/init.cpp
        2. In src/test
        3. In src/wallet/test
        4. In src/qt/test

    A few things to note:

    • The above ordering is constructed according to the overall call graph of our codebase such that we avoid touching the same function/module twice.
    • Due to the length of this overall change, each commit aims to be trivially-reviewable and only requires the reviewer to reason about the correctness of one function/module at a time.
    • There are a lot of review-only assertions which can be used to check for correctness. They are removed in 2236237070a45fe570cd0113f0025b0a46ac89be.
  2. DrahtBot added the label Consensus on Oct 15, 2020
  3. DrahtBot added the label GUI on Oct 15, 2020
  4. DrahtBot added the label Mempool on Oct 15, 2020
  5. DrahtBot added the label Mining on Oct 15, 2020
  6. DrahtBot added the label P2P on Oct 15, 2020
  7. DrahtBot added the label RPC/REST/ZMQ on Oct 15, 2020
  8. DrahtBot added the label UTXO Db and Indexes on Oct 15, 2020
  9. DrahtBot added the label Validation on Oct 15, 2020
  10. DrahtBot added the label Wallet on Oct 15, 2020
  11. DrahtBot commented at 9:03 pm on October 15, 2020: member

    The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #21148 (Split orphan handling from net_processing into txorphanage by ajtowns)
    • #21146 ([WIP] validation/coins: limit MemPoolAccept access to coins cache by glozow)
    • #21142 (fuzz: Add tx_pool fuzz target by MarcoFalke)
    • #21121 ([test] Small unit test improvements, including helper to make mempool transaction by amitiuttarwar)
    • #21090 (Default to NODE_WITNESS in nLocalServices by dhruv)
    • #21062 (refactor: return MempoolAcceptResult from ATMP by glozow)
    • #21061 ([p2p] Introduce node rebroadcast module by amitiuttarwar)
    • #21009 (Remove RewindBlockIndex logic by dhruv)
    • #21003 (test: Move MakeNoLogFileContext to libtest_util, and use it in bench by MarcoFalke)
    • #20942 ([refactor] Move some net_processing globals into PeerManagerImpl by ajtowns)
    • #20925 (RFC: Move Peer and PeerManagerImpl declarations to separate header by jnewbery)
    • #20799 (net processing: Only support version 2 compact blocks by jnewbery)
    • #20750 ([Bundle 2/n] Prune g_chainman usage in mempool-related validation functions by dongcarl)
    • #20729 (p2p: standardize outbound full/block relay connection type naming by jonatack)
    • #20726 (p2p: Add DISABLETX message for negotiating block-relay-only connections by sdaftuar)
    • #20429 (refactor: replace (sizeof(a)/sizeof(a[0])) with C++17 std::size by theStack)
    • #20331 (allow -loadblock blocks to be unsorted by LarryRuane)
    • #19806 (validation: UTXO snapshot activation by jamesob)
    • #19573 (Replace unused BIP 9 logic with draft BIP 8 by luke-jr)
    • #19438 (Introduce deploymentstatus by ajtowns)
    • #19259 (fuzz: Add fuzzing harness for LoadMempool(…) and DumpMempool(…) by practicalswift)
    • #16981 (Improve runtime performance of –reindex by LarryRuane)
    • #15946 (Allow maintaining the blockfilterindex when using prune by jonasschnelli)

    If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

  12. laanwj commented at 10:01 am on October 16, 2020: member
    Concept ACK.
  13. jamesob commented at 4:03 pm on October 16, 2020: member
    Concept ACK - really like the direction of this work.
  14. in src/validation.cpp:155 in 8615dbd125 outdated
    169@@ -170,11 +170,12 @@ namespace {
    170     std::set<int> setDirtyFileInfo;
    171 } // anon namespace
    172 
    173-CBlockIndex* LookupBlockIndex(const uint256& hash)
    174+CBlockIndex* BlockManager::LookupBlockIndex(const uint256& hash)
    


    ryanofsky commented at 9:41 pm on October 22, 2020:

    In commit “validation: Move LookupBlockIndex to BlockManager” (8615dbd1250c2dddec2f54bf80e2a1b7013bc871)

    Commit doesn’t compile, not sure if this is intended. Could make this a wrapper function until after the scripted diff


    dongcarl commented at 7:20 pm on November 4, 2020:
    Done!
  15. in src/validation.h:423 in 8dbedcb3bf outdated
    436@@ -440,6 +437,9 @@ class BlockManager
    437 
    438     CBlockIndex* LookupBlockIndex(const uint256& hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
    439 
    440+    /** Find the last common block between the parameter chain and a locator. */
    441+    CBlockIndex* FindForkInGlobalIndex(const CChain& chain, const CBlockLocator& locator) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
    


    ryanofsky commented at 9:47 pm on October 22, 2020:

    In commit “validation: Move FindForkInGlobalIndex to BlockManager” (8dbedcb3bf123411ebcd9ccb7521b44cacc8e385)

    re: “Let me know if this should be changed”, this makes sense to me. A possible alternative might be to make this a chain method, too

  16. in src/txmempool.cpp:635 in 05a9e983b4 outdated
    631@@ -632,7 +632,7 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const
    632     uint64_t innerUsage = 0;
    633 
    634     CCoinsViewCache mempoolDuplicate(const_cast<CCoinsViewCache*>(pcoins));
    635-    const int64_t spendheight = GetSpendHeight(mempoolDuplicate);
    636+    const int64_t spendheight = WITH_LOCK(::cs_main, return g_chainman.m_blockman.GetSpendHeight(mempoolDuplicate));
    


    ryanofsky commented at 9:57 pm on October 22, 2020:

    In commit “validation: Move GetSpendHeight to BlockManager” (05a9e983b421f7728c6cf4c18525abba8a68c82a)

    This isn’t changing behavior, but I don’t think it’s correct to lock cs_main after mempool.cs. Other code locks in the opposite order so there could be a deadlock if cs_main lock is actually acquired here and this isn’t a redundant recursive lock. Maybe it is possible to clean this up simply by annotating CTxMemPool::check to already require cs_main.


    ryanofsky commented at 9:34 pm on October 23, 2020:

    re: #20158 (review)

    In commit “validation: Move GetSpendHeight to BlockManager” (05a9e98)

    This isn’t changing behavior, but I don’t think it’s correct to lock cs_main after mempool.cs. Other code locks in the opposite order so there could be a deadlock if cs_main lock is actually acquired here and this isn’t a redundant recursive lock. Maybe it is possible to clean this up simply by annotating CTxMemPool::check to already require cs_main.

    Another way to address this could be to move later commit 0af807545a93891df691acb43e07fd465c996ecd up, and pass the height into check() instead of locking cs_main to figure out the height. Though it seems like cs_main probably needs to be held during the whole check() call anyway and maybe it should just be annotated


    dongcarl commented at 6:53 pm on November 4, 2020:

    The reason why I thought it’d be okay to lock cs_main after mempool.cs was because that’s basically what’s happening in GetSpendHeight prior to this changeset. As in:

    1. We lock mempool.cs at the start of CTxMemPool::check
    2. We call GetSpendHeight, which locks cs_main

    Are you saying that this was wrong all along?


    ryanofsky commented at 3:14 pm on November 10, 2020:

    re: #20158 (review)

    In commit “validation: Move GetSpendHeight to BlockManager” (f2fded4d0d938eec936076a65bfab6932b73fb50)

    The reason why I thought it’d be okay to lock cs_main after mempool.cs was because that’s basically what’s happening in GetSpendHeight prior to this changeset. As in:

    1. We lock mempool.cs at the start of CTxMemPool::check
    2. We call GetSpendHeight, which locks cs_main

    Are you saying that this was wrong all along?

    Yes that can’t be right because if you have different threads that lock two mutexes, all the threads have to lock the mutexes in the same order to prevent deadlocks:

    0$ git grep -n LOCK2.*mempool
    1src/interfaces/chain.cpp:408:        LOCK2(::cs_main, m_node.mempool->cs);
    2src/miner.cpp:119:    LOCK2(cs_main, m_mempool.cs);
    3src/node/coin.cpp:14:    LOCK2(cs_main, node.mempool->cs);
    4src/rest.cpp:553:            LOCK2(cs_main, mempool->cs);
    5src/rpc/rawtransaction.cpp:1610:        LOCK2(cs_main, mempool.cs);
    

    Probably the lock should be a lock assert.


    dongcarl commented at 4:52 pm on February 1, 2021:
  17. in src/validation.h:670 in 7e15a2c88e outdated
    666@@ -672,7 +667,7 @@ class CChainState {
    667     bool ActivateBestChain(
    668         BlockValidationState& state,
    669         const CChainParams& chainparams,
    670-        std::shared_ptr<const CBlock> pblock) LOCKS_EXCLUDED(cs_main);
    671+        std::shared_ptr<const CBlock> pblock = std::shared_ptr<const CBlock>()) LOCKS_EXCLUDED(cs_main);
    


    ryanofsky commented at 10:07 pm on October 22, 2020:

    In commit “validation: Remove global ::ActivateBestChain” (7e15a2c88e49ec6719997e2cdd8481ddd4e7f6be)

    Would seem clearer to say = nullptr if that works and you don’t prefer this longer version


    dongcarl commented at 7:19 pm on November 4, 2020:
    Fixed!
  18. in src/validation.cpp:4976 in b60c7e5a5a outdated
    5035@@ -5036,24 +5036,6 @@ CBlockFileInfo* GetBlockFileInfo(size_t n)
    5036     return &vinfoBlockFile.at(n);
    5037 }
    5038 
    5039-ThresholdState VersionBitsTipState(const Consensus::Params& params, Consensus::DeploymentPos pos)
    5040-{
    5041-    LOCK(cs_main);
    


    ryanofsky commented at 10:33 pm on October 22, 2020:

    In commit “validation: Remove global ::VersionBitsTip{State,SinceHeight,Statistics}” (b60c7e5a5a60fe60a3bc8ba540dc7c8d5c935869)

    I’m a little unclear why it’s safe to drop these locks, or why they were here to begin with, or if VersionBits or ChainActive or Tip functions should have been annotated to require cs_main. It seems like something should have be annotated if cs_main was required here


    dongcarl commented at 7:19 pm on November 4, 2020:

    Digging in the git history a bit, it seems that the earliest of this trio – namely VersionBitsTipState – was introduced in d23f6c6a0d2. My hypothesis is that the LOCK(cs_main) was added in order to stop the chain from advancing and make sure that the caller got info on the actual tip. However, it seems like a AssertLockHeld(cs_main); annotation would have been much more suitable in that case (and existed in the codebase at d23f6c6a0d2).

    I’m not entirely sure about the original intent here, so perhaps @sipa can enlighten me and make sure I’m not missing something!


    ariard commented at 1:12 am on November 8, 2020:
    At least add a comment about the fact the cs_main lock is already taken in this code path L1317 (src/rpc/blockchain.cpp) ?

    ryanofsky commented at 3:38 pm on November 10, 2020:

    re: #20158 (review)

    In commit “validation: Remove global ::VersionBitsTip{State,SinceHeight,Statistics}” (ff894f9f710118a13b51f2496e1261c795844840)

    Digging in the git history a bit, it seems that the earliest of this trio – namely VersionBitsTipState – was introduced in d23f6c6.

    Thanks for checking! I see EXCLUSIVE_LOCKS_REQUIRED(cs_main) is used where the new code is called so there should not actually be a concern here.

    At least add a comment about the fact the cs_main lock is already taken in this code path L1317 (src/rpc/blockchain.cpp) ?

    Line 1317 seems to be referring to LOCK(cs_main) getblockchaininfo. Writing a comment referencing a specific lock in a specific calling function seems a little fragile, and hopefully unnecessary with EXCLUSIVE_LOCKS_REQUIRED(cs_main) annotation.


    dongcarl commented at 10:24 pm on December 18, 2020:
    @ariard @ryanofsky would it be preferable to add a EXCLUSIVE_LOCKS_REQUIRED(cs_main) annotation to VersionBitsTip{State,SinceHeight,Statistics} here just in case they get new callers in the future?

    ryanofsky commented at 1:38 pm on December 22, 2020:

    re: #20158 (review)

    In commit “validation: Remove global ::VersionBitsTip{State,SinceHeight,Statistics}” (6ed743d86fb1b5466076eaacf1e8ebc830abde62)

    @ariard @ryanofsky would it be preferable to add a EXCLUSIVE_LOCKS_REQUIRED(cs_main) annotation to VersionBitsTip{State,SinceHeight,Statistics} here just in case they get new callers in the future?

    I’d keep what you have now unless there’s a reason to think conclusion from digging into history is incorrect.

    It would be confusing to add a lock required annotation if we don’t think a lock is required. In theory you could write EXCLUSIVE_LOCKS_REQUIRED(cs_main) with a comment “There is no known reason to think a lock is required to call this function, but the original code had an explicit recursive lock, so locking is stilll required to be conservative in case there is an unknown reason locking is needed.” This would probably be overkill though.

  19. ryanofsky commented at 10:41 pm on October 22, 2020: member

    This is all pretty straightforward. I suppose I’m about halfway done reviewing (will update list below with progress).

    • b419519dd2535ad1e4a62f7ea151cc22672057be test: Add new ChainTestingSetup and use it (1/79)
    • ef1b08c0738da2248fbddc0190320f5ed34b7f44 bench: [FIX] Use existing NodeContext in WalletBalance benchmarks (2/79)
    • a9539e725bb109fb8d98970223fa8eff6a582b4a wallet/test: [FIX] Use existing NodeContext in wallet_tests (3/79)
    • b927d6891eb21d364e92a6e4363836e3e9849a24 qt/test: [FIX] Add forgotten Context setting in RPCNestedTests (4/79)
    • 8615dbd1250c2dddec2f54bf80e2a1b7013bc871 validation: Move LookupBlockIndex to BlockManager (5/79)
    • 7ef17f7a52fcce19fa9380ca876310b14ae3c803 scripted-diff: Use BlockManager::LookupBlockIndex (6/79)
    • 8dbedcb3bf123411ebcd9ccb7521b44cacc8e385 validation: Move FindForkInGlobalIndex to BlockManager (7/79)
    • 05a9e983b421f7728c6cf4c18525abba8a68c82a validation: Move GetSpendHeight to BlockManager (8/79)
    • 6d66fca3cfa891554ed1840df9231de91e60a5f1 validation: Move GetLastCheckpoint to BlockManager (9/79)
    • 8f2aadb89fdfe36274743352048382bafb6c389d validation: Pass in blockman to ContextualCheckBlockHeader (10/79)
    • 867330aedfd4dc12379bc0dcd27c50c26a5ebd9f validation: Make CChainState.m_blockman public (11/79)
    • dfdb9eaa9c1ff62696c07cf38f5b7b7efcce8b2a validation: Pass in chainstate to TestBlockValidity (12/79)
    • af1e05864588309a50e36c927d343b06a8bfe5ce validation: Pass in chainstate to ::NotifyHeaderTip (13/79)
    • 7e15a2c88e49ec6719997e2cdd8481ddd4e7f6be validation: Remove global ::ActivateBestChain (14/79)
    • 2f2e8a23959ad8f5dcd9d568af0019274a2757df validation: Move LoadExternalBlockFile to CChainState (15/79)
    • 18fab989be1b994f27fd607a12180694c0836337 validation: Use existing chainstate in ChainstateManager::ProcessNewBlockHeaders (16/79)
    • 0fc234246f068dfe969ef8ea9461186a857a8b57 validation: Use existing chainman in ChainstateManager::ProcessNewBlock (17/79)
    • 0cca6ce81f1bd4852b4bf8963164d38c1fe60491 validation: Pass in chainstate to ::LimitMempoolSize (18/79)
    • 27586e82658d6bf4c4600a7c5e220b145293e899 validation: Pass in chainstate to IsCurrentForFeeEstimation (19/79)
    • 72b4896f5c8ceb3fdead4381260821e6d6f4b9bd validation: Pass in chainstate to CheckInputsFromMempoolAndCache (20/79)
    • 6ca04c8deca436cb98bfe8206dd3d2a29737c672 validation: Pass in chain tip to ::CheckFinalTx (21/79)
    • 6c57bfbfd1a755b3db156ff2c7b1db65652eb684 scripted-diff: Invoke ::CheckFinalTx with chain tip (22/79)
    • ea1cedfd4a4eff5bf58b6be2f098fa01f8c36231 validation: Pass in chainstate to ::CheckSequenceLocks (23/79)
    • bf33651c004f2bafc8cf60c882543f3e5e9a9224 validation: Add chainstate member to MemPoolAccept (24/79)
    • dcbfe76e89370962aae2cf100263ea9ea608b084 validation: Pass in chainstate to AcceptToMemoryPoolWithTime (25/79)
    • 44970c069aa24c4b9daf214424c326719b03fd5e validation: Pass in chainstate to ::LoadMempool (26/79)
    • a1c43172255c958ae37abf1d2476d5f5c4e99bf1 validation: Pass in chainstate to ::AcceptToMemoryPool (27/79)
    • d6c12f35a5d1a62365874d46f290e759e77c34c8 scripted-diff: Invoke ::AcceptToMemoryPool with chainstate (28/79)
    • 96d7c6853eb11a10b5cd04ae6af4ebd549074fa8 tree-wide: Fix erroneous AcceptToMemoryPool replacements (29/79)
    • e9b18db098728caf0bd1bca1a6eba73807abf9a6 validation: Pass in chain to ::TestLockPointValidity (30/79)
    • 0cc108613620673b6ec0340bc44f48cf0f69dd91 validation: Pass in chainstate to CTxMemPool::removeForReorg (31/79)
    • d2c51fabc9336cfb43f3b6d2c0bb9cb34dc32d7b validation: Pass in chainstate to UpdateMempoolForReorg (32/79)
    • bd182bf90dfb61c083f8144ce5f2c7a82b545de5 validation: Use *this in CChainState::LoadMempool (33/79)
    • aa22d51cb358b810ee017f020593e18b8b5795d5 validation: Remove global ::LoadGenesisBlock (34/79)
    • 2629be14ea812bfe28717ba3e3eb7a0be54a8262 validation: Remove global ::{{Precious,Invalidate}Block,ResetBlockFailureFlags} (35/79)
    • e2857609c0f405a9088076f444c54fc5df27e489 validation: Pass in chainstate to UpdateTip (36/79)
    • d88dbdcdcf7f66c730d14007973696ec02e87ffc validation: Pass in chainstate to ::PruneBlockFilesManual (37/79)
    • b60c7e5a5a60fe60a3bc8ba540dc7c8d5c935869 validation: Remove global ::VersionBitsTip{State,SinceHeight,Statistics} (38/79)
    • d71c9415aaa0f5e40218bf8aa04763764ba00a2e validation: Pass in chainstate to CVerifyDB::VerifyDB (39/79)
    • ac517a557ce6d82ad9d25ad7218c572907b6e579 validation: Move invalid block handling to CChainState (40/79)
    • 2af348748db645c69995eee9daf307552760cde0 validation: Move LoadBlockIndexDB to CChainState (41/79)
    • be29d47b2f113a2fb40268589ba2bfa433c2792a validation: Use *this in CChainState::InvalidateBlock (42/79)
    • 0af807545a93891df691acb43e07fd465c996ecd validation: Pass in spendheight to CTxMemPool::check (43/79)
    • 9ffe170d7e431f3f64d52b5a38ff8fbc963cb191 validation: Use *this in CChainState::ActivateBestChainStep (44/79)
    • b81cbeea3dd0e6f2640bbcc57ba4228f944b593c validation: Pass in chain to FindBlockPos+SaveBlockToDisk (45/79)
    • 4067a37ad782d1b12f82540da448e3d4fe754d3a validation: Use existing chain member in CChainState::AcceptBlock (46/79)
    • 7494e811c152b492021a8a3bdac28a47e639dbe2 validation: Use existing chain member in CChainState::LoadGenesisBlock (47/79)
    • 9d74aa3fd30810197d24ec0768f3e28467abe114 miner: Add chainstate member to BlockAssembler (48/79)
    • f0802f74b5b2e1f6b1be06bbb104efbd1a7da397 scripted-diff: Construct BlockAssembler with chainstate (49/79)
    • a1acd859bd06ead8fb38fac2d10340a658d7a061 miner: Pass in blockman to ::RegenerateCommitments (50/79)
    • a9e77bb0a70a473aab0a52e0d411af8f692ab700 node/coinstats: Pass in CChainState to GetUTXOStats (51/79)
    • 9165950b1cbba037404572b774b46c0cd4a48c31 node: Use existing NodeContext (52/79)
    • 053c84ce5a99f0ef87fe23164dc11a0eac725680 net_processing: Move some static functions to PeerManager (53/79)
    • b09919fae00d80900d28ba4debc7aa5e3fe4c126 scripted-diff: net_processing: Use existing chainman (54/79)
    • afedcdf259bc55f2fffc81074a29f3570d1f8070 net_processing: Add review-only assertion to PeerManager (55/79)
    • 67e4b99446e6ad1788eb74abf4596b82745483ad rpc/*,rest: Add review-only assertion to EnsureChainman (56/79)
    • 11055b65f9e51060d3143c093ef74f4b4de4c57b rpc/blockchain: Use existing NodeContext (57/79)
    • b55de5c0e0fa32401c97f80078bcbef0f51ab6bf rpc/mining: Use existing NodeContext (58/79)
    • b776e175fd6173d89deff7616fbde1002385757e rpc/rawtx: Use existing NodeContext (59/79)
    • 5a6c0bf6f4657dba0de6fc09ed1fd3642313173f rest: Pass in NodeContext to rest_block (60/79)
    • 5451c5ae7eeadafb285bc909e0542fd517ff34a8 rest: Use existing NodeContext (61/79)
    • 6fe8909bbeeb1402e65e2363d1737c1acd108739 ifaces/chain: Reformat isInitialBlockDownload for scripted-diff (62/79)
    • c87ebae490d489d0221b4a0791734b9fba185287 scripted-diff: ifaces/chain: Use existing chainman (63/79)
    • 73c7eec16dfc3d74d31b766589fbba152520a16e ifaces/node: Reformat isInitialBlockDownload for scripted-diff (64/79)
    • e78349a4c3adbccae74d5577cf440842d8b8e63a scripted-diff: ifaces/node: Use existing chainman (65/79)
    • 5491653b8e2eb5469c6fafceb8e6337e1e804f6f bench: Use existing NodeContext in DuplicateInputs (66/79)
    • 7c352902d100497992ddaab6c7d01ad0726c6d20 bench: Use existing chainman in AssembleBlock (67/79)
    • 7d5c4da70071c632b3bba15e82d758be510455b9 index: Add chainstate member to BaseIndex (68/79)
    • a689f68e07a50859db0d2fd0335fa5fecd72a6e9 init: Use existing chainman (69/79)
    • aaa60e594043ea85873570966a5e6f0d240c8bb0 test/util: Use existing chainman in ::PrepareBlock (70/79)
    • 2852e6eded84be75aefee670135be16e47674508 test/miner_tests: Pass in chain tip to CreateBlockIndex (71/79)
    • 2b3e9c36145839bd87fdc686734dde3990c21b18 test: Pass in CoinsTip to ValidateCheckInputsForAllFlags (72/79)
    • 8617326a9122d34fe8a231138c3dd93dfc62bb32 scripted-diff: test: Use existing chainman in unit tests (73/79)
    • a19ee747bd40941b929eec4c5ccf9eca4ad4372f scripted-diff: wallet/test: Use existing chainman (74/79)
    • cbc113cc8653b87a33448a888e8f8cca8a0e8234 qt/test: Use existing chainman in ::TestGUI (can be scripted-diff) (75/79)
    • 09a153e13506d6352e478256ce4220232455000f scripted-diff: tree-wide: Remove all review-only assertions (76/79)
    • 92aa8fc5007f4f497fb5ded96140876b16090066 validation: Farewell, global Chainstate! (77/79)
    • 50f680b402a84b605aa9b9aa58cb571ef32e190e qt/test: No need to reset g_chainman anymore (78/79)
    • 2a05215114f2e4ebf764647af7e48ca1a8cb9ff9 miner: Remove review-only vestigial locks (79/79)
  20. in src/txmempool.cpp:636 in 0af807545a outdated
    632@@ -633,7 +633,7 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const
    633     uint64_t innerUsage = 0;
    634 
    635     CCoinsViewCache mempoolDuplicate(const_cast<CCoinsViewCache*>(pcoins));
    636-    const int64_t spendheight = WITH_LOCK(::cs_main, return g_chainman.m_blockman.GetSpendHeight(mempoolDuplicate));
    637+    assert(WITH_LOCK(::cs_main, return g_chainman.m_blockman.GetSpendHeight(mempoolDuplicate)) == spendheight); // TODO: REVIEW-ONLY, REMOVE IN FUTURE COMMIT
    


    ryanofsky commented at 9:24 pm on October 23, 2020:

    In commit “validation: Pass in spendheight to CTxMemPool::check” (0af807545a93891df691acb43e07fd465c996ecd)

    ~This is fine, but not sure if it was intentional to keep this TODO comment here, but not in the other asserts~

    EDIT: Apparently this is done to help the 09a153e13506d6352e478256ce4220232455000f scripted-diff, and the other asserts treat addressof as the TODO

  21. in src/miner.h:149 in 9d74aa3fd3 outdated
    145@@ -146,6 +146,7 @@ class BlockAssembler
    146     int64_t nLockTimeCutoff;
    147     const CChainParams& chainparams;
    148     const CTxMemPool& m_mempool;
    149+    CChainState& m_active_chainstate;
    


    ryanofsky commented at 9:50 pm on October 23, 2020:

    In commit “miner: Add chainstate member to BlockAssembler” (9d74aa3fd30810197d24ec0768f3e28467abe114)

    This appears to be safe because cs_main is held the entire time a BlockAssembler object is constructed is used cs_main is held, but because unlike m_mempool, m_active_chainstate will be able to change at runtime with utxo snapshot loading, it might be safer to just pass CChainState as a regular function argument to methods that need it. Another alternative would might be to add BlockAssembler documentation to say that it’s meant to be used and thrown away, not kept alive and reused, at least if the active chain might change

  22. in src/rpc/mining.cpp:381 in a1acd859bd outdated
    373@@ -374,7 +374,10 @@ static RPCHelpMan generateblock()
    374 
    375     // Add transactions
    376     block.vtx.insert(block.vtx.end(), txs.begin(), txs.end());
    377-    RegenerateCommitments(block);
    378+    {
    379+        LOCK(::cs_main);
    


    ryanofsky commented at 9:58 pm on October 23, 2020:

    In commit “miner: Pass in blockman to ::RegenerateCommitments” (a1acd859bd06ead8fb38fac2d10340a658d7a061)

    If this lock is needed now can RegenerateCommitments be annotated to require cs_main? Also, why is this lock needed now if it wasn’t needed before?

  23. in src/node/coinstats.cpp:57 in a9e77bb0a7 outdated
    53@@ -54,16 +54,18 @@ static void ApplyStats(CCoinsStats& stats, std::nullptr_t, const uint256& hash,
    54 
    55 //! Calculate statistics about the unspent transaction output set
    56 template <typename T>
    57-static bool GetUTXOStats(CCoinsView* view, CCoinsStats& stats, T hash_obj, const std::function<void()>& interruption_point)
    58+static bool GetUTXOStats(CChainState& chainstate, CCoinsStats& stats, T hash_obj, const std::function<void()>& interruption_point)
    


    ryanofsky commented at 10:03 pm on October 23, 2020:

    In commit “node/coinstats: Pass in CChainState to GetUTXOStats” (a9e77bb0a70a473aab0a52e0d411af8f692ab700)

    From the commit description “ATTENTION” this may be a work in progress, but a suggestion here might be to just pass in CCoinsView and blockman as separate arguments, instead of passing the whole chain state class.

  24. in src/net_processing.cpp:673 in 053c84ce5a outdated
    560@@ -563,41 +561,6 @@ static bool MarkBlockAsInFlight(CTxMemPool& mempool, NodeId nodeid, const uint25
    561     return true;
    562 }
    563 
    564-/** Check whether the last unknown block a peer advertised is not yet known. */
    


    ryanofsky commented at 10:09 pm on October 23, 2020:

    In commit “net_processing: Move some static functions to PeerManager” (053c84ce5a99f0ef87fe23164dc11a0eac725680)

    Might be nice to split this commit, and move the function bodies in a MOVEONLY commit. But this is maybe less important than it used to be now that git diff displays moved code better than it used to

  25. ryanofsky approved
  26. ryanofsky commented at 10:34 pm on October 23, 2020: member
    Code review near-ACK 2a05215114f2e4ebf764647af7e48ca1a8cb9ff9. Main change I’d like to see is for all the intermediate commits to compile and work. Otherwise this looks good and cleans up a lot of leftover mess from previous changes.
  27. ryanofsky commented at 4:20 pm on October 26, 2020: member

    Reproduced ci error locally https://cirrus-ci.com/task/5403931733917696?command=ci#L4078

    0git checkout 2a05215114f2e4ebf764647af7e48ca1a8cb9ff9
    1./autogen.sh
    2./configure CXX=clang++ CXXFLAGS="-fsanitize=address -fno-omit-frame-pointer" LDFLAGS=-fsanitize=address --enable-debug --enable-werror --disable-ccache
    3make -C src qt/test/test_bitcoin-qt && ASAN_OPTIONS=abort_on_error=1 gdb -ex run --args src/qt/test/test_bitcoin-qt
    
     0Thread 1 "b-test" received signal SIGABRT, Aborted.
     1__GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
     251      ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
     3(gdb) bt
     4[#0](/bitcoin-bitcoin/0/)  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
     5[#1](/bitcoin-bitcoin/1/)  0x00007ffff337f8b1 in __GI_abort () at abort.c:79
     6[#2](/bitcoin-bitcoin/2/)  0x0000555555ac21ab in __sanitizer::Abort() ()
     7[#3](/bitcoin-bitcoin/3/)  0x0000555555abf4d8 in __sanitizer::Die() ()
     8[#4](/bitcoin-bitcoin/4/)  0x0000555555aa175d in __asan::ReportGenericError(unsigned long, unsigned long, unsigned long, unsigned long, bool, unsigned long, unsigned int, bool) ()
     9[#5](/bitcoin-bitcoin/5/)  0x0000555555aa1f48 in __asan_report_load4 ()
    10[#6](/bitcoin-bitcoin/6/)  0x00005555575f4d03 in base_uint<256u>::CompareTo (this=0x60d00016c958, b=...) at arith_uint256.cpp:112
    11[#7](/bitcoin-bitcoin/7/)  0x000055555615213a in operator< (a=..., b=...) at ./arith_uint256.h:220
    12[#8](/bitcoin-bitcoin/8/)  0x0000555556a710e4 in BlockManager::AddToBlockIndex (this=0x611000129720, block=...) at validation.cpp:3183
    13[#9](/bitcoin-bitcoin/9/)  0x0000555556a9466d in CChainState::LoadGenesisBlock (this=0x612000101440, chainparams=...) at validation.cpp:4631
    14[#10](/bitcoin-bitcoin/10/) 0x0000555556d1dcaa in TestingSetup::TestingSetup (this=0x7fffffffb2b0, chainName="main", extra_args=std::vector of length 0, capacity 0) at test/util/setup_common.cpp:183
    15[#11](/bitcoin-bitcoin/11/) 0x0000555555af39df in RPCNestedTests::rpcNestedTests (this=0x7fffffffded0) at qt/test/rpcnestedtests.cpp:36
    16[#12](/bitcoin-bitcoin/12/) 0x0000555555b990be in RPCNestedTests::qt_static_metacall (_o=0x7fffffffded0, _c=QMetaObject::InvokeMetaMethod, _id=0, _a=0x7fffffffd2c0)
    17    at qt/test/moc_rpcnestedtests.cpp:70
    18[#13](/bitcoin-bitcoin/13/) 0x00007ffff6b9e003 in QMetaMethod::invoke(QObject*, Qt::ConnectionType, QGenericReturnArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument) const () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
    19[#14](/bitcoin-bitcoin/14/) 0x00007ffff66dc79a in ?? () from /usr/lib/x86_64-linux-gnu/libQt5Test.so.5
    20[#15](/bitcoin-bitcoin/15/) 0x00007ffff66dd4f0 in ?? () from /usr/lib/x86_64-linux-gnu/libQt5Test.so.5
    21[#16](/bitcoin-bitcoin/16/) 0x00007ffff66dda61 in ?? () from /usr/lib/x86_64-linux-gnu/libQt5Test.so.5
    22[#17](/bitcoin-bitcoin/17/) 0x00007ffff66de02b in QTest::qExec(QObject*, int, char**) () from /usr/lib/x86_64-linux-gnu/libQt5Test.so.5
    23[#18](/bitcoin-bitcoin/18/) 0x0000555555afead1 in main (argc=1, argv=0x7fffffffe298) at qt/test/test_main.cpp:85
    
  28. ryanofsky commented at 5:01 pm on October 26, 2020: member

    Following change partially reverting 50f680b402a84b605aa9b9aa58cb571ef32e190e seems to fix the error:

     0--- a/src/qt/test/apptests.cpp
     1+++ b/src/qt/test/apptests.cpp
     2@@ -84,6 +84,10 @@ void AppTests::appTests()
     3     // Reset global state to avoid interfering with later tests.
     4     LogInstance().DisconnectTestLogger();
     5     AbortShutdown();
     6+    {
     7+        LOCK(cs_main);
     8+        ::pindexBestHeader = nullptr;
     9+    }
    10 }
    11 
    12 //! Entry point for BitcoinGUI tests.
    

    Error is happening here:

    0[#8](/bitcoin-bitcoin/8/)  0x0000555556a710e4 in BlockManager::AddToBlockIndex (this=0x611000129860, block=...) at validation.cpp:3183
    13183        if (pindexBestHeader == nullptr || pindexBestHeader->nChainWork < pindexNew->nChainWork)
    
  29. dongcarl force-pushed on Oct 27, 2020
  30. dongcarl force-pushed on Oct 27, 2020
  31. dongcarl force-pushed on Oct 28, 2020
  32. practicalswift commented at 6:59 am on October 28, 2020: contributor
    Concept ACK
  33. in src/init.cpp:310 in 09daa42b60 outdated
    302@@ -303,6 +303,9 @@ void Shutdown(NodeContext& node)
    303     GetMainSignals().UnregisterBackgroundSignalScheduler();
    304     globalVerifyHandle.reset();
    305     ECC_Stop();
    306+    if (node.chainman) {
    307+        UnloadBlockIndex(node.mempool.get(), *node.chainman);
    308+    }
    309     node.mempool.reset();
    310     node.chainman = nullptr;
    


    jnewbery commented at 12:12 pm on October 28, 2020:
    I think this should be changed to reset() like the other unique pointers.
  34. in src/test/util/setup_common.h:89 in 09daa42b60 outdated
    81@@ -82,12 +82,17 @@ struct BasicTestingSetup {
    82     const fs::path m_path_root;
    83 };
    84 
    85+struct ChainTestingSetup : public BasicTestingSetup {
    


    jnewbery commented at 12:37 pm on October 28, 2020:
    This is only used in validation_chainstatemanager_tests.cpp. Rather than adding complexity to the common setup for all tests, can you define this struct inside validation_chainstatemanager_tests.cpp and leave setup_common unchanged?
  35. jnewbery commented at 12:46 pm on October 28, 2020: member

    Super duper concept ACK. Managing ChainstateManager’s lifetime and access through init and node.context is delightful.

    The first 4 commits to test/bench code could easily by sliced off into a small PR.

  36. dongcarl force-pushed on Nov 2, 2020
  37. dongcarl force-pushed on Nov 2, 2020
  38. in src/validation.h:422 in 5d587c26af outdated
    436@@ -440,6 +437,9 @@ class BlockManager
    437 
    438     CBlockIndex* LookupBlockIndex(const uint256& hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
    439 
    440+    /** Find the last common block between the parameter chain and a locator. */
    


    ariard commented at 6:22 pm on November 3, 2020:

    What would be the utility of finding a fork against a chain which isn’t the current active one ? May we have a future module interested in learning the common ancestor between a discovered locator and a chain known to not-be the best one ?

    E.g, in src/net_processing, at NetMsgType::GETBLOCKS reception, this common ancestor is used at a starting point to send the rest of the chain to the forked-off GETBLOCKS requester. IMO, I don’t see how it can be useful computation for a requester to chain-sync on a chain which is known as not being the best. Even if you don’t have live-access to the rest of the p2p network, you still have a notion of a most-work chain.

  39. in src/validation.h:429 in 4d1456824b outdated
    439@@ -440,6 +440,13 @@ class BlockManager
    440     /** Find the last common block between the parameter chain and a locator. */
    441     CBlockIndex* FindForkInGlobalIndex(const CChain& chain, const CBlockLocator& locator) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
    442 
    443+    /**
    444+     * Return the spend height, which is one more than the inputs.GetBestBlock().
    


    ariard commented at 6:32 pm on November 3, 2020:

    I think interpretation of this comment can be confusing.

    It does say “one more than the inputs.GetBestBlock()” where GetBestBlock is defined as “Get best block at the time this cursor was created” (L173, in src/coins.h). If GetSpendHeight means the spend height of a utxo, you may have between “one to infinite numbers of blocks” between utxo creation height and its spending height.

    But still the code of this function return pindexPrev->nHeight + 1 where pindexPrev is the indice of inputs.GetBestBlock(). So this function return the earliest valid spending height of a given utxo set ?


    ryanofsky commented at 3:25 pm on November 10, 2020:

    re: #20158 (review)

    I think interpretation of this comment can be confusing.

    Comment is not new, just moved.

    It does say “one more than the inputs.GetBestBlock()” where GetBestBlock is defined as “Get best block at the time this cursor was created” (L173, in src/coins.h). If GetSpendHeight means the spend height of a utxo, you may have between “one to infinite numbers of blocks” between utxo creation height and its spending height.

    But still the code of this function return pindexPrev->nHeight + 1 where pindexPrev is the indice of inputs.GetBestBlock(). So this function return the earliest valid spending height of a given utxo set ?

    Yes this seems all correct. I think there could be a standalone PR if the hope is to clarify something here, but on the surface this seems like a simple two line function and one sentence description of what the function returns. Nothing seems too related to this PR.

  40. in src/validation.cpp:3379 in c6a46621fc outdated
    3470@@ -3472,14 +3471,15 @@ std::vector<unsigned char> GenerateCoinbaseCommitment(CBlock& block, const CBloc
    3471 }
    3472 
    3473 //! Returns last CBlockIndex* that is a checkpoint
    3474-static CBlockIndex* GetLastCheckpoint(const CCheckpointData& data) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
    3475+CBlockIndex* BlockManager::GetLastCheckpoint(const CCheckpointData& data)
    3476 {
    


    ariard commented at 6:45 pm on November 3, 2020:

    Should you introduce a AssertLockHeld(cs_main) here to demonstrate the lock tacking is still enforced ? Some moved function (FindForkInGlobalIndex) already have such one.

    More generally, I think you PR description could talk about what the actual lock model of this subsystem and how do you convey to reviewers that old code lock model is equivalent to the new one (or not if you’ve changed some locks for good reasons).

  41. in src/validation.h:536 in 959f626823 outdated
    556 
    557 public:
    558+    //! Reference to a BlockManager instance which itself is shared across all
    559+    //! CChainState instances. Keeping a local reference allows us to test more
    560+    //! easily as opposed to referencing a global.
    561+    BlockManager& m_blockman GUARDED_BY(::cs_main);
    


    ariard commented at 6:55 pm on November 3, 2020:
    This comment can be improved by specifying how m_blockman is used by CChainState thus documenting the rational of its presence.
  42. ariard commented at 7:05 pm on November 3, 2020: member

    Reviewing at 3b36443, but so far I agree on the changeset and review approach, thanks for the clear PR description and commit organization.

    I’ve a branch with more comments here : https://github.com/ariard/bitcoin/tree/2020-06-libbitcoinruntime-rw, feel free to pick up what you like on your branch, suggestion commits are in-order and tagged REVIEW in their message.

  43. troygiorshev commented at 6:41 am on November 4, 2020: contributor
    Concept ACK, excited for this to be sliced into smaller PRs for deeper review!
  44. dongcarl force-pushed on Nov 5, 2020
  45. dongcarl force-pushed on Nov 5, 2020
  46. dongcarl commented at 7:01 pm on November 5, 2020: member
    Reviewers: Just split off the first few fix commits in a non-draft PR #20323!
  47. in src/validation.h:172 in 6a4f33ad98 outdated
    174@@ -175,13 +175,6 @@ void ThreadScriptCheck(int worker_num);
    175  * @returns                    The tx if found, otherwise nullptr
    176  */
    177 CTransactionRef GetTransaction(const CBlockIndex* const block_index, const CTxMemPool* const mempool, const uint256& hash, const Consensus::Params& consensusParams, uint256& hashBlock);
    178-/**
    179- * Find the best known block, and make it the tip of the block chain
    180- *
    181- * May not be called with cs_main held. May not be called in a
    


    ariard commented at 0:45 am on November 6, 2020:
    This comment still holds on CChainState::ActivateBestChain. But I wonder if it shouldn’t be changed to a “Must not be called with cs_main held given we assert that lock isn't held L2878 (src/validation.cpp`).

    dongcarl commented at 8:38 pm on November 17, 2020:
    Don’t think we need to add that bit, I think the rationale is more clearly explained by: https://github.com/bitcoin/bitcoin/blob/912512a27c1caa59eb928e10f1022d1b33c2d711/src/validation.cpp#L2867-L2871
  48. in src/validation.cpp:3765 in f8bb296937 outdated
    3860@@ -3860,18 +3861,18 @@ bool ChainstateManager::ProcessNewBlock(const CChainParams& chainparams, const s
    3861         bool ret = CheckBlock(*pblock, state, chainparams.GetConsensus());
    3862         if (ret) {
    3863             // Store to disk
    3864-            ret = ::ChainstateActive().AcceptBlock(pblock, state, chainparams, &pindex, fForceProcessing, nullptr, fNewBlock);
    3865+            ret = ActiveChainstate().AcceptBlock(pblock, state, chainparams, &pindex, fForceProcessing, nullptr, fNewBlock);
    


    ariard commented at 0:53 am on November 6, 2020:
    I think this commit message should say something like “Use accessible chainstate in ChainstateManager::ProcessNewBlock”
  49. in src/validation.h:204 in 5433a716e7 outdated
    217@@ -218,7 +218,7 @@ void UpdateCoins(const CTransaction& tx, CCoinsViewCache& inputs, int nHeight);
    218  *
    219  * See consensus/consensus.h for flag definitions.
    220  */
    221-bool CheckFinalTx(const CTransaction &tx, int flags = -1) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
    222+bool CheckFinalTx(CBlockIndex* active_chain_tip, const CTransaction &tx, int flags = -1) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
    


    ariard commented at 1:07 am on November 6, 2020:
    This commit doesn’t compile as CheckFinalTx is used L197 (src/interfaces/chain.cpp). But fixed in next commit AFAICT.

    ryanofsky commented at 4:27 pm on November 10, 2020:

    re: #20158 (review)

    This commit doesn’t compile as CheckFinalTx is used L197 (src/interfaces/chain.cpp). But fixed in next commit AFAICT.

    I’m seeing this problem in commit “validation: Pass in chain tip to ::CheckFinalTx” (5433a716e7f871204474117b0f9bdcd6ad8a16ce)

  50. ariard commented at 1:22 am on November 6, 2020: member
    Reviewed until 7cdd921
  51. fjahr commented at 7:20 pm on November 7, 2020: member
    Concept ACK
  52. in src/rpc/blockchain.cpp:1223 in ff894f9f71 outdated
    1219@@ -1220,7 +1220,7 @@ static void BIP9SoftForkDescPushBack(UniValue& softforks, const std::string &nam
    1220     if (consensusParams.vDeployments[id].nTimeout <= 1230768000) return;
    1221 
    1222     UniValue bip9(UniValue::VOBJ);
    1223-    const ThresholdState thresholdState = VersionBitsTipState(consensusParams, id);
    1224+    const ThresholdState thresholdState = VersionBitsState(::ChainActive().Tip(), consensusParams, id, versionbitscache);
    


    ariard commented at 1:11 am on November 8, 2020:
    Maybe add a friendly comment in commit about the fact that versionbitscache is currently a global and thus the stays the same. Though we can’t assert it ?
  53. in src/net_processing.cpp:2269 in d7db6ec342 outdated
    2051@@ -2052,7 +2052,9 @@ void PeerManager::ProcessOrphanTx(std::set<uint256>& orphan_work_set)
    2052             break;
    2053         }
    2054     }
    2055-    m_mempool.check(&::ChainstateActive().CoinsTip());
    2056+    CChainState& active_chainstate = m_chainman.ActiveChainstate();
    2057+    CCoinsViewCache& active_coins_tip = active_chainstate.CoinsTip();
    2058+    m_mempool.check(&active_coins_tip, active_chainstate.m_blockman.GetSpendHeight(active_coins_tip));
    


    ariard commented at 1:19 am on November 8, 2020:
    I don’t follow what you mean by commit message “This is the only instance where validation reaches for something outside of it”, you mean the mempool accessing spendheight ?

    dongcarl commented at 9:02 pm on November 17, 2020:
    I mean that in the codepath I’m touching, CChainState::ActivateBestChainStep (which resides in validation.cpp) is calling (reaching for) CTXMemPool::Check (which resides in txmempool.cpp), which means that I need to resolve CTXMemPool::Check’s reference of g_chainman first.
  54. in src/test/util/setup_common.cpp:220 in d227dfedfd outdated
    216@@ -217,7 +217,7 @@ CBlock TestChain100Setup::CreateAndProcessBlock(const std::vector<CMutableTransa
    217     for (const CMutableTransaction& tx : txns) {
    218         block.vtx.push_back(MakeTransactionRef(tx));
    219     }
    220-    RegenerateCommitments(block);
    221+    RegenerateCommitments(block, WITH_LOCK(::cs_main, return std::ref(g_chainman.m_blockman)));
    


    ariard commented at 1:39 am on November 8, 2020:

    Can we pass directly the result of LookupBlockIndex(block.hashPrevBlock) ? Block is already known here. Because AFAIU, the lock isn’t held once RegenerateCommitment argument are loaded on the stack thus do you have guarantee you’re calling the new blockman.LookupBlockIndex() with a lock ?

    I think so otherwise LookupBlockIndex’s lock annotation would yelled but I can’t convince myself of it…


    dongcarl commented at 9:28 pm on November 17, 2020:

    Right, this is a shitty situation where the lock in this diff is only needed because: https://github.com/bitcoin/bitcoin/blob/831675c8dccfa6525ffe751da3cc60709c380953/src/validation.h#L944 and https://github.com/bitcoin/bitcoin/blob/831675c8dccfa6525ffe751da3cc60709c380953/src/validation.h#L840

    Then the lock is released as RegenerateCommitments’s assembly function prologue is run, and the same lock is taken again when LookupBlockIndex is called inside RegenerateCommitments.

    The original reason why I wanted to just pass in the blockman is because I didn’t want to impose the constraint of “arg 2 must be the block index of arg 1” on RegenerateCommitments’s arguments, which seems like something that might be easy to cause a bug if someone were to work with multiple blocks or multiple block indices. Perhaps adequate documentation can prevent this?

  55. in src/net_processing.h:226 in 4cdf32b5ca outdated
    195+                                   BlockFilterIndex*& filter_index);
    196+    void ProcessGetCFilters(CNode& peer, CDataStream& vRecv, const CChainParams& chain_params,
    197+                                   CConnman& connman);
    198+    void ProcessGetCFHeaders(CNode& peer, CDataStream& vRecv, const CChainParams& chain_params,
    199+                                    CConnman& connman);
    200+    void ProcessGetCFCheckPt(CNode& peer, CDataStream& vRecv, const CChainParams& chain_params,
    


    ariard commented at 1:43 am on November 8, 2020:
    Maybe drag comments here ? Can’t remember the style policy on this.
  56. ariard commented at 1:54 am on November 8, 2020: member
    Approach ACK, sound work. I had a look on everything, though more lightly on tests-touching commits, I’ll try to review the first split-off soon.
  57. ryanofsky approved
  58. ryanofsky commented at 4:13 pm on November 10, 2020: member
    Code review ACK 912512a27c1caa59eb928e10f1022d1b33c2d711. Just rebase and responses to various suggestions since last review
  59. in src/validation.h:187 in f75c7ca1cb outdated
    191@@ -192,7 +192,7 @@ void PruneBlockFilesManual(int nManualPruneHeight);
    192 /** (try to) add transaction to memory pool
    193  * plTxnReplaced will be appended to with all transactions replaced from mempool
    194  * @param[out] fee_out optional argument to return tx fee to the caller **/
    195-bool AcceptToMemoryPool(CTxMemPool& pool, TxValidationState &state, const CTransactionRef &tx,
    196+bool AcceptToMemoryPool(CChainState& active_chainstate, CTxMemPool& pool, TxValidationState &state, const CTransactionRef &tx,
    


    ryanofsky commented at 4:36 pm on November 10, 2020:

    In commit “validation: Pass in chainstate to ::AcceptToMemoryPool” (f75c7ca1cb46eb5824c3c5db666143f9a74c0eda)

    This commit also doesn’t compile, looks like there are calls in net_processing to update

  60. MarcoFalke referenced this in commit a3586d5920 on Dec 9, 2020
  61. ryanofsky commented at 2:37 pm on December 18, 2020: member

    re: #20158#issue-504296351

    Current split-off PRs ready for review

    Last updated Nov 5th, 2020

    • #20323 | tests: Create or use existing properly initialized NodeContexts

    #20323 is now merged, so it would be good to post a followup or rebase this

  62. dongcarl force-pushed on Dec 18, 2020
  63. dongcarl commented at 10:13 pm on December 18, 2020: member

    Pushed 912512a27c1caa59eb928e10f1022d1b33c2d711 -> abcde917ddec206cd938d6d418094d5db645f740 | Thanks ryanofsky for the reminder!

    • Rebased over current master
    • All commits should now compile
  64. ryanofsky approved
  65. ryanofsky commented at 2:27 pm on December 22, 2020: member

    Code review ACK abcde917ddec206cd938d6d418094d5db645f740. Changes since last review: rebase, adding temporary CheckFinalTx, AcceptToMemoryPool, CreateNewBlock wrappers I think to fix intermediate commits, adding new temporary asserts in Node/Chain interfaces, dropping ::pindexBestHeader == null shutdown assert

    I see todo list includes resolving #20158 (review) about consistent cs_main/mempool.cs lock order for GetSpendHeight, and it would be nice to resolve, but it’s about preexisting behavior so maybe isn’t too important

  66. jnewbery commented at 5:45 pm on December 22, 2020: member
    @dongcarl are you planning on carving off some more commits into a separate PR? I’d love to help this make some progress.
  67. dongcarl commented at 5:47 pm on December 22, 2020: member
    @jnewbery Yup, got a bit caught up on other things but will open that first PR today!
  68. Sjors commented at 2:21 pm on December 30, 2020: member
    Concept ACK. Thanks for chopping this into smaller PR’s.
  69. dongcarl referenced this in commit 12e90007f6 on Jan 20, 2021
  70. dongcarl referenced this in commit b8ac27c636 on Jan 20, 2021
  71. dongcarl referenced this in commit b396467053 on Jan 20, 2021
  72. MarcoFalke referenced this in commit 1f45e85509 on Jan 21, 2021
  73. sidhujag referenced this in commit c0b3bb2d2a on Jan 21, 2021
  74. remyers referenced this in commit 3ccc0834cb on Jan 26, 2021
  75. dongcarl force-pushed on Jan 28, 2021
  76. laanwj referenced this in commit 44f4bcd302 on Feb 1, 2021
  77. jnewbery commented at 12:16 pm on February 1, 2021: member
    #20749 is merged. I think next up is #20750. @dongcarl - do you mind linking these bundle PRs in the PR description so it’s easy to see the project progress at a glance?
  78. dongcarl commented at 4:51 pm on February 1, 2021: member
    @jnewbery Good point, done!
  79. dongcarl force-pushed on Feb 1, 2021
  80. validation: Pass in chainstate to ::LimitMempoolSize 333d823afd
  81. validation: Pass in chainstate to IsCurrentForFeeEstimation 7f51417327
  82. validation: Pass in chainstate to CheckInputsFromMempoolAndCache e83c8538ec
  83. validation: Pass in chain tip to ::CheckFinalTx e5198eff4b
  84. scripted-diff: Invoke ::CheckFinalTx with chain tip
    -BEGIN VERIFY SCRIPT-
    find_regex='\bCheckFinalTx\(' \
        && git grep -l -E "$find_regex" -- src \
            | grep -v '^src/validation\.\(cpp\|h\)$' \
            | xargs sed -i -E 's@'"$find_regex"'@\0::ChainActive().Tip(), @g'
    -END VERIFY SCRIPT-
    6e0f4ae2ac
  85. validation: Remove old CheckFinalTx w/o chain tip param 3404ac0f1f
  86. validation: Pass in chainstate to ::CheckSequenceLocks 76e0811629
  87. validation: Add chainstate member to MemPoolAccept dd7e989b0a
  88. validation: Pass in chainstate to AcceptToMemoryPoolWithTime 7d90cf900a
  89. validation: Pass in chainstate to ::LoadMempool cffd76a750
  90. validation: Pass in chainstate to ::AcceptToMemoryPool 314c92bef1
  91. scripted-diff: Invoke ::AcceptToMemoryPool with chainstate
    -BEGIN VERIFY SCRIPT-
    find_regex='\bAcceptToMemoryPool\(' \
        && git grep -l -E "$find_regex" -- src \
            | grep -v '^src/validation\.\(cpp\|h\)$' \
            | xargs sed -i -E 's@'"$find_regex"'@\0::ChainstateActive(), @g'
    -END VERIFY SCRIPT-
    8b65ddd399
  92. validation: Remove old AcceptToMemoryPool w/o chainstate param 85f9844bc4
  93. tree-wide: Fix erroneous AcceptToMemoryPool replacements d722f7ddcd
  94. validation: Pass in chain to ::TestLockPointValidity b9185dc29a
  95. validation: Pass in chainstate to CTxMemPool::removeForReorg 28dd955dc0
  96. validation: Pass in chainstate to UpdateMempoolForReorg 5203b85220
  97. validation: Use *this in CChainState::LoadMempool 64db9d61f4
  98. COMMITS AFTER THIS ARE NON-BASE 107a028253
  99. validation: Remove global ::LoadGenesisBlock eb8fff3497
  100. validation: Remove global ::{{Precious,Invalidate}Block,ResetBlockFailureFlags} 7b76fdbbbd
  101. validation: Pass in chainstate to UpdateTip 403c5cbffd
  102. validation: Pass in chainstate to ::PruneBlockFilesManual 081631efcc
  103. validation: Remove global ::VersionBitsTip{State,SinceHeight,Statistics}
    Tip: versionbitscache is currently a global so we didn't need to pass it
         in to any of ::VersionBitsTip*'s callers
    a756ecb7bc
  104. validation: Pass in chainstate to CVerifyDB::VerifyDB bcf23b5283
  105. validation: Move invalid block handling to CChainState
    - InvalidChainFound
    - ForkWarningConditions
    - ForkWarningConditionsOnNewFork
    61a45ad2ba
  106. validation: Move LoadBlockIndexDB to CChainState
    CChainState needed cuz setBlockIndexCandidates
    fa730f7a87
  107. validation: Use *this in CChainState::InvalidateBlock 6b7cf5d996
  108. validation: Pass in spendheight to CTxMemPool::check
    This is the only instance where validation reaches for something outside
    of it.
    a765747415
  109. validation: Use *this in CChainState::ActivateBestChainStep 4582551c20
  110. validation: Pass in chain to FindBlockPos+SaveBlockToDisk 55a2f2cf55
  111. validation: Use existing chain member in CChainState::AcceptBlock 1886642f64
  112. validation: Use existing chain member in CChainState::LoadGenesisBlock f5ee2f3774
  113. COMMITS AFTER THIS ARE NON-BASE 15b6e6ad96
  114. miner: Pass in chainstate to BlockAssembler::CreateNewBlock f80378c8a5
  115. scripted-diff: Invoke CreateNewBlock with chainstate
    -BEGIN VERIFY SCRIPT-
    find_regex='(\.|->)CreateNewBlock\(' \
        && git grep -l -E "$find_regex" -- src \
            | grep -v '^src/miner\.\(cpp\|h\)$' \
            | xargs sed -i -E 's@'"$find_regex"'@\0::ChainstateActive(), @g'
    -END VERIFY SCRIPT-
    363d6d5351
  116. miner: Remove old CreateNewBlock w/o chainstate param ff5326300f
  117. miner: Pass in blockman to ::RegenerateCommitments
    REQUIRES ATTENTION
    4620ba194a
  118. node/coinstats: Pass in BlockManager to GetUTXOStats 05083dc127
  119. node: Use existing NodeContext 973fbe888f
  120. node/ifaces: NodeImpl: Use existing NodeContext member b652f403a5
  121. node/ifaces: ChainImpl: Use existing NodeContext member 1bd97da9d4
  122. net_processing: Move some static functions to PeerManager
    - BlockRequestAllowed
    - AlreadyHaveTx
    - AlreadyHaveBlock
    - ProcessGetBlockData
    - ProcessGetData
    - PrepareBlockFilterRequest
    - ProcessGetCFilters
    - ProcessGetCFHeaders
    - ProcessGetCFCheckPt
    
    Moved out of anonymous namespace:
    - ProcessBlockAvailability
    - UpdateBlockAvailability
    - CanDirectFetch
    - FindNextBlocksToDownload
    2ad7239a84
  123. scripted-diff: net_processing: Use existing chainman
    -BEGIN VERIFY SCRIPT-
    sed -i -E \
        -e 's/g_chainman/m_chainman/g' \
        -e 's@([^:])(Chain(state|)Active)@\1::\2@g' \
        -e 's@::Chain(state|)Active\(\)@m_chainman.ActiveChain\1()@g' \
        -- src/net_processing.cpp
    -END VERIFY SCRIPT-
    4328d09e69
  124. net_processing: Add review-only assertion to PeerManager 98904649c0
  125. COMMITS AFTER THIS ARE NON-BASE fa970fbfa9
  126. rpc/*,rest: Add review-only assertion to EnsureChainman 8919757c2b
  127. rpc/blockchain: Use existing NodeContext
    Also pass in appropriate object to:
    - BIP9SoftForkDescPushBack
    - BuriedForkDescPushBack
    1ac12e958d
  128. rpc/mining: Use existing NodeContext
    Also pass in appropriate object to:
    - GetNetworkHashPS
    - [gG]enerateBlock{,s}
    2cb0446d10
  129. rpc/rawtx: Use existing NodeContext
    Also pass in appropriate object to:
    - TxToJSON
    a910e41c6f
  130. rest: Pass in NodeContext to rest_block 0be47f8626
  131. rest: Use existing NodeContext 3a2a8cfa4a
  132. fixup! rpc/mining: Use existing NodeContext 2acbe46fce
  133. COMMITS AFTER THIS ARE NON-BASE 711f37ac3e
  134. bench: Use existing NodeContext in DuplicateInputs 409ebc3bc6
  135. bench: Use existing chainman in AssembleBlock 053893acdc
  136. index: Add chainstate member to BaseIndex b476400d84
  137. COMMITS AFTER THIS ARE NON-BASE 9cac0b0a69
  138. init: Use existing chainman e391187676
  139. test/util: Use existing chainman in ::PrepareBlock a7461a5c6b
  140. test/miner_tests: Pass in chain tip to CreateBlockIndex 755ceeac73
  141. test: Pass in CoinsTip to ValidateCheckInputsForAllFlags b38c3c9529
  142. scripted-diff: test: Use existing chainman in unit tests
    -BEGIN VERIFY SCRIPT-
    git ls-files -- src/test \
        | grep -v '^src/test/fuzz' \
        | xargs sed -i -E \
                -e 's@g_chainman\.m_blockman@m_node.chainman->m_blockman@g' \
                -e 's@([^:])(Chain(state|)Active)@\1::\2@g' \
                -e 's@::Chain(state|)Active\(\)@m_node.chainman->ActiveChain\1()@g'
    -END VERIFY SCRIPT-
    3d54028c48
  143. fuzz: Initialize a TestingSetup for test_one_input
    For fuzz tests that need it.
    c3efbcb2b9
  144. scripted-diff: wallet/test: Use existing chainman
    -BEGIN VERIFY SCRIPT-
    git ls-files -- src/wallet/test \
        | xargs sed -i -E \
                -e 's@g_chainman\.m_blockman@m_node.chainman->m_blockman@g' \
                -e 's@([^:])(Chain(state|)Active)@\1::\2@g' \
                -e 's@::Chain(state|)Active\(\)@m_node.chainman->ActiveChain\1()@g'
    -END VERIFY SCRIPT-
    b24576ecde
  145. qt/test: Use existing chainman in ::TestGUI (can be scripted-diff) 947b3c59d2
  146. miner: Remove stray review-only assertion
    Unfortunately, this assertion doesn't fit the regex in the
    scripted-diff. Therefore, we remove it manually.
    a3d401cb0b
  147. scripted-diff: tree-wide: Remove all review-only assertions
    -BEGIN VERIFY SCRIPT-
    git grep -lwE '(assert\(std::addressof|TODO: REVIEW-ONLY)' | xargs sed -i -E -e '/(assert\(std::addressof|TODO: REVIEW-ONLY)/d'
    -END VERIFY SCRIPT-
    9b3925b8be
  148. qt/test: Reset chainman in ~ChainstateManager instead
    There are some mutable, global state variables that are currently reset
    by UnloadBlockIndex such as pindexBestHeader which should be cleaned up
    whenever the ChainstateManager is unloaded/reset/destructed/etc.
    
    Not cleaning them up leads to bugs like a use-after-free that happens
    like so:
    
    1. At the end of a test, ChainstateManager is destructed, which also
       destructs BlockManager, which calls BlockManager::Unload to free all
       CBlockIndexes in its BlockMap
    2. Since pindexBestHeader is not cleaned up, it now points to an invalid
       location
    3. Another test starts to init, and calls LoadGenesisBlock, which calls
       AddToBlockIndex, which compares the genesis block with an invalid
       location
    4. Cute puppies perish by the hundreds
    
    Previously, for normal codepaths (e.g. bitcoind), we relied on the fact
    that our program will be unloaded by the operating system which
    effectively resets these variables. The one exception is in QT tests,
    where these variables had to be manually reset.
    
    Since now ChainstateManager is no longer a global, we can just put this
    logic in its destructor to make sure that callers are always correct.
    
    Over time, we should probably move these mutable global state variables
    into ChainstateManager or CChainState so it's easier to reason about
    their lifecycles.
    62893af086
  149. validation: Farewell, global Chainstate! 6bda9eb9e2
  150. dongcarl force-pushed on Feb 2, 2021
  151. ryanofsky approved
  152. ryanofsky commented at 8:40 pm on February 2, 2021: member
    Light code review re-ACK 6bda9eb9e26012fd75db079555d2f75e742c8c18. Changes since last review: rebase after #20749 merge, adding new chainstatemanager m_state commits, adding COMMITS-AFTER-THIS-ARE-NON-BASE commits, making other rebase updates including adding consts, updating peermanager method declarations, updating IsInitialBlockDownload calls.
  153. MarcoFalke referenced this in commit f1239b70d1 on Feb 4, 2021
  154. sidhujag referenced this in commit 203242fcfc on Feb 4, 2021
  155. MarcoFalke referenced this in commit 828bb776d2 on Feb 20, 2021
  156. alizeyni approved
  157. alizeyni commented at 2:47 pm on February 27, 2021: none
    A
  158. fanquake deleted a comment on Feb 27, 2021
  159. laanwj referenced this in commit 702cfc8c53 on Mar 4, 2021
  160. laanwj referenced this in commit 767bb7d5c5 on Mar 11, 2021
  161. MarcoFalke referenced this in commit 0dd7b23489 on Apr 17, 2021
  162. MarcoFalke referenced this in commit 599000903e on May 24, 2021
  163. MarcoFalke referenced this in commit f63fc53c2a on Jun 1, 2021
  164. fanquake referenced this in commit a55904a80c on Jun 12, 2021
  165. dongcarl commented at 4:19 pm on June 16, 2021: member
    Thanks everyone for the reviews, seems like the last bundle is merged. I would like to call attention to #21766, where a few leftover improvements were collated.
  166. dongcarl closed this on Jun 16, 2021

  167. Fabcien referenced this in commit ab4c27192a on Jan 19, 2022
  168. MarcoFalke referenced this in commit 98e9d8e8e2 on Mar 24, 2022
  169. DrahtBot locked this on Nov 27, 2022

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2024-11-21 09:12 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me