mirror of
https://github.com/ElementsProject/elements.git
synced 2026-08-13 12:33:42 +02:00
Merge #753: getnewblockhex: Take data push for arbitrary data in block coinbase c…
6d9639b21 getnewblockhex: Take data push for arbitrary data in block coinbase commitment (Gregory Sanders)
Pull request description:
…ommitment
Useful for non-consensus proof of publication of data.
Tree-SHA512: 8967238c97b5188db50f99d7a8d8a1b26712a6b4c02812880502b5eb9572f7ca6a509a2020cb9661b2931f7d2b06f0580baa8652516b529b2386e92e73767a73
This commit is contained in:
commit
1ff3a39d11
4 changed files with 33 additions and 5 deletions
|
|
@ -102,7 +102,7 @@ void BlockAssembler::resetBlock()
|
|||
Optional<int64_t> BlockAssembler::m_last_block_num_txs{nullopt};
|
||||
Optional<int64_t> BlockAssembler::m_last_block_weight{nullopt};
|
||||
|
||||
std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& scriptPubKeyIn, int min_tx_age, DynaFedParamEntry* proposed_entry)
|
||||
std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& scriptPubKeyIn, int min_tx_age, DynaFedParamEntry* proposed_entry, CScript const* commit_script)
|
||||
{
|
||||
assert(min_tx_age >= 0);
|
||||
int64_t nTimeStart = GetTimeMicros();
|
||||
|
|
@ -195,6 +195,10 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
|
|||
}
|
||||
}
|
||||
coinbaseTx.vin[0].scriptSig = CScript() << nHeight << OP_0;
|
||||
// Non-consensus commitment output before finishing coinbase transaction
|
||||
if (commit_script) {
|
||||
coinbaseTx.vout.insert(coinbaseTx.vout.begin(), CTxOut(policyAsset, 0, *commit_script));
|
||||
}
|
||||
pblock->vtx[0] = MakeTransactionRef(std::move(coinbaseTx));
|
||||
pblocktemplate->vchCoinbaseCommitment = GenerateCoinbaseCommitment(*pblock, pindexPrev, chainparams.GetConsensus());
|
||||
pblocktemplate->vTxFees[0] = -nFees;
|
||||
|
|
|
|||
|
|
@ -159,7 +159,7 @@ public:
|
|||
BlockAssembler(const CChainParams& params, const Options& options);
|
||||
|
||||
/** Construct a new block template with coinbase to scriptPubKeyIn. min_tx_age is in seconds */
|
||||
std::unique_ptr<CBlockTemplate> CreateNewBlock(const CScript& scriptPubKeyIn, int min_tx_age=0, DynaFedParamEntry* = nullptr);
|
||||
std::unique_ptr<CBlockTemplate> CreateNewBlock(const CScript& scriptPubKeyIn, int min_tx_age=0, DynaFedParamEntry* = nullptr, CScript const* commit_script = nullptr);
|
||||
|
||||
static Optional<int64_t> m_last_block_num_txs;
|
||||
static Optional<int64_t> m_last_block_weight;
|
||||
|
|
|
|||
|
|
@ -999,7 +999,7 @@ static UniValue estimaterawfee(const JSONRPCRequest& request)
|
|||
|
||||
UniValue getnewblockhex(const JSONRPCRequest& request)
|
||||
{
|
||||
if (request.fHelp || request.params.size() > 2)
|
||||
if (request.fHelp || request.params.size() > 3)
|
||||
throw std::runtime_error(
|
||||
RPCHelpMan{"getnewblockhex",
|
||||
"\nGets hex representation of a proposed, unmined new block\n",
|
||||
|
|
@ -1017,6 +1017,7 @@ UniValue getnewblockhex(const JSONRPCRequest& request)
|
|||
},
|
||||
},
|
||||
"proposed_parameters"},
|
||||
{"commit_data", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "Data in hex to be committed to in an additional coinbase output."},
|
||||
},
|
||||
RPCResult{
|
||||
"blockhex (hex) The block hex\n"
|
||||
|
|
@ -1071,9 +1072,17 @@ UniValue getnewblockhex(const JSONRPCRequest& request)
|
|||
proposed.m_serialize_type = 2;
|
||||
}
|
||||
|
||||
// Any commitment required for non-consensus reasons.
|
||||
// This will be placed in the first coinbase output.
|
||||
CScript data_commitment;
|
||||
if (!request.params[2].isNull()) {
|
||||
std::vector<unsigned char> data_bytes = ParseHex(request.params[2].get_str());
|
||||
data_commitment = CScript() << OP_RETURN << data_bytes;
|
||||
}
|
||||
|
||||
CScript feeDestinationScript = Params().GetConsensus().mandatory_coinbase_destination;
|
||||
if (feeDestinationScript == CScript()) feeDestinationScript = CScript() << OP_TRUE;
|
||||
std::unique_ptr<CBlockTemplate> pblocktemplate(BlockAssembler(Params()).CreateNewBlock(feeDestinationScript, required_wait, &proposed));
|
||||
std::unique_ptr<CBlockTemplate> pblocktemplate(BlockAssembler(Params()).CreateNewBlock(feeDestinationScript, required_wait, &proposed, data_commitment.empty() ? nullptr : &data_commitment));
|
||||
if (!pblocktemplate.get()) {
|
||||
throw JSONRPCError(RPC_INTERNAL_ERROR, "Wallet keypool empty");
|
||||
}
|
||||
|
|
@ -1474,7 +1483,7 @@ static const CRPCCommand commands[] =
|
|||
{ "mining", "getblocktemplate", &getblocktemplate, {"template_request"} },
|
||||
{ "generating", "combineblocksigs", &combineblocksigs, {"blockhex","signatures"} },
|
||||
{ "mining", "submitheader", &submitheader, {"hexdata"} },
|
||||
{ "generating", "getnewblockhex", &getnewblockhex, {"min_tx_age", "proposed_parameters"} },
|
||||
{ "generating", "getnewblockhex", &getnewblockhex, {"min_tx_age", "proposed_parameters", "commit_data"} },
|
||||
{ "generating", "getcompactsketch", &getcompactsketch, {"block_hex"} },
|
||||
{ "generating", "consumecompactsketch", &consumecompactsketch, {"sketch"} },
|
||||
{ "generating", "consumegetblocktxn", &consumegetblocktxn, {"full_block", "block_tx_req"} },
|
||||
|
|
|
|||
|
|
@ -10,6 +10,13 @@ from test_framework import (
|
|||
address,
|
||||
key,
|
||||
)
|
||||
from test_framework.messages import (
|
||||
FromHex,
|
||||
CBlock,
|
||||
)
|
||||
from test_framework.script import (
|
||||
CScript
|
||||
)
|
||||
|
||||
# Generate wallet import format from private key.
|
||||
def wif(pk):
|
||||
|
|
@ -115,6 +122,14 @@ class BlockSignTest(BitcoinTestFramework):
|
|||
miner.sendtoaddress(miner_next.getnewaddress(), int(miner.getbalance()['bitcoin']/10), "", "", True)
|
||||
# miner makes a block
|
||||
block = miner.getnewblockhex()
|
||||
block_struct = FromHex(CBlock(), block)
|
||||
|
||||
# make another block with the commitment field filled out
|
||||
dummy_block = miner.getnewblockhex(commit_data="deadbeef")
|
||||
dummy_struct = FromHex(CBlock(), dummy_block)
|
||||
assert_equal(len(dummy_struct.vtx[0].vout), len(block_struct.vtx[0].vout) + 1)
|
||||
# OP_RETURN deadbeef
|
||||
assert_equal(CScript(dummy_struct.vtx[0].vout[0].scriptPubKey).hex(), '6a04deadbeef')
|
||||
|
||||
# All nodes get compact blocks, first node may get complete
|
||||
# block in 0.5 RTT even with transactions thanks to p2p connection
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue