Skip to content

Commit ffdf8ee

Browse files
author
MarcoFalke
committed
Merge bitcoin/bitcoin#23602: wallet: Split stuff from rpcwallet
fae2392 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 fae2392. Confirmed move only meshcollider: Code review ACK fae2392 Tree-SHA512: 250445cd544e39376f225871270cdcae462f16cfd9d25ede4b148e915642bfac9ee7ef3e8eccdd2443dc74dbf794d3bcd5fe5c58b1d05a2dcec70b8e03b37dff
2 parents 29074ba + fae2392 commit ffdf8ee

File tree

4 files changed

+73
-59
lines changed

4 files changed

+73
-59
lines changed

src/Makefile.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,7 @@ libbitcoin_wallet_a_SOURCES = \
409409
wallet/interfaces.cpp \
410410
wallet/load.cpp \
411411
wallet/receive.cpp \
412+
wallet/rpc/signmessage.cpp \
412413
wallet/rpcdump.cpp \
413414
wallet/rpcwallet.cpp \
414415
wallet/scriptpubkeyman.cpp \

src/wallet/rpc/signmessage.cpp

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// Copyright (c) 2011-2021 The Bitcoin Core developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
#include <key_io.h>
6+
#include <rpc/util.h>
7+
#include <util/message.h>
8+
#include <wallet/rpcwallet.h>
9+
#include <wallet/wallet.h>
10+
11+
#include <univalue.h>
12+
13+
RPCHelpMan signmessage()
14+
{
15+
return RPCHelpMan{"signmessage",
16+
"\nSign a message with the private key of an address" +
17+
HELP_REQUIRING_PASSPHRASE,
18+
{
19+
{"address", RPCArg::Type::STR, RPCArg::Optional::NO, "The bitcoin address to use for the private key."},
20+
{"message", RPCArg::Type::STR, RPCArg::Optional::NO, "The message to create a signature of."},
21+
},
22+
RPCResult{
23+
RPCResult::Type::STR, "signature", "The signature of the message encoded in base 64"
24+
},
25+
RPCExamples{
26+
"\nUnlock the wallet for 30 seconds\n"
27+
+ HelpExampleCli("walletpassphrase", "\"mypassphrase\" 30") +
28+
"\nCreate the signature\n"
29+
+ HelpExampleCli("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"my message\"") +
30+
"\nVerify the signature\n"
31+
+ HelpExampleCli("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"signature\" \"my message\"") +
32+
"\nAs a JSON-RPC call\n"
33+
+ HelpExampleRpc("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\", \"my message\"")
34+
},
35+
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
36+
{
37+
const std::shared_ptr<const CWallet> pwallet = GetWalletForJSONRPCRequest(request);
38+
if (!pwallet) return NullUniValue;
39+
40+
LOCK(pwallet->cs_wallet);
41+
42+
EnsureWalletIsUnlocked(*pwallet);
43+
44+
std::string strAddress = request.params[0].get_str();
45+
std::string strMessage = request.params[1].get_str();
46+
47+
CTxDestination dest = DecodeDestination(strAddress);
48+
if (!IsValidDestination(dest)) {
49+
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address");
50+
}
51+
52+
const PKHash* pkhash = std::get_if<PKHash>(&dest);
53+
if (!pkhash) {
54+
throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key");
55+
}
56+
57+
std::string signature;
58+
SigningResult err = pwallet->SignMessage(strMessage, *pkhash, signature);
59+
if (err == SigningResult::SIGNING_FAILED) {
60+
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, SigningResultString(err));
61+
} else if (err != SigningResult::OK) {
62+
throw JSONRPCError(RPC_WALLET_ERROR, SigningResultString(err));
63+
}
64+
65+
return signature;
66+
},
67+
};
68+
}

src/wallet/rpcwallet.cpp

Lines changed: 2 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
#include <script/sign.h>
2121
#include <util/bip32.h>
2222
#include <util/fees.h>
23-
#include <util/message.h> // For MessageSign()
2423
#include <util/moneystr.h>
2524
#include <util/string.h>
2625
#include <util/system.h>
@@ -48,7 +47,7 @@
4847
using interfaces::FoundBlock;
4948

5049
static const std::string WALLET_ENDPOINT_BASE = "/wallet/";
51-
static const std::string HELP_REQUIRING_PASSPHRASE{"\nRequires wallet passphrase to be set with walletpassphrase call if wallet is encrypted.\n"};
50+
const std::string HELP_REQUIRING_PASSPHRASE{"\nRequires wallet passphrase to be set with walletpassphrase call if wallet is encrypted.\n"};
5251

5352
static inline bool GetAvoidReuseFlag(const CWallet& wallet, const UniValue& param) {
5453
bool can_avoid_reuse = wallet.IsWalletFlagSet(WALLET_FLAG_AVOID_REUSE);
@@ -612,63 +611,6 @@ static RPCHelpMan listaddressgroupings()
612611
};
613612
}
614613

615-
static RPCHelpMan signmessage()
616-
{
617-
return RPCHelpMan{"signmessage",
618-
"\nSign a message with the private key of an address" +
619-
HELP_REQUIRING_PASSPHRASE,
620-
{
621-
{"address", RPCArg::Type::STR, RPCArg::Optional::NO, "The bitcoin address to use for the private key."},
622-
{"message", RPCArg::Type::STR, RPCArg::Optional::NO, "The message to create a signature of."},
623-
},
624-
RPCResult{
625-
RPCResult::Type::STR, "signature", "The signature of the message encoded in base 64"
626-
},
627-
RPCExamples{
628-
"\nUnlock the wallet for 30 seconds\n"
629-
+ HelpExampleCli("walletpassphrase", "\"mypassphrase\" 30") +
630-
"\nCreate the signature\n"
631-
+ HelpExampleCli("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"my message\"") +
632-
"\nVerify the signature\n"
633-
+ HelpExampleCli("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"signature\" \"my message\"") +
634-
"\nAs a JSON-RPC call\n"
635-
+ HelpExampleRpc("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\", \"my message\"")
636-
},
637-
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
638-
{
639-
const std::shared_ptr<const CWallet> pwallet = GetWalletForJSONRPCRequest(request);
640-
if (!pwallet) return NullUniValue;
641-
642-
LOCK(pwallet->cs_wallet);
643-
644-
EnsureWalletIsUnlocked(*pwallet);
645-
646-
std::string strAddress = request.params[0].get_str();
647-
std::string strMessage = request.params[1].get_str();
648-
649-
CTxDestination dest = DecodeDestination(strAddress);
650-
if (!IsValidDestination(dest)) {
651-
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address");
652-
}
653-
654-
const PKHash* pkhash = std::get_if<PKHash>(&dest);
655-
if (!pkhash) {
656-
throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key");
657-
}
658-
659-
std::string signature;
660-
SigningResult err = pwallet->SignMessage(strMessage, *pkhash, signature);
661-
if (err == SigningResult::SIGNING_FAILED) {
662-
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, SigningResultString(err));
663-
} else if (err != SigningResult::OK){
664-
throw JSONRPCError(RPC_WALLET_ERROR, SigningResultString(err));
665-
}
666-
667-
return signature;
668-
},
669-
};
670-
}
671-
672614
static CAmount GetReceived(const CWallet& wallet, const UniValue& params, bool by_label) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet)
673615
{
674616
std::set<CTxDestination> address_set;
@@ -4862,6 +4804,7 @@ RPCHelpMan removeprunedfunds();
48624804
RPCHelpMan importmulti();
48634805
RPCHelpMan importdescriptors();
48644806
RPCHelpMan listdescriptors();
4807+
RPCHelpMan signmessage();
48654808

48664809
Span<const CRPCCommand> GetWalletRPCCommands()
48674810
{

src/wallet/rpcwallet.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ class CTransaction;
2121
struct PartiallySignedTransaction;
2222
struct WalletContext;
2323

24+
extern const std::string HELP_REQUIRING_PASSPHRASE;
25+
2426
Span<const CRPCCommand> GetWalletRPCCommands();
2527

2628
/**

0 commit comments

Comments
 (0)