rpc: Add submit option to generateblock

This commit is contained in:
MarcoFalke committed 2023-03-10 10:39:14 +01:00
1 parent fab9a08e14
commit fa18504d57
3 files changed
+21 -4

No files matched your search

+1
View File
@@ -37,6 +37,7 @@ static const CRPCConvertParam vRPCConvertParams[] =
{ "generatetodescriptor", 0, "num_blocks" }, { "generatetodescriptor", 0, "num_blocks" },
{ "generatetodescriptor", 2, "maxtries" }, { "generatetodescriptor", 2, "maxtries" },
{ "generateblock", 1, "transactions" }, { "generateblock", 1, "transactions" },
{ "generateblock", 2, "submit" },
{ "getnetworkhashps", 0, "nblocks" }, { "getnetworkhashps", 0, "nblocks" },
{ "getnetworkhashps", 1, "height" }, { "getnetworkhashps", 1, "height" },
{ "sendtoaddress", 1, "amount" }, { "sendtoaddress", 1, "amount" },
+14 -3
View File
@@ -115,7 +115,7 @@ static RPCHelpMan getnetworkhashps()
}; };
} }
static bool GenerateBlock(ChainstateManager& chainman, CBlock& block, uint64_t& max_tries, std::shared_ptr<const CBlock>& block_out) static bool GenerateBlock(ChainstateManager& chainman, CBlock& block, uint64_t& max_tries, std::shared_ptr<const CBlock>& block_out, bool process_new_block)
{ {
block_out.reset(); block_out.reset();
block.hashMerkleRoot = BlockMerkleRoot(block); block.hashMerkleRoot = BlockMerkleRoot(block);
@@ -132,6 +132,9 @@ static bool GenerateBlock(ChainstateManager& chainman, CBlock& block, uint64_t&
} }
block_out = std::make_shared<const CBlock>(block); block_out = std::make_shared<const CBlock>(block);
if (!process_new_block) return true;
if (!chainman.ProcessNewBlock(block_out, /*force_processing=*/true, /*min_pow_checked=*/true, nullptr)) { if (!chainman.ProcessNewBlock(block_out, /*force_processing=*/true, /*min_pow_checked=*/true, nullptr)) {
throw JSONRPCError(RPC_INTERNAL_ERROR, "ProcessNewBlock, block not accepted"); throw JSONRPCError(RPC_INTERNAL_ERROR, "ProcessNewBlock, block not accepted");
} }
@@ -148,7 +151,7 @@ static UniValue generateBlocks(ChainstateManager& chainman, const CTxMemPool& me
throw JSONRPCError(RPC_INTERNAL_ERROR, "Couldn't create new block"); throw JSONRPCError(RPC_INTERNAL_ERROR, "Couldn't create new block");
std::shared_ptr<const CBlock> block_out; std::shared_ptr<const CBlock> block_out;
if (!GenerateBlock(chainman, pblocktemplate->block, nMaxTries, block_out)) { if (!GenerateBlock(chainman, pblocktemplate->block, nMaxTries, block_out, /*process_new_block=*/true)) {
break; break;
} }
@@ -293,11 +296,13 @@ static RPCHelpMan generateblock()
{"rawtx/txid", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, ""}, {"rawtx/txid", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, ""},
}, },
}, },
{"submit", RPCArg::Type::BOOL, RPCArg::Default{true}, "Whether to submit the block before the RPC call returns or to return it as hex."},
}, },
RPCResult{ RPCResult{
RPCResult::Type::OBJ, "", "", RPCResult::Type::OBJ, "", "",
{ {
{RPCResult::Type::STR_HEX, "hash", "hash of generated block"}, {RPCResult::Type::STR_HEX, "hash", "hash of generated block"},
{RPCResult::Type::STR_HEX, "hex", /*optional=*/true, "hex of generated block, only present when submit=false"},
} }
}, },
RPCExamples{ RPCExamples{
@@ -346,6 +351,7 @@ static RPCHelpMan generateblock()
} }
} }
const bool process_new_block{request.params[2].isNull() ? true : request.params[2].get_bool()};
CBlock block; CBlock block;
ChainstateManager& chainman = EnsureChainman(node); ChainstateManager& chainman = EnsureChainman(node);
@@ -377,12 +383,17 @@ static RPCHelpMan generateblock()
std::shared_ptr<const CBlock> block_out; std::shared_ptr<const CBlock> block_out;
uint64_t max_tries{DEFAULT_MAX_TRIES}; uint64_t max_tries{DEFAULT_MAX_TRIES};
if (!GenerateBlock(chainman, block, max_tries, block_out) || !block_out) { if (!GenerateBlock(chainman, block, max_tries, block_out, process_new_block) || !block_out) {
throw JSONRPCError(RPC_MISC_ERROR, "Failed to make block."); throw JSONRPCError(RPC_MISC_ERROR, "Failed to make block.");
} }
UniValue obj(UniValue::VOBJ); UniValue obj(UniValue::VOBJ);
obj.pushKV("hash", block_out->GetHash().GetHex()); obj.pushKV("hash", block_out->GetHash().GetHex());
if (!process_new_block) {
CDataStream block_ser{SER_NETWORK, PROTOCOL_VERSION | RPCSerializationFlags()};
block_ser << *block_out;
obj.pushKV("hex", HexStr(block_ser));
}
return obj; return obj;
}, },
}; };
+6 -1
View File
@@ -29,8 +29,13 @@ class RPCGenerateTest(BitcoinTestFramework):
node = self.nodes[0] node = self.nodes[0]
miniwallet = MiniWallet(node) miniwallet = MiniWallet(node)
self.log.info('Generate an empty block to address') self.log.info('Mine an empty block to address and return the hex')
address = miniwallet.get_address() address = miniwallet.get_address()
generated_block = self.generateblock(node, output=address, transactions=[], submit=False)
node.submitblock(hexdata=generated_block['hex'])
assert_equal(generated_block['hash'], node.getbestblockhash())
self.log.info('Generate an empty block to address')
hash = self.generateblock(node, output=address, transactions=[])['hash'] hash = self.generateblock(node, output=address, transactions=[])['hash']
block = node.getblock(blockhash=hash, verbose=2) block = node.getblock(blockhash=hash, verbose=2)
assert_equal(len(block['tx']), 1) assert_equal(len(block['tx']), 1)