mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-06-09 06:09:48 +02:00
Merge #21467: Move external signer out of wallet module
88d4d5ff2frpc: add help for enumeratesigners and walletdisplayaddress (Sjors Provoost)b0db187e5bci: use --enable-external-signer instead of --with-boost-process (Sjors Provoost)b54b2e7b1aMove external signer out of wallet module (Sjors Provoost) Pull request description: In addition, this PR enables external signer testing on CI. This PR moves the ExternalSigner class and RPC methods out of the wallet module. The `enumeratesigners` RPC can be used without a wallet since #21417. With additional modifications external signers could be used without a wallet in general, e.g. via `signrawtransaction`. The `signerdisplayaddress` RPC is ranamed to `walletdisplayaddress` because it requires wallet context. A future `displayaddress` RPC call without wallet context could take a descriptor argument. This commit fixes a `rpc_help.py` failure when configured with `--disable-wallet`. ACKs for top commit: ryanofsky: Code review ACK88d4d5ff2ffanquake: ACK88d4d5ff2fTree-SHA512: 3242a24e22313aed97eee32a520bfcb1c17495ba32a2b8e06a5e151e2611320e2da5ef35b572d84623af0a49a210d2f9377a2531250868d1a0ccf3e144352a97
This commit is contained in:
@@ -144,6 +144,7 @@ BITCOIN_CORE_H = \
|
||||
core_memusage.h \
|
||||
cuckoocache.h \
|
||||
dbwrapper.h \
|
||||
external_signer.h \
|
||||
flatfile.h \
|
||||
fs.h \
|
||||
httprpc.h \
|
||||
@@ -267,13 +268,11 @@ BITCOIN_CORE_H = \
|
||||
wallet/crypter.h \
|
||||
wallet/db.h \
|
||||
wallet/dump.h \
|
||||
wallet/external_signer.h \
|
||||
wallet/external_signer_scriptpubkeyman.h \
|
||||
wallet/feebumper.h \
|
||||
wallet/fees.h \
|
||||
wallet/ismine.h \
|
||||
wallet/load.h \
|
||||
wallet/rpcsigner.h \
|
||||
wallet/rpcwallet.h \
|
||||
wallet/salvage.h \
|
||||
wallet/scriptpubkeyman.h \
|
||||
@@ -387,13 +386,11 @@ libbitcoin_wallet_a_SOURCES = \
|
||||
wallet/db.cpp \
|
||||
wallet/dump.cpp \
|
||||
wallet/external_signer_scriptpubkeyman.cpp \
|
||||
wallet/external_signer.cpp \
|
||||
wallet/feebumper.cpp \
|
||||
wallet/fees.cpp \
|
||||
wallet/interfaces.cpp \
|
||||
wallet/load.cpp \
|
||||
wallet/rpcdump.cpp \
|
||||
wallet/rpcsigner.cpp \
|
||||
wallet/rpcwallet.cpp \
|
||||
wallet/scriptpubkeyman.cpp \
|
||||
wallet/wallet.cpp \
|
||||
@@ -520,6 +517,7 @@ libbitcoin_common_a_SOURCES = \
|
||||
compressor.cpp \
|
||||
core_read.cpp \
|
||||
core_write.cpp \
|
||||
external_signer.cpp \
|
||||
key.cpp \
|
||||
key_io.cpp \
|
||||
merkleblock.cpp \
|
||||
@@ -532,6 +530,7 @@ libbitcoin_common_a_SOURCES = \
|
||||
protocol.cpp \
|
||||
psbt.cpp \
|
||||
rpc/rawtransaction_util.cpp \
|
||||
rpc/external_signer.cpp \
|
||||
rpc/util.cpp \
|
||||
scheduler.cpp \
|
||||
script/descriptor.cpp \
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#include <psbt.h>
|
||||
#include <util/strencodings.h>
|
||||
#include <util/system.h>
|
||||
#include <wallet/external_signer.h>
|
||||
#include <external_signer.h>
|
||||
|
||||
ExternalSigner::ExternalSigner(const std::string& command, const std::string& fingerprint, std::string chain, std::string name): m_command(command), m_fingerprint(fingerprint), m_chain(chain), m_name(name) {}
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef BITCOIN_WALLET_EXTERNAL_SIGNER_H
|
||||
#define BITCOIN_WALLET_EXTERNAL_SIGNER_H
|
||||
#ifndef BITCOIN_EXTERNAL_SIGNER_H
|
||||
#define BITCOIN_EXTERNAL_SIGNER_H
|
||||
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
@@ -48,7 +48,7 @@ public:
|
||||
//! @param[in] command the command which handles interaction with the external signer
|
||||
//! @param[in,out] signers vector to which new signers (with a unique master key fingerprint) are added
|
||||
//! @param chain "main", "test", "regtest" or "signet"
|
||||
//! @param[out] success Boolean
|
||||
//! @returns success
|
||||
static bool Enumerate(const std::string& command, std::vector<ExternalSigner>& signers, std::string chain, bool ignore_errors = false);
|
||||
|
||||
//! Display address on the device. Calls `<command> displayaddress --desc <descriptor>`.
|
||||
@@ -59,7 +59,7 @@ public:
|
||||
//! Get receive and change Descriptor(s) from device for a given account.
|
||||
//! Calls `<command> getdescriptors --account <account>`
|
||||
//! @param[in] account which BIP32 account to use (e.g. `m/44'/0'/account'`)
|
||||
//! @param[out] UniValue see doc/external-signer.md
|
||||
//! @returns see doc/external-signer.md
|
||||
UniValue GetDescriptors(int account);
|
||||
|
||||
//! Sign PartiallySignedTransaction on the device.
|
||||
@@ -70,4 +70,4 @@ public:
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // BITCOIN_WALLET_EXTERNAL_SIGNER_H
|
||||
#endif // BITCOIN_EXTERNAL_SIGNER_H
|
||||
@@ -3,20 +3,17 @@
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <chainparamsbase.h>
|
||||
#include <key_io.h>
|
||||
#include <external_signer.h>
|
||||
#include <rpc/server.h>
|
||||
#include <rpc/util.h>
|
||||
#include <util/strencodings.h>
|
||||
#include <wallet/rpcsigner.h>
|
||||
#include <wallet/rpcwallet.h>
|
||||
#include <wallet/wallet.h>
|
||||
#include <rpc/protocol.h>
|
||||
|
||||
#ifdef ENABLE_EXTERNAL_SIGNER
|
||||
|
||||
static RPCHelpMan enumeratesigners()
|
||||
{
|
||||
return RPCHelpMan{
|
||||
"enumeratesigners",
|
||||
return RPCHelpMan{"enumeratesigners",
|
||||
"Returns a list of external signers from -signer.",
|
||||
{},
|
||||
RPCResult{
|
||||
@@ -30,10 +27,14 @@ static RPCHelpMan enumeratesigners()
|
||||
}
|
||||
}
|
||||
},
|
||||
RPCExamples{""},
|
||||
[](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue {
|
||||
RPCExamples{
|
||||
HelpExampleCli("enumeratesigners", "")
|
||||
+ HelpExampleRpc("enumeratesigners", "")
|
||||
},
|
||||
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
||||
{
|
||||
const std::string command = gArgs.GetArg("-signer", "");
|
||||
if (command == "") throw JSONRPCError(RPC_WALLET_ERROR, "Error: restart bitcoind with -signer=<cmd>");
|
||||
if (command == "") throw JSONRPCError(RPC_MISC_ERROR, "Error: restart bitcoind with -signer=<cmd>");
|
||||
std::string chain = gArgs.GetChainName();
|
||||
UniValue signers_res = UniValue::VARR;
|
||||
try {
|
||||
@@ -46,7 +47,7 @@ static RPCHelpMan enumeratesigners()
|
||||
signers_res.push_back(signer_res);
|
||||
}
|
||||
} catch (const ExternalSignerException& e) {
|
||||
throw JSONRPCError(RPC_WALLET_ERROR, e.what());
|
||||
throw JSONRPCError(RPC_MISC_ERROR, e.what());
|
||||
}
|
||||
UniValue result(UniValue::VOBJ);
|
||||
result.pushKV("signers", signers_res);
|
||||
@@ -55,54 +56,18 @@ static RPCHelpMan enumeratesigners()
|
||||
};
|
||||
}
|
||||
|
||||
static RPCHelpMan signerdisplayaddress()
|
||||
void RegisterSignerRPCCommands(CRPCTable &t)
|
||||
{
|
||||
return RPCHelpMan{
|
||||
"signerdisplayaddress",
|
||||
"Display address on an external signer for verification.\n",
|
||||
{
|
||||
{"address", RPCArg::Type::STR, RPCArg::Optional::NO, /* default_val */ "", "bitcoin address to display"},
|
||||
},
|
||||
RPCResult{RPCResult::Type::NONE,"",""},
|
||||
RPCExamples{""},
|
||||
[](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue {
|
||||
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
|
||||
if (!wallet) return NullUniValue;
|
||||
CWallet* const pwallet = wallet.get();
|
||||
|
||||
LOCK(pwallet->cs_wallet);
|
||||
|
||||
CTxDestination dest = DecodeDestination(request.params[0].get_str());
|
||||
|
||||
// Make sure the destination is valid
|
||||
if (!IsValidDestination(dest)) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address");
|
||||
}
|
||||
|
||||
if (!pwallet->DisplayAddress(dest)) {
|
||||
throw JSONRPCError(RPC_WALLET_ERROR, "Failed to display address");
|
||||
}
|
||||
|
||||
UniValue result(UniValue::VOBJ);
|
||||
result.pushKV("address", request.params[0].get_str());
|
||||
return result;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Span<const CRPCCommand> GetSignerRPCCommands()
|
||||
{
|
||||
|
||||
// clang-format off
|
||||
static const CRPCCommand commands[] =
|
||||
{ // category actor (function)
|
||||
// --------------------- ------------------------
|
||||
{ "signer", &enumeratesigners, },
|
||||
{ "signer", &signerdisplayaddress, },
|
||||
};
|
||||
// clang-format on
|
||||
return MakeSpan(commands);
|
||||
for (const auto& c : commands) {
|
||||
t.appendCommand(c.name, &c);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif // ENABLE_EXTERNAL_SIGNER
|
||||
@@ -19,6 +19,8 @@ void RegisterMiscRPCCommands(CRPCTable &tableRPC);
|
||||
void RegisterMiningRPCCommands(CRPCTable &tableRPC);
|
||||
/** Register raw transaction RPC commands */
|
||||
void RegisterRawTransactionRPCCommands(CRPCTable &tableRPC);
|
||||
/** Register raw transaction RPC commands */
|
||||
void RegisterSignerRPCCommands(CRPCTable &tableRPC);
|
||||
|
||||
static inline void RegisterAllCoreRPCCommands(CRPCTable &t)
|
||||
{
|
||||
@@ -27,6 +29,9 @@ static inline void RegisterAllCoreRPCCommands(CRPCTable &t)
|
||||
RegisterMiscRPCCommands(t);
|
||||
RegisterMiningRPCCommands(t);
|
||||
RegisterRawTransactionRPCCommands(t);
|
||||
#ifdef ENABLE_EXTERNAL_SIGNER
|
||||
RegisterSignerRPCCommands(t);
|
||||
#endif // ENABLE_EXTERNAL_SIGNER
|
||||
}
|
||||
|
||||
#endif // BITCOIN_RPC_REGISTER_H
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <chainparams.h>
|
||||
#include <wallet/external_signer.h>
|
||||
#include <external_signer.h>
|
||||
#include <wallet/external_signer_scriptpubkeyman.h>
|
||||
|
||||
#ifdef ENABLE_EXTERNAL_SIGNER
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
#include <wallet/fees.h>
|
||||
#include <wallet/ismine.h>
|
||||
#include <wallet/load.h>
|
||||
#include <wallet/rpcsigner.h>
|
||||
#include <wallet/rpcwallet.h>
|
||||
#include <wallet/wallet.h>
|
||||
|
||||
@@ -520,17 +519,6 @@ public:
|
||||
}, command.argNames, command.unique_id);
|
||||
m_rpc_handlers.emplace_back(m_context.chain->handleRpc(m_rpc_commands.back()));
|
||||
}
|
||||
|
||||
#ifdef ENABLE_EXTERNAL_SIGNER
|
||||
for (const CRPCCommand& command : GetSignerRPCCommands()) {
|
||||
m_rpc_commands.emplace_back(command.category, command.name, [this, &command](const JSONRPCRequest& request, UniValue& result, bool last_handler) {
|
||||
JSONRPCRequest wallet_request = request;
|
||||
wallet_request.context = &m_context;
|
||||
return command.actor(wallet_request, result, last_handler);
|
||||
}, command.argNames, command.unique_id);
|
||||
m_rpc_handlers.emplace_back(m_context.chain->handleRpc(m_rpc_commands.back()));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
bool verify() override { return VerifyWallets(*m_context.chain); }
|
||||
bool load() override { return LoadWallets(*m_context.chain); }
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
// Copyright (c) 2018-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.
|
||||
|
||||
#ifndef BITCOIN_WALLET_RPCSIGNER_H
|
||||
#define BITCOIN_WALLET_RPCSIGNER_H
|
||||
|
||||
#include <span.h>
|
||||
#include <util/system.h>
|
||||
#include <vector>
|
||||
|
||||
#ifdef ENABLE_EXTERNAL_SIGNER
|
||||
|
||||
class CRPCCommand;
|
||||
|
||||
namespace interfaces {
|
||||
class Chain;
|
||||
class Handler;
|
||||
}
|
||||
|
||||
Span<const CRPCCommand> GetSignerRPCCommands();
|
||||
|
||||
#endif // ENABLE_EXTERNAL_SIGNER
|
||||
|
||||
#endif //BITCOIN_WALLET_RPCSIGNER_H
|
||||
@@ -4526,6 +4526,48 @@ static RPCHelpMan upgradewallet()
|
||||
};
|
||||
}
|
||||
|
||||
#ifdef ENABLE_EXTERNAL_SIGNER
|
||||
static RPCHelpMan walletdisplayaddress()
|
||||
{
|
||||
return RPCHelpMan{"walletdisplayaddress",
|
||||
"Display address on an external signer for verification.",
|
||||
{
|
||||
{"address", RPCArg::Type::STR, RPCArg::Optional::NO, /* default_val */ "", "bitcoin address to display"},
|
||||
},
|
||||
RPCResult{
|
||||
RPCResult::Type::OBJ,"","",
|
||||
{
|
||||
{RPCResult::Type::STR, "address", "The address as confirmed by the signer"},
|
||||
}
|
||||
},
|
||||
RPCExamples{""},
|
||||
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
||||
{
|
||||
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
|
||||
if (!wallet) return NullUniValue;
|
||||
CWallet* const pwallet = wallet.get();
|
||||
|
||||
LOCK(pwallet->cs_wallet);
|
||||
|
||||
CTxDestination dest = DecodeDestination(request.params[0].get_str());
|
||||
|
||||
// Make sure the destination is valid
|
||||
if (!IsValidDestination(dest)) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address");
|
||||
}
|
||||
|
||||
if (!pwallet->DisplayAddress(dest)) {
|
||||
throw JSONRPCError(RPC_MISC_ERROR, "Failed to display address");
|
||||
}
|
||||
|
||||
UniValue result(UniValue::VOBJ);
|
||||
result.pushKV("address", request.params[0].get_str());
|
||||
return result;
|
||||
}
|
||||
};
|
||||
}
|
||||
#endif // ENABLE_EXTERNAL_SIGNER
|
||||
|
||||
RPCHelpMan abortrescan();
|
||||
RPCHelpMan dumpprivkey();
|
||||
RPCHelpMan importprivkey();
|
||||
@@ -4602,6 +4644,9 @@ static const CRPCCommand commands[] =
|
||||
{ "wallet", &unloadwallet, },
|
||||
{ "wallet", &upgradewallet, },
|
||||
{ "wallet", &walletcreatefundedpsbt, },
|
||||
#ifdef ENABLE_EXTERNAL_SIGNER
|
||||
{ "wallet", &walletdisplayaddress, },
|
||||
#endif // ENABLE_EXTERNAL_SIGNER
|
||||
{ "wallet", &walletlock, },
|
||||
{ "wallet", &walletpassphrase, },
|
||||
{ "wallet", &walletpassphrasechange, },
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#include <util/system.h>
|
||||
#include <util/time.h>
|
||||
#include <util/translation.h>
|
||||
#include <wallet/external_signer.h>
|
||||
#include <external_signer.h>
|
||||
#include <wallet/scriptpubkeyman.h>
|
||||
|
||||
#include <optional>
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
#include <wallet/coinselection.h>
|
||||
#include <wallet/crypter.h>
|
||||
#include <wallet/scriptpubkeyman.h>
|
||||
#include <wallet/external_signer.h>
|
||||
#include <external_signer.h>
|
||||
#include <wallet/walletdb.h>
|
||||
#include <wallet/walletutil.h>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user