Merge #16943: test: Add generatetodescriptor RPC

fa144e6fde rpc: Add generatetodescriptor (MarcoFalke)

Pull request description:

  The existing `generatetoaddress` RPC can only generate to scriptPubKeys that can be represented by an address. However, raw scripts (such as `OP_TRUE`) or P2PK can not be represented by an address, which complicates testing.

ACKs for top commit:
  laanwj:
    ACK fa144e6fde

Tree-SHA512: aee934ab7e33f07c81f3b4c8ec23e7b6ddf63a1f4b86051af0bd76b75d8da1f51627cc682e5c6e42582340ca576bbf8ff724bdd43f87128ccecfa91e52d30ae7
This commit is contained in:
Wladimir J. van der Laan
2019-10-30 15:22:47 +01:00
4 changed files with 50 additions and 3 deletions

View File

@@ -19,7 +19,9 @@
#include <rpc/blockchain.h>
#include <rpc/server.h>
#include <rpc/util.h>
#include <script/descriptor.h>
#include <script/script.h>
#include <script/signingprovider.h>
#include <shutdown.h>
#include <txmempool.h>
#include <univalue.h>
@@ -141,6 +143,47 @@ static UniValue generateBlocks(const CScript& coinbase_script, int nGenerate, ui
return blockHashes;
}
static UniValue generatetodescriptor(const JSONRPCRequest& request)
{
RPCHelpMan{
"generatetodescriptor",
"\nMine blocks immediately to a specified descriptor (before the RPC call returns)\n",
{
{"num_blocks", RPCArg::Type::NUM, RPCArg::Optional::NO, "How many blocks are generated immediately."},
{"descriptor", RPCArg::Type::STR, RPCArg::Optional::NO, "The descriptor to send the newly generated bitcoin to."},
{"maxtries", RPCArg::Type::NUM, /* default */ "1000000", "How many iterations to try."},
},
RPCResult{
"[ blockhashes ] (array) hashes of blocks generated\n"},
RPCExamples{
"\nGenerate 11 blocks to mydesc\n" + HelpExampleCli("generatetodescriptor", "11 \"mydesc\"")},
}
.Check(request);
const int num_blocks{request.params[0].get_int()};
const int64_t max_tries{request.params[2].isNull() ? 1000000 : request.params[2].get_int()};
FlatSigningProvider key_provider;
std::string error;
const auto desc = Parse(request.params[1].get_str(), key_provider, error, /* require_checksum = */ false);
if (!desc) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, error);
}
if (desc->IsRange()) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "Ranged descriptor not accepted. Maybe pass through deriveaddresses first?");
}
FlatSigningProvider provider;
std::vector<CScript> coinbase_script;
if (!desc->Expand(0, key_provider, coinbase_script, provider)) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Cannot derive script without private keys"));
}
CHECK_NONFATAL(coinbase_script.size() == 1);
return generateBlocks(coinbase_script.at(0), num_blocks, max_tries);
}
static UniValue generatetoaddress(const JSONRPCRequest& request)
{
RPCHelpMan{"generatetoaddress",
@@ -962,6 +1005,7 @@ static const CRPCCommand commands[] =
{ "generating", "generatetoaddress", &generatetoaddress, {"nblocks","address","maxtries"} },
{ "generating", "generatetodescriptor", &generatetodescriptor, {"num_blocks","descriptor","maxtries"} },
{ "util", "estimatesmartfee", &estimatesmartfee, {"conf_target", "estimate_mode"} },