Add unmodified-but-with-checksum to getdescriptorinfo

This commit is contained in:
Pieter Wuille 2019-05-08 14:03:29 -07:00
parent 104b3a5069
commit 26d3fad109
4 changed files with 22 additions and 0 deletions

View file

@ -136,6 +136,7 @@ UniValue getdescriptorinfo(const JSONRPCRequest& request)
RPCResult{ RPCResult{
"{\n" "{\n"
" \"descriptor\" : \"desc\", (string) The descriptor in canonical form, without private keys\n" " \"descriptor\" : \"desc\", (string) The descriptor in canonical form, without private keys\n"
" \"checksum\" : \"chksum\", (string) The checksum for the input descriptor\n"
" \"isrange\" : true|false, (boolean) Whether the descriptor is ranged\n" " \"isrange\" : true|false, (boolean) Whether the descriptor is ranged\n"
" \"issolvable\" : true|false, (boolean) Whether the descriptor is solvable\n" " \"issolvable\" : true|false, (boolean) Whether the descriptor is solvable\n"
" \"hasprivatekeys\" : true|false, (boolean) Whether the input descriptor contained at least one private key\n" " \"hasprivatekeys\" : true|false, (boolean) Whether the input descriptor contained at least one private key\n"
@ -156,6 +157,7 @@ UniValue getdescriptorinfo(const JSONRPCRequest& request)
UniValue result(UniValue::VOBJ); UniValue result(UniValue::VOBJ);
result.pushKV("descriptor", desc->ToString()); result.pushKV("descriptor", desc->ToString());
result.pushKV("checksum", GetDescriptorChecksum(request.params[0].get_str()));
result.pushKV("isrange", desc->IsRange()); result.pushKV("isrange", desc->IsRange());
result.pushKV("issolvable", desc->IsSolvable()); result.pushKV("issolvable", desc->IsSolvable());
result.pushKV("hasprivatekeys", provider.keys.size() > 0); result.pushKV("hasprivatekeys", provider.keys.size() > 0);

View file

@ -938,6 +938,14 @@ std::unique_ptr<Descriptor> Parse(const std::string& descriptor, FlatSigningProv
return nullptr; return nullptr;
} }
std::string GetDescriptorChecksum(const std::string& descriptor)
{
std::string ret;
Span<const char> sp(descriptor.data(), descriptor.size());
if (!CheckChecksum(sp, false, &ret)) return "";
return ret;
}
std::unique_ptr<Descriptor> InferDescriptor(const CScript& script, const SigningProvider& provider) std::unique_ptr<Descriptor> InferDescriptor(const CScript& script, const SigningProvider& provider)
{ {
return InferScript(script, ParseScriptContext::TOP, provider); return InferScript(script, ParseScriptContext::TOP, provider);

View file

@ -81,6 +81,14 @@ struct Descriptor {
*/ */
std::unique_ptr<Descriptor> Parse(const std::string& descriptor, FlatSigningProvider& out, bool require_checksum = false); std::unique_ptr<Descriptor> Parse(const std::string& descriptor, FlatSigningProvider& out, bool require_checksum = false);
/** Get the checksum for a descriptor.
*
* If it already has one, and it is correct, return the checksum in the input.
* If it already has one that is wrong, return "".
* If it does not already have one, return the checksum that would need to be added.
*/
std::string GetDescriptorChecksum(const std::string& descriptor);
/** Find a descriptor for the specified script, using information from provider where possible. /** Find a descriptor for the specified script, using information from provider where possible.
* *
* A non-ranged descriptor which only generates the specified script will be returned in all * A non-ranged descriptor which only generates the specified script will be returned in all

View file

@ -175,6 +175,10 @@ class AddressTypeTest(BitcoinTestFramework):
assert info['desc'] == descsum_create(info['desc'][:-9]) assert info['desc'] == descsum_create(info['desc'][:-9])
# Verify that stripping the checksum and feeding it to getdescriptorinfo roundtrips # Verify that stripping the checksum and feeding it to getdescriptorinfo roundtrips
assert info['desc'] == self.nodes[0].getdescriptorinfo(info['desc'][:-9])['descriptor'] assert info['desc'] == self.nodes[0].getdescriptorinfo(info['desc'][:-9])['descriptor']
assert_equal(info['desc'][-8:], self.nodes[0].getdescriptorinfo(info['desc'][:-9])['checksum'])
# Verify that keeping the checksum and feeding it to getdescriptorinfo roundtrips
assert info['desc'] == self.nodes[0].getdescriptorinfo(info['desc'])['descriptor']
assert_equal(info['desc'][-8:], self.nodes[0].getdescriptorinfo(info['desc'])['checksum'])
if not multisig and typ == 'legacy': if not multisig and typ == 'legacy':
# P2PKH # P2PKH