Skip to content

mining: replace interrupt methods with cancellation arguments - #36097

Draft
xyzconstant wants to merge 2 commits into
bitcoin:masterfrom
xyzconstant:ipc-cancellation-support
Draft

mining: replace interrupt methods with cancellation arguments#36097
xyzconstant wants to merge 2 commits into
bitcoin:masterfrom
xyzconstant:ipc-cancellation-support

Conversation

@xyzconstant

Copy link
Copy Markdown
Contributor

Depends on bitcoin-core/libmultiprocess#342. Only the last commit belongs to this PR.


The blocking methods (waitTipChanged, createNewBlock, and BlockTemplate::waitNext) currently rely on interrupt()/interruptWait() to cancel them when they are in progress (#33676, #34184). With request cancellation support in libmultiprocess (bitcoin-core/libmultiprocess#342), this is no longer needed.

This PR adds CancelArg arguments to those blocking methods to register a callback that runs on cancellation and deprecates the interrupt methods.

In the capnp schema, use the Proxy.extraParam annotation for the C++ CancelArg parameter and the Cxx.allowCancellation annotation to enable request cancellation at the RPC layer.

In tests, update miner_tests to cancel waitNext() from another thread, and interface_ipc_mining.py to drop the response promise. Also add drop_promise() to ipc_util.py to abandon capnp promises.

Additional note: this is the Bitcoin Core side of approach 4 in #33575.

Add an optional `CancelArg` parameter to the blocking Mining methods
`waitTipChanged`, `createNewBlock` and `waitNext`, and deprecate `interrupt()`
and `interruptWait()`. The methods pass a CancelFn to the argument, which
registers it to run if the call is canceled.

In capnp schema, use the `Proxy.extraParam` annotation for the C++ `CancelArg`
parameter and the `Cxx.allowCancellation` annotation to enable request
cancels at the RPC layer.

Update miner_tests to cancel `waitNext()` from another thread, and
interface_ipc_mining.py to drop the response promise and check the node
logs the cancellation. Also add `drop_promise()` to ipc_util.py to
abandon capnp promises.
@DrahtBot

DrahtBot commented Aug 27, 2026

Copy link
Copy Markdown
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/36097.

Reviews

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

Conflicts

Reviewers, this pull request conflicts with the following ones:

  • #35932 (ipc: make ipc::disconnectIncoming wait for in-progress calls to complete by ryanofsky)
  • #35671 (mining: add TxCollection to bandwidth-efficiently validate external block templates by Sjors)
  • #32387 (ipc: add windows support by ryanofsky)
  • #31117 (miner: Reorg Testnet4 minimum difficulty blocks by fjahr)

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.

LLM Linter (✨ experimental)

Possible typos and grammar issues:

  • src/ipc/libmultiprocess/doc/versions.md: nonunix -> non-Unix [misspelled; the intended meaning is clearer with standard wording]
  • src/interfaces/mining.h: std::nullptr -> nullptr [invalid term; likely meant nullptr]
  • src/ipc/libmultiprocess/include/mp/proxy-io.h: It safe to access post_writer here... -> It's safe to access post_writer here... [missing verb; slightly broken English]
  • src/ipc/libmultiprocess/src/mp/proxy.cpp: It safe to access post_writer here... -> It's safe to access post_writer here... [missing verb; slightly broken English]

2026-08-27 05:33:17

@DrahtBot

Copy link
Copy Markdown
Contributor

🚧 At least one of the CI tasks failed.
Task test ancestor commits: https://github.com/bitcoin/bitcoin/actions/runs/33042822923/job/98420040676
LLM reason (✨ experimental): CI failed due to a clang build error treated as fatal: a C++23 lambda attribute ([[noreturn]]) is used in mp/proxy-types.h, triggering -Wc++23-lambda-attributes under -Werror.

Hints

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.

@ryanofsky

Copy link
Copy Markdown
Contributor

Wow, this is very cool. The PR contains a lot of boilerplate updates but the heart of the change (5cdb565) is simply:

--- a/src/node/interfaces.cpp
+++ b/src/node/interfaces.cpp
@@ -926,8 +926,9 @@ public:
         return SubmitBlock(chainman(), std::make_shared<const CBlock>(m_block_template->block), reason, debug);
     }
 
-    std::unique_ptr<BlockTemplate> waitNext(BlockWaitOptions options) override
+    std::unique_ptr<BlockTemplate> waitNext(BlockWaitOptions options, interfaces::CancelArg cancel) override
     {
+        if (cancel) cancel([this] { InterruptWait(notifications(), m_interrupt_wait); });
         auto new_template = WaitAndCreateNewBlock(chainman(),
                                                   notifications(),
                                                   m_node.mempool.get(),
@@ -939,11 +940,6 @@ public:
         return nullptr;
     }
 
-    void interruptWait() override
-    {
-        InterruptWait(notifications(), m_interrupt_wait);
-    }
-
     const BlockCreateOptions m_create_options;
 
     const std::unique_ptr<CBlockTemplate> m_block_template;

Dropping the interruptWait method, replacing it with a CancelArg argument, and calling the argument with a lambda containing the code that used to be in interruptWait method.

With that change rust, python, and c++ clients can now cancel blocking requests more simply and efficiently using cap'n protos native cancellation mechanism, instead of needing to make new IPC calls to cancel previous ones.

There's an nontrivial amount of code to review here, but this is a very nice end-to-end implementation and demonstration that supporting this cancellation mechanism is worthwhile and makes things simpler for clients and servers. It could also become more important in the future if we want to have blocking calls that are individually cancellable instead of the current situation where interrupt methods can cancel multiple calls.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants