Mining interface tracking issue #33777

issue Sjors openend this issue on November 4, 2025
  1. Sjors commented at 3:05 pm on November 4, 2025: member

    The mining interface is defined in:

    Clients that are known to depend on it:

    At this state it’s OK to make breaking changes, such as deleting a method or changing its signature. But ideally we should do so once in a major release, collecting a bunch of fixes.

    Non-breaking changes can be made any time, such as adding a new method.

    The changes below are not breaking, unless mentioned otherwise.

  2. fanquake added the label Mining on Nov 4, 2025
  3. fanquake added the label interfaces on Nov 4, 2025
  4. Sjors commented at 2:40 pm on November 7, 2025: member
    @ismaelsadeeq I’m thinking about deprecating getBlock() in favour of a new getTransactions() on BlockTemplate. That would allow us to avoid shoehorning block templates into a CBlock, which e.g. means we no longer need a dummy coinbase transaction.
  5. ismaelsadeeq commented at 3:22 pm on November 7, 2025: member
    Why is this important? Just because of shorhorning is not convincing imo, copying the txs is the most work which has to be done and then copy the header again. Previously, they could access it with a single call, but after what you propose it will requires two calls. Another downside is that they now have to calculate the block subsidy themselves, whereas previously it was included in the vout value of the first output of the coinbase tx.
  6. Sjors commented at 3:43 pm on November 7, 2025: member

    Previously, they could access it with a single call, but after what you propose it will requires two calls.

    Clients are already expected to call getHeader() to get the header. Combined with getCoinbaseMerklePath() and getCoinbase() they can construct a template without having to download the full block.

    In Stratum v2 clients only call getBlock() if the pool wants to inspect their proposed template (see RequestTransactionData.Success in sv2-tp). This happens later and currently involves dropping the coinbase from vtx.

    Another downside is that they now have to calculate the block subsidy themselves

    The CoinbaseTemplate struct proposed in #33819 provides the amount.

    Why is this important?

    Currently it’s not, but it does seem better in the long run to only serve clients data they need and not expose implementation details like our dummy coinbase.

    I was wondering if it makes #33421 easier, because templates for different sizes could just be spans over the transaction list.

    I can also think of a downside: submitBlock() currently relies on a ready-to-go CBlock.


    Update: getBlock() is also used by clients to download a backup / copy of the submitted block, so I decided to just keep it.

  7. Sjors commented at 3:54 pm on November 7, 2025: member

    See inline discussion in #33819 (review) about whether we should just go ahead and make breaking changes now, or pile them up until there’s a bigger / more important breaking change.

    A similar discussion occurred on IRC a few days ago: https://www.erisian.com.au/bitcoin-core-dev/log-2025-11-04.html#l-186

  8. ryanofsky commented at 5:48 pm on November 13, 2025: contributor

    Was looking at the IRC discussion and I think a nuance it doesn’t address is that there is a difference between breaking compatibility explicitly so clients see an error if they try to call a method that’s been changed or removed, and breaking compatibility silently so if a client tries to call a method that’s changed or removed, a different method may be called instead or arguments may be interpreted incorrectly.

    How to break compatibility explicitly

    You can break compatibility explicitly when you follow the rules at https://capnproto.org/language.html#evolving-your-protocol and avoid doing this things like changing field numbers, or break compatibility silently by ignoring these rules. A way to break compatibility explicitly is to bump the field number of a changed method like:

     0--- a/src/ipc/capnp/init.capnp
     1+++ b/src/ipc/capnp/init.capnp
     2@@ -19,5 +19,8 @@ using Mining = import "mining.capnp";
     3 interface Init $Proxy.wrap("interfaces::Init") {
     4     construct [@0](/bitcoin-bitcoin/contributor/0/) (threadMap: Proxy.ThreadMap) -> (threadMap :Proxy.ThreadMap);
     5     makeEcho [@1](/bitcoin-bitcoin/contributor/1/) (context :Proxy.Context) -> (result :Echo.Echo);
     6-    makeMining [@2](/bitcoin-bitcoin/contributor/2/) (context :Proxy.Context) -> (result :Mining.Mining);
     7+    makeMining [@3](/bitcoin-bitcoin/contributor/3/) (context :Proxy.Context) -> (result :Mining.Mining);
     8+
     9+    # DEPRECATED: no longer supported; server returns an error.
    10+    makeMiningV2 [@2](/bitcoin-bitcoin/contributor/2/) () -> ();
    11 }
    12--- a/src/interfaces/init.h
    13+++ b/src/interfaces/init.h
    14@@ -39,6 +39,7 @@ public:
    15     virtual Ipc* ipc() { return nullptr; }
    16     virtual bool canListenIpc() { return false; }
    17     virtual const char* exeName() { return nullptr; }
    18+    virtual void makeMiningV2() { throw std::runtime_error("Old mining interface (@2) not supported. Please update your client!"); }
    19 };
    20 
    21 //! Return implementation of Init interface for the node process. If the argv
    

    This is actually more complicated than I expected because I forgot capnproto forbids gaps between ordinal numbers, and thought that it would automatically generate errors if a method with a missing ordinal was called. This could be simplified a little with a helper annotation like:

    0makeMiningV2 [@2](/bitcoin-bitcoin/contributor/2/) () -> () $Proxy.Error("Old mining interface (@2) not supported. Please update your client!");
    

    so no c++ changes would be required.

    Breaking compatibility in master

    IMO, for interfaces like Chain (#29409) which are not intended to be called externally it should be ok to break compatibility silently not explicitly in master, and ignore schema evolution rules. But for the mining interface I think it’d be better only break compatibility explicitly even in master to avoid debugging headaches and make errors obvious when older clients are used.

    Also in many cases, like when adding new methods or new parameters with default values, it could be easy to avoid breaking compatibility at all.

    Source vs binary compatibility

    Everything above refers to binary compatibility not source compatibility. It’s possible to break source compatibility without breaking binary compatibility by doing things like renaming fields or methods without changing their ordinal numbers and types. Source compatibility should generally be less of a concern since it should result in compile-time errors not runtime errors.

  9. ryanofsky commented at 6:08 pm on November 13, 2025: contributor

    re: #33777 (comment)

    That would allow us to avoid shoehorning block templates into a CBlock, which e.g. means we no longer need a dummy coinbase transaction.

    It does seem error-prone to expose the dummy coinbase transaction, because if any clients are relying on it and we make internal changes, they could easily break.

    At some point after getCoinbase() is introduced in #33819, it could make sense to swap m_block_template->block.vtx[0] with an empty transaction in the BlockTemplateImpl constructor so clients will not rely on it and will switch to using getCoinbase() instead

  10. willcl-ark added the label Tracking Issue on Nov 18, 2025
  11. ryanofsky commented at 12:31 pm on November 25, 2025: contributor

    @Sjors I’m wondering which mining PRs & issues to focus on since there seem to be a lot open now. Feel free to tag me on any or mention any priorities here. I noticed there seemed to be a lot of these while updating the multiprocess tracking issue #28722 yesterday.

    I was also wondering if there are bitcoin or libmultiprocess features I should start working on. Ones I was thinking of were:

    • Adding exception types that could be thrown from IPC methods to return capnp failed / overloaded / unimplemented errors to clients.
    • Adding $Unimplemented or $Error method annotations that could be used in .capnp files to make it easier to remove old methods without needing c++ code (mentioned #33777 (comment)).
    • Adding an interfaces::Cancel c++ parameter that IPC methods could check and register callbacks with to know if the IPC client cancelled the call or disconnected (mentioned #33575).

    Other things I was thinking of doing:

    • Backporting #33676
    • Adding a doc/IPC-interface.md file similar to JSON-RPC-interface.md and REST-interface.md files to document things that plebhash has asked about like how to use server threads and Context objects and destroy methods.
  12. Sjors commented at 2:05 pm on November 25, 2025: member

    In terms of interface changes I’d like to focus on #33819 getCoinbase() and #33922 getMemoryLoad() which add new functionality. The smaller breaking interface changes can wait until either we have a bigger breaking change or nothing else on our plate.

    On the IPC side I don’t really have priorities in mind, so maybe pick what’s useful for @plebhash (as a stand-in for others who are both unfamiliar with the Bitcoin Core codebase and using other programming languages to connect).

    Documentation sounds like a very good idea. Another thing that would be useful is if we can automatically bubble up code comments from header files to the capnp definitions. Maybe a little Python script? It shouldn’t be (or at least doesn’t need to) adding methods and changing signatures, but it could find and update matching documentation.

  13. plebhash commented at 2:21 pm on November 25, 2025: none

    we’re doing a SRI release this week that is planned to include https://github.com/stratum-mining/sv2-apps/pull/59, and it’s meant to support v30

    but it will come with two major limitations, namely:

    • the initial iteration of bitcoin_core_sv2 crate is marked with a bunch of todos that are workarounds for the lack of interruptWait, and are being tracked at https://github.com/stratum-mining/sv2-apps/issues/81
    • running it on systems with low RAM for extended periods of time can lead to crashes

    we’re going to proceed with the release anyways, while making these points clear on the release notes


    so on our side, I’d say biggest priorities would be:

    • backporting #33676 so it lands on v30.1, which I’m happy to see @ryanofsky already mentioned above, and I also requested here #33609 (comment)
    • having a fix for #33940 that ideally also lands on v30.1

    that way, we can direct Sv2 adopters to run v30.1 as soon as it’s out, while dropping support to v30 entirely


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-11-26 06:13 UTC

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