Sort mempool by min(feerate, ancestor_feerate) #12118

pull sdaftuar wants to merge 4 commits into bitcoin:master from sdaftuar:2018-01-fix-mempool-score changing 4 files +71 −37
  1. sdaftuar commented at 6:58 pm on January 8, 2018: member

    This more closely approximates the desirability of a given transaction for mining, and should result in less re-sorting when transactions get removed from the mempool after being mined.

    I measured this as approximately a 5% speedup in removeForBlock.

  2. fanquake added the label Mempool on Jan 8, 2018
  3. in src/txmempool.h:298 in f0aef6c7df outdated
    298+
    299+    // Calculate which score to use for an entry (avoiding division).
    300+    // Picks min(feerate, feerate_with_ancestors)
    301+    bool UseAncestorScore(const CTxMemPoolEntry &a) const
    302+    {
    303+        double f1 = (double)a.GetModifiedFee() * a.GetSizeWithAncestors();
    


    promag commented at 11:51 pm on January 8, 2018:
    Remove double cast?
  4. in src/txmempool.h:276 in f0aef6c7df outdated
    273-        double aFees = a.GetModFeesWithAncestors();
    274-        double aSize = a.GetSizeWithAncestors();
    275+        bool fUseAAncestors = UseAncestorScore(a);
    276+        bool fUseBAncestors = UseAncestorScore(b);
    277+
    278+        double aModFee = fUseAAncestors ? a.GetModFeesWithAncestors() : a.GetModifiedFee();
    


    promag commented at 11:54 pm on January 8, 2018:
    Why floating point? Aren’t these all 64 integers?
  5. in src/txmempool.h:279 in f0aef6c7df outdated
    278+        double aModFee = fUseAAncestors ? a.GetModFeesWithAncestors() : a.GetModifiedFee();
    279+        double aSize = fUseAAncestors ? a.GetSizeWithAncestors() : a.GetTxSize();
    280 
    281-        double bFees = b.GetModFeesWithAncestors();
    282-        double bSize = b.GetSizeWithAncestors();
    283+        double bModFee = fUseBAncestors ? b.GetModFeesWithAncestors() : b.GetModifiedFee();
    


    promag commented at 0:01 am on January 9, 2018:

    Instead of factoring out UseAncestorScore, do (missing comments):

     0void GetModFeeAndSize(const CTxMemPoolEntry& a, int64_t& mod_fee, int64_t& size) {
     1    int64_t f1 = a.GetModifiedFee() * a.GetSizeWithAncestors();
     2    int64_t f2 = a.GetModFeesWithAncestors() * a.GetTxSize();
     3    if (f1 > f2) {
     4        mod_fee = a.GetModFeesWithAncestors();
     5        size = a.GetSizeWithAncestors();
     6    } else {
     7        mod_fee = a.GetModifiedFee();
     8        size = a.GetTxSize();
     9    }
    10}
    
  6. in src/txmempool.h:294 in f0aef6c7df outdated
    295 
    296         return f1 > f2;
    297     }
    298+
    299+    // Calculate which score to use for an entry (avoiding division).
    300+    // Picks min(feerate, feerate_with_ancestors)
    


    promag commented at 0:01 am on January 9, 2018:
    Nit, missing ..
  7. sdaftuar commented at 4:02 pm on January 9, 2018: member

    @promag Thanks for taking a look. I mimicked CompareTxMempoolEntryByDescendantScore in this PR to make review easier, since the two concepts have a symmetry.

    The use of double for the intermediate value is to prevent overflow of an int64_t, which is theoretically possible. That’s also why there’s an explicit double cast before multiplication.

    I’ll rewrite the helper function along the lines of your suggestion.

  8. Refactor CompareTxMemPoolEntryByDescendantScore 6773f92b30
  9. Sort mempool by min(feerate, ancestor_feerate)
    This more closely approximates the desirability of a given transaction for
    mining.
    9a51319578
  10. sdaftuar force-pushed on Jan 9, 2018
  11. promag commented at 11:57 pm on January 9, 2018: member

    The use of double for the intermediate value is to prevent overflow of an int64_t, which is theoretically possible.

    How about http://releases.llvm.org/4.0.0/tools/clang/docs/LanguageExtensions.html#checked-arithmetic-builtins?

  12. sdaftuar commented at 3:19 pm on January 10, 2018: member

    @promag The style of where to put the & doesn’t seem to be in our style guide and is inconsistent already in this file, so I’m going to leave it the way I have it (which happens to be my preference for where to put the & :) ).

    I don’t think it’s a problem for code-correctness if the arithmetic overflows, so I’d rather just handle it as we currently do than introduce complication from calculating things two ways.

  13. promag commented at 3:45 pm on January 10, 2018: member

    utACK 9a51319.

    I’m going to leave it the way I have it

    Fine.

    so I’d rather just handle it as we currently do

    It was just curiosity. Maybe GetModFeeAndSize values could be cached in CTxMemPoolEntry to improve even further? (adding 128 bytes per entry)

  14. ryanofsky commented at 9:55 pm on January 10, 2018: member

    utACK 9a51319578091234fdd218a1eb144d517ea82b85

    I measured this as approximately a 5% speedup in removeForBlock.

    I’m always interested to know how you benchmark these things, in case you want to post details.

    The style of where to put the & doesn’t seem to be in our style guide

    Not important, but we do currently use the opposite setting for the code formatter:

    https://github.com/bitcoin/bitcoin/blob/45173fa6fca9537abb0a0554f731d14b9f89c456/src/.clang-format#L40

  15. sdaftuar commented at 2:21 am on January 11, 2018: member

    I measured this as approximately a 5% speedup in removeForBlock.

    I’m always interested to know how you benchmark these things, in case you want to post details. @ryanofsky I ran through nearly 3 months of historical block & transaction data (roughly March-May 2017), which I record and can play back to a patched bitcoind. I ran two historical studies, one with this patch and one without, each with added benchmarks to specifically measure the time spent in removeForBlock.

  16. TheBlueMatt commented at 5:59 pm on January 11, 2018: member
    utACK 9a51319578091234fdd218a1eb144d517ea82b85
  17. laanwj added this to the milestone 0.16.0 on Jan 11, 2018
  18. gmaxwell commented at 8:34 pm on January 11, 2018: contributor
    ACK
  19. jimpo commented at 8:32 am on January 12, 2018: contributor
    Maybe augment the MempoolAncestorIndexingTest with a case of a higher fee parent with a lower fee child (for which the sort order has changed).
  20. Add test for new ancestor feerate sort behavior 7abfa538b5
  21. sdaftuar commented at 5:43 pm on January 12, 2018: member
    @jimpo Sounds good; I added a test.
  22. Use mempool's ancestor sort in transaction selection
    Transaction selection for mining tracks ancestor feerates that are
    modified based on transactions that have already been selected.  This
    commit de-duplicates the code so that the ancestor feerate sorting used
    by the mempool can also be directly applied to the miner.
    0a22a52918
  23. sdaftuar commented at 9:07 pm on January 13, 2018: member
    I just remembered that the mining code had this ancestor feerate sorting logic duplicated; I just added a commit that attempts to re-use the mempool code so that the new behavior will apply there as well.
  24. in src/miner.cpp:355 in 0a22a52918
    351@@ -352,7 +352,7 @@ void BlockAssembler::addPackageTxs(int &nPackagesSelected, int &nDescendantsUpda
    352             // Try to compare the mapTx entry to the mapModifiedTx entry
    353             iter = mempool.mapTx.project<0>(mi);
    354             if (modit != mapModifiedTx.get<ancestor_score>().end() &&
    355-                    CompareModifiedEntry()(*modit, CTxMemPoolModifiedEntry(iter))) {
    356+                    CompareTxMemPoolEntryByAncestorFee()(*modit, CTxMemPoolModifiedEntry(iter))) {
    


    TheBlueMatt commented at 5:30 pm on January 14, 2018:
    Just to check my understanding, this should have zero effect, correct? The highest element in mapTx and mapModifiedTx should always be the element we want, if the min() is hit, it will never have sorted as the top element in either mapModifedTx or mapTx, as all modifiedTx entries also have their parents in modifiedTx?

    sdaftuar commented at 2:01 pm on January 16, 2018:

    Yes – this change was only because I wanted to delete the code for CompareModifiedEntry, which is otherwise no longer needed.

    all modifiedTx entries also have their parents in modifiedTx

    Not quite – the parents of entries in mapModifiedTx are not in mapModifiedTx if they have been included in the candidate block. Also a parent could be missing from mapModifiedTx if we already considered it for inclusion and it failed for some reason (eg the package it’s part of would be too big).

  25. TheBlueMatt commented at 6:11 pm on January 14, 2018: member
    uACK 0a22a52918ad5af6d105b4f5ae9dd6c52199f0e8
  26. laanwj commented at 2:27 pm on January 15, 2018: member
    utACK 0a22a5291
  27. laanwj merged this on Jan 15, 2018
  28. laanwj closed this on Jan 15, 2018

  29. laanwj referenced this in commit 44080a90a2 on Jan 15, 2018
  30. promag commented at 2:43 pm on January 15, 2018: member
    re-utACK 0a22a52. Added test looks good.
  31. laanwj referenced this in commit 67447ba060 on Feb 8, 2018
  32. Mengerian referenced this in commit e62ca5b8f8 on Aug 6, 2019
  33. jonspock referenced this in commit 463b475f44 on Sep 8, 2019
  34. jonspock referenced this in commit 019a0141b9 on Sep 9, 2019
  35. proteanx referenced this in commit 781a5048fa on Sep 10, 2019
  36. PastaPastaPasta referenced this in commit 80351b68b4 on Feb 25, 2020
  37. PastaPastaPasta referenced this in commit f4f9724709 on Feb 27, 2020
  38. PastaPastaPasta referenced this in commit eefc95d3de on Feb 27, 2020
  39. PastaPastaPasta referenced this in commit c4ffc620d0 on Feb 27, 2020
  40. PastaPastaPasta referenced this in commit 361cd424b7 on Jul 17, 2020
  41. PastaPastaPasta referenced this in commit c0a094ebe3 on Jul 17, 2020
  42. PastaPastaPasta referenced this in commit ed5f046a99 on Jul 17, 2020
  43. ckti referenced this in commit 443adcc8b1 on Mar 28, 2021
  44. DrahtBot locked this on Sep 8, 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-12-22 15:12 UTC

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