aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcoFalke <falke.marco@gmail.com>2019-09-23 14:27:23 -0400
committerMarcoFalke <falke.marco@gmail.com>2019-10-30 10:01:32 -0400
commitfa144e6fde1f546a952023af715032cb6789d948 (patch)
tree2eb7751e4cb149397fa436d95c9789c8c15989d7
parentecad0a8019fb9e8503ec92b6057a5e649866e25e (diff)
downloadbitcoin-fa144e6fde1f546a952023af715032cb6789d948.tar.xz
rpc: Add generatetodescriptor
-rw-r--r--src/rpc/client.cpp2
-rw-r--r--src/rpc/mining.cpp44
-rwxr-xr-xtest/functional/rpc_invalidateblock.py6
-rw-r--r--test/functional/test_framework/address.py1
4 files changed, 50 insertions, 3 deletions
diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp
index 32e18312e1..dfca1697c1 100644
--- a/src/rpc/client.cpp
+++ b/src/rpc/client.cpp
@@ -30,6 +30,8 @@ static const CRPCConvertParam vRPCConvertParams[] =
{ "utxoupdatepsbt", 1, "descriptors" },
{ "generatetoaddress", 0, "nblocks" },
{ "generatetoaddress", 2, "maxtries" },
+ { "generatetodescriptor", 0, "num_blocks" },
+ { "generatetodescriptor", 2, "maxtries" },
{ "getnetworkhashps", 0, "nblocks" },
{ "getnetworkhashps", 1, "height" },
{ "sendtoaddress", 1, "amount" },
diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp
index 07c2958635..9020a616e3 100644
--- a/src/rpc/mining.cpp
+++ b/src/rpc/mining.cpp
@@ -18,7 +18,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>
@@ -140,6 +142,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",
@@ -961,6 +1004,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"} },
diff --git a/test/functional/rpc_invalidateblock.py b/test/functional/rpc_invalidateblock.py
index 595b40f7cb..1fdc134f97 100755
--- a/test/functional/rpc_invalidateblock.py
+++ b/test/functional/rpc_invalidateblock.py
@@ -5,7 +5,7 @@
"""Test the invalidateblock RPC."""
from test_framework.test_framework import BitcoinTestFramework
-from test_framework.address import ADDRESS_BCRT1_UNSPENDABLE
+from test_framework.address import ADDRESS_BCRT1_UNSPENDABLE_DESCRIPTOR
from test_framework.util import (
assert_equal,
connect_nodes,
@@ -62,7 +62,7 @@ class InvalidateTest(BitcoinTestFramework):
wait_until(lambda: self.nodes[1].getblockcount() == 4, timeout=5)
self.log.info("Verify that we reconsider all ancestors as well")
- blocks = self.nodes[1].generatetoaddress(10, ADDRESS_BCRT1_UNSPENDABLE)
+ blocks = self.nodes[1].generatetodescriptor(10, ADDRESS_BCRT1_UNSPENDABLE_DESCRIPTOR)
assert_equal(self.nodes[1].getbestblockhash(), blocks[-1])
# Invalidate the two blocks at the tip
self.nodes[1].invalidateblock(blocks[-1])
@@ -74,7 +74,7 @@ class InvalidateTest(BitcoinTestFramework):
assert_equal(self.nodes[1].getbestblockhash(), blocks[-1])
self.log.info("Verify that we reconsider all descendants")
- blocks = self.nodes[1].generatetoaddress(10, ADDRESS_BCRT1_UNSPENDABLE)
+ blocks = self.nodes[1].generatetodescriptor(10, ADDRESS_BCRT1_UNSPENDABLE_DESCRIPTOR)
assert_equal(self.nodes[1].getbestblockhash(), blocks[-1])
# Invalidate the two blocks at the tip
self.nodes[1].invalidateblock(blocks[-2])
diff --git a/test/functional/test_framework/address.py b/test/functional/test_framework/address.py
index 194f2f061b..97585fe054 100644
--- a/test/functional/test_framework/address.py
+++ b/test/functional/test_framework/address.py
@@ -12,6 +12,7 @@ from .util import hex_str_to_bytes
from . import segwit_addr
ADDRESS_BCRT1_UNSPENDABLE = 'bcrt1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq3xueyj'
+ADDRESS_BCRT1_UNSPENDABLE_DESCRIPTOR = 'addr(bcrt1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq3xueyj)#juyq9d97'
class AddressType(enum.Enum):