BlockAssembler: return selected packages virtual size and fee #30391

pull ismaelsadeeq wants to merge 1 commits into bitcoin:master from ismaelsadeeq:07-2024-miner-return-package-sizes-and-fees changing 3 files +28 −3
  1. ismaelsadeeq commented at 11:04 am on July 4, 2024: member

    This PR enables BlockAssembler to add all selected packages’ fee and virtual size to a vector, and then return the vector as a member of CBlockTemplate struct.

    This PR is the first step in the #30392 project.

    The packages’ vsize and fee are used in #30157 to select a percentile fee rate of the top block in the mempool.

  2. DrahtBot commented at 11:04 am on July 4, 2024: contributor

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

    Code Coverage & Benchmarks

    For details see: https://corecheck.dev/bitcoin/bitcoin/pulls/30391.

    Reviews

    See the guideline for information on the review process.

    Type Reviewers
    ACK rkrux, ryanofsky, glozow

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

    Conflicts

    No conflicts as of last run.

  3. in src/policy/feerate.cpp:1 in 550a6c29e0 outdated


    maflcko commented at 3:53 pm on July 5, 2024:

    first commit: could adjust the test

    0src/test/amount_tests.cpp:86:    // Maximum size in bytes, should not crash
    

    To std::numeric_limits<uint64_t>::max() >> 1 ?

    And

    0src/test/fuzz/fee_rate.cpp:23:    const auto bytes = fuzzed_data_provider.ConsumeIntegral<uint32_t>();
    

    to fuzzed_data_provider.ConsumeIntegral<uint64_t>() >> 1?


    ismaelsadeeq commented at 8:21 am on July 8, 2024:

    This causes a fuzz failure during the conversion of the size to feerate per KB because CAmount is int64_t.

    So I reverted back and static_cast the packageSize to be uint32_t, it is safe to do so because we are certain that nSizeWithAncestors will always be positive in BlockAssembler::addPackageTxs.


    It’s already done https://github.com/bitcoin/bitcoin/blob/bd5d1688b4311e21c0e0ff89a3ae02ef7d0543b8/src/node/miner.cpp#L365


    maflcko commented at 8:31 am on July 8, 2024:

    This causes a fuzz failure during the conversion of the size to feerate per KB because CAmount is int64_t.

    The fuzz failure is because you also changed MultiplicationOverflow to uint64_t, which is wrong.


    maflcko commented at 8:32 am on July 8, 2024:

    So I reverted back and static_cast the packageSize to be uint32_t, it is safe to do so because we are certain that nSizeWithAncestors will always be positive in BlockAssembler::addPackageTxs.

    Another thing to consider is that the package size is small enough to be representable in uint32_t.


    ismaelsadeeq commented at 8:50 am on July 8, 2024:

    Yeah thanks.


    unrelated but I wonder why we are using this big data type to represent size, not only while working in this PR, there are size datype inconsistencies in several places which sometimes cause overflows during calculation.

    Is it safe to instead represent a type alias for size just like it was done for CAmount in consensus/amount.h. And prevent generating large values for size in the fuzz test?

    Apart from the fuzz test size can never be greater than 4,000,000? https://github.com/bitcoin/bitcoin/blob/bd5d1688b4311e21c0e0ff89a3ae02ef7d0543b8/src/consensus/consensus.h#L12-L15


    ismaelsadeeq commented at 8:55 am on July 8, 2024:

    The fuzz failure is because you also changed MultiplicationOverflow to uint64_t, which is wrong.

    Yeah, I did that because MultiplicationOverflow requires that the type of both parameters be the same.


    maflcko commented at 9:27 am on July 8, 2024:

    Apart from the fuzz test size can never be greater than 4,000,000?

    In blocks, yes. In the mempool, it may depend on the user’s config.


    ismaelsadeeq commented at 10:04 am on July 8, 2024:
    thanks the commit is gone now.
  4. ismaelsadeeq force-pushed on Jul 6, 2024
  5. DrahtBot added the label CI failed on Jul 6, 2024
  6. ismaelsadeeq force-pushed on Jul 7, 2024
  7. DrahtBot removed the label CI failed on Jul 7, 2024
  8. ismaelsadeeq force-pushed on Jul 8, 2024
  9. ismaelsadeeq force-pushed on Jul 8, 2024
  10. in src/node/miner.h:44 in 83ac35e3eb outdated
    39@@ -38,6 +40,7 @@ struct CBlockTemplate
    40     std::vector<CAmount> vTxFees;
    41     std::vector<int64_t> vTxSigOpsCost;
    42     std::vector<unsigned char> vchCoinbaseCommitment;
    43+    std::vector<std::tuple<CFeeRate, uint32_t>> vFeeratePerSize;
    


    glozow commented at 11:22 am on July 10, 2024:
    probably FeeFrac would be better? CFeeRate loses precision and can be inferred from the fee and size

    ismaelsadeeq commented at 11:39 am on July 12, 2024:

    @glozow

    probably FeeFrac would be better? CFeeRate loses precision and can be inferred from the fee and size

    We will be using the package size to calculate the percentile package and select its fee rate as an estimate to return to the user.

    We then have to convert the fee and size to fee rate either by CFeeRate(const CAmount& nFeePaid, uint32_t num_bytes).GetFeePerK or introduce and use a similar GetFeeRate method for the FeeFrac struct.

    So, I think using CFeeRate is okay for getting MEMPOOL_FORECAST estimate.


    I think the place we could benefit from changing this to FeeFrac is when comparing forecasters’ estimates.

    But this can’t be done now because the BLOCK_POLICY_ESTIMATOR forecaster performs its operations in nSatoshiPerK and returns a CFeeRate value as an estimate.

    It will require a refactor to change BLOCK_POLICY_ESTIMATOR to use and return FeeFrac as an estimate.

    But the forecasters estimates are values greater than 1 s/vb. Given this, I think using CFeeRate is okay and will avoid the conversions, or adding duplicate GetFeePerK method for FeeFrac and refactoring CBlockPolicyEstimator to use FeeFrac?


    ismaelsadeeq commented at 9:28 pm on November 4, 2024:
    @glozow, is the idea of making CFeeRate a wrapper around FeeFrac better, as suggested #30535 (comment)? If so, then no changes are needed, and we can proceed with this approach while pursuing that direction and mark this comment as resolved. Otherwise, I’m happy to change this to FeeFrac as you suggested if it’s a blocking comment.

    glozow commented at 8:11 pm on November 5, 2024:
    Nonblocking, I can understand it’s a larger change to use it.

    ismaelsadeeq commented at 8:34 pm on November 8, 2024:

    I’ve updated the code to use FeeFrac, and it simplified things – no need for tuples from the initial approach, just a vector of FeeFrac values which achieved same aim.

    Smaller diff and no precision loss 💯 I will update all the dependent commits to follow suite.

  11. DrahtBot added the label Needs rebase on Jul 18, 2024
  12. ismaelsadeeq force-pushed on Jul 18, 2024
  13. DrahtBot removed the label Needs rebase on Jul 18, 2024
  14. in src/test/miner_tests.cpp:182 in f581657b3a outdated
    181+
    182+    CFeeRate packageRate(packageFee, packageSize);
    183+    auto packageFeeRateFound = findFeeRate(blockFeeAndVsizes, packageRate);
    184+
    185+    CFeeRate mediumRate(mediumFeeTx.GetFee(), mediumFeeTx.GetTxSize());
    186+    auto mediumTxFeeRateFound = findFeeRate(blockFeeAndVsizes, mediumRate);
    


    rkrux commented at 11:58 am on August 11, 2024:
    IMO, depending upon finding only the feeRate in the vector of tuples gets rid of some level of robustness in the verification here because it ignores the possibility of duplicate feeRates, and makes the tester/author wary of writing the test in a way that ensures there are no duplicates. How about also checking for the packageSize as well?

    ismaelsadeeq commented at 8:41 am on August 12, 2024:
    That makes sense. I removed findFeeRate and explicitly checked the vector for the packages and verify the fee and size were as expected. I also took the opportunity to change the variables to be initialized uniformly.

    rkrux commented at 2:16 pm on August 12, 2024:
    Thank you for accepting the suggestion, the diff now has become smaller and to the point.
  15. rkrux approved
  16. rkrux commented at 11:59 am on August 11, 2024: none

    tACK f581657

    make, make check are successful. Left a suggestion. Thanks for keeping the PR short and focussed.

  17. ismaelsadeeq force-pushed on Aug 12, 2024
  18. Theschorpioen approved
  19. rkrux approved
  20. rkrux commented at 2:16 pm on August 12, 2024: none
    reACK 8a830f1
  21. achow101 requested review from Sjors on Oct 15, 2024
  22. achow101 requested review from josibake on Oct 15, 2024
  23. ismaelsadeeq force-pushed on Nov 7, 2024
  24. ismaelsadeeq renamed this:
    BlockAssembler: return selected packages vsize and feerate
    BlockAssembler: return selected packages virtual size and fee
    on Nov 7, 2024
  25. Sjors commented at 3:38 pm on November 8, 2024: member

    Just a comment about how this interacts with the Mining interface changes I’m working on.

    The Mining interface contains BlockTemplate:

    https://github.com/bitcoin/bitcoin/blob/018e5fcc462caebb25cf5d3eb6a19dc2787466c8/src/interfaces/mining.h#L31-L40

    I wonder if adding a field to CBlockTemplate would cause a breaking change for clients connecting via IPC. cc @ryanofsky?

    Update: I don’t think it does, because the interface doesn’t use CBlockTemplate directly.

    In any case it won’t matter as long as this PR is merged before v29, since we don’t ship the interface until then, so there’s clients to break.

  26. ismaelsadeeq commented at 10:00 pm on November 14, 2024: member

    so there’s clients to break. @Sjors, could you clarify your coment? Which clients would this affect?

  27. Sjors commented at 8:29 am on November 15, 2024: member

    @ismaelsadeeq are you referring to my statement at the end “so there’s clients to break”?

    Once we release the Mining interface, and multiprocess, people can build clients. If we then make changes in the next release, we could break those clients. But that’s not an issue yet.

  28. DrahtBot added the label Needs rebase on Nov 20, 2024
  29. ismaelsadeeq force-pushed on Nov 25, 2024
  30. DrahtBot removed the label Needs rebase on Nov 25, 2024
  31. glozow commented at 2:58 pm on December 4, 2024: member
    ACK 5171f16e6f96030fcc91b30bb196a2790e37848c
  32. DrahtBot requested review from rkrux on Dec 4, 2024
  33. glozow added this to the milestone 29.0 on Dec 5, 2024
  34. glozow commented at 4:57 pm on December 5, 2024: member

    In any case it won’t matter as long as this PR is merged before v29

    fwiw added to milestone and this seems like a fairly simple change. @Sjors @ryanofsky would you mind taking another look? I don’t think I have full context on Mining interface.

  35. DrahtBot added the label Needs rebase on Dec 17, 2024
  36. in src/node/miner.h:153 in 5171f16e6f outdated
    149@@ -148,6 +150,7 @@ class BlockAssembler
    150     uint64_t nBlockSigOpsCost;
    151     CAmount nFees;
    152     std::unordered_set<Txid, SaltedTxidHasher> inBlock;
    153+    std::vector<FeeFrac> feerateHistogram;
    


    ryanofsky commented at 7:25 pm on December 17, 2024:

    In commit “miner: CreateNewBlock will now track fee and virtual size of selected packages” (5171f16e6f96030fcc91b30bb196a2790e37848c)

    It seems like it would be simpler and less fragile if BlockAssembler::addPackageTxs just populated pblocktemplate->FeerateHistogram directly, instead of filling this new BlockAssembler::feerateHistogram variable, which is effectively a temporary variable, and then moved from BlockAssembler::feerateHistogram to pblocktemplate->FeerateHistogram. It would be nice to be able to drop this new variable, and drop the new code moving the histogram from one variable to another.


    ismaelsadeeq commented at 8:37 pm on December 17, 2024:
    Good Suggestion. Done!
  37. ryanofsky approved
  38. ryanofsky commented at 7:39 pm on December 17, 2024: contributor

    Code review ACK 5171f16e6f96030fcc91b30bb196a2790e37848c

    fwiw added to milestone and this seems like a fairly simple change. @Sjors @ryanofsky would you mind taking another look? I don’t think I have full context on Mining interface.

    There’s actually no risk of this change breaking the mining interface because the mining interface isn’t directly exposing the CBlockTemplate struct. Also even if the CBlockTemplate struct were directly exposed it wouldn’t necessarily be a breaking change because old clients or servers encountering the new field would just ignore it, and new clients or servers expecting the new field could detect that the field is missing and handle that case appropriately.

  39. ismaelsadeeq force-pushed on Dec 17, 2024
  40. ismaelsadeeq commented at 8:39 pm on December 17, 2024: member
    Thank you for your review, @glozow and @ryanofsky.
    I’ve force-pushed to rebase and address #30391 (review)
  41. DrahtBot removed the label Needs rebase on Dec 17, 2024
  42. Sjors commented at 4:02 am on December 18, 2024: member
    I’m fine with adding vFeerateHistogram to CBlockTemplate. I haven’t looked into #30157 so I don’t have a strong take on the rest of this PR. Seems pretty straightforward though.
  43. ryanofsky approved
  44. ryanofsky commented at 7:57 pm on December 18, 2024: contributor
    Code review ACK 7de205d2c12a0e5c0dee68728b088b022f63e84d. Seems very simple now, just a two line code change + tests
  45. DrahtBot requested review from glozow on Dec 18, 2024
  46. glozow commented at 8:46 pm on January 2, 2025: member
    ACK 7de205d2c12a0e5c0dee68728b088b022f63e84d
  47. in src/node/miner.cpp:424 in 7de205d2c1 outdated
    420@@ -421,6 +421,7 @@ void BlockAssembler::addPackageTxs(int& nPackagesSelected, int& nDescendantsUpda
    421         }
    422 
    423         ++nPackagesSelected;
    424+        pblocktemplate->vFeerateHistogram.emplace_back(packageFees, static_cast<int32_t>(packageSize));
    


  48. in src/node/miner.h:43 in 7de205d2c1 outdated
    39@@ -39,6 +40,7 @@ struct CBlockTemplate
    40     std::vector<CAmount> vTxFees;
    41     std::vector<int64_t> vTxSigOpsCost;
    42     std::vector<unsigned char> vchCoinbaseCommitment;
    43+    std::vector<FeeFrac> vFeerateHistogram;
    


    rkrux commented at 12:51 pm on January 3, 2025:

    Getting thrown off a bit by the name here. Is it really a histogram at this point or just a vector of fee rates/fracs? Going by this def: https://en.wikipedia.org/wiki/Histogram

    Sorry for not raising this earlier.


    rkrux commented at 12:56 pm on January 3, 2025:
    Might be helpful to add a comment here telling that the values in this vector are sorted. That’s what I assumed while going through the CalculatePercentiles function here: https://github.com/bitcoin/bitcoin/pull/30157/files#diff-34fc4771c305399b6f7634acd8c5fd2d0b89115f998397d41676180d742c28daR10

    ismaelsadeeq commented at 4:44 pm on January 3, 2025:

    Is it really a histogram at this point or just a vector of fee rates/fracs?

    It is a vector of package fee frac’s, which can be used to build a histogram.

    Might be helpful to add a comment here telling that the values in this vector are sorted. That’s what I assumed while going through the CalculatePercentiles function here.

    Yes, it is sorted by the order in which the packages are selected in the block template. I believe this is obvious because we are emplacing the fee frac’s after adding the selected package. However, adding a comment could be useful for clarity.

    I will update if there is a need to retouch.


    rkrux commented at 5:43 pm on January 3, 2025:

    It is a vector of package fee frac’s, which can be used to build a histogram.

    Building a histogram seems to be one of the use cases of this field. I don’t feel it should be called a histogram only because of this. Is there any other reason as well? I hope I’m not missing any context here.


    ismaelsadeeq commented at 6:17 pm on January 3, 2025:
    I think you are, You can see #21422 for context

    rkrux commented at 1:12 pm on January 6, 2025:
    Thank you for sharing that PR. The term vFeerateHistogram in itself is fine and in the #21422 PR a histogram is indeed created. What I find confusing here is calling a simple vector of feefrac’s a histogram. If a histogram will be created using this field later, let’s call that field a histogram and not this one?

    ismaelsadeeq commented at 8:57 pm on January 6, 2025:

    I’ve seen the vectors above vFeerateHistogram, are also simple vector types containing integers, unsigned chars, or CAmounts.

    However, we do not name these vectors vCAmounts, vInts, or vUnsignedChars. Instead, they are named based on some context, such as vTxFees, vTxSigOpsCost, and vchCoinbaseCommitment. For this reason, I believe naming this vector vFeeFrac does not add much clarity because thats obvious. Instead, I consider vFeerateHistogram to be the closest meaningful name, based on the context of #21422.

    Consider this block template vector of package of fee rates: [20/5, 20/5, 20/5, 20/6, 20/6, 15/6]. after sorting by increasing feerate this implicitly represent a histogram-like structure:

    • The x-axis could represent distinct fee rate packages.
    • The y-axis could represent their frequencies.

    Same as with @glozow comment in #30391 (review).

    This vector is also implicitly a fee rate diagram. As we can use it to construct a feerate diagram after sorting by increasing feerate.

    • The points in the x axis would be the accumulated size of the packages from i to n.
    • The points in the y axis would be the fees of each package from i to n. @rkrux If a more explicit name is desired, vPackagesFeerates would be the most accurate IMO.

    We can continue the discussion , but since this PR already has two A CKs I was hesitating to update, I will proceed to update the variable name and add a comment if a rebase or blocking suggestion arises.

    Let me know if this a blocking comment, I am happy to update.


    achow101 commented at 10:06 pm on January 6, 2025:
    nit: The style guide says to use the new style for new code, regardless of the style of the surrounding code. So this should use snake_case with m_ prefix: m_feerate_histogram.

    rkrux commented at 8:20 am on January 7, 2025:

    However, we do not name these vectors vCAmounts, vInts, or vUnsignedChars. Instead, they are named based on some context, such as vTxFees, vTxSigOpsCost, and vchCoinbaseCommitment. For this reason, I believe naming this vector vFeeFrac does not add much clarity because thats obvious. Instead, I consider vFeerateHistogram to be the closest meaningful name, based on the context of #21422.

    I agree with naming variables based on context, this is quite a common practice. I have raised this point because as a reviewer I found it confusing to see a field that’s called a histogram but is not, and therefore I don’t think it is the closest meaningful name. Either feeRateDiagram or packageFeeRates sound good to me.

    We can continue the discussion , but since this PR already has two A CKs I was hesitating to update, I will proceed to update the variable name and add a comment if a rebase or blocking suggestion arises.

    I understand that naming variables can be in the bikeshed territory and as an author it’s difficult to incorporate changes after getting multiple ACKs. That’s why I didn’t request changes and instead started a discussion because to me this name is confusing and was even more so to read it in the test, and thus I could not ACK the PR.


    ismaelsadeeq commented at 2:06 pm on January 8, 2025:
    Fixed now. Thanks for the review.

    ismaelsadeeq commented at 2:06 pm on January 8, 2025:
    fixed
  49. rkrux commented at 12:59 pm on January 3, 2025: none
    Nit: In the PR description, a draft PR is mentioned as the project. Can add this link for project issue: #30392
  50. DrahtBot requested review from rkrux on Jan 3, 2025
  51. ismaelsadeeq commented at 4:45 pm on January 3, 2025: member

    Nit: In the PR description, a draft PR is mentioned as the project. Can add this link for project issue: #30392

    Added, and addressed your comments!

  52. in src/test/miner_tests.cpp:157 in 7de205d2c1 outdated
    156+    BOOST_CHECK(blockFeerateHistogram.size() == 2);
    157+    // lowFeeTx and highFeeChildTx are added to the block as a package.
    158+    const auto packageFee{lowFeeTx.GetFee() + highFeeChildTx.GetFee()};
    159+    const auto packageSize{lowFeeTx.GetTxSize() + highFeeChildTx.GetTxSize()};
    160+    FeeFrac packageFeeFrac{packageFee, packageSize};
    161+    BOOST_CHECK(blockFeerateHistogram[0] == packageFeeFrac);
    


    rkrux commented at 1:24 pm on January 6, 2025:
    Related to this comment, I find the language here confusing as well. A fee rate histogram element, which I would expect to be a feeRate interval/group, is being compared to a feeFrac element, which is just a pair of fee and size.

    glozow commented at 2:28 pm on January 6, 2025:

    Ah, @ismaelsadeeq did you mean to call this a feerate diagram instead? @rkrux We’ve previously represented feerate diagrams as a vector of FeeFracs / chunks

  53. DrahtBot requested review from rkrux on Jan 6, 2025
  54. in src/test/miner_tests.cpp:125 in 7de205d2c1 outdated
    121@@ -121,28 +122,43 @@ void MinerTestingSetup::TestPackageSelection(const CScript& scriptPubKey, const
    122     tx.vout[0].nValue = 5000000000LL - 1000;
    123     // This tx has a low fee: 1000 satoshis
    124     Txid hashParentTx = tx.GetHash(); // save this txid for later use
    125-    AddToMempool(tx_mempool, entry.Fee(1000).Time(Now<NodeSeconds>()).SpendsCoinbase(true).FromTx(tx));
    126+    const auto lowFeeTx{entry.Fee(1000).Time(Now<NodeSeconds>()).SpendsCoinbase(true).FromTx(tx)};
    


    achow101 commented at 10:08 pm on January 6, 2025:

    nit: This should be named similarly to the txid to avoid confusion that this might be a different tx altogether. I suggest either calling this parent_tx or renaming hashParentTx to hash_low_fee_tx.

    Also snake_case here and elsewhere in this test.


    ismaelsadeeq commented at 2:07 pm on January 8, 2025:
    Thanks this is fixed, I’ll use snake_case henceforth.
  55. DrahtBot added the label Needs rebase on Jan 6, 2025
  56. ismaelsadeeq force-pushed on Jan 7, 2025
  57. ismaelsadeeq force-pushed on Jan 7, 2025
  58. DrahtBot removed the label Needs rebase on Jan 7, 2025
  59. DrahtBot added the label CI failed on Jan 7, 2025
  60. DrahtBot commented at 6:17 pm on January 7, 2025: contributor

    🚧 At least one of the CI tasks failed. Debug: https://github.com/bitcoin/bitcoin/runs/35265010233

    Try to run the tests locally, according to the documentation. However, a CI failure may still happen due to a number of reasons, for example:

    • Possibly due to a silent merge conflict (the changes in this pull request being incompatible with the current code in the target branch). If so, make sure to rebase on the latest commit of the target branch.

    • A sanitizer issue, which can only be found by compiling with the sanitizer and running the affected test.

    • An intermittent issue.

    Leave a comment here, if you need help tracking down a confusing failure.

  61. miner: add package feerate vector to CBlockTemplate
    - The package feerates are ordered by the sequence in which
      packages are selected for inclusion in the block template.
    
    - The commit also tests this new behaviour.
    
    Co-authored-by: willcl-ark <will@256k1.dev>
    7c123c08dd
  62. ismaelsadeeq force-pushed on Jan 7, 2025
  63. DrahtBot removed the label CI failed on Jan 7, 2025
  64. rkrux approved
  65. rkrux commented at 5:11 pm on January 8, 2025: none

    tACK 7c123c08ddce87ae55abfa83bea4a691bc0bd5e7

    Thank you for incorporating the changes.

  66. DrahtBot requested review from ryanofsky on Jan 8, 2025
  67. DrahtBot requested review from glozow on Jan 8, 2025
  68. ryanofsky approved
  69. ryanofsky commented at 5:43 pm on January 8, 2025: contributor
    Code review ACK 7c123c08ddce87ae55abfa83bea4a691bc0bd5e7. Changes since last review are rebasing due to a test conflict, giving the new field a better name and description, resolving the test conflict, and renaming a lot of test variables. The actual code change is still one-line change.
  70. glozow commented at 6:00 pm on January 8, 2025: member
    reACK 7c123c08ddce87ae55abfa83bea4a691bc0bd5e7
  71. glozow merged this on Jan 8, 2025
  72. glozow closed this on Jan 8, 2025

  73. ismaelsadeeq deleted the branch on Jan 8, 2025

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

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