Skip to content

Commit

Permalink
mining: add -coinbaselocktime
Browse files Browse the repository at this point in the history
To prepare for a potential soft fork that would mandate nLockTime of the coinbase to be set to the block height, allow miners to opt-in to doing this sooner.

By using this setting, miners can check if there is any ancillary software they're relying on that is incompatible with such a proposed change.
  • Loading branch information
Sjors committed Aug 20, 2024
1 parent d79ea80 commit c74fb4a
Show file tree
Hide file tree
Showing 5 changed files with 21 additions and 2 deletions.
1 change: 1 addition & 0 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -659,6 +659,7 @@ void SetupServerArgs(ArgsManager& argsman)
argsman.AddArg("-blockmaxweight=<n>", strprintf("Set maximum BIP141 block weight (default: %d)", DEFAULT_BLOCK_MAX_WEIGHT), ArgsManager::ALLOW_ANY, OptionsCategory::BLOCK_CREATION);
argsman.AddArg("-blockmintxfee=<amt>", strprintf("Set lowest fee rate (in %s/kvB) for transactions to be included in block creation. (default: %s)", CURRENCY_UNIT, FormatMoney(DEFAULT_BLOCK_MIN_TX_FEE)), ArgsManager::ALLOW_ANY, OptionsCategory::BLOCK_CREATION);
argsman.AddArg("-blockversion=<n>", "Override block version to test forking scenarios", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::BLOCK_CREATION);
argsman.AddArg("-coinbaselocktime", strprintf("Set maximum BIP141 block weight (default: %d)", DEFAULT_COINBASE_LOCKTIME), ArgsManager::ALLOW_ANY, OptionsCategory::BLOCK_CREATION);

argsman.AddArg("-rest", strprintf("Accept public REST requests (default: %u)", DEFAULT_REST_ENABLE), ArgsManager::ALLOW_ANY, OptionsCategory::RPC);
argsman.AddArg("-rpcallowip=<ip>", "Allow JSON-RPC connections from specified source. Valid values for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0), a network/CIDR (e.g. 1.2.3.4/24), all ipv4 (0.0.0.0/0), or all ipv6 (::/0). This option can be specified multiple times", ArgsManager::ALLOW_ANY, OptionsCategory::RPC);
Expand Down
4 changes: 4 additions & 0 deletions src/node/miner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ void ApplyArgsManOptions(const ArgsManager& args, BlockAssembler::Options& optio
if (const auto parsed{ParseMoney(*blockmintxfee)}) options.blockMinFeeRate = CFeeRate{*parsed};
}
options.print_modified_fee = args.GetBoolArg("-printpriority", options.print_modified_fee);
options.coinbase_locktime = args.GetBoolArg("-coinbaselocktime", DEFAULT_COINBASE_LOCKTIME);
}

void BlockAssembler::resetBlock()
Expand Down Expand Up @@ -151,6 +152,9 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
coinbaseTx.vout[0].scriptPubKey = scriptPubKeyIn;
coinbaseTx.vout[0].nValue = nFees + GetBlockSubsidy(nHeight, chainparams.GetConsensus());
coinbaseTx.vin[0].scriptSig = CScript() << nHeight << OP_0;
if (m_options.coinbase_locktime) {
coinbaseTx.nLockTime = nHeight;
}
pblock->vtx[0] = MakeTransactionRef(std::move(coinbaseTx));
pblocktemplate->vchCoinbaseCommitment = m_chainstate.m_chainman.GenerateCoinbaseCommitment(*pblock, pindexPrev);
pblocktemplate->vTxFees[0] = -nFees;
Expand Down
2 changes: 2 additions & 0 deletions src/node/miner.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,8 @@ class BlockAssembler
// Configuration parameters for the block size
size_t nBlockMaxWeight{DEFAULT_BLOCK_MAX_WEIGHT};
CFeeRate blockMinFeeRate{DEFAULT_BLOCK_MIN_TX_FEE};
// Whether to set nLockTime to the current height
bool coinbase_locktime{DEFAULT_COINBASE_LOCKTIME};
// Whether to call TestBlockValidity() at the end of CreateNewBlock().
bool test_block_validity{true};
bool print_modified_fee{DEFAULT_PRINT_MODIFIED_FEE};
Expand Down
2 changes: 2 additions & 0 deletions src/policy/policy.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ class CScript;
static constexpr unsigned int DEFAULT_BLOCK_MAX_WEIGHT{MAX_BLOCK_WEIGHT - 4000};
/** Default for -blockmintxfee, which sets the minimum feerate for a transaction in blocks created by mining code **/
static constexpr unsigned int DEFAULT_BLOCK_MIN_TX_FEE{1000};
/** Default for -coinbaselocktime, which sets the coinbase nLockTime in blocks created by mining code **/
static constexpr bool DEFAULT_COINBASE_LOCKTIME{false};
/** The maximum weight for transactions we're willing to relay/mine */
static constexpr int32_t MAX_STANDARD_TX_WEIGHT{400000};
/** The minimum non-witness size for transactions we're willing to relay/mine: one larger than 64 */
Expand Down
14 changes: 12 additions & 2 deletions test/functional/mining_basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ def mine_chain(self):
assert_equal(VERSIONBITS_TOP_BITS + (1 << VERSIONBITS_DEPLOYMENT_TESTDUMMY_BIT), self.nodes[0].getblocktemplate(NORMAL_GBT_REQUEST_PARAMS)['version'])
self.restart_node(0)
self.connect_nodes(0, 1)
return t

def test_blockmintxfee_parameter(self):
self.log.info("Test -blockmintxfee setting")
Expand Down Expand Up @@ -118,7 +119,7 @@ def test_blockmintxfee_parameter(self):
def run_test(self):
node = self.nodes[0]
self.wallet = MiniWallet(node)
self.mine_chain()
t = self.mine_chain()

def assert_submitblock(block, result_str_1, result_str_2=None):
block.solve()
Expand All @@ -136,6 +137,15 @@ def assert_submitblock(block, result_str_1, result_str_2=None):
assert_equal(mining_info['networkhashps'], Decimal('0.003333333333333334'))
assert_equal(mining_info['pooledtx'], 0)

self.log.info('check coinbase transaction')
coinbase = node.getblock(node.getbestblockhash(), verbosity=3)['tx'][0]
assert_equal(coinbase['locktime'], 0)
self.restart_node(0, extra_args=[f'-mocktime={t}', '-coinbaselocktime'])
self.connect_nodes(0, 1)
self.generate(self.wallet, 1, sync_fun=self.no_op)
coinbase = node.getblock(node.getbestblockhash(), verbosity=3)['tx'][0]
assert_equal(coinbase['locktime'], 201)

self.log.info("getblocktemplate: Test default witness commitment")
txid = int(self.wallet.send_self_transfer(from_node=node)['wtxid'], 16)
tmpl = node.getblocktemplate(NORMAL_GBT_REQUEST_PARAMS)
Expand Down Expand Up @@ -265,7 +275,7 @@ def assert_submitblock(block, result_str_1, result_str_2=None):
block.solve()

def chain_tip(b_hash, *, status='headers-only', branchlen=1):
return {'hash': b_hash, 'height': 202, 'branchlen': branchlen, 'status': status}
return {'hash': b_hash, 'height': 203, 'branchlen': branchlen, 'status': status}

assert chain_tip(block.hash) not in node.getchaintips()
node.submitheader(hexdata=block.serialize().hex())
Expand Down

0 comments on commit c74fb4a

Please sign in to comment.