mirror of
https://github.com/dashpay/dash.git
synced 2024-12-25 03:52:49 +01:00
Merge #18032: rpc: Output a descriptor in createmultisig and addmultisigaddress
19a354b11f85a3c6c81ff83bf702bf7a40cf5046 Output a descriptor in createmultisig and addmultisigaddress (Andrew Chow) Pull request description: Give a descriptor from `createmultisig` and `addmultisigaddress`. Extracted from #16528 with `addmultisgaddress` and tests added. ACKs for top commit: Sjors: tACK 19a354b11f85a3c6c81ff83bf702bf7a40cf5046 MarcoFalke: ACK 19a354b11f85a3c6c81ff83bf702bf7a40cf5046 promag: Code review ACK 19a354b11f85a3c6c81ff83bf702bf7a40cf5046. meshcollider: utACK 19a354b11f85a3c6c81ff83bf702bf7a40cf5046 Tree-SHA512: e813125fbbc358ea8d45b1748de16a29a94efd83175b748fb8fa3b0bfc8e783ed36b6c554d84f5d4ead1ba252a83a3e937b6c3f75da7b8d3b4e55f94d6013771
This commit is contained in:
parent
be3b359fa3
commit
dceee33ebe
@ -17,6 +17,7 @@ Supporting RPCs are:
|
|||||||
(`regtest` only, since v0.19).
|
(`regtest` only, since v0.19).
|
||||||
- `utxoupdatepsbt` takes as input descriptors to add information to the psbt
|
- `utxoupdatepsbt` takes as input descriptors to add information to the psbt
|
||||||
(since v0.19).
|
(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
|
This document describes the language. For the specifics on usage, see the RPC
|
||||||
documentation for the functions mentioned above.
|
documentation for the functions mentioned above.
|
||||||
|
@ -255,6 +255,7 @@ static UniValue createmultisig(const JSONRPCRequest& request)
|
|||||||
{
|
{
|
||||||
{RPCResult::Type::STR, "address", "The value of the new multisig address."},
|
{RPCResult::Type::STR, "address", "The value of the new multisig address."},
|
||||||
{RPCResult::Type::STR_HEX, "redeemScript", "The string value of the hex-encoded redemption script."},
|
{RPCResult::Type::STR_HEX, "redeemScript", "The string value of the hex-encoded redemption script."},
|
||||||
|
{RPCResult::Type::STR, "descriptor", "The descriptor for this multisig."},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
RPCExamples{
|
RPCExamples{
|
||||||
@ -283,9 +284,13 @@ static UniValue createmultisig(const JSONRPCRequest& request)
|
|||||||
CScript inner;
|
CScript inner;
|
||||||
const CTxDestination dest = AddAndGetMultisigDestination(required, pubkeys, keystore, inner);
|
const CTxDestination dest = AddAndGetMultisigDestination(required, pubkeys, keystore, inner);
|
||||||
|
|
||||||
|
// Make the descriptor
|
||||||
|
std::unique_ptr<Descriptor> descriptor = InferDescriptor(GetScriptForDestination(dest), keystore);
|
||||||
|
|
||||||
UniValue result(UniValue::VOBJ);
|
UniValue result(UniValue::VOBJ);
|
||||||
result.pushKV("address", EncodeDestination(dest));
|
result.pushKV("address", EncodeDestination(dest));
|
||||||
result.pushKV("redeemScript", HexStr(inner));
|
result.pushKV("redeemScript", HexStr(inner));
|
||||||
|
result.pushKV("descriptor", descriptor->ToString());
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -980,6 +980,7 @@ UniValue addmultisigaddress(const JSONRPCRequest& request)
|
|||||||
{
|
{
|
||||||
{RPCResult::Type::STR, "address", "The value of the new multisig address"},
|
{RPCResult::Type::STR, "address", "The value of the new multisig address"},
|
||||||
{RPCResult::Type::STR_HEX, "redeemScript", "The string value of the hex-encoded redemption script"},
|
{RPCResult::Type::STR_HEX, "redeemScript", "The string value of the hex-encoded redemption script"},
|
||||||
|
{RPCResult::Type::STR, "descriptor", "The descriptor for this multisig."},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
RPCExamples{
|
RPCExamples{
|
||||||
@ -1020,9 +1021,13 @@ UniValue addmultisigaddress(const JSONRPCRequest& request)
|
|||||||
CTxDestination dest = AddAndGetMultisigDestination(required, pubkeys, spk_man, inner);
|
CTxDestination dest = AddAndGetMultisigDestination(required, pubkeys, spk_man, inner);
|
||||||
pwallet->SetAddressBook(dest, label, "send");
|
pwallet->SetAddressBook(dest, label, "send");
|
||||||
|
|
||||||
|
// Make the descriptor
|
||||||
|
std::unique_ptr<Descriptor> descriptor = InferDescriptor(GetScriptForDestination(dest), spk_man);
|
||||||
|
|
||||||
UniValue result(UniValue::VOBJ);
|
UniValue result(UniValue::VOBJ);
|
||||||
result.pushKV("address", EncodeDestination(dest));
|
result.pushKV("address", EncodeDestination(dest));
|
||||||
result.pushKV("redeemScript", HexStr(inner));
|
result.pushKV("redeemScript", HexStr(inner));
|
||||||
|
result.pushKV("descriptor", descriptor->ToString());
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
"""Test multisig RPCs"""
|
"""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.test_framework import BitcoinTestFramework
|
||||||
from test_framework.util import (
|
from test_framework.util import (
|
||||||
assert_raises_rpc_error,
|
assert_raises_rpc_error,
|
||||||
@ -115,9 +115,20 @@ class RpcCreateMultiSigTest(BitcoinTestFramework):
|
|||||||
def do_multisig(self):
|
def do_multisig(self):
|
||||||
node0, node1, node2 = self.nodes
|
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)
|
msig = node2.createmultisig(self.nsigs, self.pub, self.output_type)
|
||||||
madd = msig["address"]
|
madd = msig["address"]
|
||||||
mredeem = msig["redeemScript"]
|
mredeem = msig["redeemScript"]
|
||||||
|
assert_equal(desc, msig['descriptor'])
|
||||||
if self.output_type == 'bech32':
|
if self.output_type == 'bech32':
|
||||||
assert madd[0:4] == "bcrt" # actually a bech32 address
|
assert madd[0:4] == "bcrt" # actually a bech32 address
|
||||||
|
|
||||||
@ -125,6 +136,7 @@ class RpcCreateMultiSigTest(BitcoinTestFramework):
|
|||||||
msigw = node1.addmultisigaddress(self.nsigs, self.pub, None, self.output_type)
|
msigw = node1.addmultisigaddress(self.nsigs, self.pub, None, self.output_type)
|
||||||
maddw = msigw["address"]
|
maddw = msigw["address"]
|
||||||
mredeemw = msigw["redeemScript"]
|
mredeemw = msigw["redeemScript"]
|
||||||
|
assert_equal(desc, drop_origins(msigw['descriptor']))
|
||||||
# addmultisigiaddress and createmultisig work the same
|
# addmultisigiaddress and createmultisig work the same
|
||||||
assert maddw == madd
|
assert maddw == madd
|
||||||
assert mredeemw == mredeem
|
assert mredeemw == mredeem
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
"""Utility functions related to output descriptors"""
|
"""Utility functions related to output descriptors"""
|
||||||
|
|
||||||
|
import re
|
||||||
|
|
||||||
INPUT_CHARSET = "0123456789()[],'/*abcdefgh@:$%{}IJKLMNOPQRSTUVWXYZ&+-.;<=>?!^_|~ijklmnopqrstuvwxyzABCDEFGH`#\"\\ "
|
INPUT_CHARSET = "0123456789()[],'/*abcdefgh@:$%{}IJKLMNOPQRSTUVWXYZ&+-.;<=>?!^_|~ijklmnopqrstuvwxyzABCDEFGH`#\"\\ "
|
||||||
CHECKSUM_CHARSET = "qpzry9x8gf2tvdw0s3jn54khce6mua7l"
|
CHECKSUM_CHARSET = "qpzry9x8gf2tvdw0s3jn54khce6mua7l"
|
||||||
GENERATOR = [0xf5dee51989, 0xa9fdca3312, 0x1bab10e32d, 0x3706b1677a, 0x644d626ffd]
|
GENERATOR = [0xf5dee51989, 0xa9fdca3312, 0x1bab10e32d, 0x3706b1677a, 0x644d626ffd]
|
||||||
@ -53,3 +55,10 @@ def descsum_check(s, require=True):
|
|||||||
return False
|
return False
|
||||||
symbols = descsum_expand(s[:-9]) + [CHECKSUM_CHARSET.find(x) for x in s[-8:]]
|
symbols = descsum_expand(s[:-9]) + [CHECKSUM_CHARSET.find(x) for x in s[-8:]]
|
||||||
return descsum_polymod(symbols) == 1
|
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)
|
||||||
|
Loading…
Reference in New Issue
Block a user