Fix chain tip data race and corrupt rest response #25077

pull maflcko wants to merge 4 commits into bitcoin:master from maflcko:2205-tip-race-🤠 changing 12 files +68 −35
  1. maflcko commented at 2:25 pm on May 6, 2022: member

    This fixes two issues:

    • A data race in ActiveChain, which returns a reference to the chain (a std::vector), which is not thread safe. See also below traceback.
    • A corrupt rest response, which returns a blockheight and blockhash, which are unrelated to each other and to the result, as the chain might advance between each call without cs_main held.

    The issues are fixed by taking cs_main and holding it for the required time.

     0==================
     1WARNING: ThreadSanitizer: data race (pid=32335)
     2  Write of size 8 at 0x7b3c000008f0 by thread T22 (mutexes: write M131626, write M151, write M131553):
     3    [#0](/bitcoin-bitcoin/0/) std::__1::enable_if<(is_move_constructible<CBlockIndex**>::value) && (is_move_assignable<CBlockIndex**>::value), void>::type std::__1::swap<CBlockIndex**>(CBlockIndex**&, CBlockIndex**&) /usr/lib/llvm-13/bin/../include/c++/v1/__utility/swap.h:39:7 (bitcoind+0x501239)
     4    [#1](/bitcoin-bitcoin/1/) std::__1::vector<CBlockIndex*, std::__1::allocator<CBlockIndex*> >::__swap_out_circular_buffer(std::__1::__split_buffer<CBlockIndex*, std::__1::allocator<CBlockIndex*>&>&) /usr/lib/llvm-13/bin/../include/c++/v1/vector:977:5 (bitcoind+0x501239)
     5    [#2](/bitcoin-bitcoin/2/) std::__1::vector<CBlockIndex*, std::__1::allocator<CBlockIndex*> >::__append(unsigned long) /usr/lib/llvm-13/bin/../include/c++/v1/vector:1117:9 (bitcoind+0x501239)
     6    [#3](/bitcoin-bitcoin/3/) std::__1::vector<CBlockIndex*, std::__1::allocator<CBlockIndex*> >::resize(unsigned long) /usr/lib/llvm-13/bin/../include/c++/v1/vector:2046:15 (bitcoind+0x4ffe29)
     7    [#4](/bitcoin-bitcoin/4/) CChain::SetTip(CBlockIndex*) src/chain.cpp:19:12 (bitcoind+0x4ffe29)
     8    [#5](/bitcoin-bitcoin/5/) CChainState::ConnectTip(BlockValidationState&, CBlockIndex*, std::__1::shared_ptr<CBlock const> const&, ConnectTrace&, DisconnectedBlockTransactions&) src/validation.cpp:2748:13 (bitcoind+0x475d00)
     9    [#6](/bitcoin-bitcoin/6/) CChainState::ActivateBestChainStep(BlockValidationState&, CBlockIndex*, std::__1::shared_ptr<CBlock const> const&, bool&, ConnectTrace&) src/validation.cpp:2884:18 (bitcoind+0x47739e)
    10    [#7](/bitcoin-bitcoin/7/) CChainState::ActivateBestChain(BlockValidationState&, std::__1::shared_ptr<CBlock const>) src/validation.cpp:3011:22 (bitcoind+0x477baf)
    11    [#8](/bitcoin-bitcoin/8/) node::ThreadImport(ChainstateManager&, std::__1::vector<fs::path, std::__1::allocator<fs::path> >, ArgsManager const&) src/node/blockstorage.cpp:883:30 (bitcoind+0x23cd74)
    12    [#9](/bitcoin-bitcoin/9/) AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7::operator()() const src/init.cpp:1657:9 (bitcoind+0x15863e)
    13    [#10](/bitcoin-bitcoin/10/) decltype(static_cast<AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7&>(fp)()) std::__1::__invoke<AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7&>(AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7&) /usr/lib/llvm-13/bin/../include/c++/v1/type_traits:3918:1 (bitcoind+0x15863e)
    14    [#11](/bitcoin-bitcoin/11/) void std::__1::__invoke_void_return_wrapper<void, true>::__call<AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7&>(AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7&) /usr/lib/llvm-13/bin/../include/c++/v1/__functional/invoke.h:61:9 (bitcoind+0x15863e)
    15    [#12](/bitcoin-bitcoin/12/) std::__1::__function::__alloc_func<AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7, std::__1::allocator<AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7>, void ()>::operator()() /usr/lib/llvm-13/bin/../include/c++/v1/__functional/function.h:171:16 (bitcoind+0x15863e)
    16    [#13](/bitcoin-bitcoin/13/) std::__1::__function::__func<AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7, std::__1::allocator<AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7>, void ()>::operator()() /usr/lib/llvm-13/bin/../include/c++/v1/__functional/function.h:345:12 (bitcoind+0x15863e)
    17    [#14](/bitcoin-bitcoin/14/) std::__1::__function::__value_func<void ()>::operator()() const /usr/lib/llvm-13/bin/../include/c++/v1/__functional/function.h:498:16 (bitcoind+0x88891f)
    18    [#15](/bitcoin-bitcoin/15/) std::__1::function<void ()>::operator()() const /usr/lib/llvm-13/bin/../include/c++/v1/__functional/function.h:1175:12 (bitcoind+0x88891f)
    19    [#16](/bitcoin-bitcoin/16/) util::TraceThread(char const*, std::__1::function<void ()>) src/util/thread.cpp:18:9 (bitcoind+0x88891f)
    20    [#17](/bitcoin-bitcoin/17/) decltype(static_cast<void (*>(fp)(static_cast<char const*>(fp0), static_cast<AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7>(fp0))) std::__1::__invoke<void (*)(char const*, std::__1::function<void ()>), char const*, AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7>(void (*&&)(char const*, std::__1::function<void ()>), char const*&&, AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7&&) /usr/lib/llvm-13/bin/../include/c++/v1/type_traits:3918:1 (bitcoind+0x157e6a)
    21    [#18](/bitcoin-bitcoin/18/) void std::__1::__thread_execute<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void (*)(char const*, std::__1::function<void ()>), char const*, AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7, 2ul, 3ul>(std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void (*)(char const*, std::__1::function<void ()>), char const*, AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7>&, std::__1::__tuple_indices<2ul, 3ul>) /usr/lib/llvm-13/bin/../include/c++/v1/thread:280:5 (bitcoind+0x157e6a)
    22    [#19](/bitcoin-bitcoin/19/) void* std::__1::__thread_proxy<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void (*)(char const*, std::__1::function<void ()>), char const*, AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7> >(void*) /usr/lib/llvm-13/bin/../include/c++/v1/thread:291:5 (bitcoind+0x157e6a)
    23  Previous read of size 8 at 0x7b3c000008f0 by main thread:
    24    [#0](/bitcoin-bitcoin/0/) std::__1::vector<CBlockIndex*, std::__1::allocator<CBlockIndex*> >::size() const /usr/lib/llvm-13/bin/../include/c++/v1/vector:680:61 (bitcoind+0x15179d)
    25    [#1](/bitcoin-bitcoin/1/) CChain::Tip() const src/./chain.h:449:23 (bitcoind+0x15179d)
    26    [#2](/bitcoin-bitcoin/2/) ChainstateManager::ActiveTip() const src/./validation.h:927:59 (bitcoind+0x15179d)
    27    [#3](/bitcoin-bitcoin/3/) AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*) src/init.cpp:1841:35 (bitcoind+0x15179d)
    28    [#4](/bitcoin-bitcoin/4/) AppInit(node::NodeContext&, int, char**) src/bitcoind.cpp:231:43 (bitcoind+0x133fd2)
    29    [#5](/bitcoin-bitcoin/5/) main src/bitcoind.cpp:275:13 (bitcoind+0x133fd2)
    30  Location is heap block of size 232 at 0x7b3c00000870 allocated by main thread:
    31    [#0](/bitcoin-bitcoin/0/) operator new(unsigned long) <null> (bitcoind+0x132668)
    32    [#1](/bitcoin-bitcoin/1/) ChainstateManager::InitializeChainstate(CTxMemPool*, std::__1::optional<uint256> const&) src/validation.cpp:4851:21 (bitcoind+0x48e26b)
    33    [#2](/bitcoin-bitcoin/2/) node::LoadChainstate(bool, ChainstateManager&, CTxMemPool*, bool, Consensus::Params const&, bool, long, long, long, bool, bool, std::__1::function<bool ()>, std::__1::function<void ()>) src/node/chainstate.cpp:31:14 (bitcoind+0x24de07)
    34    [#3](/bitcoin-bitcoin/3/) AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*) src/init.cpp:1438:32 (bitcoind+0x14e994)
    35    [#4](/bitcoin-bitcoin/4/) AppInit(node::NodeContext&, int, char**) src/bitcoind.cpp:231:43 (bitcoind+0x133fd2)
    36    [#5](/bitcoin-bitcoin/5/) main src/bitcoind.cpp:275:13 (bitcoind+0x133fd2)
    37  Mutex M131626 (0x7b3c00000898) created at:
    38    [#0](/bitcoin-bitcoin/0/) pthread_mutex_lock <null> (bitcoind+0xda898)
    39    [#1](/bitcoin-bitcoin/1/) std::__1::mutex::lock() <null> (libc++.so.1+0x49f35)
    40    [#2](/bitcoin-bitcoin/2/) node::ThreadImport(ChainstateManager&, std::__1::vector<fs::path, std::__1::allocator<fs::path> >, ArgsManager const&) src/node/blockstorage.cpp:883:30 (bitcoind+0x23cd74)
    41    [#3](/bitcoin-bitcoin/3/) AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7::operator()() const src/init.cpp:1657:9 (bitcoind+0x15863e)
    42    [#4](/bitcoin-bitcoin/4/) decltype(static_cast<AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7&>(fp)()) std::__1::__invoke<AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7&>(AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7&) /usr/lib/llvm-13/bin/../include/c++/v1/type_traits:3918:1 (bitcoind+0x15863e)
    43    [#5](/bitcoin-bitcoin/5/) void std::__1::__invoke_void_return_wrapper<void, true>::__call<AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7&>(AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7&) /usr/lib/llvm-13/bin/../include/c++/v1/__functional/invoke.h:61:9 (bitcoind+0x15863e)
    44    [#6](/bitcoin-bitcoin/6/) std::__1::__function::__alloc_func<AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7, std::__1::allocator<AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7>, void ()>::operator()() /usr/lib/llvm-13/bin/../include/c++/v1/__functional/function.h:171:16 (bitcoind+0x15863e)
    45    [#7](/bitcoin-bitcoin/7/) std::__1::__function::__func<AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7, std::__1::allocator<AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7>, void ()>::operator()() /usr/lib/llvm-13/bin/../include/c++/v1/__functional/function.h:345:12 (bitcoind+0x15863e)
    46    [#8](/bitcoin-bitcoin/8/) std::__1::__function::__value_func<void ()>::operator()() const /usr/lib/llvm-13/bin/../include/c++/v1/__functional/function.h:498:16 (bitcoind+0x88891f)
    47    [#9](/bitcoin-bitcoin/9/) std::__1::function<void ()>::operator()() const /usr/lib/llvm-13/bin/../include/c++/v1/__functional/function.h:1175:12 (bitcoind+0x88891f)
    48    [#10](/bitcoin-bitcoin/10/) util::TraceThread(char const*, std::__1::function<void ()>) src/util/thread.cpp:18:9 (bitcoind+0x88891f)
    49    [#11](/bitcoin-bitcoin/11/) decltype(static_cast<void (*>(fp)(static_cast<char const*>(fp0), static_cast<AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7>(fp0))) std::__1::__invoke<void (*)(char const*, std::__1::function<void ()>), char const*, AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7>(void (*&&)(char const*, std::__1::function<void ()>), char const*&&, AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7&&) /usr/lib/llvm-13/bin/../include/c++/v1/type_traits:3918:1 (bitcoind+0x157e6a)
    50    [#12](/bitcoin-bitcoin/12/) void std::__1::__thread_execute<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void (*)(char const*, std::__1::function<void ()>), char const*, AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7, 2ul, 3ul>(std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void (*)(char const*, std::__1::function<void ()>), char const*, AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7>&, std::__1::__tuple_indices<2ul, 3ul>) /usr/lib/llvm-13/bin/../include/c++/v1/thread:280:5 (bitcoind+0x157e6a)
    51    [#13](/bitcoin-bitcoin/13/) void* std::__1::__thread_proxy<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void (*)(char const*, std::__1::function<void ()>), char const*, AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7> >(void*) /usr/lib/llvm-13/bin/../include/c++/v1/thread:291:5 (bitcoind+0x157e6a)
    52  Mutex M151 (0x55aacb8ea030) created at:
    53    [#0](/bitcoin-bitcoin/0/) pthread_mutex_init <null> (bitcoind+0xbed2f)
    54    [#1](/bitcoin-bitcoin/1/) std::__1::recursive_mutex::recursive_mutex() <null> (libc++.so.1+0x49fb3)
    55    [#2](/bitcoin-bitcoin/2/) __libc_start_main <null> (libc.so.6+0x29eba)
    56  Mutex M131553 (0x7b4c000042e0) created at:
    57    [#0](/bitcoin-bitcoin/0/) pthread_mutex_init <null> (bitcoind+0xbed2f)
    58    [#1](/bitcoin-bitcoin/1/) std::__1::recursive_mutex::recursive_mutex() <null> (libc++.so.1+0x49fb3)
    59    [#2](/bitcoin-bitcoin/2/) std::__1::__unique_if<CTxMemPool>::__unique_single std::__1::make_unique<CTxMemPool, CBlockPolicyEstimator*, int const&>(CBlockPolicyEstimator*&&, int const&) /usr/lib/llvm-13/bin/../include/c++/v1/__memory/unique_ptr.h:728:32 (bitcoind+0x15c81d)
    60    [#3](/bitcoin-bitcoin/3/) AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*) src/init.cpp:1426:24 (bitcoind+0x14e7b4)
    61    [#4](/bitcoin-bitcoin/4/) AppInit(node::NodeContext&, int, char**) src/bitcoind.cpp:231:43 (bitcoind+0x133fd2)
    62    [#5](/bitcoin-bitcoin/5/) main src/bitcoind.cpp:275:13 (bitcoind+0x133fd2)
    63  Thread T22 'b-loadblk' (tid=32370, running) created by main thread at:
    64    [#0](/bitcoin-bitcoin/0/) pthread_create <null> (bitcoind+0xbd5bd)
    65    [#1](/bitcoin-bitcoin/1/) std::__1::__libcpp_thread_create(unsigned long*, void* (*)(void*), void*) /usr/lib/llvm-13/bin/../include/c++/v1/__threading_support:443:10 (bitcoind+0x155e06)
    66    [#2](/bitcoin-bitcoin/2/) std::__1::thread::thread<void (*)(char const*, std::__1::function<void ()>), char const (&) [8], AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7, void>(void (*&&)(char const*, std::__1::function<void ()>), char const (&) [8], AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7&&) /usr/lib/llvm-13/bin/../include/c++/v1/thread:307:16 (bitcoind+0x155e06)
    67    [#3](/bitcoin-bitcoin/3/) AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*) src/init.cpp:1656:29 (bitcoind+0x150164)
    68    [#4](/bitcoin-bitcoin/4/) AppInit(node::NodeContext&, int, char**) src/bitcoind.cpp:231:43 (bitcoind+0x133fd2)
    69    [#5](/bitcoin-bitcoin/5/) main src/bitcoind.cpp:275:13 (bitcoind+0x133fd2)
    70SUMMARY: ThreadSanitizer: data race /usr/lib/llvm-13/bin/../include/c++/v1/__utility/swap.h:39:7 in std::__1::enable_if<(is_move_constructible<CBlockIndex**>::value) && (is_move_assignable<CBlockIndex**>::value), void>::type std::__1::swap<CBlockIndex**>(CBlockIndex**&, CBlockIndex**&)
    71==================
    

    From https://cirrus-ci.com/task/5612886578954240?logs=ci#L4868

  2. DrahtBot added the label Refactoring on May 6, 2022
  3. in src/init.cpp:1639 in fa35585c74 outdated
    1627@@ -1628,7 +1628,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
    1628     // Either install a handler to notify us when genesis activates, or set fHaveGenesis directly.
    1629     // No locking, as this happens before any background thread is started.
    1630     boost::signals2::connection block_notify_genesis_wait_connection;
    1631-    if (chainman.ActiveChain().Tip() == nullptr) {
    1632+    if (WITH_LOCK(::cs_main, return chainman.ActiveChain().Tip() == nullptr)) {
    


    Crypt-iQ commented at 2:52 pm on May 6, 2022:
    Should callers be using ActiveTip instead of ActiveChain().Tip() since I think Tip() itself doesn’t require a mutex and could change?

    Crypt-iQ commented at 2:53 pm on May 6, 2022:
    Nevermind, I see the WITH_LOCK. mb

    maflcko commented at 3:49 pm on May 6, 2022:
    Calling Tip() will need the mutex, as it accesses the underlying std:vector. Using a CBlockIndex* may or may not need the mutex, so I think it it fine to request the caller to figure that out.

    Crypt-iQ commented at 5:28 pm on May 9, 2022:
    Should the CChain functions that use vChain have the exclusive lock annotation?

    maflcko commented at 1:37 pm on June 21, 2022:

    I am not sure if we want to add validation mutex lock annotations to classes that are only supposed to be primitive data structures.

    Maybe for now this could make sense to document the status quo. However, I’d like to postpone this to the future.

    Alternatively, we could start thinking about adding a CChain member mutex, similar to the mempool one?


    Crypt-iQ commented at 9:07 pm on June 21, 2022:
    I think adding a member mutex would be a good idea in the future
  4. DrahtBot commented at 7:57 pm on May 6, 2022: contributor

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

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #25704 (refactor: Remove almost all validation option globals by MarcoFalke)
    • #25296 (Add DataStream without ser-type and ser-version and use it where possible by MarcoFalke)

    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.

  5. pk-b2 approved
  6. pk-b2 commented at 4:03 am on May 7, 2022: none
    ACK fa35585c74ca48d622d0b2fb9bbfb1c2148eeb00
  7. luke-jr referenced this in commit dd6e44b560 on May 21, 2022
  8. luke-jr referenced this in commit d300cd95c0 on May 22, 2022
  9. ajtowns commented at 3:59 pm on June 13, 2022: contributor

    Approach ACK. I think this needs a more thorough API cleanup somehow, but this improves things in the meantime.

    This is mostly a bug fix; I don’t think it should have the refactoring tag?

  10. maflcko removed the label Refactoring on Jun 13, 2022
  11. maflcko added the label Bug on Jun 13, 2022
  12. maflcko commented at 4:01 pm on June 13, 2022: member
    @DrahtBot Bad bot!!
  13. maflcko added the label Validation on Jun 13, 2022
  14. DrahtBot added the label Needs rebase on Jun 16, 2022
  15. maflcko force-pushed on Jun 21, 2022
  16. maflcko force-pushed on Jun 21, 2022
  17. maflcko commented at 1:39 pm on June 21, 2022: member
    Rebased, answered question, and started removing ::cs_main
  18. in src/validation.h:882 in fa35905c0a outdated
    854+     * - Clarify that the method will acquire a mutex that heavily affects
    855+     *   overall performance.
    856+     * - Force call sites to think how long they need to acquire the mutex to
    857+     *   get consistent results.
    858+     */
    859+    RecursiveMutex& GetMutex() const LOCK_RETURNED(::cs_main) { return ::cs_main; }
    


    jamesob commented at 2:21 pm on June 21, 2022:
    Nice, this is a good direction I think. :+1:
  19. jamesob commented at 2:22 pm on June 21, 2022: member
    Concept ACK
  20. DrahtBot removed the label Needs rebase on Jun 21, 2022
  21. Crypt-iQ commented at 11:03 pm on June 21, 2022: contributor
    crACK fa35905c0a5d45ab16283536fb98124db71ef897
  22. Riahiamirreza approved
  23. in src/validation.h:955 in fa35905c0a outdated
    927@@ -915,9 +928,9 @@ class ChainstateManager
    928 
    929     //! The most-work chain.
    930     CChainState& ActiveChainstate() const;
    931-    CChain& ActiveChain() const { return ActiveChainstate().m_chain; }
    932-    int ActiveHeight() const { return ActiveChain().Height(); }
    933-    CBlockIndex* ActiveTip() const { return ActiveChain().Tip(); }
    934+    CChain& ActiveChain() const EXCLUSIVE_LOCKS_REQUIRED(GetMutex()) { return ActiveChainstate().m_chain; }
    935+    int ActiveHeight() const EXCLUSIVE_LOCKS_REQUIRED(GetMutex()) { return ActiveChain().Height(); }
    


    ajtowns commented at 12:05 pm on July 4, 2022:
    Needs { LOCK(::cs_main); ... } added to bitcoin-chainstate.cpp around the Main program logic starts here section.

    maflcko commented at 2:18 pm on July 4, 2022:
    Good find. Thanks and fixed.
  24. maflcko force-pushed on Jul 4, 2022
  25. maflcko commented at 2:19 pm on July 4, 2022: member

    Added “missing” lock to single-threaded bitcoin-chainstate.cpp.

    Should be easy re-ACK with git range-diff bitcoin-core/master fa35905c0a fadb84b05f.

  26. maflcko force-pushed on Jul 6, 2022
  27. maflcko commented at 4:41 pm on July 6, 2022: member
    Rebased due to silent and benign conflict.
  28. maflcko force-pushed on Jul 12, 2022
  29. maflcko commented at 3:49 pm on July 12, 2022: member
    Rebased (for fun)
  30. maflcko force-pushed on Jul 12, 2022
  31. maflcko commented at 3:50 pm on July 12, 2022: member
    Reworked commits to make review easier
  32. maflcko commented at 8:01 am on July 14, 2022: member
  33. michaelfolkson commented at 5:36 pm on July 15, 2022: contributor

    Concept ACK, Approach ACK

    I haven’t been able to replicate the issues this PR resolves myself but convinced at the PR review club last week that they exist and this PR is the best way to resolve them.

    This keeps happening in CI: https://cirrus-ci.com/task/6262715361525760?logs=ci#L5141

    Sorry, what is “this” Marco? You link to a merge commit for a doc change? The following?

    “Scheduling was delayed due to a concurrency limit on community tasks Consider upgrading to a $10/month plan to get 2x the limits on any public and private repository”

  34. maflcko commented at 7:52 am on July 16, 2022: member

    Sorry, what is “this” Marco? You link to a merge commit for a doc change? The following?

    This is a link to a CI log to line 5141 (see # in the URL), the excerpt is:

     0feature_reindex.py                                     | ✖ Failed  | 5 s
     1ALL                                                    | ✖ Failed  | 1410 s (accumulated) 
     2Runtime: 181 s
     3==================
     4WARNING: ThreadSanitizer: data race (pid=31956)
     5  Read of size 8 at 0x7b3c000008f8 by main thread:
     6    [#0](/bitcoin-bitcoin/0/) std::__1::vector<CBlockIndex*, std::__1::allocator<CBlockIndex*> >::size() const /usr/lib/llvm-13/bin/../include/c++/v1/vector:680:46 (bitcoind+0x15382d)
     7    [#1](/bitcoin-bitcoin/1/) CChain::Tip() const src/./chain.h:449:23 (bitcoind+0x15382d)
     8    [#2](/bitcoin-bitcoin/2/) ChainstateManager::ActiveTip() const src/./validation.h:918:59 (bitcoind+0x15382d)
     9    [#3](/bitcoin-bitcoin/3/) AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*) src/init.cpp:1857:35 (bitcoind+0x15382d)
    10    [#4](/bitcoin-bitcoin/4/) AppInit(node::NodeContext&, int, char**) src/bitcoind.cpp:234:43 (bitcoind+0x135c99)
    11    [#5](/bitcoin-bitcoin/5/) main src/bitcoind.cpp:278:13 (bitcoind+0x135c99)
    12  Previous write of size 8 at 0x7b3c000008f8 by thread T22 (mutexes: write M131617, write M151, write M131548):
    13    [#0](/bitcoin-bitcoin/0/) std::__1::enable_if<(is_move_constructible<CBlockIndex**>::value) && (is_move_assignable<CBlockIndex**>::value), void>::type std::__1::swap<CBlockIndex**>(CBlockIndex**&, CBlockIndex**&) /usr/lib/llvm-13/bin/../include/c++/v1/__utility/swap.h:39:7 (bitcoind+0x52c116)
    14    [#1](/bitcoin-bitcoin/1/) std::__1::vector<CBlockIndex*, std::__1::allocator<CBlockIndex*> >::__swap_out_circular_buffer(std::__1::__split_buffer<CBlockIndex*, std::__1::allocator<CBlockIndex*>&>&) /usr/lib/llvm-13/bin/../include/c++/v1/vector:978:5 (bitcoind+0x52c116)
    15    [#2](/bitcoin-bitcoin/2/) std::__1::vector<CBlockIndex*, std::__1::allocator<CBlockIndex*> >::__append(unsigned long) /usr/lib/llvm-13/bin/../include/c++/v1/vector:1117:9 (bitcoind+0x52c116)
    16    [#3](/bitcoin-bitcoin/3/) std::__1::vector<CBlockIndex*, std::__1::allocator<CBlockIndex*> >::resize(unsigned long) /usr/lib/llvm-13/bin/../include/c++/v1/vector:2046:15 (bitcoind+0x52acf9)
    17    [#4](/bitcoin-bitcoin/4/) CChain::SetTip(CBlockIndex*) src/chain.cpp:19:12 (bitcoind+0x52acf9)
    18    [#5](/bitcoin-bitcoin/5/) CChainState::ConnectTip(BlockValidationState&, CBlockIndex*, std::__1::shared_ptr<CBlock const> const&, ConnectTrace&, DisconnectedBlockTransactions&) src/validation.cpp:2739:13 (bitcoind+0x49f9e5)
    19    [#6](/bitcoin-bitcoin/6/) CChainState::ActivateBestChainStep(BlockValidationState&, CBlockIndex*, std::__1::shared_ptr<CBlock const> const&, bool&, ConnectTrace&) src/validation.cpp:2875:18 (bitcoind+0x4a108e)
    20    [#7](/bitcoin-bitcoin/7/) CChainState::ActivateBestChain(BlockValidationState&, std::__1::shared_ptr<CBlock const>) src/validation.cpp:3002:22 (bitcoind+0x4a186f)
    21    [#8](/bitcoin-bitcoin/8/) node::ThreadImport(ChainstateManager&, std::__1::vector<fs::path, std::__1::allocator<fs::path> >, ArgsManager const&) src/node/blockstorage.cpp:883:30 (bitcoind+0x235d74)
    22    [#9](/bitcoin-bitcoin/9/) AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7::operator()() const src/init.cpp:1673:9 (bitcoind+0x15a68e)
    23    [#10](/bitcoin-bitcoin/10/) decltype(static_cast<AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7&>(fp)()) std::__1::__invoke<AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7&>(AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7&) /usr/lib/llvm-13/bin/../include/c++/v1/type_traits:3918:1 (bitcoind+0x15a68e)
    24    [#11](/bitcoin-bitcoin/11/) void std::__1::__invoke_void_return_wrapper<void, true>::__call<AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7&>(AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7&) /usr/lib/llvm-13/bin/../include/c++/v1/__functional/invoke.h:61:9 (bitcoind+0x15a68e)
    25    [#12](/bitcoin-bitcoin/12/) std::__1::__function::__alloc_func<AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7, std::__1::allocator<AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7>, void ()>::operator()() /usr/lib/llvm-13/bin/../include/c++/v1/__functional/function.h:171:16 (bitcoind+0x15a68e)
    26    [#13](/bitcoin-bitcoin/13/) std::__1::__function::__func<AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7, std::__1::allocator<AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7>, void ()>::operator()() /usr/lib/llvm-13/bin/../include/c++/v1/__functional/function.h:345:12 (bitcoind+0x15a68e)
    27    [#14](/bitcoin-bitcoin/14/) std::__1::__function::__value_func<void ()>::operator()() const /usr/lib/llvm-13/bin/../include/c++/v1/__functional/function.h:498:16 (bitcoind+0x8d917f)
    28    [#15](/bitcoin-bitcoin/15/) std::__1::function<void ()>::operator()() const /usr/lib/llvm-13/bin/../include/c++/v1/__functional/function.h:1175:12 (bitcoind+0x8d917f)
    29    [#16](/bitcoin-bitcoin/16/) util::TraceThread(char const*, std::__1::function<void ()>) src/util/thread.cpp:18:9 (bitcoind+0x8d917f)
    30    [#17](/bitcoin-bitcoin/17/) decltype(static_cast<void (*>(fp)(static_cast<char const*>(fp0), static_cast<AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7>(fp0))) std::__1::__invoke<void (*)(char const*, std::__1::function<void ()>), char const*, AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7>(void (*&&)(char const*, std::__1::function<void ()>), char const*&&, AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7&&) /usr/lib/llvm-13/bin/../include/c++/v1/type_traits:3918:1 (bitcoind+0x159eba)
    31    [#18](/bitcoin-bitcoin/18/) void std::__1::__thread_execute<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void (*)(char const*, std::__1::function<void ()>), char const*, AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7, 2ul, 3ul>(std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void (*)(char const*, std::__1::function<void ()>), char const*, AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7>&, std::__1::__tuple_indices<2ul, 3ul>) /usr/lib/llvm-13/bin/../include/c++/v1/thread:280:5 (bitcoind+0x159eba)
    32    [#19](/bitcoin-bitcoin/19/) void* std::__1::__thread_proxy<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void (*)(char const*, std::__1::function<void ()>), char const*, AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7> >(void*) /usr/lib/llvm-13/bin/../include/c++/v1/thread:291:5 (bitcoind+0x159eba)
    33  Location is heap block of size 232 at 0x7b3c00000870 allocated by main thread:
    34    [#0](/bitcoin-bitcoin/0/) operator new(unsigned long) <null> (bitcoind+0x1342b8)
    35    [#1](/bitcoin-bitcoin/1/) ChainstateManager::InitializeChainstate(CTxMemPool*, std::__1::optional<uint256> const&) src/validation.cpp:4844:21 (bitcoind+0x4b818b)
    36    [#2](/bitcoin-bitcoin/2/) node::LoadChainstate(bool, ChainstateManager&, CTxMemPool*, bool, bool, long, long, long, bool, bool, std::__1::function<bool ()>, std::__1::function<void ()>) src/node/chainstate.cpp:30:14 (bitcoind+0x246e48)
    37    [#3](/bitcoin-bitcoin/3/) AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*) src/init.cpp:1457:32 (bitcoind+0x150ad2)
    38    [#4](/bitcoin-bitcoin/4/) AppInit(node::NodeContext&, int, char**) src/bitcoind.cpp:234:43 (bitcoind+0x135c99)
    39    [#5](/bitcoin-bitcoin/5/) main src/bitcoind.cpp:278:13 (bitcoind+0x135c99)
    40  Mutex M131617 (0x7b3c00000898) created at:
    41    [#0](/bitcoin-bitcoin/0/) pthread_mutex_trylock <null> (bitcoind+0xc0c18)
    42    [#1](/bitcoin-bitcoin/1/) std::__1::mutex::try_lock() <null> (libc++.so.1+0x49f55)
    43    [#2](/bitcoin-bitcoin/2/) UniqueLock<AnnotatedMixin<std::__1::mutex>, std::__1::unique_lock<std::__1::mutex> >::UniqueLock(AnnotatedMixin<std::__1::mutex>&, char const*, char const*, int, bool) src/./sync.h:181:13 (bitcoind+0x4a15a0)
    44    [#3](/bitcoin-bitcoin/3/) CChainState::ActivateBestChain(BlockValidationState&, std::__1::shared_ptr<CBlock const>) src/validation.cpp:2966:5 (bitcoind+0x4a15a0)
    45    [#4](/bitcoin-bitcoin/4/) node::ThreadImport(ChainstateManager&, std::__1::vector<fs::path, std::__1::allocator<fs::path> >, ArgsManager const&) src/node/blockstorage.cpp:883:30 (bitcoind+0x235d74)
    46    [#5](/bitcoin-bitcoin/5/) AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7::operator()() const src/init.cpp:1673:9 (bitcoind+0x15a68e)
    47    [#6](/bitcoin-bitcoin/6/) decltype(static_cast<AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7&>(fp)()) std::__1::__invoke<AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7&>(AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7&) /usr/lib/llvm-13/bin/../include/c++/v1/type_traits:3918:1 (bitcoind+0x15a68e)
    48    [#7](/bitcoin-bitcoin/7/) void std::__1::__invoke_void_return_wrapper<void, true>::__call<AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7&>(AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7&) /usr/lib/llvm-13/bin/../include/c++/v1/__functional/invoke.h:61:9 (bitcoind+0x15a68e)
    49    [#8](/bitcoin-bitcoin/8/) std::__1::__function::__alloc_func<AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7, std::__1::allocator<AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7>, void ()>::operator()() /usr/lib/llvm-13/bin/../include/c++/v1/__functional/function.h:171:16 (bitcoind+0x15a68e)
    50    [#9](/bitcoin-bitcoin/9/) std::__1::__function::__func<AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7, std::__1::allocator<AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7>, void ()>::operator()() /usr/lib/llvm-13/bin/../include/c++/v1/__functional/function.h:345:12 (bitcoind+0x15a68e)
    51    [#10](/bitcoin-bitcoin/10/) std::__1::__function::__value_func<void ()>::operator()() const /usr/lib/llvm-13/bin/../include/c++/v1/__functional/function.h:498:16 (bitcoind+0x8d917f)
    52    [#11](/bitcoin-bitcoin/11/) std::__1::function<void ()>::operator()() const /usr/lib/llvm-13/bin/../include/c++/v1/__functional/function.h:1175:12 (bitcoind+0x8d917f)
    53    [#12](/bitcoin-bitcoin/12/) util::TraceThread(char const*, std::__1::function<void ()>) src/util/thread.cpp:18:9 (bitcoind+0x8d917f)
    54    [#13](/bitcoin-bitcoin/13/) decltype(static_cast<void (*>(fp)(static_cast<char const*>(fp0), static_cast<AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7>(fp0))) std::__1::__invoke<void (*)(char const*, std::__1::function<void ()>), char const*, AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7>(void (*&&)(char const*, std::__1::function<void ()>), char const*&&, AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7&&) /usr/lib/llvm-13/bin/../include/c++/v1/type_traits:3918:1 (bitcoind+0x159eba)
    55    [#14](/bitcoin-bitcoin/14/) void std::__1::__thread_execute<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void (*)(char const*, std::__1::function<void ()>), char const*, AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7, 2ul, 3ul>(std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void (*)(char const*, std::__1::function<void ()>), char const*, AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7>&, std::__1::__tuple_indices<2ul, 3ul>) /usr/lib/llvm-13/bin/../include/c++/v1/thread:280:5 (bitcoind+0x159eba)
    56    [#15](/bitcoin-bitcoin/15/) void* std::__1::__thread_proxy<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void (*)(char const*, std::__1::function<void ()>), char const*, AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7> >(void*) /usr/lib/llvm-13/bin/../include/c++/v1/thread:291:5 (bitcoind+0x159eba)
    57  Mutex M151 (0x55cf3ac0d3c0) created at:
    58    [#0](/bitcoin-bitcoin/0/) pthread_mutex_init <null> (bitcoind+0xc097f)
    59    [#1](/bitcoin-bitcoin/1/) std::__1::recursive_mutex::recursive_mutex() <null> (libc++.so.1+0x49fb3)
    60    [#2](/bitcoin-bitcoin/2/) __libc_start_main <null> (libc.so.6+0x29eba)
    61  Mutex M131548 (0x7b5000000c60) created at:
    62    [#0](/bitcoin-bitcoin/0/) pthread_mutex_init <null> (bitcoind+0xc097f)
    63    [#1](/bitcoin-bitcoin/1/) std::__1::recursive_mutex::recursive_mutex() <null> (libc++.so.1+0x49fb3)
    64    [#2](/bitcoin-bitcoin/2/) std::__1::__unique_if<CTxMemPool>::__unique_single std::__1::make_unique<CTxMemPool, kernel::MemPoolOptions&>(kernel::MemPoolOptions&) /usr/lib/llvm-13/bin/../include/c++/v1/__memory/unique_ptr.h:728:32 (bitcoind+0x15e7a2)
    65    [#3](/bitcoin-bitcoin/3/) AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*) src/init.cpp:1441:24 (bitcoind+0x1508c0)
    66    [#4](/bitcoin-bitcoin/4/) AppInit(node::NodeContext&, int, char**) src/bitcoind.cpp:234:43 (bitcoind+0x135c99)
    67    [#5](/bitcoin-bitcoin/5/) main src/bitcoind.cpp:278:13 (bitcoind+0x135c99)
    68  Thread T22 'b-loadblk' (tid=32032, running) created by main thread at:
    69    [#0](/bitcoin-bitcoin/0/) pthread_create <null> (bitcoind+0xbf20d)
    70    [#1](/bitcoin-bitcoin/1/) std::__1::__libcpp_thread_create(unsigned long*, void* (*)(void*), void*) /usr/lib/llvm-13/bin/../include/c++/v1/__threading_support:443:10 (bitcoind+0x157fb6)
    71    [#2](/bitcoin-bitcoin/2/) std::__1::thread::thread<void (*)(char const*, std::__1::function<void ()>), char const (&) [8], AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7, void>(void (*&&)(char const*, std::__1::function<void ()>), char const (&) [8], AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7&&) /usr/lib/llvm-13/bin/../include/c++/v1/thread:307:16 (bitcoind+0x157fb6)
    72    [#3](/bitcoin-bitcoin/3/) AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*) src/init.cpp:1672:29 (bitcoind+0x152237)
    73    [#4](/bitcoin-bitcoin/4/) AppInit(node::NodeContext&, int, char**) src/bitcoind.cpp:234:43 (bitcoind+0x135c99)
    74    [#5](/bitcoin-bitcoin/5/) main src/bitcoind.cpp:278:13 (bitcoind+0x135c99)
    75SUMMARY: ThreadSanitizer: data race /usr/lib/llvm-13/bin/../include/c++/v1/vector:680:46 in std::__1::vector<CBlockIndex*, std::__1::allocator<CBlockIndex*> >::size() const
    76==================
    

    The CI ran Commit 8479ed0 on branch master.

  35. michaelfolkson commented at 6:49 pm on July 27, 2022: contributor

    ACK fa547051bae19c7510e808d929f5d8df9a882758

    Built on MacOS Monterey, updated unit tests pass and reviewed code (not particularly qualified though on this kind of PR). As I said here I haven’t replicated the issues either.

  36. maflcko added this to the milestone 24.0 on Aug 10, 2022
  37. achow101 commented at 7:32 pm on August 15, 2022: member
    ACK fa547051bae19c7510e808d929f5d8df9a882758
  38. achow101 commented at 7:45 pm on August 15, 2022: member

    Looks like a silent merge conflict with master:

    0wallet/test/availablecoins_tests.cpp:47:90: error: calling function 'ActiveChain' requires holding mutex 'cs_main' exclusively [-Werror,-Wthread-safety-analysis]
    1        wallet->SetLastBlockProcessed(wallet->GetLastBlockHeight() + 1, m_node.chainman->ActiveChain().Tip()->GetBlockHash());
    2                                                                                         ^
    3wallet/test/availablecoins_tests.cpp:50:64: error: calling function 'ActiveChain' requires holding mutex 'cs_main' exclusively [-Werror,-Wthread-safety-analysis]
    4        it->second.m_state = TxStateConfirmed{m_node.chainman->ActiveChain().Tip()->GetBlockHash(), m_node.chainman->ActiveChain().Height(), /*index=*/1};
    5                                                               ^
    6wallet/test/availablecoins_tests.cpp:50:118: error: calling function 'ActiveChain' requires holding mutex 'cs_main' exclusively [-Werror,-Wthread-safety-analysis]
    7        it->second.m_state = TxStateConfirmed{m_node.chainman->ActiveChain().Tip()->GetBlockHash(), m_node.chainman->ActiveChain().Height(), /*index=*/1};
    8                                                                                                                     ^
    93 errors generated.
    
  39. Add ChainstateManager::GetMutex(), an alias for ::cs_main fa530bcb9c
  40. Fix UB/data-race in RPCNotifyBlockChange
    ActiveTip() is *not* thread-safe, as the required ::cs_main lock will be
    released as ActiveChainstate() returns.
    
    ActiveTip() is an alias for ActiveChainstate().m_chain.Tip(), so m_chain
    may be involved in a data-race (UB).
    fa97a528d6
  41. Fix logical race in rest_getutxos
    Calling ActiveHeight() and ActiveTip() subsequently without holding the
    ::cs_main lock over both calls may result in a height that does not
    correspond to the tip due to a race.
    
    Fix this by holding the lock.
    fac15ff673
  42. refactor: Add lock annotations to Active* methods
    This is a refactor, putting the burden to think about thread safety to
    the caller. Otherwise, there is a risk that the caller will assume
    thread safety where none exists, as is evident in the previous two
    commits.
    fac04cb6ba
  43. maflcko force-pushed on Aug 16, 2022
  44. maflcko commented at 3:29 pm on August 16, 2022: member
    Thanks, rebased to fix silent conflict. Should be trivial to re-ACK with range-diff
  45. achow101 commented at 9:25 pm on August 16, 2022: member
    re-ACK fac04cb6ba1d032587bd02eab2247fd655a548cd
  46. theStack approved
  47. theStack commented at 1:49 pm on August 17, 2022: contributor
    Code-review ACK fac04cb6ba1d032587bd02eab2247fd655a548cd
  48. fanquake merged this on Aug 17, 2022
  49. fanquake closed this on Aug 17, 2022

  50. sidhujag referenced this in commit 16c3326541 on Aug 17, 2022
  51. maflcko deleted the branch on Feb 23, 2023
  52. Fabcien referenced this in commit 6722d82641 on Oct 18, 2023
  53. Fabcien referenced this in commit 1d6aeef072 on Dec 21, 2023
  54. bitcoin locked this on Feb 23, 2024

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-12-21 15:12 UTC

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