Skip to content

Commit 1816cac

Browse files
committed
Merge 1ff3a39 into merged_master (Elements PR ElementsProject#753)
2 parents e4ab943 + 1ff3a39 commit 1816cac

4 files changed

Lines changed: 33 additions & 5 deletions

File tree

src/miner.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ void BlockAssembler::resetBlock()
9898
Optional<int64_t> BlockAssembler::m_last_block_num_txs{nullopt};
9999
Optional<int64_t> BlockAssembler::m_last_block_weight{nullopt};
100100

101-
std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& scriptPubKeyIn, std::chrono::seconds min_tx_age, DynaFedParamEntry* proposed_entry)
101+
std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& scriptPubKeyIn, std::chrono::seconds min_tx_age, DynaFedParamEntry* proposed_entry, CScript const* commit_script)
102102
{
103103
assert(min_tx_age >= std::chrono::seconds(0));
104104
int64_t nTimeStart = GetTimeMicros();
@@ -191,6 +191,10 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
191191
}
192192
}
193193
coinbaseTx.vin[0].scriptSig = CScript() << nHeight << OP_0;
194+
// Non-consensus commitment output before finishing coinbase transaction
195+
if (commit_script) {
196+
coinbaseTx.vout.insert(coinbaseTx.vout.begin(), CTxOut(policyAsset, 0, *commit_script));
197+
}
194198
pblock->vtx[0] = MakeTransactionRef(std::move(coinbaseTx));
195199
pblocktemplate->vchCoinbaseCommitment = GenerateCoinbaseCommitment(*pblock, pindexPrev, chainparams.GetConsensus());
196200
pblocktemplate->vTxFees[0] = -nFees;

src/miner.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ class BlockAssembler
159159
BlockAssembler(const CChainParams& params, const Options& options);
160160

161161
/** Construct a new block template with coinbase to scriptPubKeyIn. min_tx_age is in seconds */
162-
std::unique_ptr<CBlockTemplate> CreateNewBlock(const CScript& scriptPubKeyIn, std::chrono::seconds min_tx_age = std::chrono::seconds(0), DynaFedParamEntry* = nullptr);
162+
std::unique_ptr<CBlockTemplate> CreateNewBlock(const CScript& scriptPubKeyIn, std::chrono::seconds min_tx_age = std::chrono::seconds(0), DynaFedParamEntry* = nullptr, CScript const* commit_script = nullptr);
163163

164164
static Optional<int64_t> m_last_block_num_txs;
165165
static Optional<int64_t> m_last_block_weight;

src/rpc/mining.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -976,7 +976,7 @@ static UniValue estimaterawfee(const JSONRPCRequest& request)
976976

977977
UniValue getnewblockhex(const JSONRPCRequest& request)
978978
{
979-
if (request.fHelp || request.params.size() > 2)
979+
if (request.fHelp || request.params.size() > 3)
980980
throw std::runtime_error(
981981
RPCHelpMan{"getnewblockhex",
982982
"\nGets hex representation of a proposed, unmined new block\n",
@@ -994,6 +994,7 @@ UniValue getnewblockhex(const JSONRPCRequest& request)
994994
},
995995
},
996996
"proposed_parameters"},
997+
{"commit_data", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "Data in hex to be committed to in an additional coinbase output."},
997998
},
998999
RPCResult{
9991000
"blockhex (hex) The block hex\n"
@@ -1048,9 +1049,17 @@ UniValue getnewblockhex(const JSONRPCRequest& request)
10481049
proposed.m_serialize_type = 2;
10491050
}
10501051

1052+
// Any commitment required for non-consensus reasons.
1053+
// This will be placed in the first coinbase output.
1054+
CScript data_commitment;
1055+
if (!request.params[2].isNull()) {
1056+
std::vector<unsigned char> data_bytes = ParseHex(request.params[2].get_str());
1057+
data_commitment = CScript() << OP_RETURN << data_bytes;
1058+
}
1059+
10511060
CScript feeDestinationScript = Params().GetConsensus().mandatory_coinbase_destination;
10521061
if (feeDestinationScript == CScript()) feeDestinationScript = CScript() << OP_TRUE;
1053-
std::unique_ptr<CBlockTemplate> pblocktemplate(BlockAssembler(Params()).CreateNewBlock(feeDestinationScript, std::chrono::seconds(required_wait), &proposed));
1062+
std::unique_ptr<CBlockTemplate> pblocktemplate(BlockAssembler(Params()).CreateNewBlock(feeDestinationScript, std::chrono::seconds(required_wait), &proposed, data_commitment.empty() ? nullptr : &data_commitment));
10541063
if (!pblocktemplate.get()) {
10551064
throw JSONRPCError(RPC_INTERNAL_ERROR, "Wallet keypool empty");
10561065
}
@@ -1451,7 +1460,7 @@ static const CRPCCommand commands[] =
14511460
{ "mining", "getblocktemplate", &getblocktemplate, {"template_request"} },
14521461
{ "generating", "combineblocksigs", &combineblocksigs, {"blockhex","signatures"} },
14531462
{ "mining", "submitheader", &submitheader, {"hexdata"} },
1454-
{ "generating", "getnewblockhex", &getnewblockhex, {"min_tx_age", "proposed_parameters"} },
1463+
{ "generating", "getnewblockhex", &getnewblockhex, {"min_tx_age", "proposed_parameters", "commit_data"} },
14551464
{ "generating", "getcompactsketch", &getcompactsketch, {"block_hex"} },
14561465
{ "generating", "consumecompactsketch", &consumecompactsketch, {"sketch"} },
14571466
{ "generating", "consumegetblocktxn", &consumegetblocktxn, {"full_block", "block_tx_req"} },

test/functional/feature_blocksign.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,13 @@
1010
address,
1111
key,
1212
)
13+
from test_framework.messages import (
14+
FromHex,
15+
CBlock,
16+
)
17+
from test_framework.script import (
18+
CScript
19+
)
1320

1421
# Generate wallet import format from private key.
1522
def wif(pk):
@@ -113,6 +120,14 @@ def mine_block(self, make_transactions):
113120
miner.sendtoaddress(miner_next.getnewaddress(), int(miner.getbalance()['bitcoin']/10), "", "", True)
114121
# miner makes a block
115122
block = miner.getnewblockhex()
123+
block_struct = FromHex(CBlock(), block)
124+
125+
# make another block with the commitment field filled out
126+
dummy_block = miner.getnewblockhex(commit_data="deadbeef")
127+
dummy_struct = FromHex(CBlock(), dummy_block)
128+
assert_equal(len(dummy_struct.vtx[0].vout), len(block_struct.vtx[0].vout) + 1)
129+
# OP_RETURN deadbeef
130+
assert_equal(CScript(dummy_struct.vtx[0].vout[0].scriptPubKey).hex(), '6a04deadbeef')
116131

117132
# All nodes get compact blocks, first node may get complete
118133
# block in 0.5 RTT even with transactions thanks to p2p connection

0 commit comments

Comments
 (0)