Add waitNext() to BlockTemplate interface #31283

pull Sjors wants to merge 2 commits into bitcoin:master from Sjors:2024/11/wait-next changing 4 files +218 −79
  1. Sjors commented at 12:30 pm on November 13, 2024: member

    Alternative approach to #31003, suggested in #31109 (comment).

    This PR introduces waitNext(). It waits for either the tip to update or for fees at the top of the mempool to rise sufficiently. It then returns a new template, with which the caller can rinse and repeat.

  2. DrahtBot commented at 12:30 pm on November 13, 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/31283.

    Reviews

    See the guideline for information on the review process. A summary of reviews will appear here.

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #30391 (BlockAssembler: return selected packages virtual size and fee by ismaelsadeeq)

    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.

  3. in src/node/interfaces.cpp:1012 in f955b8e406 outdated
    993+        }
    994+
    995+        return block_template;
    996+    }
    997+
    998+    const CScript m_script_pub_key;
    


    Sjors commented at 12:34 pm on November 13, 2024:
    Separate from this PR, I’m looking into whether we can avoid passing script_pub_key around. Afaik it’s only used by tests and for solo CPU mining.

    Sjors commented at 3:33 pm on November 18, 2024:
    #31318 drops this argument. It’s only slightly easier to merge that first, so I’ll leave this PR open.
  4. in src/node/interfaces.cpp:943 in f955b8e406 outdated
    937@@ -938,9 +938,71 @@ class BlockTemplateImpl : public BlockTemplate
    938         return chainman().ProcessNewBlock(block_ptr, /*force_processing=*/true, /*min_pow_checked=*/true, /*new_block=*/nullptr);
    939     }
    940 
    941+    std::unique_ptr<BlockTemplate> waitNext(CAmount fee_threshold, MillisecondsDouble timeout) override
    942+    {
    943+        if (timeout > std::chrono::years{100}) timeout = std::chrono::years{100}; // Upper bound to avoid UB in std::chrono
    


    Sjors commented at 12:37 pm on November 13, 2024:
    I still need to study #31003 (review) in more detail to see if this code isn’t making similar mistakes.

    Sjors commented at 1:30 pm on November 14, 2024:

    I dropped this line.

    Additionally this PR does not make use of last_mempool_update, since it’s not very useful in a typical production setting where something in the mempool updates all the time.

    I think the race condition mentioned there is not an issue here because we don’t pass in the current fees via argument, but instead derive them from the original template.

    I did forget to update now at the end of the loop, which I fixed.

  5. Sjors commented at 7:46 pm on November 13, 2024: member
    I pushed a commit refactoring miner_tests to use the Mining interface. I plan to expand those tests to cover waitNext().
  6. in src/test/miner_tests.cpp:68 in a316ba58cb outdated
    71-BlockAssembler MinerTestingSetup::AssemblerForTest(CTxMemPool& tx_mempool)
    72-{
    73-    BlockAssembler::Options options;
    74-
    75-    options.nBlockMaxWeight = MAX_BLOCK_WEIGHT;
    76-    options.blockMinFeeRate = blockMinFeeRate;
    


    Sjors commented at 7:47 pm on November 13, 2024:
    a316ba58cba5df8aadb05737959b97eeb6a350b4: I think dropping this doesn’t matter?
  7. in src/test/miner_tests.cpp:662 in a316ba58cb outdated
    684         }
    685-        std::shared_ptr<const CBlock> shared_pblock = std::make_shared<const CBlock>(*pblock);
    686-        BOOST_CHECK(Assert(m_node.chainman)->ProcessNewBlock(shared_pblock, true, true, nullptr));
    687-        pblock->hashPrevBlock = pblock->GetHash();
    688+        std::shared_ptr<const CBlock> shared_pblock = std::make_shared<const CBlock>(block);
    689+        BOOST_REQUIRE(Assert(m_node.chainman)->ProcessNewBlock(shared_pblock, /*force_processing=*/true, /*min_pow_checked=*/true, nullptr));
    


    Sjors commented at 7:51 pm on November 13, 2024:
    a316ba58cba5df8aadb05737959b97eeb6a350b4: I’m tempted to use miner.submitSolution() here.

    Sjors commented at 12:16 pm on November 14, 2024:
    Done
  8. DrahtBot added the label CI failed on Nov 13, 2024
  9. DrahtBot commented at 8:24 pm on November 13, 2024: contributor

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

    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.

  10. Sjors force-pushed on Nov 13, 2024
  11. DrahtBot removed the label CI failed on Nov 13, 2024
  12. Sjors force-pushed on Nov 14, 2024
  13. Sjors commented at 12:17 pm on November 14, 2024: member
    I made the test code alternate calls between Chainman’s ProcessNewBlock and submitSolution via the Mining interface. The latter approach is much simpler, but both are used in production code, so should be covered.
  14. Sjors force-pushed on Nov 14, 2024
  15. Sjors force-pushed on Nov 14, 2024
  16. Sjors force-pushed on Nov 14, 2024
  17. Sjors marked this as ready for review on Nov 14, 2024
  18. Sjors commented at 1:05 pm on November 14, 2024: member
    I added test coverage for waitNext().
  19. Sjors force-pushed on Nov 14, 2024
  20. Sjors force-pushed on Nov 14, 2024
  21. TheCharlatan commented at 1:18 pm on November 14, 2024: contributor

    In commit f9200f6c65b5a97a4842cc1ec34e688ec13bffcd

    “Use createNewBlock via the interface instead of calling Chainman’s CreateNewBlock.”

    Do you mean “Use createNewBlock via the interface instead of calling CreateNewBlock through the BlockAssembler directly”? There is no CreateNewBlock in the chainman.

  22. Sjors force-pushed on Nov 14, 2024
  23. Sjors commented at 1:31 pm on November 14, 2024: member
    Made some adjustments based on #31283 (review)
  24. Sjors force-pushed on Nov 14, 2024
  25. Sjors commented at 1:33 pm on November 14, 2024: member
    @TheCharlatan I adjusted the commit message
  26. in src/node/interfaces.cpp:1000 in e5a9b73210 outdated
    987+                CAmount new_fees = 0;
    988+                for (CAmount fee : block_template->m_block_template->vTxFees) {
    989+                    // Skip coinbase
    990+                    if (fee < 0) continue;
    991+                    new_fees += fee;
    992+                    if (new_fees >= current_fees + fee_threshold) return block_template;
    


    Sjors commented at 10:55 am on November 15, 2024:
    A fee_threshold of 0 combined with a timeout of 0 will immediately return a new template. This is useful for the Template Provider, because it needs to unconditionally send new templates to all connected clients if fees increased sufficiently for one its connected clients. (at least until cluster mempool makes the fee calculation trivially cheap)
  27. Sjors force-pushed on Nov 15, 2024
  28. Sjors commented at 5:37 pm on November 15, 2024: member
    Added early return logic. Similar to #31297 this would be less tedious if notifications().m_tip_block was set to the tip earlier.
  29. Sjors commented at 1:33 pm on November 19, 2024: member
    Marking this draft, let’s review the early return and m_tip_block block changes in #31297 first.
  30. Sjors marked this as a draft on Nov 19, 2024
  31. Sjors commented at 7:11 pm on November 19, 2024: member

    #31297 is on hold, as it’s probably unnecessary.

    Please review #31325 first, so I can decide whether to build this PR on top of it.

  32. DrahtBot added the label Needs rebase on Nov 20, 2024
  33. ryanofsky referenced this in commit 22ef95dbe3 on Nov 20, 2024
  34. Sjors commented at 1:35 pm on November 21, 2024: member

    Rebased after #31288 and #31122.

    This PR is now based on #31325 since that has enough support. Keeping this draft until that’s merged (or dropped).

    The test changes will probably cause a merge conflict with #31318, but it should be trivial. Ditto for the waitNext() implementation since that would no longer need to pump script_pub_key around.

    I dropped the early return in waitNext() because wait_until should already take care of that. I also made the while loop use <= instead of < so this actually works: #31283 (review) Added a test for that.

  35. Sjors force-pushed on Nov 21, 2024
  36. Sjors force-pushed on Nov 21, 2024
  37. DrahtBot removed the label Needs rebase on Nov 21, 2024
  38. Sjors force-pushed on Nov 22, 2024
  39. Sjors commented at 1:50 pm on November 22, 2024: member
    Fixed a bug found while testing https://github.com/Sjors/bitcoin/pull/49, where it was spuriously making new block templates every tick even if fees didn’t rise. diff
  40. in src/node/interfaces.cpp:963 in 5d294d86f4 outdated
    958+                WAIT_LOCK(notifications().m_tip_block_mutex, lock);
    959+                notifications().m_tip_block_cv.wait_until(lock, std::min(now + tick, deadline), [&]() EXCLUSIVE_LOCKS_REQUIRED(notifications().m_tip_block_mutex) {
    960+                    // Although C++17 allows safe comparison of optional<T> with
    961+                    // another T, we need to wait for m_tip_block to be set AND
    962+                    // for the value to be different than the current_tip value.
    963+                    tip_changed = notifications().m_tip_block && notifications().m_tip_block != m_block_template->block.hashPrevBlock;
    


    Sjors commented at 7:15 pm on November 22, 2024:

    If #31346 lands first, notifications().m_tip_block could be an Assert and the comment removed, see #31346 (comment)

    Though I have to make sure there’s no race condition where you call createNewBlock() followed by waitNext() right at node startup, without first calling waitTipChanged(ZERO).

  41. Sjors referenced this in commit a8da99a25e on Nov 29, 2024
  42. Sjors referenced this in commit 9634b8ae00 on Dec 2, 2024
  43. Sjors referenced this in commit 392967375b on Dec 2, 2024
  44. DrahtBot added the label Needs rebase on Dec 3, 2024
  45. Sjors force-pushed on Dec 4, 2024
  46. Sjors commented at 5:44 am on December 4, 2024: member
    Rebased after #31112.
  47. Sjors force-pushed on Dec 4, 2024
  48. DrahtBot removed the label Needs rebase on Dec 4, 2024
  49. DrahtBot added the label Needs rebase on Dec 13, 2024
  50. Sjors force-pushed on Dec 14, 2024
  51. Sjors commented at 4:38 am on December 14, 2024: member
    Rebased after #31346.
  52. DrahtBot removed the label Needs rebase on Dec 14, 2024
  53. Sjors referenced this in commit a263cda285 on Dec 16, 2024
  54. DrahtBot added the label Needs rebase on Dec 17, 2024
  55. Sjors force-pushed on Dec 18, 2024
  56. Sjors commented at 2:51 am on December 18, 2024: member
    Rebased after #31318 and #31197.
  57. DrahtBot commented at 3:15 am on December 18, 2024: contributor

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

    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.

  58. DrahtBot added the label CI failed on Dec 18, 2024
  59. DrahtBot removed the label Needs rebase on Dec 18, 2024
  60. Sjors force-pushed on Dec 18, 2024
  61. Sjors commented at 3:44 am on December 18, 2024: member
    Fixed tidy error.
  62. DrahtBot removed the label CI failed on Dec 18, 2024
  63. Sjors force-pushed on Dec 19, 2024
  64. Sjors commented at 1:32 am on December 19, 2024: member
    The changes here don’t conflict with the merged #31196, but I rebased just in case.
  65. test: use Mining interface in miner_tests
    Alternate calls between Chainman's ProcessNewBlock and submitSolution. The Chainman code path is used in production, so it's important to keep test coverage for it.
    
    Use createNewBlock via the interface instead of using the BlockAssembler directly. The latter is always called via the interface in production code.
    f5f68c7382
  66. Add waitNext() to BlockTemplate interface a19a5f92df
  67. Sjors force-pushed on Dec 20, 2024
  68. Sjors marked this as ready for review on Dec 20, 2024
  69. Sjors commented at 1:44 am on December 20, 2024: member
    #31325 landed so this is ready for review.

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 03:12 UTC

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