diff options
Diffstat (limited to 'src/rpc/misc.cpp')
-rw-r--r-- | src/rpc/misc.cpp | 75 |
1 files changed, 48 insertions, 27 deletions
diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 39bd9c6091..0e33bd6f28 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2020 The Bitcoin Core developers +// Copyright (c) 2009-2021 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -16,6 +16,7 @@ #include <outputtype.h> #include <rpc/blockchain.h> #include <rpc/server.h> +#include <rpc/server_util.h> #include <rpc/util.h> #include <scheduler.h> #include <script/descriptor.h> @@ -36,32 +37,38 @@ static RPCHelpMan validateaddress() { - return RPCHelpMan{"validateaddress", - "\nReturn information about the given bitcoin address.\n", - { - {"address", RPCArg::Type::STR, RPCArg::Optional::NO, "The bitcoin address to validate"}, - }, - RPCResult{ - RPCResult::Type::OBJ, "", "", + return RPCHelpMan{ + "validateaddress", + "\nReturn information about the given bitcoin address.\n", + { + {"address", RPCArg::Type::STR, RPCArg::Optional::NO, "The bitcoin address to validate"}, + }, + RPCResult{ + RPCResult::Type::OBJ, "", "", + { + {RPCResult::Type::BOOL, "isvalid", "If the address is valid or not"}, + {RPCResult::Type::STR, "address", /*optional=*/true, "The bitcoin address validated"}, + {RPCResult::Type::STR_HEX, "scriptPubKey", /*optional=*/true, "The hex-encoded scriptPubKey generated by the address"}, + {RPCResult::Type::BOOL, "isscript", /*optional=*/true, "If the key is a script"}, + {RPCResult::Type::BOOL, "iswitness", /*optional=*/true, "If the address is a witness address"}, + {RPCResult::Type::NUM, "witness_version", /*optional=*/true, "The version number of the witness program"}, + {RPCResult::Type::STR_HEX, "witness_program", /*optional=*/true, "The hex value of the witness program"}, + {RPCResult::Type::STR, "error", /*optional=*/true, "Error message, if any"}, + {RPCResult::Type::ARR, "error_locations", /*optional=*/true, "Indices of likely error locations in address, if known (e.g. Bech32 errors)", { - {RPCResult::Type::BOOL, "isvalid", "If the address is valid or not"}, - {RPCResult::Type::STR, "address", /* optional */ true, "The bitcoin address validated"}, - {RPCResult::Type::STR_HEX, "scriptPubKey", /* optional */ true, "The hex-encoded scriptPubKey generated by the address"}, - {RPCResult::Type::BOOL, "isscript", /* optional */ true, "If the key is a script"}, - {RPCResult::Type::BOOL, "iswitness", /* optional */ true, "If the address is a witness address"}, - {RPCResult::Type::NUM, "witness_version", /* optional */ true, "The version number of the witness program"}, - {RPCResult::Type::STR_HEX, "witness_program", /* optional */ true, "The hex value of the witness program"}, - {RPCResult::Type::STR, "error", /* optional */ true, "Error message, if any"}, - } - }, - RPCExamples{ - HelpExampleCli("validateaddress", "\"" + EXAMPLE_ADDRESS[0] + "\"") + - HelpExampleRpc("validateaddress", "\"" + EXAMPLE_ADDRESS[0] + "\"") - }, + {RPCResult::Type::NUM, "index", "index of a potential error"}, + }}, + } + }, + RPCExamples{ + HelpExampleCli("validateaddress", "\"" + EXAMPLE_ADDRESS[0] + "\"") + + HelpExampleRpc("validateaddress", "\"" + EXAMPLE_ADDRESS[0] + "\"") + }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { std::string error_msg; - CTxDestination dest = DecodeDestination(request.params[0].get_str(), error_msg); + std::vector<int> error_locations; + CTxDestination dest = DecodeDestination(request.params[0].get_str(), error_msg, &error_locations); const bool isValid = IsValidDestination(dest); CHECK_NONFATAL(isValid == error_msg.empty()); @@ -77,6 +84,9 @@ static RPCHelpMan validateaddress() UniValue detail = DescribeAddress(dest); ret.pushKVs(detail); } else { + UniValue error_indices(UniValue::VARR); + for (int i : error_locations) error_indices.push_back(i); + ret.pushKV("error_locations", error_indices); ret.pushKV("error", error_msg); } @@ -104,6 +114,10 @@ static RPCHelpMan createmultisig() {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, "descriptor", "The descriptor for this multisig"}, + {RPCResult::Type::ARR, "warnings", /* optional */ true, "Any warnings resulting from the creation of this multisig", + { + {RPCResult::Type::STR, "", ""}, + }}, } }, RPCExamples{ @@ -152,6 +166,13 @@ static RPCHelpMan createmultisig() result.pushKV("redeemScript", HexStr(inner)); result.pushKV("descriptor", descriptor->ToString()); + UniValue warnings(UniValue::VARR); + if (!request.params[2].isNull() && OutputTypeFromDestination(dest) != output_type) { + // Only warns if the user has explicitly chosen an address type we cannot generate + warnings.push_back("Unable to make chosen address type, please ensure no uncompressed public keys are present."); + } + if (warnings.size()) result.pushKV("warnings", warnings); + return result; }, }; @@ -265,13 +286,13 @@ static RPCHelpMan deriveaddresses() FlatSigningProvider provider; std::vector<CScript> scripts; if (!desc->Expand(i, key_provider, scripts, provider)) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Cannot derive script without private keys")); + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Cannot derive script without private keys"); } for (const CScript &script : scripts) { CTxDestination dest; if (!ExtractDestination(script, dest)) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Descriptor does not have a corresponding address")); + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Descriptor does not have a corresponding address"); } addresses.push_back(EncodeDestination(dest)); @@ -291,7 +312,7 @@ static RPCHelpMan deriveaddresses() static RPCHelpMan verifymessage() { return RPCHelpMan{"verifymessage", - "\nVerify a signed message\n", + "Verify a signed message.", { {"address", RPCArg::Type::STR, RPCArg::Optional::NO, "The bitcoin address to use for the signature."}, {"signature", RPCArg::Type::STR, RPCArg::Optional::NO, "The signature provided by the signer in base 64 encoding (see signmessage)."}, @@ -550,7 +571,7 @@ static RPCHelpMan getmemoryinfo() #ifdef HAVE_MALLOC_INFO return RPCMallocInfo(); #else - throw JSONRPCError(RPC_INVALID_PARAMETER, "mallocinfo is only available when compiled with glibc 2.10+"); + throw JSONRPCError(RPC_INVALID_PARAMETER, "mallocinfo mode not available"); #endif } else { throw JSONRPCError(RPC_INVALID_PARAMETER, "unknown mode " + mode); |