0diff --git a/src/miner.cpp b/src/miner.cpp
1index 61d27d17c1..b769121d97 100644
2--- a/src/miner.cpp
3+++ b/src/miner.cpp
4@@ -39,6 +39,17 @@ int64_t UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParam
5 return nNewTime - nOldTime;
6 }
7
8+void ReGenerateCommitments(CBlock& block)
9+{
10+ CMutableTransaction tx{*block.vtx.at(0)};
11+ tx.vout.erase(tx.vout.begin() + GetWitnessCommitmentIndex(block));
12+ block.vtx.at(0) = MakeTransactionRef(tx);
13+
14+ GenerateCoinbaseCommitment(block, WITH_LOCK(cs_main, return LookupBlockIndex(block.hashPrevBlock)), Params().GetConsensus());
15+
16+ block.hashMerkleRoot = BlockMerkleRoot(block);
17+}
18+
19 BlockAssembler::Options::Options() {
20 blockMinFeeRate = CFeeRate(DEFAULT_BLOCK_MIN_TX_FEE);
21 nBlockMaxWeight = DEFAULT_BLOCK_MAX_WEIGHT;
22diff --git a/src/miner.h b/src/miner.h
23index cc8fc31a9f..fee02b591d 100644
24--- a/src/miner.h
25+++ b/src/miner.h
26@@ -203,4 +203,7 @@ private:
27 void IncrementExtraNonce(CBlock* pblock, const CBlockIndex* pindexPrev, unsigned int& nExtraNonce);
28 int64_t UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev);
29
30+/** Update an old GenerateCoinbaseCommitment from CreateNewBlock after the block txs have changed */
31+void ReGenerateCommitments(CBlock& block);
32+
33 #endif // BITCOIN_MINER_H
34diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp
35index 007d9253a1..58aaccd1c3 100644
36--- a/src/rpc/mining.cpp
37+++ b/src/rpc/mining.cpp
38@@ -104,6 +104,11 @@ static bool GenerateBlock(CBlock& block, uint64_t& max_tries, unsigned int& extr
39 {
40 block_hash.SetNull();
41
42+ {
43+ LOCK(cs_main);
44+ IncrementExtraNonce(&block, ::ChainActive().Tip(), extra_nonce);
45+ }
46+
47 CChainParams chainparams(Params());
48
49 while (max_tries > 0 && block.nNonce < std::numeric_limits<uint32_t>::max() && !CheckProofOfWork(block.GetHash(), block.nBits, chainparams.GetConsensus()) && !ShutdownRequested()) {
50@@ -143,11 +148,6 @@ static UniValue generateBlocks(const CTxMemPool& mempool, const CScript& coinbas
51 if (!pblocktemplate.get())
52 throw JSONRPCError(RPC_INTERNAL_ERROR, "Couldn't create new block");
53 CBlock *pblock = &pblocktemplate->block;
54- {
55- LOCK(cs_main);
56- IncrementExtraNonce(pblock, ::ChainActive().Tip(), nExtraNonce);
57- }
58-
59 uint256 block_hash;
60 if (!GenerateBlock(*pblock, nMaxTries, nExtraNonce, block_hash)) {
61 break;
62@@ -329,51 +329,29 @@ static UniValue generateblock(const JSONRPCRequest& request)
63 }
64 }
65
66- CChainParams chainparams(Params());
67+ const CChainParams& chainparams = Params();
68+ unsigned int extra_nonce{0};
69 CBlock block;
70-
71- CBlockIndex* previous_index;
72 {
73 LOCK(cs_main);
74- previous_index = ::ChainActive().Tip();
75- }
76- CHECK_NONFATAL(previous_index != nullptr);
77-
78- const int height = previous_index->nHeight + 1;
79
80- // Create coinbase transaction.
81- CMutableTransaction coinbase_tx;
82- coinbase_tx.vin.resize(1);
83- coinbase_tx.vin[0].prevout.SetNull();
84- coinbase_tx.vout.resize(1);
85- coinbase_tx.vout[0].scriptPubKey = coinbase_script;
86- coinbase_tx.vout[0].nValue = GetBlockSubsidy(height, chainparams.GetConsensus());
87- coinbase_tx.vin[0].scriptSig = CScript() << height << OP_0;
88- block.vtx.push_back(MakeTransactionRef(std::move(coinbase_tx)));
89+ CTxMemPool empty_pool;
90+ std::unique_ptr<CBlockTemplate> blocktemplate(BlockAssembler(empty_pool, chainparams).CreateNewBlock(coinbase_script));
91+ if (!blocktemplate) {
92+ throw JSONRPCError(RPC_INTERNAL_ERROR, "Couldn't create new block");
93+ }
94+ block = blocktemplate->block;
95+ CHECK_NONFATAL(block.vtx.size() == 1);
96+ }
97
98 // Add transactions
99 block.vtx.insert(block.vtx.end(), txs.begin(), txs.end());
100+ ReGenerateCommitments(block);
101
102- block.nVersion = ComputeBlockVersion(previous_index, chainparams.GetConsensus());
103- if (chainparams.MineBlocksOnDemand())
104- block.nVersion = gArgs.GetArg("-blockversion", block.nVersion);
105-
106- // Fill in header
107- block.hashPrevBlock = previous_index->GetBlockHash();
108- block.nTime = GetAdjustedTime();
109- UpdateTime(&block, chainparams.GetConsensus(), previous_index);
110- block.nBits = GetNextWorkRequired(previous_index, &block, chainparams.GetConsensus());
111- block.nNonce = 0;
112-
113- GenerateCoinbaseCommitment(block, previous_index, chainparams.GetConsensus());
114-
115- unsigned int extra_nonce{0};
116 {
117 LOCK(cs_main);
118- IncrementExtraNonce(&block, ::ChainActive().Tip(), extra_nonce);
119-
120 BlockValidationState state;
121- if (!TestBlockValidity(state, chainparams, block, previous_index, false, false)) {
122+ if (!TestBlockValidity(state, chainparams, block, LookupBlockIndex(block.hashPrevBlock), false, false)) {
123 throw JSONRPCError(RPC_VERIFY_ERROR, strprintf("TestBlockValidity failed: %s", state.ToString()));
124 }
125 }