Reduce default mempool size in -blocksonly mode #26471

pull willcl-ark wants to merge 3 commits into bitcoin:master from willcl-ark:blocksonly_mempool_cache changing 4 files +22 −4
  1. willcl-ark commented at 3:22 pm on November 8, 2022: contributor

    Fixes #9526

    When -blocksonly has been set reduce default mempool size to avoid surprising resource usage via sharing un-used mempool cache space with dbcache.

    In comparison to #9569 which either set maxmempool size to 0 when -blocksonly was set or else errored on startup, this change will permit maxmempool options being set.

    This preserves the current (surprising?) behaviour of having a functional mempool in -blocksonly mode, to permit whitelisted peer transaction relay, whilst reducing average runtime memory usage for blocksonly nodes which either use the default settings or have otherwise configured a maxmempool size.

    To use the previous old defaults node operators can configure their node with: -blocksonly -maxmempool=300.

  2. in src/validation.cpp:2342 in d68dc8244d outdated
    2335@@ -2336,8 +2336,16 @@ CoinsCacheSizeState Chainstate::GetCoinsCacheSizeState(
    2336     AssertLockHeld(::cs_main);
    2337     const int64_t nMempoolUsage = m_mempool ? m_mempool->DynamicMemoryUsage() : 0;
    2338     int64_t cacheSize = CoinsTip().DynamicMemoryUsage();
    2339-    int64_t nTotalSpace =
    2340-        max_coins_cache_size_bytes + std::max<int64_t>(int64_t(max_mempool_size_bytes) - nMempoolUsage, 0);
    2341+    int64_t nTotalSpace;
    2342+    // Don't share unused mempool space with dbcache in blocksonly mode to avoid surprising resource usage
    2343+    // Keeping the mempool enabled will still permit transaction relay for whitelisted peers
    2344+    if (gArgs.GetBoolArg("-blocksonly", false)) {
    


    stickies-v commented at 5:48 pm on November 10, 2022:
    0    if (gArgs.GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY)) {
    

    willcl-ark commented at 1:39 pm on November 11, 2022:
    This is in net.h, which I don’t really want to add as a new dependency for validation.cpp 🤔

    stickies-v commented at 2:13 pm on November 11, 2022:
    Fair enough, but then I think DEFAULT_BLOCKSONLY should be declared in a different header (not too sure where that would be, hopefully someone more familiar can chime in). Redeclaring default values in multiple locations scares me.

    dergoegge commented at 3:02 pm on January 16, 2023:
    Ideally we should probably remove Chainstate’s dependency on ArgsManager and introduce some chainstate options. That should probably happen in a separate PR though.

    willcl-ark commented at 3:28 pm on January 17, 2023:
    Right. Have taken a new direction though for now as per #26471 (review)
  3. in src/validation.cpp:2348 in d68dc8244d outdated
    2345+        nTotalSpace =
    2346+            max_coins_cache_size_bytes;
    2347+    } else {
    2348+        nTotalSpace =
    2349+            max_coins_cache_size_bytes + std::max<int64_t>(int64_t(max_mempool_size_bytes) - nMempoolUsage, 0);
    2350+    }
    


    stickies-v commented at 5:52 pm on November 10, 2022:
    0    int64_t nTotalSpace{max_coins_cache_size_bytes};
    1    // Don't share unused mempool space with dbcache in blocksonly mode to avoid surprising resource usage
    2    // Keeping the mempool enabled will still permit transaction relay for whitelisted peers
    3    if (!gArgs.GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY)) {
    4        nTotalSpace += std::max<int64_t>(int64_t(max_mempool_size_bytes) - nMempoolUsage, 0);
    5    }
    
  4. in src/init.cpp:1470 in d68dc8244d outdated
    1466@@ -1467,7 +1467,8 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
    1467     if (mempool_opts.max_size_bytes < 0 || mempool_opts.max_size_bytes < descendant_limit_bytes) {
    1468         return InitError(strprintf(_("-maxmempool must be at least %d MB"), std::ceil(descendant_limit_bytes / 1'000'000.0)));
    1469     }
    1470-    LogPrintf("* Using %.1f MiB for in-memory UTXO set (plus up to %.1f MiB of unused mempool space)\n", cache_sizes.coins * (1.0 / 1024 / 1024), mempool_opts.max_size_bytes * (1.0 / 1024 / 1024));
    1471+    float shared_mempool_space = args.GetBoolArg("-blocksonly", false) ? 0 : mempool_opts.max_size_bytes * (1.0 / 1024 / 1024);
    


    stickies-v commented at 5:53 pm on November 10, 2022:
    0    float shared_mempool_space{args.GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY) ? 0 : mempool_opts.max_size_bytes * (1.0 / 1024 / 1024)};
    
  5. glozow added the label Resource usage on Nov 10, 2022
  6. stickies-v commented at 8:19 pm on November 10, 2022: contributor

    It took me a surprisingly long time to figure out the rationale here. I’ll write down my understanding both to have it validated/corrected, as well as hopefully to inform other people looking at this.


    My understanding:

    Users running with -blocksonly expect to have a near zero-sized mempool, because it’ll only contain transactions broadcasted by their own wallet (disabled by default) or transactions received from whitelisted peers (non-default). As such, when provisioning their system, a user would expect to only have to allocate dbcache amount of memory, instead of currently actually requiring dbcache + maxmempool, which could lead to stability issues.

    Without -blocksonly, a user needs to ensure that his system is provisioned to support both the full dbcache and mempool. Since it’s provisioned anyway, we might as well use the unused mempool space for dbcache, which is especially helpful during IBD.

    The misunderstanding for me was that the resource sharing between dbcache and maxmempool is not a resource optimization (in which case “we would benefit even more with -blocksonly, so why disable the optimization?!”) but rather an accounting trick. Users running in -blocksonly should just increase their dbcache by whatever size maxmempool is for a similar effect (but not entirely, as explained below)


    If my understanding is correct, I’m Concept ACK (i.e. making resource usage less surprising) but not yet Approach ACK, because:

    • this would be a performance degradation for users running -blocksonly that don’t realize they should update their -dbcache. Users running -blocksonly could get higher default dbcache defaults, but that seems messy too.
    • users can’t really replicate current behaviour even if they’re aware of the change. The intuitive solution would be to increase -dbcache by -maxmempool, however, dbcache is shared by multiple caches, of which the coins cache receives 25-50%. It seems there’s no way to allocate an extra 300MB (assuming default) to just the coins cache without increasing the dbcache by a total of 600MB - 1.2GB?
  7. willcl-ark commented at 11:16 am on November 11, 2022: contributor

    Thanks for your review at this conceptual stage @stickies-v. Your understanding of the problem and solution matches my own, although I had not fully considered the knock-on effect that:

    users can’t really replicate current behaviour even if they’re aware of the change … without increasing the dbcache by a total of 600MB - 1.2GB?

    I also concur with you that altering default dbcache size for users who enable blocksonly seems kind of messy, although it could be made to work.

    Therefore I see x options available from here:

    1. Keep current behaviour, document it better, and close #9526 as wontfix
    2. Implement (something like) this change which introduces the performance reduction in IBD for blocksonly nodes and document it
    3. Add special-casing for dbcache size when nodes are run in blocksonly mode.

    In writing the options out like that, my first preference might actually be 1), followed by 3) and last 2).

  8. stickies-v commented at 12:47 pm on November 11, 2022: contributor

    Therefore I see x options available from here:

    I think I’m not in favour of 1 & 3. Imo the direction should always be to reduce exceptional behaviour, if the short-term cost of that change is not exorbitant. I think in this case, the cost (potentially slower IBD which can be fixed with user config) is not exorbitant and increased stability (because of reduction of unexpected behaviour) is a worthwhile improvement.

    I can think of two other alternatives, both building on top of what you’ve currently implemented:

    1. add a -increase-coins-cache=<n> parameter to allow users keeping the current behaviour (and maybe even set it to 300 by default if -blocksonly in the first release to give users time to transition, and then change it to 0 in the release after. Pretty user-friendly/straightforward option, but it introduces another kinda one-off parameter.

    2. Allowing users to manually define sub-cache allocations (overriding the defaults), e.g. through -dbcache.coins=<n|f> where n is an absolute amount and f a 0-1 float indicating a percentage of total dbcache. This seems like the most transparent and generic solution, but probably at the cost of reduced user-friendliness. It would also be a significantly bigger code change introducing the new parameters as well as a bunch of validation, and allowing the auto-allocation to deal with partial specification (e.g. only coins and tx_index are specified but not the other ones)

  9. willcl-ark commented at 1:38 pm on November 11, 2022: contributor

    Yes 4) is a possible solution.

    IMO by the time we hit 5), we’re probably almost talking about people who have such an understanding of the system (developers) that they can most likely make the change to the source themselves before compiling if they truely need such fine-grained settings changes.

    Will leave it as is to see if we get any other suggestions, and mull it over myself…

  10. luke-jr commented at 11:13 pm on November 14, 2022: member

    The intuitive solution would be to increase -dbcache by -maxmempool, however, dbcache is shared by multiple caches, of which the coins cache receives 25-50%. It seems there’s no way to allocate an extra 300MB (assuming default) to just the coins cache without increasing the dbcache by a total of 600MB - 1.2GB?

    FWIW, I have a related thought process for Knots, where it makes sense to leave the coins cache unlimited (and let memory pressure trigger flushing), yet it isn’t sane to just increase -dbcache to the system memory size, because that would also increase other cache sizes which aren’t handled when under memory pressure.

    Therefore I see x options available from here:

    1. support specifying “+mempool” on the end of the -dbcache option to get the current behaviour even in blocksonly mode.
  11. glozow commented at 5:01 pm on January 12, 2023: member

    It seems the key issue is “surprising memory usage,” i.e. -dbcache=n -blocksonly can use n+300 while the user may have expected n. The trick of using -blocksonly to add mempool’s memory to the coins cache seems quite esoteric (lmk if I’m mistaken), so preserving it would be a bit less important imo.

    the current (surprising) behaviour of having a functional mempool in -blocksonly mode

    Given how surprising this is to so many people (including those affected by this problem), I can see how disabling mempool in blocksonly would be the easiest option. But can also see how it’s not acceptable for users that rely on the current whitelist relay behavior according to #9569.

    1. Perhaps setting a very small mempool m_max_size_bytes when in blocksonly mode unless overridden by -maxmempool, would be one solution? That seems to preserve the trick for those using it intentionally, while reducing the amount of “surprising memory usage” for those that assume 0 memory for -blocksonly. Those who benefit from the extra 300MB by accident can perhaps get their answer from the release notes if they see a performance reduction. If they want to continue doing what they were doing, they just need to set -maxmempool.
  12. DrahtBot commented at 5:01 pm on January 12, 2023: contributor

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

    Reviews

    See the guideline for information on the review process.

    Type Reviewers
    ACK ajtowns
    Stale ACK aureleoules
    Ignored review stickies-v

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

  13. willcl-ark commented at 7:54 pm on January 13, 2023: contributor
    1. Perhaps setting a very small mempool m_max_size_bytes when in blocksonly mode unless overridden by -maxmempool, would be one solution? That seems to preserve the trick for those using it intentionally, while reducing the amount of “surprising memory usage” for those that assume 0 memory for -blocksonly. Those who benefit from the extra 300MB by accident can perhaps get their answer from the release notes if they see a performance reduction. If they want to continue doing what they were doing, they just need to set -maxmempool.

    I think this is a neat solution which covers all requirements so implemented it in this second branch (it’s also much cleaner implementation-wise).

    The only question I had was how small is “smaller”? I opted for 5MB in blocksonly mode as this should be enough for quite a few transactions to be relayed for whitelisted peers, I think…

    If this is preferred I will move it over to this branch…?

  14. glozow commented at 3:05 pm on January 16, 2023: member

    The only question I had was how small is “smaller”? I opted for 5MB in blocksonly mode as this should be enough for quite a few transactions to be relayed for whitelisted peers, I think…

    That definitely seems sufficient, and they can still make it higher if they need to. 5MB is the minimum -maxmempool config allowed as well, as the smaller the mempool size, the easier it is for your mempool min feerate to get driven up really high. Thinking out loud I guess this isn’t as much of a concern for -blocksonly since you won’t consider any transactions from strangers, so maybe smaller would be okay… but I can’t say a different number with confidence.

    If this is preferred I will move it over to this branch…?

    I think it’s a relatively simple change to lessen this problem with minimal side effects? :shrug: though I don’t know if we could say we’ve completely fixed it. fwiw I think it’s sensible regardless since we’re probably unlikely to need 300MB in blocksonly mode.

  15. willcl-ark force-pushed on Jan 16, 2023
  16. willcl-ark force-pushed on Jan 16, 2023
  17. willcl-ark renamed this:
    Don't share mempool with dbcache in -blocksonly mode
    Reduce default mempool size in -blocksonly mode
    on Jan 17, 2023
  18. willcl-ark marked this as ready for review on Jan 17, 2023
  19. willcl-ark commented at 9:12 am on January 17, 2023: contributor
    OK I have moved the commits across, and updated the PR title and description. I also added a new release note commit which I thought was worth it, but happy to be persuaded otherwise.
  20. in src/init.cpp:1473 in 4a17be6d4d outdated
    1466@@ -1467,7 +1467,16 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
    1467     if (mempool_opts.max_size_bytes < 0 || mempool_opts.max_size_bytes < descendant_limit_bytes) {
    1468         return InitError(strprintf(_("-maxmempool must be at least %d MB"), std::ceil(descendant_limit_bytes / 1'000'000.0)));
    1469     }
    1470-    LogPrintf("* Using %.1f MiB for in-memory UTXO set (plus up to %.1f MiB of unused mempool space)\n", cache_sizes.coins * (1.0 / 1024 / 1024), mempool_opts.max_size_bytes * (1.0 / 1024 / 1024));
    1471+    // If we are running in blocksonly mode don't allocate the default 300MB of space for mempool
    1472+    // unless the user specifies -maxmempool, as otherwise it will leak into dbcache allowance.
    1473+    // Keeping the mempool enabled will still permit transaction relay for whitelisted peers
    1474+    if (args.GetBoolArg("-blocksonly", 0) && !args.IsArgSet("-maxmempool")) {
    


    aureleoules commented at 9:44 am on January 17, 2023:

    in 4a17be6d4d025e1381fc37e43794a413b3654b6d: Now that you’re in init.cpp you can use DEFAULT_BLOCKSONLY.

    0    if (args.GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY) && !args.IsArgSet("-maxmempool")) {
    

    willcl-ark commented at 10:15 am on January 17, 2023:
    Ah yes indeed. Thanks!
  21. in doc/reduce-memory.md:19 in a0af9931bc outdated
    15@@ -16,10 +16,14 @@ The size of some in-memory caches can be reduced. As caches trade off memory usa
    16   - The minimum value for `-maxmempool` is 5.
    17   - A lower maximum mempool size means that transactions will be evicted sooner. This will affect any uses of `bitcoind` that process unconfirmed transactions.
    18 
    19-- To completely disable mempool functionality there is the option `-blocksonly`. This will make the client opt out of receiving (and thus relaying) transactions completely, except as part of blocks.
    20+- To disable mempool functionality there is the option `-blocksonly`. This will make the client opt out of receiving (and thus relaying) transactions, except for from whitelisted peers and as part of blocks.
    


    aureleoules commented at 9:50 am on January 17, 2023:

    in a0af9931bc84f44a64daa87860c524eab44c76b1

    0- To disable mempool functionality there is the option `-blocksonly`. This will make the client opt out of receiving (and thus relaying) transactions, except from whitelisted peers and as part of blocks.
    
  22. in src/init.cpp:1475 in 4a17be6d4d outdated
    1471+    // If we are running in blocksonly mode don't allocate the default 300MB of space for mempool
    1472+    // unless the user specifies -maxmempool, as otherwise it will leak into dbcache allowance.
    1473+    // Keeping the mempool enabled will still permit transaction relay for whitelisted peers
    1474+    if (args.GetBoolArg("-blocksonly", 0) && !args.IsArgSet("-maxmempool")) {
    1475+        // Re-use descendant_limit_bytes as the minimum mempool size
    1476+        mempool_opts.max_size_bytes = descendant_limit_bytes;
    


    aureleoules commented at 10:07 am on January 17, 2023:
    nit: descendant_limit_bytes is around 3.9MB and not 5MB as claimed. Should the documentation be changed to reflect this or it doesn’t really matter?
  23. in doc/reduce-memory.md:25 in dd4325981b outdated
    21 
    22   - Do not use this when using the client to broadcast transactions as any transaction sent will stick out like a sore thumb, affecting privacy. When used with the wallet it should be combined with `-walletbroadcast=0` and `-spendzeroconfchange=0`. Another mechanism for broadcasting outgoing transactions (if any) should be used.
    23 
    24+  - In `-blocksonly` mode the node will by default use a 5MB mempool size, avoiding unexpected memory usage from dbcache sharing the 300MB default mempool cache size.
    25+
    26+  - If you would like to continue using the mempool cache allocation for dbcache in `-blocksonly` mode then you can specify the mempool size using the `maxmempoolsize` option.
    


    aureleoules commented at 10:13 am on January 17, 2023:

    nit: Maybe also add a note saying that setting -limitdescendantsize can also alter the cache size with -blocksonly?

    ./src/bitcoind -limitdescendantsize=0

    Using 440.0 MiB for in-memory UTXO set (plus up to 286.1 MiB of unused mempool space)

    ./src/bitcoind -limitdescendantsize=300

    Using 440.0 MiB for in-memory UTXO set (plus up to 286.1 MiB of unused mempool space)


    ./src/bitcoind -limitdescendantsize=0 -blocksonly

    Using 440.0 MiB for in-memory UTXO set (plus up to 0.0 MiB of unused mempool space)

    ./src/bitcoind -limitdescendantsize=300 -blocksonly

    Using 440.0 MiB for in-memory UTXO set (plus up to 11.4 MiB of unused mempool space)


    willcl-ark commented at 10:17 am on January 17, 2023:
    Hmmm you are right. I wanted to avoid another magic constant if possible, but this does indeed have unintended side effects. I am going to revert it to 5MB for now
  24. willcl-ark force-pushed on Jan 17, 2023
  25. in src/init.cpp:1474 in 931924f5cc outdated
    1466@@ -1467,7 +1467,15 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
    1467     if (mempool_opts.max_size_bytes < 0 || mempool_opts.max_size_bytes < descendant_limit_bytes) {
    1468         return InitError(strprintf(_("-maxmempool must be at least %d MB"), std::ceil(descendant_limit_bytes / 1'000'000.0)));
    1469     }
    1470-    LogPrintf("* Using %.1f MiB for in-memory UTXO set (plus up to %.1f MiB of unused mempool space)\n", cache_sizes.coins * (1.0 / 1024 / 1024), mempool_opts.max_size_bytes * (1.0 / 1024 / 1024));
    1471+    // If we are running in blocksonly mode don't allocate the default 300MB of space for mempool
    1472+    // unless the user specifies -maxmempool, as otherwise it will leak into dbcache allowance.
    1473+    // Keeping the mempool enabled will still permit transaction relay for whitelisted peers
    1474+    if (args.GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY) && !args.IsArgSet("-maxmempool")) {
    1475+        mempool_opts.max_size_bytes = 5 * 1'000'000;
    


    aureleoules commented at 10:57 am on January 17, 2023:
    nit: This should probably be stored as a constant such as DEFAULT_BLOCKSONLY_MEMPOOL_MAX_SIZE.

    stickies-v commented at 12:36 pm on January 17, 2023:

    Have you considered adding this logic to mempool_args.cpp::ApplyArgsManOptions() instead, so we don’t set our mempool_opts.max_size_bytes in two different locations? I think this has the benefit of 1) being easier to understand why options are set to the values they are and 2) avoid unexpected issues/behaviour where mempool_opts.max_size_bytes is temporarily set to 300MB before being changed to 5MB.

    The downside, as previously discussed, is including net.h, which probably needs fixing anyway (perhaps in separate PR?).

    I think I’d much prefer this approach.

     0diff --git a/src/init.cpp b/src/init.cpp
     1index c4b15392c..641fef81c 100644
     2--- a/src/init.cpp
     3+++ b/src/init.cpp
     4@@ -1467,12 +1467,6 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
     5     if (mempool_opts.max_size_bytes < 0 || mempool_opts.max_size_bytes < descendant_limit_bytes) {
     6         return InitError(strprintf(_("-maxmempool must be at least %d MB"), std::ceil(descendant_limit_bytes / 1'000'000.0)));
     7     }
     8-    // If we are running in blocksonly mode don't allocate the default 300MB of space for mempool
     9-    // unless the user specifies -maxmempool, as otherwise it will leak into dbcache allowance.
    10-    // Keeping the mempool enabled will still permit transaction relay for whitelisted peers
    11-    if (args.GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY) && !args.IsArgSet("-maxmempool")) {
    12-        mempool_opts.max_size_bytes = 5 * 1'000'000;
    13-    }
    14     LogPrintf("* Using %.1f MiB for in-memory UTXO set (plus up to %.1f MiB of unused mempool space)\n",
    15               cache_sizes.coins * (1.0 / 1024 / 1024),
    16               mempool_opts.max_size_bytes * (1.0 / 1024 / 1024));
    17diff --git a/src/node/mempool_args.cpp b/src/node/mempool_args.cpp
    18index 8c929e5e0..b530ac981 100644
    19--- a/src/node/mempool_args.cpp
    20+++ b/src/node/mempool_args.cpp
    21@@ -10,6 +10,7 @@
    22 #include <chainparams.h>
    23 #include <consensus/amount.h>
    24 #include <logging.h>
    25+#include <net.h>
    26 #include <policy/feerate.h>
    27 #include <policy/policy.h>
    28 #include <script/standard.h>
    29@@ -42,7 +43,14 @@ std::optional<bilingual_str> ApplyArgsManOptions(const ArgsManager& argsman, con
    30 {
    31     mempool_opts.check_ratio = argsman.GetIntArg("-checkmempool", mempool_opts.check_ratio);
    32 
    33-    if (auto mb = argsman.GetIntArg("-maxmempool")) mempool_opts.max_size_bytes = *mb * 1'000'000;
    34+    if (auto mb = argsman.GetIntArg("-maxmempool")) {
    35+        mempool_opts.max_size_bytes = *mb * 1'000'000;
    36+    } else if (argsman.GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY)) {
    37+        // If we are running in blocksonly mode don't allocate the default 300MB of space for mempool
    38+        // unless the user specifies -maxmempool, as otherwise it will leak into dbcache allowance.
    39+        // Keeping the mempool enabled will still permit transaction relay for whitelisted peers
    40+        mempool_opts.max_size_bytes = 5 * 1'000'000;
    41+    }
    42 
    43     if (auto hours = argsman.GetIntArg("-mempoolexpiry")) mempool_opts.expiry = std::chrono::hours{*hours};
    

    stickies-v commented at 2:26 pm on January 17, 2023:
    The docstring can also be simplified now btw, since the described behaviour is in the same if/else

    willcl-ark commented at 3:32 pm on January 17, 2023:
    Done (as DEFAULT_BLOCKSONLY_MAX_MEMPOOL_SIZE_MB)

    willcl-ark commented at 3:34 pm on January 17, 2023:

    Moved logic into mempool_args.cpp::ApplyArgsManOptions() as this seems both cleaner, and a more logical place for it.

    Adding net.h to mempool_args.cpp increased translation unit line count by 29 lines

  26. aureleoules approved
  27. aureleoules commented at 11:10 am on January 17, 2023: member

    ACK 931924f5cc1dd9c82306a0ce59b62cf5c9276565 Tested with -blocksonly and -blocksonly -maxmempool=n and verified the logs, seems to work as intended.

    (Please avoid rebasing when there is no need.)

  28. in doc/reduce-memory.md:19 in 931924f5cc outdated
    15@@ -16,10 +16,14 @@ The size of some in-memory caches can be reduced. As caches trade off memory usa
    16   - The minimum value for `-maxmempool` is 5.
    17   - A lower maximum mempool size means that transactions will be evicted sooner. This will affect any uses of `bitcoind` that process unconfirmed transactions.
    18 
    19-- To completely disable mempool functionality there is the option `-blocksonly`. This will make the client opt out of receiving (and thus relaying) transactions completely, except as part of blocks.
    20+- To disable mempool functionality there is the option `-blocksonly`. This will make the client opt out of receiving (and thus relaying) transactions, except from whitelisted peers and as part of blocks.
    


    stickies-v commented at 12:03 pm on January 17, 2023:
    0- To disable most of the mempool functionality there is the option `-blocksonly`. This will make the client opt out of receiving (and thus relaying) transactions, except from whitelisted peers and as part of blocks.
    

    willcl-ark commented at 2:47 pm on January 17, 2023:
    Done
  29. in doc/reduce-memory.md:23 in 931924f5cc outdated
    15@@ -16,10 +16,14 @@ The size of some in-memory caches can be reduced. As caches trade off memory usa
    16   - The minimum value for `-maxmempool` is 5.
    17   - A lower maximum mempool size means that transactions will be evicted sooner. This will affect any uses of `bitcoind` that process unconfirmed transactions.
    18 
    19-- To completely disable mempool functionality there is the option `-blocksonly`. This will make the client opt out of receiving (and thus relaying) transactions completely, except as part of blocks.
    20+- To disable mempool functionality there is the option `-blocksonly`. This will make the client opt out of receiving (and thus relaying) transactions, except from whitelisted peers and as part of blocks.
    21 
    22   - Do not use this when using the client to broadcast transactions as any transaction sent will stick out like a sore thumb, affecting privacy. When used with the wallet it should be combined with `-walletbroadcast=0` and `-spendzeroconfchange=0`. Another mechanism for broadcasting outgoing transactions (if any) should be used.
    23 
    24+  - In `-blocksonly` mode the node will by default use a 5MB mempool size, avoiding unexpected memory usage from dbcache sharing the 300MB default mempool cache size.
    


    stickies-v commented at 12:08 pm on January 17, 2023:

    It seems we’re not doing this in other parts of the document, but if we reference the constant (suggested by aureleoules which I +1) that would make it easier to keep the docs in sync with future changes to the constant?

    0  - In `-blocksonly` mode the node will by default use a 5MB mempool size (`DEFAULT_BLOCKSONLY_MEMPOOL_MAX_SIZE`), avoiding unexpected memory usage from dbcache sharing the 300MB default mempool cache size.
    

    willcl-ark commented at 2:47 pm on January 17, 2023:
    Done (for now, pending including net.h)
  30. in doc/reduce-memory.md:25 in 931924f5cc outdated
    21 
    22   - Do not use this when using the client to broadcast transactions as any transaction sent will stick out like a sore thumb, affecting privacy. When used with the wallet it should be combined with `-walletbroadcast=0` and `-spendzeroconfchange=0`. Another mechanism for broadcasting outgoing transactions (if any) should be used.
    23 
    24+  - In `-blocksonly` mode the node will by default use a 5MB mempool size, avoiding unexpected memory usage from dbcache sharing the 300MB default mempool cache size.
    25+
    26+  - If you would like to continue using the mempool cache allocation for dbcache in `-blocksonly` mode then you can specify the mempool size using the `maxmempoolsize` option.
    


    stickies-v commented at 12:12 pm on January 17, 2023:
    0  - If you would like to continue using the mempool cache allocation for dbcache in `-blocksonly` mode then you can specify the mempool size using the `-maxmempool` option.
    

    willcl-ark commented at 2:47 pm on January 17, 2023:
    Whoops, fixed.
  31. in doc/release-notes-26471.md:4 in 931924f5cc outdated
    0@@ -0,0 +1,14 @@
    1+Updated settings
    2+----------------
    3+
    4+- Previously running with the `-blocksonly` option effectively disabled the
    


    stickies-v commented at 12:13 pm on January 17, 2023:
    0- Previously running with the `-blocksonly` option all but disabled the
    

    willcl-ark commented at 2:48 pm on January 17, 2023:
    Personally I feel “effectively disabled” is cleared here, so I’ve left it as-is for now (but happy to be persuaded)

    stickies-v commented at 3:22 pm on January 17, 2023:
    The definition “actually but not officially or explicitly” captures “effectively” quite well for me, and in that sense I think is wrong here. But won’t comment further, not that important.

    willcl-ark commented at 1:22 pm on January 20, 2023:
    Removed in new version
  32. in doc/release-notes-26471.md:7 in 931924f5cc outdated
    0@@ -0,0 +1,14 @@
    1+Updated settings
    2+----------------
    3+
    4+- Previously running with the `-blocksonly` option effectively disabled the
    5+  mempool but continued to allocate 300MB of cache for it, which would be
    6+  shared with the dbcache. This might lead to unexpected resource usage of
    7+  nodes running with this option during for example IBD.
    


    stickies-v commented at 12:14 pm on January 17, 2023:
    0  shared with the dbcache. This might lead to nodes running with this
    1  option using more resources than anticipated, especially during IBD.
    

    willcl-ark commented at 2:48 pm on January 17, 2023:
    Done
  33. in doc/release-notes-26471.md:11 in 931924f5cc outdated
     6+  shared with the dbcache. This might lead to unexpected resource usage of
     7+  nodes running with this option during for example IBD.
     8+
     9+  In this release running with `-blocksonly` will only allocate 5MB to the
    10+  mempool by default, permitting the use-case of relaying transactions from
    11+  whitelisted peers, but avoiding unexpected resource usage.
    


    stickies-v commented at 12:16 pm on January 17, 2023:
    0  whitelisted peers, but avoiding unexpected resource usage. It reduces the
    1  available `dbcache` size by 295MB, impacting performance especially during
    2  IBD.
    

    willcl-ark commented at 2:48 pm on January 17, 2023:
    Done
  34. in src/init.cpp:1471 in 931924f5cc outdated
    1466@@ -1467,7 +1467,15 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
    1467     if (mempool_opts.max_size_bytes < 0 || mempool_opts.max_size_bytes < descendant_limit_bytes) {
    1468         return InitError(strprintf(_("-maxmempool must be at least %d MB"), std::ceil(descendant_limit_bytes / 1'000'000.0)));
    1469     }
    1470-    LogPrintf("* Using %.1f MiB for in-memory UTXO set (plus up to %.1f MiB of unused mempool space)\n", cache_sizes.coins * (1.0 / 1024 / 1024), mempool_opts.max_size_bytes * (1.0 / 1024 / 1024));
    1471+    // If we are running in blocksonly mode don't allocate the default 300MB of space for mempool
    1472+    // unless the user specifies -maxmempool, as otherwise it will leak into dbcache allowance.
    


    stickies-v commented at 12:23 pm on January 17, 2023:

    In quite a few places we refer to mempool cache being added to dbcache, but it’s added specifically to the coins/UTXO cache so I think our language should reflect that consistently? (here and in other places)

    0    // unless the user specifies -maxmempool, as otherwise it will leak into UTXO cache allowance.
    

    willcl-ark commented at 2:49 pm on January 17, 2023:
    Agreed and changed.
  35. stickies-v commented at 12:39 pm on January 17, 2023: contributor

    Approach ACK 931924f5cc1dd9c82306a0ce59b62cf5c9276565, except for setting mempool_opts.max_size_bytes in two different locations and times.

    I think this approach tackles a nice balance between addressing the most important issue (node crashing because of unexpected resource usage), reducing additional code overhead (compared to the other approaches considered) and allowing users to maintain existing performance profile without too much admin overhead. The biggest (but manageable) downside is that everyone that upgrades and doesn’t manually override -maxmempool will silently experience a performance degradation, especially during IBD. I expect this performance degradation to be manageable, especially since most users that have the resources available, will probably have manually increased their dbcache anyway for IBD, lowering the relative impact of this change.

  36. willcl-ark force-pushed on Jan 17, 2023
  37. willcl-ark force-pushed on Jan 17, 2023
  38. glozow added the label Mempool on Jan 17, 2023
  39. in src/kernel/mempool_options.h:21 in d4b0d062e4 outdated
    17@@ -18,6 +18,8 @@ class CBlockPolicyEstimator;
    18 
    19 /** Default for -maxmempool, maximum megabytes of mempool memory usage */
    20 static constexpr unsigned int DEFAULT_MAX_MEMPOOL_SIZE_MB{300};
    21+//** Defaul for -maxmempool when blocksonly is set */
    


    glozow commented at 9:58 am on January 18, 2023:

    nit d4b0d062e413e73c70de4532cab677bd026db655

    0/** Default for -maxmempool when blocksonly is set */
    

    stickies-v commented at 5:48 pm on January 19, 2023:
    0/** Default for -maxmempool when blocksonly is set */
    

    stickies-v commented at 10:49 am on January 20, 2023:
    beat ya to it #26471 (review)

    willcl-ark commented at 1:05 pm on January 20, 2023:
    Done

    willcl-ark commented at 1:23 pm on January 20, 2023:
    Fixed
  40. in src/node/mempool_args.cpp:51 in ed5ce6d0c9 outdated
    47+    if (auto mb = argsman.GetIntArg("-maxmempool")) {
    48+        mempool_opts.max_size_bytes = *mb * 1'000'000;
    49+    } else if (argsman.GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY)) {
    50+        // If we are running in blocksonly mode don't allocate the default 300MB of space for mempool
    51+        // unless the user specifies -maxmempool, as otherwise it will leak into coins/UTXO cache allowance.
    52+        // Keeping the mempool enabled will still permit transaction relay for whitelisted peers
    


    glozow commented at 10:17 am on January 18, 2023:

    d4b0d062e413e73c70de4532cab677bd026db655

    “leaking” doesn’t seem like the right term for this, and I think the more precise explanation is “we probably won’t need it.”

    0        // If we are running in blocksonly mode, unless the user specified -maxmempool,
    1        // reduce the capacity to 5MB, as we only expect to store transactions from whitelisted
    2        // peers and are thus unlikely to require 300MB.
    

    willcl-ark commented at 1:05 pm on January 20, 2023:
    Removed text as part of using AJ’s suggestion with InitParameterInteraction. I think combined with git log it should be easy enough for people to find out why this interaction was added.
  41. in doc/reduce-memory.md:21 in a5c33e7e5f outdated
    15@@ -16,11 +16,15 @@ The size of some in-memory caches can be reduced. As caches trade off memory usa
    16   - The minimum value for `-maxmempool` is 5.
    17   - A lower maximum mempool size means that transactions will be evicted sooner. This will affect any uses of `bitcoind` that process unconfirmed transactions.
    18 
    19-- To completely disable mempool functionality there is the option `-blocksonly`. This will make the client opt out of receiving (and thus relaying) transactions completely, except as part of blocks.
    20+- Since `0.14.0`, unused memory allocated to the mempool (default: 300MB) is shared with the UTXO cache, so when trying to reduce memory usage you should limit the mempool, with the `-maxmempool` command line argument.
    21+
    22+- To disable most of the mempool functionality there is the `-blocksonly` option. This will make the client opt out of receiving (and thus relaying) transactions, except from whitelisted peers and as part of blocks.
    


    glozow commented at 10:40 am on January 18, 2023:

    a5c33e7e5f8dc068b66178830e80431f87e0e4b8

    0- To disable most of the mempool functionality there is the `-blocksonly` option. This will reduce the default memory usage to 5MB and make the client opt out of receiving (and thus relaying) transactions, except from whitelisted peers and as part of blocks.
    

    willcl-ark commented at 1:03 pm on January 20, 2023:
    Done
  42. in doc/reduce-memory.md:27 in a5c33e7e5f outdated
    24   - Do not use this when using the client to broadcast transactions as any transaction sent will stick out like a sore thumb, affecting privacy. When used with the wallet it should be combined with `-walletbroadcast=0` and `-spendzeroconfchange=0`. Another mechanism for broadcasting outgoing transactions (if any) should be used.
    25 
    26-- Since `0.14.0`, unused memory allocated to the mempool (default: 300MB) is shared with the UTXO cache, so when trying to reduce memory usage you should limit the mempool, with the `-maxmempool` command line argument.
    27+  - In `-blocksonly` mode the node will by default use a 5MB (`DEFAULT_BLOCKSONLY_MEMPOOL_MAX_SIZE_MB`) mempool size, avoiding unexpected memory usage from the UTXO cache sharing the 300MB default mempool cache size.
    28+
    29+  - If you would like to continue using the mempool cache allocation for the UTXO cache in `-blocksonly` mode (to help speed up IBD) then you can specify the mempool size using the `-maxmempool` option.
    


    glozow commented at 10:42 am on January 18, 2023:

    a5c33e7e5f8dc068b66178830e80431f87e0e4b8

    I would recommend just adding the 5MB note to the -blocksonly bullet point (see other comment). This last bullet point is unnecessary imo, this is the doc about saving memory.


    willcl-ark commented at 1:03 pm on January 20, 2023:
    Agreed and done
  43. in doc/release-notes-26471.md:13 in ed5ce6d0c9 outdated
     8+
     9+  In this release running with `-blocksonly` will only allocate 5MB to the
    10+  mempool by default, permitting the use-case of relaying transactions from
    11+  whitelisted peers, but avoiding unexpected resource usage. It reduces the
    12+  available `dbcache` size by 295MB, impacting performance especially during
    13+  IBD.
    


    glozow commented at 10:46 am on January 18, 2023:

    ed5ce6d0c911ac66bd5870a1711edef03a18ebeb

    Previously running with the -blocksonly option effectively disabled the mempool …

    … In this release running with -blocksonly will only allocate 5MB to the mempool by default, permitting the use-case of relaying transactions from whitelisted peers"

    I think “effectively disabled” is fine. But this mention of the whitelist relay behavior later sounds, to me, sounds like it is new. I don’t think it needs to be mentioned at all?

    0- Setting `-blocksonly` will now reduce the maximum mempool memory
    1  to 5MB (users may still use `-maxmempool` to override). Previously,
    2  the default 300MB would be used, leading to unexpected memory usage
    3  for users running with `-blocksonly` expecting it to eliminate
    4  mempool memory usage.
    5  
    6  As unused mempool memory is shared with dbcache, this also reduces
    7  the dbcache size for users running with `-blocksonly`, potentially
    8  impacting performance.
    

    willcl-ark commented at 1:25 pm on January 20, 2023:

    I agree that we don’t need to mention the whitelist relay behaviour, but its apparently something some people (might) have been doing.

    Anyway, removed/

  44. aureleoules approved
  45. aureleoules commented at 11:16 am on January 19, 2023: member
    reACK ed5ce6d0c911ac66bd5870a1711edef03a18ebeb - Wording updated and logic cleaned up since my last review.
  46. in doc/release-notes-26471.md:12 in ed5ce6d0c9 outdated
     7+  option using more resources than anticipated, especially during IBD.
     8+
     9+  In this release running with `-blocksonly` will only allocate 5MB to the
    10+  mempool by default, permitting the use-case of relaying transactions from
    11+  whitelisted peers, but avoiding unexpected resource usage. It reduces the
    12+  available `dbcache` size by 295MB, impacting performance especially during
    


    stickies-v commented at 5:50 pm on January 19, 2023:
    Perhaps need to add here that this is only true if -maxmempool is not set? We say it in other places, but better to not assume everyone reads everything, so seems like a safe option.

    ajtowns commented at 7:52 pm on January 19, 2023:
    Maybe “-blocksonly will reduce the default for -maxmempool from 300MB to 5MB” ?
  47. stickies-v approved
  48. stickies-v commented at 5:51 pm on January 19, 2023: contributor
    ACK ed5ce6d0c
  49. in doc/reduce-memory.md:25 in ed5ce6d0c9 outdated
    22+- To disable most of the mempool functionality there is the `-blocksonly` option. This will make the client opt out of receiving (and thus relaying) transactions, except from whitelisted peers and as part of blocks.
    23 
    24   - Do not use this when using the client to broadcast transactions as any transaction sent will stick out like a sore thumb, affecting privacy. When used with the wallet it should be combined with `-walletbroadcast=0` and `-spendzeroconfchange=0`. Another mechanism for broadcasting outgoing transactions (if any) should be used.
    25 
    26-- Since `0.14.0`, unused memory allocated to the mempool (default: 300MB) is shared with the UTXO cache, so when trying to reduce memory usage you should limit the mempool, with the `-maxmempool` command line argument.
    27+  - In `-blocksonly` mode the node will by default use a 5MB (`DEFAULT_BLOCKSONLY_MEMPOOL_MAX_SIZE_MB`) mempool size, avoiding unexpected memory usage from the UTXO cache sharing the 300MB default mempool cache size.
    


    ajtowns commented at 7:50 pm on January 19, 2023:
    I don’t think the internal constant name needs to be here?

    stickies-v commented at 10:16 am on January 20, 2023:

    I agree it looks a bit awkward but I suggested it to make it less likely we forget to keep the docs up to date when the constant changes in the future: #26471 (review)

    No strong view either way.


    willcl-ark commented at 1:23 pm on January 20, 2023:
    Constant removed
  50. in src/node/mempool_args.cpp:52 in ed5ce6d0c9 outdated
    48+        mempool_opts.max_size_bytes = *mb * 1'000'000;
    49+    } else if (argsman.GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY)) {
    50+        // If we are running in blocksonly mode don't allocate the default 300MB of space for mempool
    51+        // unless the user specifies -maxmempool, as otherwise it will leak into coins/UTXO cache allowance.
    52+        // Keeping the mempool enabled will still permit transaction relay for whitelisted peers
    53+        mempool_opts.max_size_bytes = DEFAULT_BLOCKSONLY_MAX_MEMPOOL_SIZE_MB * 1'000'000;
    


    ajtowns commented at 8:03 pm on January 19, 2023:

    I would have expected:

    0if (args.GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY)) {
    1    if (args.SoftSetArg("-maxmempool", ToString(DEFAULT_BLOCKSONLY_MAX_MEMPOOL_SIZE_MB))) {
    2        LogPrintf("%s: parameter interaction: -blocksonly=1 -> setting -maxmempool=%d\n", __func__, DEFAULT_BLOCKSONLY_MAX_MEMPOOL_SIZE_MB);
    3    }
    4}
    

    in InitParameterInteraction.


    willcl-ark commented at 12:54 pm on January 20, 2023:
    Thanks! This both makes more sense, and avoids needing to include net.h in mempool_args.cpp, which I didn’t particularly like
  51. ajtowns commented at 8:04 pm on January 19, 2023: contributor
    Approach ACK
  52. mempool: Don't share mempool with dbcache in blocksonly
    When -blockonly is set, reduce mempool size to 5MB unless -maxmempool
    is also set.
    
    See #9569
    1134686ef9
  53. doc: Update blocksonly behaviour in reduce-memory
    Changes to the default mempool allocation size now documented.
    
    Provides users with guidance on the mempool implications of -blocksonly
    mode, along with instructions on how to re-enable old behaviour.
    ae797463dc
  54. willcl-ark force-pushed on Jan 20, 2023
  55. doc: release note on mempool size in -blocksonly
    Adds a release note detailing the new mempool sizing behaviour when
    running in blocksonly mode, and instruction on how to override the new
    defaults.
    8e85164e7d
  56. willcl-ark force-pushed on Jan 20, 2023
  57. willcl-ark commented at 4:13 pm on January 20, 2023: contributor
    Thanks for the comments, I’ve updated the branch taking them into consideration.
  58. ajtowns approved
  59. ajtowns commented at 10:36 pm on January 21, 2023: contributor
    ACK 8e85164e7d12be324ea1af2e288ebcf689c930b7
  60. stickies-v approved
  61. in src/kernel/mempool_options.h:21 in 8e85164e7d
    17@@ -18,6 +18,8 @@ class CBlockPolicyEstimator;
    18 
    19 /** Default for -maxmempool, maximum megabytes of mempool memory usage */
    20 static constexpr unsigned int DEFAULT_MAX_MEMPOOL_SIZE_MB{300};
    21+//** Default for -maxmempool when blocksonly is set */
    


    fanquake commented at 2:57 pm on January 22, 2023:
    0/** Default for -maxmempool when blocksonly is set */
    
  62. fanquake merged this on Jan 22, 2023
  63. fanquake closed this on Jan 22, 2023

  64. fanquake added this to the milestone 25.0 on Jan 22, 2023
  65. willcl-ark deleted the branch on Jan 22, 2023
  66. in doc/reduce-memory.md:21 in 8e85164e7d
    15@@ -16,11 +16,11 @@ The size of some in-memory caches can be reduced. As caches trade off memory usa
    16   - The minimum value for `-maxmempool` is 5.
    17   - A lower maximum mempool size means that transactions will be evicted sooner. This will affect any uses of `bitcoind` that process unconfirmed transactions.
    18 
    19-- To completely disable mempool functionality there is the option `-blocksonly`. This will make the client opt out of receiving (and thus relaying) transactions completely, except as part of blocks.
    20+- Since `0.14.0`, unused memory allocated to the mempool (default: 300MB) is shared with the UTXO cache, so when trying to reduce memory usage you should limit the mempool, with the `-maxmempool` command line argument.
    21 
    22-  - Do not use this when using the client to broadcast transactions as any transaction sent will stick out like a sore thumb, affecting privacy. When used with the wallet it should be combined with `-walletbroadcast=0` and `-spendzeroconfchange=0`. Another mechanism for broadcasting outgoing transactions (if any) should be used.
    23+- To disable most of the mempool functionality there is the `-blocksonly` option. This will reduce the default memory usage to 5MB and make the client opt out of receiving (and thus relaying) transactions, except from whitelisted peers and as part of blocks.
    


    maflcko commented at 9:09 am on January 23, 2023:
    nit: Instead of whitelisted, it would be good to mention the exact permission flag.
  67. sidhujag referenced this in commit 7613a0173d on Jan 23, 2023
  68. glozow commented at 9:37 am on January 30, 2023: member
    @willcl-ark will you be taking the followups #26471 (review) and #26471 (review)?
  69. willcl-ark commented at 9:39 am on January 30, 2023: contributor
    Yes I can do those @glozow
  70. glozow referenced this in commit 22ccf4e360 on Feb 1, 2023
  71. sidhujag referenced this in commit e1e1fab923 on Feb 1, 2023
  72. bitcoin locked this on Jan 30, 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-09-29 01:12 UTC

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