|
19 | 19 | #include <rpc/blockchain.h>
|
20 | 20 | #include <rpc/server.h>
|
21 | 21 | #include <rpc/util.h>
|
| 22 | +#include <script/descriptor.h> |
22 | 23 | #include <script/script.h>
|
| 24 | +#include <script/signingprovider.h> |
23 | 25 | #include <shutdown.h>
|
24 | 26 | #include <txmempool.h>
|
25 | 27 | #include <univalue.h>
|
@@ -141,6 +143,47 @@ static UniValue generateBlocks(const CScript& coinbase_script, int nGenerate, ui
|
141 | 143 | return blockHashes;
|
142 | 144 | }
|
143 | 145 |
|
| 146 | +static UniValue generatetodescriptor(const JSONRPCRequest& request) |
| 147 | +{ |
| 148 | + RPCHelpMan{ |
| 149 | + "generatetodescriptor", |
| 150 | + "\nMine blocks immediately to a specified descriptor (before the RPC call returns)\n", |
| 151 | + { |
| 152 | + {"num_blocks", RPCArg::Type::NUM, RPCArg::Optional::NO, "How many blocks are generated immediately."}, |
| 153 | + {"descriptor", RPCArg::Type::STR, RPCArg::Optional::NO, "The descriptor to send the newly generated bitcoin to."}, |
| 154 | + {"maxtries", RPCArg::Type::NUM, /* default */ "1000000", "How many iterations to try."}, |
| 155 | + }, |
| 156 | + RPCResult{ |
| 157 | + "[ blockhashes ] (array) hashes of blocks generated\n"}, |
| 158 | + RPCExamples{ |
| 159 | + "\nGenerate 11 blocks to mydesc\n" + HelpExampleCli("generatetodescriptor", "11 \"mydesc\"")}, |
| 160 | + } |
| 161 | + .Check(request); |
| 162 | + |
| 163 | + const int num_blocks{request.params[0].get_int()}; |
| 164 | + const int64_t max_tries{request.params[2].isNull() ? 1000000 : request.params[2].get_int()}; |
| 165 | + |
| 166 | + FlatSigningProvider key_provider; |
| 167 | + std::string error; |
| 168 | + const auto desc = Parse(request.params[1].get_str(), key_provider, error, /* require_checksum = */ false); |
| 169 | + if (!desc) { |
| 170 | + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, error); |
| 171 | + } |
| 172 | + if (desc->IsRange()) { |
| 173 | + throw JSONRPCError(RPC_INVALID_PARAMETER, "Ranged descriptor not accepted. Maybe pass through deriveaddresses first?"); |
| 174 | + } |
| 175 | + |
| 176 | + FlatSigningProvider provider; |
| 177 | + std::vector<CScript> coinbase_script; |
| 178 | + if (!desc->Expand(0, key_provider, coinbase_script, provider)) { |
| 179 | + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Cannot derive script without private keys")); |
| 180 | + } |
| 181 | + |
| 182 | + CHECK_NONFATAL(coinbase_script.size() == 1); |
| 183 | + |
| 184 | + return generateBlocks(coinbase_script.at(0), num_blocks, max_tries); |
| 185 | +} |
| 186 | + |
144 | 187 | static UniValue generatetoaddress(const JSONRPCRequest& request)
|
145 | 188 | {
|
146 | 189 | RPCHelpMan{"generatetoaddress",
|
@@ -962,6 +1005,7 @@ static const CRPCCommand commands[] =
|
962 | 1005 |
|
963 | 1006 |
|
964 | 1007 | { "generating", "generatetoaddress", &generatetoaddress, {"nblocks","address","maxtries"} },
|
| 1008 | + { "generating", "generatetodescriptor", &generatetodescriptor, {"num_blocks","descriptor","maxtries"} }, |
965 | 1009 |
|
966 | 1010 | { "util", "estimatesmartfee", &estimatesmartfee, {"conf_target", "estimate_mode"} },
|
967 | 1011 |
|
|
0 commit comments