refactor: Remove unused CTxMemPool::clear() helper #19909

pull maflcko wants to merge 1 commits into bitcoin:master from maflcko:2009-noTxpoolClear changing 3 files +13 −32
  1. maflcko commented at 2:48 PM on September 7, 2020: member

    Seems odd to have code in Bitcoin Core that is unused.

    Moreover the function was broken (see #24145) and is brittle, as there is nothing that prevents similar bugs from re-appearing.

    Fix both issues by replacing it with C++11 member initializers.

  2. maflcko added the label Refactoring on Sep 7, 2020
  3. maflcko force-pushed on Sep 7, 2020
  4. maflcko force-pushed on Sep 7, 2020
  5. hebasto commented at 3:42 PM on September 7, 2020: member

    Concept ACK. Mind elaborating "useless calls" in fa947ccbd4579c866760b3b2a032bd3765043835 "validation: Remove useless call to mempool->clear()"?

  6. maflcko commented at 3:59 PM on September 7, 2020: member

    The mempool.clear() in UnloadBlockIndex has been added in commit 51598b26319bf1ee98b399dee8152b902c62891a to clear global state between unit tests. Now that there is no global mempool anymore, this it not needed anymore. Also, I couldn't find it to be useful for anything else.

  7. in src/test/mempool_tests.cpp:765 in fa0fbb3e5e outdated
     761 | @@ -761,7 +762,7 @@ BOOST_AUTO_TEST_CASE(MempoolAncestryTests)
     762 |      tb = make_tx(/* output_values */ {5 * COIN, 3 * COIN}, /* inputs */  {ta});
     763 |      tc = make_tx(/* output_values */ {2 * COIN}, /* inputs */ {tb}, /* input_indices */ {1});
     764 |      td = make_tx(/* output_values */ {6 * COIN}, /* inputs */ {tb, tc}, /* input_indices */ {0, 0});
     765 | -    pool.clear();
     766 | +    pool.clearTxs();
    


    laanwj commented at 12:23 PM on September 8, 2020:

    What is the difference between clearing and just instantiating a new mempool?


    maflcko commented at 7:57 PM on September 8, 2020:

    No difference. Though, a new mempool needs the old cs released and the fresh cs taken, so would be a bit more code


    promag commented at 9:28 PM on September 8, 2020:

    needs the old cs released

    Why?


    maflcko commented at 10:34 AM on September 9, 2020:

    Ok, it is not needed if the scope of pool is kept the same. Though, it is still a larger diff to instantiate a new mempool pool2, lock it and replace pool with pool2. Happy to do whatever reviewers want, so let me know if I should keep this or change it.


    promag commented at 10:38 AM on September 9, 2020:

    I was just asking. It doesn't need to be a big change, something like:

    {
    CTxMemPool pool;
    // ...
    }
    
    {
    CTxMemPool pool;
    // ...
    }
    

    maflcko commented at 2:07 PM on September 9, 2020:

    thx, fixed

  8. laanwj commented at 12:24 PM on September 8, 2020: member

    Concept ACK

  9. hebasto cross-referenced this on Sep 8, 2020 from issue Avoid locking CTxMemPool::cs recursively in some cases by hebasto
  10. in src/test/util/txmempool.h:10 in fad3a7c5b9 outdated
       5 | +#ifndef BITCOIN_TEST_UTIL_TXMEMPOOL_H
       6 | +#define BITCOIN_TEST_UTIL_TXMEMPOOL_H
       7 | +
       8 | +#include <txmempool.h>
       9 | +
      10 | +struct TxMemPoolClearable : public CTxMemPool {
    


    hebasto commented at 1:44 PM on September 8, 2020:

    May I suggest to name this struct more generally, say TxMemPoolTesting, as it seems more functions could be added to it. E.g., a special version of GetTransactionAncestry() that requires external CTxMemPool::cs locking, see #19872 (review).


    hebasto commented at 5:50 PM on September 8, 2020:

    Ignore all above. It won't work.

  11. hebasto commented at 5:52 PM on September 8, 2020: member

    Wrt to preserving recursive locking of CTxMemPool::cs mind considering the following patch:

    --- a/src/test/txvalidationcache_tests.cpp
    +++ b/src/test/txvalidationcache_tests.cpp
    @@ -73,7 +73,7 @@ BOOST_FIXTURE_TEST_CASE(tx_mempool_block_doublespend, TestChain100Setup)
             LOCK(cs_main);
             BOOST_CHECK(::ChainActive().Tip()->GetBlockHash() != block.GetHash());
         }
    -    tx_pool.clearTxs();
    +    WITH_LOCK(tx_pool.cs, tx_pool.clearTxs());
     
         // Test 3: ... and should be rejected if spend2 is in the memory pool
         BOOST_CHECK(ToMemPool(spends[1]));
    @@ -82,7 +82,7 @@ BOOST_FIXTURE_TEST_CASE(tx_mempool_block_doublespend, TestChain100Setup)
             LOCK(cs_main);
             BOOST_CHECK(::ChainActive().Tip()->GetBlockHash() != block.GetHash());
         }
    -    tx_pool.clearTxs();
    +    WITH_LOCK(tx_pool.cs, tx_pool.clearTxs());
     
         // Final sanity test: first spend in tx_pool, second in block, that's OK:
         std::vector<CMutableTransaction> oneSpend;
    diff --git a/src/test/util/txmempool.h b/src/test/util/txmempool.h
    index 7edc6d607..db52377b0 100644
    --- a/src/test/util/txmempool.h
    +++ b/src/test/util/txmempool.h
    @@ -9,9 +9,9 @@
     
     struct TxMemPoolClearable : public CTxMemPool {
         /** Clear added transactions */
    -    void clearTxs()
    +    void clearTxs() EXCLUSIVE_LOCKS_REQUIRED(cs)
         {
    -        LOCK(cs);
    +        AssertLockHeld(cs);
             mapTx.clear();
             mapNextTx.clear();
             totalTxSize = 0;
    

    ?

  12. hebasto cross-referenced this on Sep 8, 2020 from issue Replace all of the RecursiveMutex instances with the Mutex ones by hebasto
  13. maflcko force-pushed on Sep 9, 2020
  14. maflcko commented at 10:42 AM on September 9, 2020: member

    @hebasto It hasn't been decided for the project whether to switch the mempool.cs to non-recursive mutex, nor in what way to do it, so I'll leave that test patch for later.

  15. maflcko force-pushed on Sep 9, 2020
  16. maflcko force-pushed on Sep 9, 2020
  17. maflcko cross-referenced this on Sep 9, 2020 from issue validation: Reduce direct g_chainman usage by dongcarl
  18. dongcarl commented at 4:48 PM on September 10, 2020: contributor

    I'm not very familiar with these tests, so I may be completely off the mark here. However, it seems to me like the purpose of clearTxs is to reset the mempool without re-instantiating it. I wonder if we shouldn't consider just re-instantiating the mempool every time we want to clear it, as:

    1. If there were a performance penalty, it wouldn't matter too much as it's in the test code
    2. We wouldn't have to have the burden of keeping TxMemPoolClearable::clearTxs() and CTxMemPool in sync.
  19. laanwj commented at 4:59 PM on September 10, 2020: member

    @dongcarl This was also my idea in the discussion here, but there wasn't really a decision: #19909 (review)

  20. dongcarl commented at 6:07 PM on September 10, 2020: contributor

    The mempool.clear() in UnloadBlockIndex has been added in commit 51598b2 to clear global state between unit tests. Now that there is no global mempool anymore, this it not needed anymore. Also, I couldn't find it to be useful for anything else.

    Does the call to UnloadBlockIndex here: https://github.com/bitcoin/bitcoin/blob/a47e5964861dfb98d61719c9852e12fd6da84c31/src/init.cpp#L1562 Make any difference to the mempool that we should keep in mind?

  21. sdaftuar commented at 11:47 PM on September 10, 2020: member

    Is this refactor important to other work? Having the ability to clear the mempool seems useful to me; even though we've never exposed it, I could imagine some situations where invoking the clear() function somehow (say via rpc) might be useful.

    Alternatively -- and even more speculatively -- in thinking about how we update the mempool after a reorg, I've wondered if there might be solutions where clearing the mempool and re-adding things back might be better in some scenarios.

    I don't think either of those is pressing though so if there's some good reason to get rid of it to help with other work in progress, then that's fine with me, we can always revisit the right design if the functionality I suggest might actually be useful. Just not sure if this might be wasted effort, if there's no important reason or followup work motivating this change?

  22. laanwj commented at 1:48 PM on September 11, 2020: member

    I think you have a point there @sdaftuar. I'm not sure in how far it's here the case (there is no standard definition of the expectation for a "mempool interface"), but in some cases some methods just belong in an API (say, add/lookup/delete in a table) even if they're temporarily not used, and going over the top to clean APIs to the minimum set can make future changes harder.

  23. DrahtBot commented at 1:47 PM on September 19, 2020: contributor

    <!--e57a25ab6845829454e8d69fc972939a-->

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

    <!--021abf342d371248e50ceaed478a90ca-->

    Reviews

    See the guideline for information on the review process.

    Type Reviewers
    ACK glozow
    Concept ACK hebasto, laanwj, jnewbery, practicalswift, fanquake

    If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update.

    <!--174a7506f384e20aa4161008e828411d-->

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #26614 (Accurately account for mempool index memory by hebasto)

    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.

  24. maflcko commented at 2:25 PM on September 19, 2020: member

    The clear method as currently implemented doesn't help with implementing a RPC that clears the mempool, because it also clears the fee estimates. If the method is kept, it should be renamed to ReInit (or similar), because all it does is (re-)initialize the member variables of the mempool.

    Though, according to our release notes, member variables should be initialized inline via C++11 initializers to avoid uninitialized values. (This is what is being done in this pull)

    Also, I can not imagine a single use case where clearing the whole mempool over RPC is useful. At most sniping a single tx might be useful. Though even that has been rejected at least twice in the past. Please refer to #15873 and #16523.

  25. sdaftuar commented at 3:15 PM on September 19, 2020: member

    If you’re a miner, I could imagine it is possible that clearing the mempool could be helpful in the event of a dos-attack where pathological transaction chains (for example) cause block template creation to be very slow. So a use case could be to empty it and use other rpcs to manually refill it.

    That’s just an example, and I don’t know if it is likely we’d support that anytime soon, but I could imagine the use case.

    (Your point about fee estimation is a reasonable one, but I believe there is work happening elsewhere to decouple that from the mempool? )

    At any rate I don’t feel strongly about this, if removing this function is helpful for other work I am not opposed either.

  26. DrahtBot cross-referenced this on Sep 19, 2020 from issue refactor: Make CCheckQueue RAII-styled by hebasto
  27. DrahtBot cross-referenced this on Sep 19, 2020 from issue Add local thread pool to CCheckQueue by hebasto
  28. DrahtBot cross-referenced this on Sep 19, 2020 from issue txmempool: split epoch logic into class by ajtowns
  29. DrahtBot cross-referenced this on Sep 19, 2020 from issue Add fee_est tool for debugging fee estimation code by ryanofsky
  30. DrahtBot cross-referenced this on Sep 22, 2020 from issue validation: re-delegate absurd fee checking from mempool to clients by glozow
  31. DrahtBot added the label Needs rebase on Sep 23, 2020
  32. maflcko force-pushed on Sep 28, 2020
  33. maflcko closed this on Sep 28, 2020

  34. maflcko deleted the branch on Sep 28, 2020
  35. jnewbery commented at 8:24 AM on October 30, 2020: contributor

    Concept ACK. Removing test-only code from the product is generally useful. Partly because it reduces the complexity of interfaces, reduces the binary size, etc, but more so because relying on test-only code paths increases the risk that the test logic diverges from the live logic. For example, if some initialization code was added to the mempool constructor, but not clear(), and tests assume that a call to clear() gives a completely freshly initialized mempool, then the test setup is not testing what we want it to.

  36. practicalswift commented at 12:52 PM on October 30, 2020: contributor

    Concept ACK for the reasons @jnewbery mentioned.

  37. maflcko cross-referenced this on Jan 26, 2022 from issue mempool: Clear vTxHashes when mapTx is cleared by Bushstar
  38. maflcko cross-referenced this on Jan 28, 2022 from issue bug: Reindex started via `ThreadSafeQuestion` will always fail by dongcarl
  39. bitcoin locked this on Feb 15, 2022
  40. bitcoin unlocked this on Apr 28, 2022
  41. maflcko restored the branch on Apr 28, 2022
  42. maflcko reopened this on Apr 28, 2022

  43. maflcko force-pushed on Apr 28, 2022
  44. DrahtBot removed the label Needs rebase on Apr 28, 2022
  45. DrahtBot cross-referenced this on Apr 29, 2022 from issue miner: bug fix? update for ancestor inclusion using modified fees, not base by glozow
  46. DrahtBot cross-referenced this on Apr 29, 2022 from issue refactor: Move calculation logic out from `CheckSequenceLocksAtTip()` by hebasto
  47. jnewbery commented at 7:47 AM on April 29, 2022: contributor

    I wonder if we shouldn't consider just re-instantiating the mempool every time we want to clear it, as:

    @dongcarl This was also my idea in the discussion here, but there wasn't really a decision: #19909 (review) @MarcoFalke did you consider this approach? On the face of it, it seems better to reinstantiate a mempool every time you want to clear it rather than having custom test code to reach into the object's members.

  48. maflcko added the label Waiting for author on Apr 29, 2022
  49. maflcko commented at 8:14 AM on April 29, 2022: member

    Yeah, I'll look into this. First part of that is #25024

  50. maflcko commented at 8:26 AM on April 29, 2022: member

    In reply to Suhas point that the clear method could be used to wipe the txs for example during a reorg or by a miner to speed up block template creation: I am still doubtful that this method can actually achieve this goal, as it also resets other members of mempool. I think it would be sufficient and clearer to just use the existing removeRecursive functionality of the mempool to wipe all txs?

  51. DrahtBot added the label Needs rebase on Apr 29, 2022
  52. maflcko cross-referenced this on May 6, 2022 from issue test: Cleanup miner_tests by maflcko
  53. maflcko removed the label Waiting for author on May 27, 2022
  54. maflcko cross-referenced this on May 28, 2022 from issue [kernel 2d/n] Reduce CTxMemPool constructor call sites by dongcarl
  55. fanquake referenced this in commit 9eaa5dbc81 on Oct 10, 2022
  56. maflcko force-pushed on Oct 10, 2022
  57. fanquake commented at 2:04 PM on October 10, 2022: member

    Concept ACK

  58. DrahtBot removed the label Needs rebase on Oct 10, 2022
  59. maflcko renamed this:
    txmempool: Remove unused clear() member function
    refactor: Remove unused CTxMemPool::clear() helper
    on Oct 10, 2022
  60. sidhujag referenced this in commit 1d932c8c4c on Oct 10, 2022
  61. fanquake requested review from glozow on Nov 30, 2022
  62. DrahtBot cross-referenced this on Dec 1, 2022 from issue Accurately account for mempool index memory by hebasto
  63. in src/test/txvalidationcache_tests.cpp:81 in fa299b39ee outdated
      76 | @@ -77,7 +77,9 @@ BOOST_FIXTURE_TEST_CASE(tx_mempool_block_doublespend, Dersig100Setup)
      77 |          LOCK(cs_main);
      78 |          BOOST_CHECK(m_node.chainman->ActiveChain().Tip()->GetBlockHash() != block.GetHash());
      79 |      }
      80 | -    m_node.mempool->clear();
      81 | +    BOOST_CHECK_EQUAL(m_node.mempool->size(), 1U);
      82 | +    WITH_LOCK(m_node.mempool->cs, m_node.mempool->removeRecursive(CTransaction{spends[0]}, MemPoolRemovalReason::CONFLICT));
    


    glozow commented at 2:45 PM on December 12, 2022:

    Question: is there a reason you are calling removeRecursive() instead of the approach from #25073 / #19909 (comment) of instantiating a new mempool between test cases?


    maflcko commented at 12:19 PM on December 13, 2022:

    25073 is using a mempool local to the test only (and passing it to the miner). However, here the "global" mempool is used, which is also used by validation. So creating a new mempool would also require updating the pointer in validation.

    I don't think this is worth it, but I am happy to work on this, if reviewers want me to.


    glozow commented at 1:54 PM on December 19, 2022:

    Thanks, resolving, seems fine to me since the test is just checking block results when a conflicting tx is in mempool.

  64. glozow commented at 2:46 PM on December 12, 2022: member

    Concept ACK to removing a function that is not used. I agree that, if manually removing individual or all transactions from mempool is a valid use case we want to implement, this function would not be sufficient.

  65. txmempool: Remove unused clear() member function fa818e103c
  66. maflcko force-pushed on Dec 13, 2022
  67. glozow commented at 3:54 PM on December 19, 2022: member

    ACK fa818e103c0ddb515f29ae9ce8de44931e12e69e

  68. glozow merged this on Jan 4, 2023
  69. glozow closed this on Jan 4, 2023

  70. maflcko deleted the branch on Jan 4, 2023
  71. sidhujag referenced this in commit db64668faf on Jan 4, 2023
  72. bitcoin locked this on Jan 4, 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: 2026-05-19 06:53 UTC