aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Chow <achow101-github@achow101.com>2019-03-25 17:00:00 -0400
committerAndrew Chow <achow101-github@achow101.com>2020-01-30 23:55:36 -0500
commit19a354b11f85a3c6c81ff83bf702bf7a40cf5046 (patch)
tree92498c0bc6745e0eb18f2b41cbc5f7f0256f737a
parent3e1bf71064ccb98d0684753e844c80d6da421287 (diff)
downloadbitcoin-19a354b11f85a3c6c81ff83bf702bf7a40cf5046.tar.xz
Output a descriptor in createmultisig and addmultisigaddress
-rw-r--r--doc/descriptors.md1
-rw-r--r--src/rpc/misc.cpp5
-rw-r--r--src/wallet/rpcwallet.cpp5
-rwxr-xr-xtest/functional/rpc_createmultisig.py14
-rw-r--r--test/functional/test_framework/descriptors.py9
5 files changed, 33 insertions, 1 deletions
diff --git a/doc/descriptors.md b/doc/descriptors.md
index e31665b129..181ff77e50 100644
--- a/doc/descriptors.md
+++ b/doc/descriptors.md
@@ -17,6 +17,7 @@ Supporting RPCs are:
(`regtest` only, since v0.19).
- `utxoupdatepsbt` takes as input descriptors to add information to the psbt
(since v0.19).
+- `createmultisig` and `addmultisigaddress` return descriptors as well (since v0.20)
This document describes the language. For the specifics on usage, see the RPC
documentation for the functions mentioned above.
diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp
index 56bd33b0ec..f360cb7525 100644
--- a/src/rpc/misc.cpp
+++ b/src/rpc/misc.cpp
@@ -83,6 +83,7 @@ static UniValue createmultisig(const JSONRPCRequest& request)
"{\n"
" \"address\":\"multisigaddress\", (string) The value of the new multisig address.\n"
" \"redeemScript\":\"script\" (string) The string value of the hex-encoded redemption script.\n"
+ " \"descriptor\":\"descriptor\" (string) The descriptor for this multisig\n"
"}\n"
},
RPCExamples{
@@ -119,9 +120,13 @@ static UniValue createmultisig(const JSONRPCRequest& request)
CScript inner;
const CTxDestination dest = AddAndGetMultisigDestination(required, pubkeys, output_type, keystore, inner);
+ // Make the descriptor
+ std::unique_ptr<Descriptor> descriptor = InferDescriptor(GetScriptForDestination(dest), keystore);
+
UniValue result(UniValue::VOBJ);
result.pushKV("address", EncodeDestination(dest));
result.pushKV("redeemScript", HexStr(inner.begin(), inner.end()));
+ result.pushKV("descriptor", descriptor->ToString());
return result;
}
diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp
index df71f97e85..36f1110f2a 100644
--- a/src/wallet/rpcwallet.cpp
+++ b/src/wallet/rpcwallet.cpp
@@ -974,6 +974,7 @@ static UniValue addmultisigaddress(const JSONRPCRequest& request)
"{\n"
" \"address\":\"multisigaddress\", (string) The value of the new multisig address.\n"
" \"redeemScript\":\"script\" (string) The string value of the hex-encoded redemption script.\n"
+ " \"descriptor\":\"descriptor\" (string) The descriptor for this multisig\n"
"}\n"
},
RPCExamples{
@@ -1018,9 +1019,13 @@ static UniValue addmultisigaddress(const JSONRPCRequest& request)
CTxDestination dest = AddAndGetMultisigDestination(required, pubkeys, output_type, spk_man, inner);
pwallet->SetAddressBook(dest, label, "send");
+ // Make the descriptor
+ std::unique_ptr<Descriptor> descriptor = InferDescriptor(GetScriptForDestination(dest), spk_man);
+
UniValue result(UniValue::VOBJ);
result.pushKV("address", EncodeDestination(dest));
result.pushKV("redeemScript", HexStr(inner.begin(), inner.end()));
+ result.pushKV("descriptor", descriptor->ToString());
return result;
}
diff --git a/test/functional/rpc_createmultisig.py b/test/functional/rpc_createmultisig.py
index aa7f12848c..a983716177 100755
--- a/test/functional/rpc_createmultisig.py
+++ b/test/functional/rpc_createmultisig.py
@@ -4,7 +4,7 @@
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Test multisig RPCs"""
-from test_framework.descriptors import descsum_create
+from test_framework.descriptors import descsum_create, drop_origins
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import (
assert_raises_rpc_error,
@@ -116,9 +116,20 @@ class RpcCreateMultiSigTest(BitcoinTestFramework):
def do_multisig(self):
node0, node1, node2 = self.nodes
+ # Construct the expected descriptor
+ desc = 'multi({},{})'.format(self.nsigs, ','.join(self.pub))
+ if self.output_type == 'legacy':
+ desc = 'sh({})'.format(desc)
+ elif self.output_type == 'p2sh-segwit':
+ desc = 'sh(wsh({}))'.format(desc)
+ elif self.output_type == 'bech32':
+ desc = 'wsh({})'.format(desc)
+ desc = descsum_create(desc)
+
msig = node2.createmultisig(self.nsigs, self.pub, self.output_type)
madd = msig["address"]
mredeem = msig["redeemScript"]
+ assert_equal(desc, msig['descriptor'])
if self.output_type == 'bech32':
assert madd[0:4] == "bcrt" # actually a bech32 address
@@ -126,6 +137,7 @@ class RpcCreateMultiSigTest(BitcoinTestFramework):
msigw = node1.addmultisigaddress(self.nsigs, self.pub, None, self.output_type)
maddw = msigw["address"]
mredeemw = msigw["redeemScript"]
+ assert_equal(desc, drop_origins(msigw['descriptor']))
# addmultisigiaddress and createmultisig work the same
assert maddw == madd
assert mredeemw == mredeem
diff --git a/test/functional/test_framework/descriptors.py b/test/functional/test_framework/descriptors.py
index 29482ce01e..46b405749b 100644
--- a/test/functional/test_framework/descriptors.py
+++ b/test/functional/test_framework/descriptors.py
@@ -4,6 +4,8 @@
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Utility functions related to output descriptors"""
+import re
+
INPUT_CHARSET = "0123456789()[],'/*abcdefgh@:$%{}IJKLMNOPQRSTUVWXYZ&+-.;<=>?!^_|~ijklmnopqrstuvwxyzABCDEFGH`#\"\\ "
CHECKSUM_CHARSET = "qpzry9x8gf2tvdw0s3jn54khce6mua7l"
GENERATOR = [0xf5dee51989, 0xa9fdca3312, 0x1bab10e32d, 0x3706b1677a, 0x644d626ffd]
@@ -53,3 +55,10 @@ def descsum_check(s, require=True):
return False
symbols = descsum_expand(s[:-9]) + [CHECKSUM_CHARSET.find(x) for x in s[-8:]]
return descsum_polymod(symbols) == 1
+
+def drop_origins(s):
+ '''Drop the key origins from a descriptor'''
+ desc = re.sub(r'\[.+?\]', '', s)
+ if '#' in s:
+ desc = desc[:desc.index('#')]
+ return descsum_create(desc)