Refactor: Start to separate wallet from node #14437

pull ryanofsky wants to merge 5 commits into bitcoin:master from ryanofsky:pr/wchain changing 34 files +722 −372
  1. ryanofsky commented at 3:33 am on October 9, 2018: member

    This creates an incomplete Chain interface in src/interfaces/ and begins to update wallet code to use it.

    #10973 builds on this, changing the wallet to use the new interface to access chain state, instead of using CBlockIndex pointers and global variables like chainActive.

  2. fanquake added the label Refactoring on Oct 9, 2018
  3. fanquake added the label Wallet on Oct 9, 2018
  4. DrahtBot commented at 3:52 am on October 9, 2018: 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:

    • #14641 (RPC: Add min/max confirmation options to fund transaction calls by promag)
    • #14602 (Bugfix: Correctly calculate balances when min_conf is used, and for getbalance("*") by luke-jr)
    • #14582 (wallet: try -avoidpartialspends mode and use its result if fees do not change by kallewoof)
    • #14530 (Use RPCHelpMan to generate RPC doc strings by MarcoFalke)
    • #14411 ([wallet] Restore ability to list incoming transactions by label by ryanofsky)
    • #14384 (Resolve validationinterface circular dependencies by 251Labs)
    • #14121 (Index for BIP 157 block filters by jimpo)
    • #13756 (wallet: “avoid_reuse” wallet flag for improved privacy by kallewoof)
    • #13612 (Qt: Only call tryGetBalances in pollBalanceChanged if the result will be used. by tecnovert)
    • #13582 (Extract AppInitLoadBlockIndex from AppInitMain by Empact)
    • #12508 (IsAllFromMe by kallewoof)
    • #11652 (Add missing locks: validation.cpp + related by practicalswift)
    • #9381 (Remove CWalletTx merging logic from AddToWallet by ryanofsky)

    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. ryanofsky commented at 2:02 am on October 10, 2018: member
    Added 2 more small commits d0af21fab95ee453a1fee4242ceb89ca79d568eb -> a10e919db4c9f37f0bb60fd62a232abf8bd3dede (pr/wchain.1 -> pr/wchain.2, compare) from #10973 to fix the thread safety warnings (which are harmless but treated like errors).
  6. scravy referenced this in commit 2f4a2365a7 on Oct 10, 2018
  7. in src/rpc/rawtransaction.cpp:759 in a10e919db4 outdated
    755@@ -754,7 +756,7 @@ static UniValue combinerawtransaction(const JSONRPCRequest& request)
    756     return EncodeHexTx(mergedTx);
    757 }
    758 
    759-UniValue SignTransaction(CMutableTransaction& mtx, const UniValue& prevTxsUnival, CBasicKeyStore *keystore, bool is_temp_keystore, const UniValue& hashType)
    760+UniValue SignTransaction(interfaces::Chain& chain, CMutableTransaction& mtx, const UniValue& prevTxsUnival, CBasicKeyStore *keystore, bool is_temp_keystore, const UniValue& hashType)
    


    practicalswift commented at 8:25 pm on October 11, 2018:

    chain unused?

    Edit: Oh, used in a follow-up PR. Sorry!

  8. meshcollider commented at 2:29 pm on October 12, 2018: contributor
    Concept ACK :+1:
  9. sipa commented at 7:39 pm on October 12, 2018: member

    Is it intentional that the interfaces code uses a different coding style than the rest of the code?

    If so, does this need documenting somewhere, and if not, can it be converted?

  10. practicalswift commented at 2:14 pm on October 14, 2018: contributor
    This PR does not seem to compile when rebased on master :-)
  11. in src/wallet/wallet.cpp:1723 in a10e919db4 outdated
    1767-        if (pindex && fAbortRescan) {
    1768-            WalletLogPrintf("Rescan aborted at block %d. Progress=%f\n", pindex->nHeight, progress_current);
    1769-        } else if (pindex && ShutdownRequested()) {
    1770-            WalletLogPrintf("Rescan interrupted by shutdown request at block %d. Progress=%f\n", pindex->nHeight, progress_current);
    1771+        if (!block_hash.IsNull() && fAbortRescan) {
    1772+            WalletLogPrintf("Rescan aborted at block %d. Progress=%f\n", *block_height, progress_current);
    


    practicalswift commented at 2:27 pm on October 14, 2018:
    This triggers undefined behaviour if the optional block_height has not been initialised?

    ryanofsky commented at 7:55 pm on October 15, 2018:

    This triggers undefined behaviour if the optional block_height has not been initialised?

    Yes, and previously it would segfault if pindex were null, but these things will not happen at the time this function is called. I think the code in this function is not beautiful and could be rewritten, but I’m trying here to change existing code as little as possible, so it is easier for reviewers to verify that that behavior is unchanged.

  12. in src/wallet/wallet.cpp:1725 in a10e919db4 outdated
    1769-        } else if (pindex && ShutdownRequested()) {
    1770-            WalletLogPrintf("Rescan interrupted by shutdown request at block %d. Progress=%f\n", pindex->nHeight, progress_current);
    1771+        if (!block_hash.IsNull() && fAbortRescan) {
    1772+            WalletLogPrintf("Rescan aborted at block %d. Progress=%f\n", *block_height, progress_current);
    1773+        } else if (!block_hash.IsNull() && ShutdownRequested()) {
    1774+            WalletLogPrintf("Rescan interrupted by shutdown request at block %d. Progress=%f\n", *block_height, progress_current);
    


    practicalswift commented at 2:27 pm on October 14, 2018:
    This triggers undefined behaviour if the optional block_height has not been initialised?

    ryanofsky commented at 7:56 pm on October 15, 2018:
  13. in src/interfaces/chain.cpp:38 in a10e919db4 outdated
    33+    }
    34+    Optional<int> getBlockHeight(const uint256& hash) override
    35+    {
    36+        auto it = ::mapBlockIndex.find(hash);
    37+        if (it != ::mapBlockIndex.end() && it->second) {
    38+            if (::chainActive.Contains(it->second)) {
    


    practicalswift commented at 2:28 pm on October 14, 2018:
    Collapse into if statement above?
  14. Sjors commented at 9:25 am on October 18, 2018: member

    Concept ACK. Thanks for splitting #10973 into more manageable sized PRs.

    • would be good to get @ken2812221’s feedback on the msvc-autogen.py changes
    • I noticed d0af21fab95ee453a1fee4242ceb89ca79d568eb adds a bunch of methods to interfaces/chain.cpp. I assume those are moved from somewhere else, but I don’t see their counterparts removed in this PR. Why is that?

    fc7442f compiles on macOS 10.14, tests and bench pass, bitcoind and QT don’t show any strange behavior.

  15. in src/Makefile.am:470 in a10e919db4 outdated
    463@@ -461,6 +464,7 @@ endif
    464 bitcoind_LDADD = \
    465   $(LIBBITCOIN_SERVER) \
    466   $(LIBBITCOIN_WALLET) \
    467+  $(LIBBITCOIN_SERVER) \
    


    ken2812221 commented at 9:39 am on October 18, 2018:
    I don’t know why do you add $(LIBBITCOIN_SERVER) here. I can see one above.

    ryanofsky commented at 5:26 pm on October 18, 2018:

    In commit “Remove direct node->wallet calls in init.cpp” (eb1709c1af21881283f3c3962ebabb5de9423a56)

    I don’t know why do you add $(LIBBITCOIN_SERVER) here. I can see one above.

    Our libraries are static and have circular dependencies, so for unix linkers which process libraries in command line order and only pull in subsets of object files needed to resolve previously unresolved symbols, it’s often necessary to list the same libraries multiple times. For background:

    https://stackoverflow.com/questions/45135/why-does-the-order-in-which-libraries-are-linked-sometimes-cause-errors-in-gcc https://eli.thegreenplace.net/2013/07/09/library-order-in-static-linking#circular-dependency

    In this specific case, there’s a mutual dependency between wallet and server libraries, and dropping server after wallet leads to:

     0  CXXLD    bitcoind
     1libbitcoin_wallet.a(libbitcoin_wallet_a-wallet.o): In function `interfaces::(anonymous namespace)::WalletImpl::handleUnload(std::function<void ()>)':
     2/home/russ/src/bitcoin/src/interfaces/wallet.cpp:444: undefined reference to `interfaces::MakeHandler(boost::signals2::connection)'
     3libbitcoin_wallet.a(libbitcoin_wallet_a-wallet.o): In function `interfaces::(anonymous namespace)::WalletImpl::handleShowProgress(std::function<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int)>)':
     4/home/russ/src/bitcoin/src/interfaces/wallet.cpp:448: undefined reference to `interfaces::MakeHandler(boost::signals2::connection)'
     5libbitcoin_wallet.a(libbitcoin_wallet_a-wallet.o): In function `interfaces::(anonymous namespace)::WalletImpl::handleStatusChanged(std::function<void ()>)':
     6/home/russ/src/bitcoin/src/interfaces/wallet.cpp:452: undefined reference to `interfaces::MakeHandler(boost::signals2::connection)'
     7libbitcoin_wallet.a(libbitcoin_wallet_a-wallet.o): In function `interfaces::(anonymous namespace)::WalletImpl::handleAddressBookChanged(std::function<void (boost::variant<CNoDestination, CKeyID, CScriptID, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessUnknown> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, ChangeType)>)':
     8/home/russ/src/bitcoin/src/interfaces/wallet.cpp:456: undefined reference to `interfaces::MakeHandler(boost::signals2::connection)'
     9libbitcoin_wallet.a(libbitcoin_wallet_a-wallet.o): In function `interfaces::(anonymous namespace)::WalletImpl::handleTransactionChanged(std::function<void (uint256 const&, ChangeType)>)':
    10/home/russ/src/bitcoin/src/interfaces/wallet.cpp:462: undefined reference to `interfaces::MakeHandler(boost::signals2::connection)'
    11libbitcoin_wallet.a(libbitcoin_wallet_a-wallet.o):/home/russ/src/bitcoin/src/interfaces/wallet.cpp:467: more undefined references to `interfaces::MakeHandler(boost::signals2::connection)' follow
    12clang: error: linker command failed with exit code 1 (use -v to see invocation)
    
  16. ryanofsky commented at 10:54 am on October 18, 2018: member

    I noticed d0af21f adds a bunch of methods to interfaces/chain.cpp. I assume those are moved from somewhere else, but I don’t see their counterparts removed in this PR. Why is that?

    The new Chain d0af21fab95ee453a1fee4242ceb89ca79d568eb methods aren’t moved from someplace else. They are fairly simple utility functions that wrapCBlockIndex/chainActive APIs so the wallet doesn’t access chain state directly.

    Also worth noting that d0af21fab95ee453a1fee4242ceb89ca79d568eb is the main commit in this PR. The other commits are basically just mechanical changes preparing for d0af21fab95ee453a1fee4242ceb89ca79d568eb.

  17. ken2812221 commented at 11:04 am on October 18, 2018: contributor
    Concept ACK. msvc-autogen.py change looks good to me.
  18. ryanofsky commented at 11:06 am on October 18, 2018: member

    would be good to get @ken2812221’s feedback on the msvc-autogen.py changes

    ken2812221 did previously review those changes: #10973 (comment). They were in the first commit of the PR at that time: d487d953c9a10b11693ba8af62f5b54a77ec7686.

  19. DrahtBot added the label Needs rebase on Oct 24, 2018
  20. MarcoFalke added this to the "Blockers" column in a project

  21. ryanofsky force-pushed on Nov 1, 2018
  22. ryanofsky commented at 9:16 pm on November 1, 2018: member

    There were some comments in IRC that the PR description here might need to be improved. Would welcome any suggestions. #10973 has a more complete description of the direction this PR starts to go in.

    re: #14437 (comment)

    Is it intentional that the interfaces code uses a different coding style than the rest of the code?

    If so, does this need documenting somewhere, and if not, can it be converted?

    I’ll create a PR to document the slight style change. It’s used in gui code so I adopted it for #10244 and #10102, sticking with it in #10973 and here for consistency, and since I do like it.

  23. DrahtBot removed the label Needs rebase on Nov 1, 2018
  24. in src/interfaces/wallet.cpp:504 in c4b750f510 outdated
    499+public:
    500+    WalletClientImpl(Chain& chain, std::vector<std::string> wallet_filenames)
    501+        : m_chain(chain), m_wallet_filenames(std::move(wallet_filenames))
    502+    {
    503+    }
    504+    void registerRpcs() override { RegisterWalletRPCCommands(::tableRPC); }
    


    MarcoFalke commented at 5:30 pm on November 2, 2018:

    in commit e615ac5960

    nit: I’d prefer to use return even in the void context. It is more verbose but seems safer in context of future changes. (Feel free to ignore this style nit)

  25. MarcoFalke commented at 6:05 pm on November 2, 2018: member
    utACK 0b2cf7c3a8
  26. in src/interfaces/chain.cpp:46 in c4b750f510 outdated
    41+    {
    42+        const Optional<int> tip_height = getHeight();
    43+        const Optional<int> height = getBlockHeight(hash);
    44+        return tip_height && height ? *tip_height - *height + 1 : 0;
    45+    }
    46+    uint256 getBlockHash(int height) override { return ::chainActive[height]->GetBlockHash(); }
    


    MarcoFalke commented at 7:16 pm on November 2, 2018:
    just a comment in c4b750f510: These could segfault on a reorg
  27. in src/interfaces/chain.h:110 in c4b750f510 outdated
    104@@ -38,6 +105,16 @@ class Chain
    105     //! method is temporary and is only used in a few places to avoid changing
    106     //! behavior while code is transitioned to use the Chain::Lock interface.
    107     virtual std::unique_ptr<Lock> assumeLocked() = 0;
    108+
    109+    //! Return whether node has the block and optionally return block metadata or contents.
    110+    virtual bool findBlock(const uint256& hash,
    


    MarcoFalke commented at 7:55 pm on November 2, 2018:

    in commit c4b750f510

    nit: Could state that block->IsNull() indicates a read-from-disk error.

  28. in src/wallet/rpcdump.cpp:540 in c4b750f510 outdated
    536@@ -538,6 +537,7 @@ UniValue importwallet(const JSONRPCRequest& request)
    537         throw JSONRPCError(RPC_WALLET_ERROR, "Wallet is currently rescanning. Abort existing rescan or wait.");
    538     }
    539 
    540+    Optional<int> tip_height;
    


    MarcoFalke commented at 8:02 pm on November 2, 2018:

    in commit c4b750f:

    Why is this needed?

  29. in src/wallet/rpcwallet.cpp:105 in c4b750f510 outdated
    100@@ -101,7 +101,11 @@ static void WalletTxToJSON(interfaces::Chain& chain, interfaces::Chain::Lock& lo
    101     {
    102         entry.pushKV("blockhash", wtx.hashBlock.GetHex());
    103         entry.pushKV("blockindex", wtx.nIndex);
    104-        entry.pushKV("blocktime", LookupBlockIndex(wtx.hashBlock)->GetBlockTime());
    105+        int64_t block_time;
    106+        if (!chain.findBlock(wtx.hashBlock, nullptr /* CBlock */, &block_time)) {
    


    MarcoFalke commented at 8:11 pm on November 2, 2018:

    in commit c4b750f:

    The name of the argument is block, not CBlock?

  30. in src/wallet/rpcwallet.cpp:106 in c4b750f510 outdated
    100@@ -101,7 +101,11 @@ static void WalletTxToJSON(interfaces::Chain& chain, interfaces::Chain::Lock& lo
    101     {
    102         entry.pushKV("blockhash", wtx.hashBlock.GetHex());
    103         entry.pushKV("blockindex", wtx.nIndex);
    104-        entry.pushKV("blocktime", LookupBlockIndex(wtx.hashBlock)->GetBlockTime());
    105+        int64_t block_time;
    106+        if (!chain.findBlock(wtx.hashBlock, nullptr /* CBlock */, &block_time)) {
    107+            throw std::logic_error("invalid wallet transaction block hash");
    


    MarcoFalke commented at 8:16 pm on November 2, 2018:

    in commit c4b750f:

    It is not immediately clear where this exceptions goes to. Crashes the node?

    I’d prefer if we sticked to jsonrpc exceptions in the rpc module, so that broken rpc code would not crash the node.

  31. in src/threadsafety.h:64 in 0b2cf7c3a8 outdated
    59+struct SCOPED_LOCKABLE LockAnnotation
    60+{
    61+    template <typename Mutex>
    62+    explicit LockAnnotation(Mutex& mutex) EXCLUSIVE_LOCK_FUNCTION(mutex)
    63+    {
    64+    }
    


    MarcoFalke commented at 8:39 pm on November 2, 2018:

    in commit 0b2cf7c3a8edd6feb4a8504675960c9cfcbc613c:

    Could add the runtime assert that the lock is taken?

    AssertLockHeld


    ryanofsky commented at 10:51 pm on November 5, 2018:

    re: #14437 (review)

    That would make this depend on sync.h and require a bitcoin debug mutex instead of working with any mutex. It would also print a less useful file/line number than a standalone assert. Better imo to have separate locking primitives that each do one job well than to have a combined one that’s worse at both jobs.

  32. MarcoFalke commented at 8:41 pm on November 2, 2018: member

    Concept ACK c4b750f510d1913a6af6549b17bd3d89e211c62c

    Last commit is (at least for me) non-trivial to verify its refactoring nature. I am wondering if it could be split up more…

  33. DrahtBot added the label Needs rebase on Nov 5, 2018
  34. in src/wallet/wallet.cpp:3758 in c4b750f510 outdated
    3753@@ -3741,7 +3754,8 @@ unsigned int CWallet::ComputeTimeSmart(const CWalletTx& wtx) const
    3754 {
    3755     unsigned int nTimeSmart = wtx.nTimeReceived;
    3756     if (!wtx.hashUnset()) {
    3757-        if (const CBlockIndex* pindex = LookupBlockIndex(wtx.hashBlock)) {
    3758+        int64_t blocktime;
    3759+        if (chain().findBlock(wtx.hashBlock, nullptr /* CBlock */, &blocktime)) {
    


    MarcoFalke commented at 8:31 pm on November 5, 2018:

    In commit c4b750f510d1913a6:

    The named argument is block, not CBlock?

  35. ryanofsky commented at 10:54 pm on November 5, 2018: member
    Added 3 commits c4b750f510d1913a6af6549b17bd3d89e211c62c -> 4072fbe3adb5289b1ef153952453e809c671a415 (pr/wchain.3 -> pr/wchain.4, compare) with suggestions from marco and practicalswift Added 1 commits 4072fbe3adb5289b1ef153952453e809c671a415 -> e4fe52e0ffb2025a1e2081f044854cdcded01689 (pr/wchain.4 -> pr/wchain.5, compare) with suggestions from marco Rebased e4fe52e0ffb2025a1e2081f044854cdcded01689 -> 081accb875412f38718f2e40ed7bbdf15e6f4ef8 (pr/wchain.5 -> pr/wchain.6) due to conflicts with #14350 and #14555. Also dropped main commit 90bbccd2c3d502d6341985b213e8f839ceeedddf (part of #10973) as suggested by Marco and James to reduce size of PR.
  36. Add skeleton chain and client classes
    This commit does not change behavior. It just adds new skeleton classes that
    don't do anything and aren't instantiated yet.
    7e2e62cf7c
  37. Pass chain and client variables where needed
    This commit does not change behavior. All it does is pass new function
    parameters.
    
    It is easiest to review this change with:
    
        git log -p -n1 -U0 --word-diff-regex=.
    8db11dd0b1
  38. Remove direct node->wallet calls in init.cpp
    Route calls during node initialization and shutdown that would happen between a
    node process and wallet processes through the serializable `Chain::Client`
    interface, rather than `WalletInitInterface` which is now simpler and only
    deals with early initialization and parameter interaction.
    
    This commit mostly does not change behavior. The only change is that the
    "Wallet disabled!" and "No wallet support compiled in!" messages are now logged
    earlier during startup.
    ea961c3d72
  39. Remove uses of cs_main in wallet code
    This commit does not change behavior.
    
    It is easiest to review this change with:
    
        git log -p -n1 -U0
    79d579f4e1
  40. Pass chain locked variables where needed
    This commit does not change behavior. All it does is pass new function
    parameters.
    
    It is easiest to review this change with:
    
        git log -p -n1 -U0 --word-diff-regex=.
    081accb875
  41. ryanofsky force-pushed on Nov 6, 2018
  42. DrahtBot removed the label Needs rebase on Nov 6, 2018
  43. MarcoFalke commented at 8:13 pm on November 6, 2018: member
    re-utACK 081accb875412f38718f2e40ed7bbdf15e6f4ef8 (Only change since previous utACK 0b2cf7c is rebase and adding the return in a void context)
  44. ken2812221 approved
  45. ken2812221 commented at 1:01 am on November 7, 2018: contributor
    utACK 081accb875412f38718f2e40ed7bbdf15e6f4ef8
  46. in src/wallet/wallet.h:37 in 081accb875
    33@@ -33,6 +34,26 @@
    34 #include <utility>
    35 #include <vector>
    36 
    37+//! Responsible for reading and validating the -wallet arguments and verifying the wallet database.
    


    promag commented at 10:58 am on November 7, 2018:
    This function doesn’t read -wallet.
  47. in src/interfaces/wallet.cpp:494 in 081accb875
    490@@ -456,8 +491,32 @@ class WalletImpl : public Wallet
    491     CWallet& m_wallet;
    492 };
    493 
    494+class WalletClientImpl : public ChainClient
    


    promag commented at 11:03 am on November 7, 2018:
    IMO this could have a better name, currently this chain client “manages all wallets”.
  48. promag commented at 11:05 am on November 7, 2018: member
    Concept ACK.
  49. jamesob approved
  50. jamesob commented at 3:20 pm on November 7, 2018: member

    utACK https://github.com/bitcoin/bitcoin/pull/14437/commits/081accb875412f38718f2e40ed7bbdf15e6f4ef8

    I’ll do manual testing later today. Summary of reviewed commits:

    • 7e2e62cf7 - Add skeleton chain and client classes

      Introduces Chain class which consolidates the node’s interface for use by clients like GUI and wallet. Also introduces ChainClient which is a class that allows the node to manage clients. No methods introduced on either.

    • 8db11dd0b - Pass chain and client variables where needed

      Constructs Chain interface (via InitInterfaces) during initialization and passes it to dependent code.

    • 79d579f4e - Remove uses of cs_main in wallet code

      Introduces Chain::Lock and uses its acquisition to replace references to cs_main in wallet code. Chain::Lock’s interface is Chain’s, but its use implies that we have a lock on the chainstate (i.e. cs_main).

      Eventually this could be replaced with a snapshot of the chainstate to avoid blocking more critical chainstate manipulations (and whatever else requires cs_main) during wallet operations.

    • 081accb87 - Pass chain locked variables where needed

      Makes explicit the dependence of various wallet methods on the Chain interface. Passing around locked_chain implies cs_main acquisition and so per-function lock annotations are removed. In a later PR, we’ll actually use locked_chain methods to replace direct access to e.g. chainActive and mapBlockIndex.

    • ea961c3d7 - Remove direct node->wallet calls in init.cpp

      Replaces wallet-specific initialization with a more general chain_clients model - allowing for the initialization of non-wallet code which consumes the chain in a read-only way.

  51. ryanofsky commented at 3:54 pm on November 7, 2018: member
    Thanks Marco, James, and Ken for the recent code reviews! James, I think I will steal your breakdown of commits and add it to the PR description.
  52. in src/init.cpp:1584 in 081accb875
    1580@@ -1562,7 +1581,11 @@ bool AppInitMain()
    1581     }
    1582 
    1583     // ********************************************************* Step 9: load wallet
    1584-    if (!g_wallet_init_interface.Open()) return false;
    1585+    for (const auto& client : interfaces.chain_clients) {
    


    practicalswift commented at 8:30 am on November 9, 2018:
    Could use std::any_of? :-)

    meshcollider commented at 8:30 am on November 9, 2018:
    @practicalswift just a meta-note, could you please put all your comments in one review rather than putting them all as separate comments?

    practicalswift commented at 8:54 am on November 9, 2018:
    @MeshCollider Sure! I’ll do that going forward. Didn’t think about the differences in workflow. Thanks for the suggestion!

    MarcoFalke commented at 3:04 pm on November 9, 2018:

    Also, I’d prefer if we didn’t leave style feedback at all.

    Of course it could use std::any_of, or it could use a while loop, or do while loop, or… It is just a different color up to the author to choose and for everyone else to accept.


    practicalswift commented at 3:49 pm on November 9, 2018:

    @MarcoFalke I should have made clear that my comment was a “nit” :-)

    The comparison you’re making isn’t fair: no one would suggest changing this to a while loop, but striving to use STL algorithms were possible is what the C++ Core Guidelines (with editors Bjarne Stroustrup and Herb Sutter) recommends:

    ES.1: Prefer the standard library to other libraries and to “handcrafted code”

    Code using a library can be much easier to write than code working directly with language features, much shorter, tend to be of a higher level of abstraction, and the library code is presumably already tested. The ISO C++ Standard Library is among the most widely known and best tested libraries. It is available as part of all C++ Implementations.

    […]

    0auto sum = accumulate(v, 0.0); // better
    

    but don’t hand-code a well-known algorithm:

    0int max = v.size();   // bad: verbose, purpose unstated
    1double sum = 0.0;
    2for (int i = 0; i < max; ++i)
    3    sum = sum + v[i];
    

    https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#es1-prefer-the-standard-library-to-other-libraries-and-to-handcrafted-code


    ryanofsky commented at 6:13 pm on November 12, 2018:

    Could use std::any_of? :-)

    This I think it would actually have to use std::all_of


    ryanofsky commented at 6:32 pm on November 12, 2018:

    re: #14437 (review)

    Could use std::any_of? :-)

    This PR is already merged so I won’t change this here. But it’s an interesting suggestion. I might prefer all_of over any_of since the bool represents success, and success only happens if all calls succeed.

    Note: one drawback to using any/all in a context like this is it makes behavior non-deterministic, because the standard doesn’t guarantee what order the calls will run in or whether calls will be skipped due to short-circuiting: https://stackoverflow.com/questions/47692180/is-stdany-of-required-to-follow-short-circuit-logic

  53. MarcoFalke merged this on Nov 9, 2018
  54. MarcoFalke closed this on Nov 9, 2018

  55. MarcoFalke referenced this in commit cbf00939b5 on Nov 9, 2018
  56. MarcoFalke deleted a comment on Nov 9, 2018
  57. MarcoFalke removed this from the "Blockers" column in a project

  58. meshcollider commented at 11:04 am on November 11, 2018: contributor
  59. meshcollider referenced this in commit 2607d960a0 on Mar 21, 2019
  60. meshcollider referenced this in commit 91fcb9ff66 on Sep 8, 2019
  61. ryanofsky added this to the "Done" column in a project

  62. random-zebra referenced this in commit 32db35fb08 on Mar 11, 2021
  63. random-zebra referenced this in commit f2827ea6c5 on Mar 12, 2021
  64. random-zebra referenced this in commit 59f27ed3b5 on Mar 18, 2021
  65. random-zebra referenced this in commit 7aa3a2158a on Mar 22, 2021
  66. random-zebra referenced this in commit 284c5a7524 on Mar 25, 2021
  67. random-zebra referenced this in commit ca3cd7df5e on Mar 25, 2021
  68. random-zebra referenced this in commit 4337b0e802 on Mar 25, 2021
  69. random-zebra referenced this in commit dd660df590 on Mar 25, 2021
  70. random-zebra referenced this in commit c0f64c91de on Mar 25, 2021
  71. random-zebra referenced this in commit fcf958ff1c on Mar 26, 2021
  72. random-zebra referenced this in commit f92b17d375 on Mar 26, 2021
  73. random-zebra referenced this in commit 6479d21886 on Mar 31, 2021
  74. random-zebra referenced this in commit 3c7b524873 on Mar 31, 2021
  75. random-zebra referenced this in commit fad741a624 on Apr 5, 2021
  76. random-zebra referenced this in commit 9f31559c82 on Apr 6, 2021
  77. random-zebra referenced this in commit 286a35e590 on Apr 7, 2021
  78. kittywhiskers referenced this in commit 84efaab57f on Aug 22, 2021
  79. kittywhiskers referenced this in commit 4d58e8947e on Aug 30, 2021
  80. PastaPastaPasta referenced this in commit ba78c27460 on Sep 18, 2021
  81. PastaPastaPasta referenced this in commit abb144c01a on Sep 24, 2021
  82. PastaPastaPasta referenced this in commit 6deaf3665f on Sep 28, 2021
  83. kittywhiskers referenced this in commit ba2179f9b5 on Oct 8, 2021
  84. kittywhiskers referenced this in commit 9a8a8f6f18 on Oct 12, 2021
  85. kittywhiskers referenced this in commit 3ebf514142 on Oct 16, 2021
  86. kittywhiskers referenced this in commit d733c18265 on Oct 16, 2021
  87. kittywhiskers referenced this in commit 6fb12f81a5 on Oct 19, 2021
  88. PastaPastaPasta referenced this in commit ff22aa299a on Oct 20, 2021
  89. PastaPastaPasta referenced this in commit 8677f45007 on Nov 1, 2021
  90. PastaPastaPasta referenced this in commit d33c4791f8 on Nov 3, 2021
  91. pravblockc referenced this in commit 7d25c869ce on Nov 18, 2021
  92. pravblockc referenced this in commit d8a0855b64 on Nov 18, 2021
  93. DrahtBot locked this on Dec 16, 2021

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-07-03 10:13 UTC

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