0
0
Fork 0
mirror of https://github.com/bitcoin/bitcoin.git synced 2025-03-04 13:55:23 -05:00

Merge bitcoin/bitcoin#23602: wallet: Split stuff from rpcwallet

fae239208d 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 fae239208d. Confirmed move only
  meshcollider:
    Code review ACK fae239208d

Tree-SHA512: 250445cd544e39376f225871270cdcae462f16cfd9d25ede4b148e915642bfac9ee7ef3e8eccdd2443dc74dbf794d3bcd5fe5c58b1d05a2dcec70b8e03b37dff
This commit is contained in:
MarcoFalke 2021-11-30 13:09:02 +01:00
commit ffdf8ee43e
No known key found for this signature in database
GPG key ID: CE2B75697E69A548
4 changed files with 73 additions and 59 deletions

View file

@ -409,6 +409,7 @@ libbitcoin_wallet_a_SOURCES = \
wallet/interfaces.cpp \ wallet/interfaces.cpp \
wallet/load.cpp \ wallet/load.cpp \
wallet/receive.cpp \ wallet/receive.cpp \
wallet/rpc/signmessage.cpp \
wallet/rpcdump.cpp \ wallet/rpcdump.cpp \
wallet/rpcwallet.cpp \ wallet/rpcwallet.cpp \
wallet/scriptpubkeyman.cpp \ wallet/scriptpubkeyman.cpp \

View file

@ -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;
},
};
}

View file

@ -20,7 +20,6 @@
#include <script/sign.h> #include <script/sign.h>
#include <util/bip32.h> #include <util/bip32.h>
#include <util/fees.h> #include <util/fees.h>
#include <util/message.h> // For MessageSign()
#include <util/moneystr.h> #include <util/moneystr.h>
#include <util/string.h> #include <util/string.h>
#include <util/system.h> #include <util/system.h>
@ -48,7 +47,7 @@
using interfaces::FoundBlock; using interfaces::FoundBlock;
static const std::string WALLET_ENDPOINT_BASE = "/wallet/"; 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) { static inline bool GetAvoidReuseFlag(const CWallet& wallet, const UniValue& param) {
bool can_avoid_reuse = wallet.IsWalletFlagSet(WALLET_FLAG_AVOID_REUSE); 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) static CAmount GetReceived(const CWallet& wallet, const UniValue& params, bool by_label) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet)
{ {
std::set<CTxDestination> address_set; std::set<CTxDestination> address_set;
@ -4862,6 +4804,7 @@ RPCHelpMan removeprunedfunds();
RPCHelpMan importmulti(); RPCHelpMan importmulti();
RPCHelpMan importdescriptors(); RPCHelpMan importdescriptors();
RPCHelpMan listdescriptors(); RPCHelpMan listdescriptors();
RPCHelpMan signmessage();
Span<const CRPCCommand> GetWalletRPCCommands() Span<const CRPCCommand> GetWalletRPCCommands()
{ {

View file

@ -21,6 +21,8 @@ class CTransaction;
struct PartiallySignedTransaction; struct PartiallySignedTransaction;
struct WalletContext; struct WalletContext;
extern const std::string HELP_REQUIRING_PASSPHRASE;
Span<const CRPCCommand> GetWalletRPCCommands(); Span<const CRPCCommand> GetWalletRPCCommands();
/** /**