diff options
author | MarcoFalke <falke.marco@gmail.com> | 2021-11-30 13:09:02 +0100 |
---|---|---|
committer | MarcoFalke <falke.marco@gmail.com> | 2021-11-30 13:09:20 +0100 |
commit | ffdf8ee43e2440ab59b85846ab98854b17e49e49 (patch) | |
tree | 957e0568f0ef445e190524791fd8324366ce1021 | |
parent | 29074ba8364d4c0bf70121210222aff3fbf1e4df (diff) | |
parent | fae239208d3676452a755f736ee5aaa17adeb493 (diff) |
Merge bitcoin/bitcoin#23602: wallet: Split stuff from rpcwallet
fae239208d3676452a755f736ee5aaa17adeb493 wallet: Split signmessage from rpcwallet (MarcoFalke)
Pull request description:
rpcwallet is the file that takes longest to compile, especially with sanitizers enabled it can take several 10s of seconds.
Allow faster incremental and parallel builds by starting to split it up. First, split off `signmessage`, which is unrelated to other stuff such as wallet file handling, wallet encryption, tx creation, or wallet status/info.
ACKs for top commit:
ryanofsky:
Code review ACK fae239208d3676452a755f736ee5aaa17adeb493. Confirmed move only
meshcollider:
Code review ACK fae239208d3676452a755f736ee5aaa17adeb493
Tree-SHA512: 250445cd544e39376f225871270cdcae462f16cfd9d25ede4b148e915642bfac9ee7ef3e8eccdd2443dc74dbf794d3bcd5fe5c58b1d05a2dcec70b8e03b37dff
-rw-r--r-- | src/Makefile.am | 1 | ||||
-rw-r--r-- | src/wallet/rpc/signmessage.cpp | 68 | ||||
-rw-r--r-- | src/wallet/rpcwallet.cpp | 61 | ||||
-rw-r--r-- | src/wallet/rpcwallet.h | 2 |
4 files changed, 73 insertions, 59 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 9d79ee0e62..6846eb9693 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -409,6 +409,7 @@ libbitcoin_wallet_a_SOURCES = \ wallet/interfaces.cpp \ wallet/load.cpp \ wallet/receive.cpp \ + wallet/rpc/signmessage.cpp \ wallet/rpcdump.cpp \ wallet/rpcwallet.cpp \ wallet/scriptpubkeyman.cpp \ diff --git a/src/wallet/rpc/signmessage.cpp b/src/wallet/rpc/signmessage.cpp new file mode 100644 index 0000000000..275eb2f1f7 --- /dev/null +++ b/src/wallet/rpc/signmessage.cpp @@ -0,0 +1,68 @@ +// Copyright (c) 2011-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. + +#include <key_io.h> +#include <rpc/util.h> +#include <util/message.h> +#include <wallet/rpcwallet.h> +#include <wallet/wallet.h> + +#include <univalue.h> + +RPCHelpMan signmessage() +{ + return RPCHelpMan{"signmessage", + "\nSign a message with the private key of an address" + + HELP_REQUIRING_PASSPHRASE, + { + {"address", RPCArg::Type::STR, RPCArg::Optional::NO, "The bitcoin address to use for the private key."}, + {"message", RPCArg::Type::STR, RPCArg::Optional::NO, "The message to create a signature of."}, + }, + RPCResult{ + RPCResult::Type::STR, "signature", "The signature of the message encoded in base 64" + }, + RPCExamples{ + "\nUnlock the wallet for 30 seconds\n" + + HelpExampleCli("walletpassphrase", "\"mypassphrase\" 30") + + "\nCreate the signature\n" + + HelpExampleCli("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"my message\"") + + "\nVerify the signature\n" + + HelpExampleCli("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"signature\" \"my message\"") + + "\nAs a JSON-RPC call\n" + + HelpExampleRpc("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\", \"my message\"") + }, + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue + { + const std::shared_ptr<const CWallet> pwallet = GetWalletForJSONRPCRequest(request); + if (!pwallet) return NullUniValue; + + LOCK(pwallet->cs_wallet); + + EnsureWalletIsUnlocked(*pwallet); + + std::string strAddress = request.params[0].get_str(); + std::string strMessage = request.params[1].get_str(); + + CTxDestination dest = DecodeDestination(strAddress); + if (!IsValidDestination(dest)) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address"); + } + + const PKHash* pkhash = std::get_if<PKHash>(&dest); + if (!pkhash) { + throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key"); + } + + std::string signature; + SigningResult err = pwallet->SignMessage(strMessage, *pkhash, signature); + if (err == SigningResult::SIGNING_FAILED) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, SigningResultString(err)); + } else if (err != SigningResult::OK) { + throw JSONRPCError(RPC_WALLET_ERROR, SigningResultString(err)); + } + + return signature; + }, + }; +} diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index bb5b388791..beda86e4b4 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -20,7 +20,6 @@ #include <script/sign.h> #include <util/bip32.h> #include <util/fees.h> -#include <util/message.h> // For MessageSign() #include <util/moneystr.h> #include <util/string.h> #include <util/system.h> @@ -48,7 +47,7 @@ using interfaces::FoundBlock; static const std::string WALLET_ENDPOINT_BASE = "/wallet/"; -static const std::string HELP_REQUIRING_PASSPHRASE{"\nRequires wallet passphrase to be set with walletpassphrase call if wallet is encrypted.\n"}; +const std::string HELP_REQUIRING_PASSPHRASE{"\nRequires wallet passphrase to be set with walletpassphrase call if wallet is encrypted.\n"}; static inline bool GetAvoidReuseFlag(const CWallet& wallet, const UniValue& param) { bool can_avoid_reuse = wallet.IsWalletFlagSet(WALLET_FLAG_AVOID_REUSE); @@ -612,63 +611,6 @@ static RPCHelpMan listaddressgroupings() }; } -static RPCHelpMan signmessage() -{ - return RPCHelpMan{"signmessage", - "\nSign a message with the private key of an address" + - HELP_REQUIRING_PASSPHRASE, - { - {"address", RPCArg::Type::STR, RPCArg::Optional::NO, "The bitcoin address to use for the private key."}, - {"message", RPCArg::Type::STR, RPCArg::Optional::NO, "The message to create a signature of."}, - }, - RPCResult{ - RPCResult::Type::STR, "signature", "The signature of the message encoded in base 64" - }, - RPCExamples{ - "\nUnlock the wallet for 30 seconds\n" - + HelpExampleCli("walletpassphrase", "\"mypassphrase\" 30") + - "\nCreate the signature\n" - + HelpExampleCli("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"my message\"") + - "\nVerify the signature\n" - + HelpExampleCli("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"signature\" \"my message\"") + - "\nAs a JSON-RPC call\n" - + HelpExampleRpc("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\", \"my message\"") - }, - [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue -{ - const std::shared_ptr<const CWallet> pwallet = GetWalletForJSONRPCRequest(request); - if (!pwallet) return NullUniValue; - - LOCK(pwallet->cs_wallet); - - EnsureWalletIsUnlocked(*pwallet); - - std::string strAddress = request.params[0].get_str(); - std::string strMessage = request.params[1].get_str(); - - CTxDestination dest = DecodeDestination(strAddress); - if (!IsValidDestination(dest)) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address"); - } - - const PKHash* pkhash = std::get_if<PKHash>(&dest); - if (!pkhash) { - throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key"); - } - - std::string signature; - SigningResult err = pwallet->SignMessage(strMessage, *pkhash, signature); - if (err == SigningResult::SIGNING_FAILED) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, SigningResultString(err)); - } else if (err != SigningResult::OK){ - throw JSONRPCError(RPC_WALLET_ERROR, SigningResultString(err)); - } - - return signature; -}, - }; -} - static CAmount GetReceived(const CWallet& wallet, const UniValue& params, bool by_label) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet) { std::set<CTxDestination> address_set; @@ -4862,6 +4804,7 @@ RPCHelpMan removeprunedfunds(); RPCHelpMan importmulti(); RPCHelpMan importdescriptors(); RPCHelpMan listdescriptors(); +RPCHelpMan signmessage(); Span<const CRPCCommand> GetWalletRPCCommands() { diff --git a/src/wallet/rpcwallet.h b/src/wallet/rpcwallet.h index 40eb49cf87..fda685e9ee 100644 --- a/src/wallet/rpcwallet.h +++ b/src/wallet/rpcwallet.h @@ -21,6 +21,8 @@ class CTransaction; struct PartiallySignedTransaction; struct WalletContext; +extern const std::string HELP_REQUIRING_PASSPHRASE; + Span<const CRPCCommand> GetWalletRPCCommands(); /** |