Skip to content

Commit ff41b9e

Browse files
committed
Drop script_pub_key arg from createNewBlock
Providing a script for the coinbase transaction is only done in test code and for CPU solo mining. Production miners use the getblocktemplate RPC which omits the coinbase transaction entirely from its block template, leaving it to external (pool) software to construct it. A coinbase script can still be passed via BlockCreateOptions instead. A temporary overload is added so that the test can be modified in the next commit.
1 parent 7ab733e commit ff41b9e

File tree

7 files changed

+39
-16
lines changed

7 files changed

+39
-16
lines changed

src/interfaces/mining.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,11 +88,10 @@ class Mining
8888
/**
8989
* Construct a new block template
9090
*
91-
* @param[in] script_pub_key the coinbase output
9291
* @param[in] options options for creating the block
9392
* @returns a block template
9493
*/
95-
virtual std::unique_ptr<BlockTemplate> createNewBlock(const CScript& script_pub_key, const node::BlockCreateOptions& options = {}) = 0;
94+
virtual std::unique_ptr<BlockTemplate> createNewBlock(const node::BlockCreateOptions& options = {}) = 0;
9695

9796
/**
9897
* Processes new block. A valid new block is automatically relayed to peers.

src/ipc/capnp/mining.capnp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ interface Mining $Proxy.wrap("interfaces::Mining") {
1717
isInitialBlockDownload @1 (context :Proxy.Context) -> (result: Bool);
1818
getTip @2 (context :Proxy.Context) -> (result: Common.BlockRef, hasResult: Bool);
1919
waitTipChanged @3 (context :Proxy.Context, currentTip: Data, timeout: Float64) -> (result: Common.BlockRef);
20-
createNewBlock @4 (scriptPubKey: Data, options: BlockCreateOptions) -> (result: BlockTemplate);
20+
createNewBlock @4 (options: BlockCreateOptions) -> (result: BlockTemplate);
2121
processNewBlock @5 (context :Proxy.Context, block: Data) -> (newBlock: Bool, result: Bool);
2222
getTransactionsUpdated @6 (context :Proxy.Context) -> (result: UInt32);
2323
testBlockValidity @7 (context :Proxy.Context, block: Data, checkMerkleRoot: Bool) -> (state: BlockValidationState, result: Bool);

src/node/interfaces.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1004,11 +1004,11 @@ class MinerImpl : public Mining
10041004
return TestBlockValidity(state, chainman().GetParams(), chainman().ActiveChainstate(), block, tip, /*fCheckPOW=*/false, check_merkle_root);
10051005
}
10061006

1007-
std::unique_ptr<BlockTemplate> createNewBlock(const CScript& script_pub_key, const BlockCreateOptions& options) override
1007+
std::unique_ptr<BlockTemplate> createNewBlock(const BlockCreateOptions& options) override
10081008
{
10091009
BlockAssembler::Options assemble_options{options};
10101010
ApplyArgsManOptions(*Assert(m_node.args), assemble_options);
1011-
return std::make_unique<BlockTemplateImpl>(BlockAssembler{chainman().ActiveChainstate(), context()->mempool.get(), assemble_options}.CreateNewBlock(script_pub_key), m_node);
1011+
return std::make_unique<BlockTemplateImpl>(BlockAssembler{chainman().ActiveChainstate(), context()->mempool.get(), assemble_options}.CreateNewBlock(), m_node);
10121012
}
10131013

10141014
NodeContext* context() override { return &m_node; }

src/node/miner.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ void BlockAssembler::resetBlock()
106106
nFees = 0;
107107
}
108108

109-
std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& scriptPubKeyIn)
109+
std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock()
110110
{
111111
const auto time_start{SteadyClock::now()};
112112

@@ -151,7 +151,7 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
151151
coinbaseTx.vin.resize(1);
152152
coinbaseTx.vin[0].prevout.SetNull();
153153
coinbaseTx.vout.resize(1);
154-
coinbaseTx.vout[0].scriptPubKey = scriptPubKeyIn;
154+
coinbaseTx.vout[0].scriptPubKey = m_options.coinbase_output_script;
155155
coinbaseTx.vout[0].nValue = nFees + GetBlockSubsidy(nHeight, chainparams.GetConsensus());
156156
coinbaseTx.vin[0].scriptSig = CScript() << nHeight << OP_0;
157157
pblock->vtx[0] = MakeTransactionRef(std::move(coinbaseTx));

src/node/miner.h

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -169,14 +169,22 @@ class BlockAssembler
169169

170170
explicit BlockAssembler(Chainstate& chainstate, const CTxMemPool* mempool, const Options& options);
171171

172-
/** Construct a new block template with coinbase to scriptPubKeyIn */
173-
std::unique_ptr<CBlockTemplate> CreateNewBlock(const CScript& scriptPubKeyIn);
172+
/** Construct a new block template */
173+
std::unique_ptr<CBlockTemplate> CreateNewBlock();
174+
175+
/** Temporary overload for tests */
176+
std::unique_ptr<CBlockTemplate> CreateNewBlock(const CScript& scriptPubKeyIn)
177+
{
178+
m_options.coinbase_output_script = scriptPubKeyIn;
179+
return CreateNewBlock();
180+
};
174181

175182
inline static std::optional<int64_t> m_last_block_num_txs{};
176183
inline static std::optional<int64_t> m_last_block_weight{};
177184

178185
private:
179-
const Options m_options;
186+
// TODO: make const again
187+
Options m_options;
180188

181189
// utility functions
182190
/** Clear the block's state and prepare for assembling a new block */

src/node/types.h

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
44

55
//! @file node/types.h is a home for public enum and struct type definitions
6-
//! that are used by internally by node code, but also used externally by wallet
7-
//! or GUI code.
6+
//! that are used by internally by node code, but also used externally by wallet,
7+
//! mining or GUI code.
88
//!
99
//! This file is intended to define only simple types that do not have external
1010
//! dependencies. More complicated types should be defined in dedicated header
@@ -14,6 +14,7 @@
1414
#define BITCOIN_NODE_TYPES_H
1515

1616
#include <cstddef>
17+
#include <script/script.h>
1718

1819
namespace node {
1920
enum class TransactionError {
@@ -43,6 +44,22 @@ struct BlockCreateOptions {
4344
* transaction outputs.
4445
*/
4546
size_t coinbase_output_max_additional_sigops{400};
47+
/**
48+
* Script to put in the coinbase transaction. The default is an
49+
* anyone-can-spend dummy.
50+
*
51+
* Should only be used for tests, when the default doesn't suffice.
52+
*
53+
* Note that higher level code like the getblocktemplate RPC may omit the
54+
* coinbase transaction entirely. It's instead constructed by pool software
55+
* using fields like coinbasevalue, coinbaseaux and default_witness_commitment.
56+
* This software typically also controls the payout outputs, even for solo
57+
* mining.
58+
*
59+
* The size and sigops are not checked against
60+
* coinbase_max_additional_weight and coinbase_output_max_additional_sigops.
61+
*/
62+
CScript coinbase_output_script{CScript() << OP_TRUE};
4663
};
4764
} // namespace node
4865

src/rpc/mining.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ static UniValue generateBlocks(ChainstateManager& chainman, Mining& miner, const
162162
{
163163
UniValue blockHashes(UniValue::VARR);
164164
while (nGenerate > 0 && !chainman.m_interrupt) {
165-
std::unique_ptr<BlockTemplate> block_template(miner.createNewBlock(coinbase_output_script));
165+
std::unique_ptr<BlockTemplate> block_template(miner.createNewBlock({ .coinbase_output_script = coinbase_output_script }));
166166
CHECK_NONFATAL(block_template);
167167

168168
std::shared_ptr<const CBlock> block_out;
@@ -371,7 +371,7 @@ static RPCHelpMan generateblock()
371371

372372
ChainstateManager& chainman = EnsureChainman(node);
373373
{
374-
std::unique_ptr<BlockTemplate> block_template{miner.createNewBlock(coinbase_output_script, {.use_mempool = false})};
374+
std::unique_ptr<BlockTemplate> block_template{miner.createNewBlock({.use_mempool = false, .coinbase_output_script = coinbase_output_script})};
375375
CHECK_NONFATAL(block_template);
376376

377377
block = block_template->getBlock();
@@ -814,8 +814,7 @@ static RPCHelpMan getblocktemplate()
814814
time_start = GetTime();
815815

816816
// Create new block
817-
CScript scriptDummy = CScript() << OP_TRUE;
818-
block_template = miner.createNewBlock(scriptDummy);
817+
block_template = miner.createNewBlock();
819818
CHECK_NONFATAL(block_template);
820819

821820

0 commit comments

Comments
 (0)