Skip to content

Commit cb3473a

Browse files
committed
Merge bitcoin/bitcoin#34568: mining: Break compatibility with existing IPC mining clients
f700609 doc: Release notes for mining IPC interface bump (Ryan Ofsky) 9453c15 ipc mining: break compatibility with existing clients (version bump) (Sjors Provoost) 70de5cc ipc mining: pass missing context to BlockTemplate methods (incompatible schema change) (Sjors Provoost) 2278f01 ipc mining: remove deprecated methods (incompatible schema change) (Ryan Ofsky) c6638fa ipc mining: provide default option values (incompatible schema change) (Ryan Ofsky) a4603ac ipc mining: declare constants for default field values (Ryan Ofsky) ff995b5 ipc test: add workaround to block_reserved_weight exception test (Ryan Ofsky) b970cdf test framework: expand expected_stderr, expected_ret_code options (Ryan Ofsky) df53a3e rpc refactor: stop using deprecated getCoinbaseCommitment method (Ryan Ofsky) Pull request description: This PR increments the field number of the `Init.makeMining` method and makes the old `makeMining` method return an error, so IPC mining clients not using the latest schema file will get an error and not be able to access the Mining interface. Normally, there shouldn't be a need to break compatibility this way, but the mining interface has evolved a lot since it was first introduced, with old clients using the original methods less stable and performant than newer clients. So now is a good time to introduce a cutoff, drop deprecated methods, and stop supporting old clients which can't function as well. Bumping the field number is also an opportunity to make other improvements that would be awkward to implement compatibly: - Making Cap'n Proto default parameter and field values match default values of corresponding C++ methods and structs. - Adding missing Context parameters to Mining.createNewBlock and checkBlock methods so these methods will be executed on separate execution threads and not block the Cap'n Proto event loop thread. More details about these changes are in the commit messages. ACKs for top commit: Sjors: ACK f700609 enirox001: ACK f700609 ismaelsadeeq: ACK f700609 sedited: ACK f700609 Tree-SHA512: 0901886af00214c138643b33cec21647de5671dfff2021afe06d78dfd970664a844cde9a1e28f685bb27edccaf6e0c3f2d1e6bb4164bde6b84f42955946e366d
2 parents 641a195 + f700609 commit cb3473a

File tree

19 files changed

+103
-122
lines changed

19 files changed

+103
-122
lines changed

doc/release-notes-33819.md

Lines changed: 0 additions & 8 deletions
This file was deleted.

doc/release-notes-34568.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
Mining IPC
2+
----------
3+
4+
The IPC mining interface now requires mining clients to use the latest `mining.capnp` schema. Clients built against older schemas will fail when calling `Init.makeMining` and receive an RPC error indicating the old mining interface is no longer supported. Mining clients must update to the latest schema and regenerate bindings to continue working. (#34568)
5+
6+
Notable IPC mining interface changes since the last release:
7+
- `Mining.createNewBlock` and `Mining.checkBlock` now require a `context` parameter.
8+
- `Mining.waitTipChanged` now has a default `timeout` (effectively infinite / `maxDouble`) if the client omits it.
9+
- `BlockTemplate.getCoinbaseTx()` now returns a structured `CoinbaseTx` instead of raw bytes.
10+
- Removed `BlockTemplate.getCoinbaseCommitment()` and `BlockTemplate.getWitnessCommitmentIndex()`.
11+
- Cap’n Proto default values were updated to match the corresponding C++ defaults for mining-related option structs (e.g. `BlockCreateOptions`, `BlockWaitOptions`, `BlockCheckOptions`).

src/interfaces/init.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ class Init
3939
virtual Ipc* ipc() { return nullptr; }
4040
virtual bool canListenIpc() { return false; }
4141
virtual const char* exeName() { return nullptr; }
42+
virtual void makeMiningOld2() { throw std::runtime_error("Old mining interface (@2) not supported. Please update your client!"); }
4243
};
4344

4445
//! Return implementation of Init interface for the node process. If the argv

src/interfaces/mining.h

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -42,31 +42,9 @@ class BlockTemplate
4242
// Sigop cost per transaction, not including coinbase transaction.
4343
virtual std::vector<int64_t> getTxSigops() = 0;
4444

45-
/**
46-
* Return serialized dummy coinbase transaction.
47-
*
48-
* @note deprecated: use getCoinbaseTx()
49-
*/
50-
virtual CTransactionRef getCoinbaseRawTx() = 0;
51-
5245
/** Return fields needed to construct a coinbase transaction */
5346
virtual node::CoinbaseTx getCoinbaseTx() = 0;
5447

55-
/**
56-
* Return scriptPubKey with SegWit OP_RETURN.
57-
*
58-
* @note deprecated: use getCoinbaseTx()
59-
*/
60-
virtual std::vector<unsigned char> getCoinbaseCommitment() = 0;
61-
62-
/**
63-
* Return which output in the dummy coinbase contains the SegWit OP_RETURN.
64-
*
65-
* @note deprecated. Scan outputs from getCoinbaseTx() outputs field for the
66-
* SegWit marker.
67-
*/
68-
virtual int getWitnessCommitmentIndex() = 0;
69-
7048
/**
7149
* Compute merkle path to the coinbase transaction
7250
*

src/ipc/capnp/init.capnp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,8 @@ using Mining = import "mining.capnp";
1919
interface Init $Proxy.wrap("interfaces::Init") {
2020
construct @0 (threadMap: Proxy.ThreadMap) -> (threadMap :Proxy.ThreadMap);
2121
makeEcho @1 (context :Proxy.Context) -> (result :Echo.Echo);
22-
makeMining @2 (context :Proxy.Context) -> (result :Mining.Mining);
22+
makeMining @3 (context :Proxy.Context) -> (result :Mining.Mining);
23+
24+
# DEPRECATED: no longer supported; server returns an error.
25+
makeMiningOld2 @2 () -> ();
2326
}

src/ipc/capnp/mining.capnp

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,18 @@ using Proxy = import "/mp/proxy.capnp";
1212
$Proxy.include("interfaces/mining.h");
1313
$Proxy.includeTypes("ipc/capnp/mining-types.h");
1414

15+
const maxMoney :Int64 = 2100000000000000;
16+
const maxDouble :Float64 = 1.7976931348623157e308;
17+
const defaultBlockReservedWeight :UInt32 = 8000;
18+
const defaultCoinbaseOutputMaxAdditionalSigops :UInt32 = 400;
19+
1520
interface Mining $Proxy.wrap("interfaces::Mining") {
1621
isTestChain @0 (context :Proxy.Context) -> (result: Bool);
1722
isInitialBlockDownload @1 (context :Proxy.Context) -> (result: Bool);
1823
getTip @2 (context :Proxy.Context) -> (result: Common.BlockRef, hasResult: Bool);
19-
waitTipChanged @3 (context :Proxy.Context, currentTip: Data, timeout: Float64) -> (result: Common.BlockRef);
20-
createNewBlock @4 (options: BlockCreateOptions) -> (result: BlockTemplate);
21-
checkBlock @5 (block: Data, options: BlockCheckOptions) -> (reason: Text, debug: Text, result: Bool);
24+
waitTipChanged @3 (context :Proxy.Context, currentTip: Data, timeout: Float64 = .maxDouble) -> (result: Common.BlockRef);
25+
createNewBlock @4 (context :Proxy.Context, options: BlockCreateOptions) -> (result: BlockTemplate);
26+
checkBlock @5 (context :Proxy.Context, block: Data, options: BlockCheckOptions) -> (reason: Text, debug: Text, result: Bool);
2227
}
2328

2429
interface BlockTemplate $Proxy.wrap("interfaces::BlockTemplate") {
@@ -27,30 +32,27 @@ interface BlockTemplate $Proxy.wrap("interfaces::BlockTemplate") {
2732
getBlock @2 (context: Proxy.Context) -> (result: Data);
2833
getTxFees @3 (context: Proxy.Context) -> (result: List(Int64));
2934
getTxSigops @4 (context: Proxy.Context) -> (result: List(Int64));
30-
getCoinbaseRawTx @5 (context: Proxy.Context) -> (result: Data);
31-
getCoinbaseTx @12 (context: Proxy.Context) -> (result: CoinbaseTx);
32-
getCoinbaseCommitment @6 (context: Proxy.Context) -> (result: Data);
33-
getWitnessCommitmentIndex @7 (context: Proxy.Context) -> (result: Int32);
34-
getCoinbaseMerklePath @8 (context: Proxy.Context) -> (result: List(Data));
35-
submitSolution @9 (context: Proxy.Context, version: UInt32, timestamp: UInt32, nonce: UInt32, coinbase :Data) -> (result: Bool);
36-
waitNext @10 (context: Proxy.Context, options: BlockWaitOptions) -> (result: BlockTemplate);
37-
interruptWait @11() -> ();
35+
getCoinbaseTx @5 (context: Proxy.Context) -> (result: CoinbaseTx);
36+
getCoinbaseMerklePath @6 (context: Proxy.Context) -> (result: List(Data));
37+
submitSolution @7 (context: Proxy.Context, version: UInt32, timestamp: UInt32, nonce: UInt32, coinbase :Data) -> (result: Bool);
38+
waitNext @8 (context: Proxy.Context, options: BlockWaitOptions) -> (result: BlockTemplate);
39+
interruptWait @9() -> ();
3840
}
3941

4042
struct BlockCreateOptions $Proxy.wrap("node::BlockCreateOptions") {
41-
useMempool @0 :Bool $Proxy.name("use_mempool");
42-
blockReservedWeight @1 :UInt64 $Proxy.name("block_reserved_weight");
43-
coinbaseOutputMaxAdditionalSigops @2 :UInt64 $Proxy.name("coinbase_output_max_additional_sigops");
43+
useMempool @0 :Bool = true $Proxy.name("use_mempool");
44+
blockReservedWeight @1 :UInt64 = .defaultBlockReservedWeight $Proxy.name("block_reserved_weight");
45+
coinbaseOutputMaxAdditionalSigops @2 :UInt64 = .defaultCoinbaseOutputMaxAdditionalSigops $Proxy.name("coinbase_output_max_additional_sigops");
4446
}
4547

4648
struct BlockWaitOptions $Proxy.wrap("node::BlockWaitOptions") {
47-
timeout @0 : Float64 $Proxy.name("timeout");
48-
feeThreshold @1 : Int64 $Proxy.name("fee_threshold");
49+
timeout @0 : Float64 = .maxDouble $Proxy.name("timeout");
50+
feeThreshold @1 : Int64 = .maxMoney $Proxy.name("fee_threshold");
4951
}
5052

5153
struct BlockCheckOptions $Proxy.wrap("node::BlockCheckOptions") {
52-
checkMerkleRoot @0 :Bool $Proxy.name("check_merkle_root");
53-
checkPow @1 :Bool $Proxy.name("check_pow");
54+
checkMerkleRoot @0 :Bool = true $Proxy.name("check_merkle_root");
55+
checkPow @1 :Bool = true $Proxy.name("check_pow");
5456
}
5557

5658
struct CoinbaseTx $Proxy.wrap("node::CoinbaseTx") {

src/ipc/test/ipc_test.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <ipc/protocol.h>
99
#include <logging.h>
1010
#include <mp/proxy-types.h>
11+
#include <ipc/capnp/mining.capnp.h>
1112
#include <ipc/test/ipc_test.capnp.h>
1213
#include <ipc/test/ipc_test.capnp.proxy.h>
1314
#include <ipc/test/ipc_test.h>
@@ -23,6 +24,11 @@
2324

2425
#include <boost/test/unit_test.hpp>
2526

27+
static_assert(ipc::capnp::messages::MAX_MONEY == MAX_MONEY);
28+
static_assert(ipc::capnp::messages::MAX_DOUBLE == std::numeric_limits<double>::max());
29+
static_assert(ipc::capnp::messages::DEFAULT_BLOCK_RESERVED_WEIGHT == DEFAULT_BLOCK_RESERVED_WEIGHT);
30+
static_assert(ipc::capnp::messages::DEFAULT_COINBASE_OUTPUT_MAX_ADDITIONAL_SIGOPS == DEFAULT_COINBASE_OUTPUT_MAX_ADDITIONAL_SIGOPS);
31+
2632
//! Remote init class.
2733
class TestInit : public interfaces::Init
2834
{

src/node/interfaces.cpp

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -890,26 +890,11 @@ class BlockTemplateImpl : public BlockTemplate
890890
return m_block_template->vTxSigOpsCost;
891891
}
892892

893-
CTransactionRef getCoinbaseRawTx() override
894-
{
895-
return m_block_template->block.vtx[0];
896-
}
897-
898893
CoinbaseTx getCoinbaseTx() override
899894
{
900895
return m_block_template->m_coinbase_tx;
901896
}
902897

903-
std::vector<unsigned char> getCoinbaseCommitment() override
904-
{
905-
return m_block_template->vchCoinbaseCommitment;
906-
}
907-
908-
int getWitnessCommitmentIndex() override
909-
{
910-
return GetWitnessCommitmentIndex(m_block_template->block);
911-
}
912-
913898
std::vector<uint256> getCoinbaseMerklePath() override
914899
{
915900
return TransactionMerklePath(m_block_template->block, 0);

src/node/miner.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock()
197197
coinbase_tx.lock_time = coinbaseTx.nLockTime;
198198

199199
pblock->vtx[0] = MakeTransactionRef(std::move(coinbaseTx));
200-
pblocktemplate->vchCoinbaseCommitment = m_chainstate.m_chainman.GenerateCoinbaseCommitment(*pblock, pindexPrev);
200+
m_chainstate.m_chainman.GenerateCoinbaseCommitment(*pblock, pindexPrev);
201201

202202
const CTransactionRef& final_coinbase{pblock->vtx[0]};
203203
if (final_coinbase->HasWitness()) {

src/node/miner.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ struct CBlockTemplate
4646
std::vector<CAmount> vTxFees;
4747
// Sigops per transaction, not including coinbase transaction (unlike CBlock::vtx).
4848
std::vector<int64_t> vTxSigOpsCost;
49-
std::vector<unsigned char> vchCoinbaseCommitment;
5049
/* A vector of package fee rates, ordered by the sequence in which
5150
* packages are selected for inclusion in the block template.*/
5251
std::vector<FeePerVSize> m_package_feerates;

0 commit comments

Comments
 (0)