0
0
Fork 0
mirror of https://github.com/bitcoin/bitcoin.git synced 2025-03-05 14:06:27 -05:00

multiprocess: add interfaces::ExternalSigner class

Add interfaces::ExternalSigner to let signer objects be passed between
processes and signer code to run in the original process, without
multiple processes linking and running signer code.
This commit is contained in:
Russell Yanofsky 2021-06-16 14:49:09 -04:00
parent 113b863f07
commit a032fa30d2
5 changed files with 41 additions and 12 deletions

View file

@ -6,7 +6,6 @@
#define BITCOIN_INTERFACES_NODE_H #define BITCOIN_INTERFACES_NODE_H
#include <consensus/amount.h> #include <consensus/amount.h>
#include <external_signer.h>
#include <net.h> // For NodeId #include <net.h> // For NodeId
#include <net_types.h> // For banmap_t #include <net_types.h> // For banmap_t
#include <netaddress.h> // For Network #include <netaddress.h> // For Network
@ -50,6 +49,16 @@ struct BlockAndHeaderTipInfo
double verification_progress; double verification_progress;
}; };
//! External signer interface used by the GUI.
class ExternalSigner
{
public:
virtual ~ExternalSigner() {};
//! Get signer display name
virtual std::string getName() = 0;
};
//! Top-level interface for a bitcoin node (bitcoind process). //! Top-level interface for a bitcoin node (bitcoind process).
class Node class Node
{ {
@ -111,8 +120,8 @@ public:
//! Disconnect node by id. //! Disconnect node by id.
virtual bool disconnectById(NodeId id) = 0; virtual bool disconnectById(NodeId id) = 0;
//! List external signers //! Return list of external signers (attached devices which can sign transactions).
virtual std::vector<ExternalSigner> externalSigners() = 0; virtual std::vector<std::unique_ptr<ExternalSigner>> listExternalSigners() = 0;
//! Get total bytes recv. //! Get total bytes recv.
virtual int64_t getTotalBytesRecv() = 0; virtual int64_t getTotalBytesRecv() = 0;

View file

@ -67,6 +67,17 @@ using interfaces::WalletClient;
namespace node { namespace node {
namespace { namespace {
#ifdef ENABLE_EXTERNAL_SIGNER
class ExternalSignerImpl : public interfaces::ExternalSigner
{
public:
ExternalSignerImpl(::ExternalSigner signer) : m_signer(std::move(signer)) {}
std::string getName() override { return m_signer.m_name; }
private:
::ExternalSigner m_signer;
};
#endif
class NodeImpl : public Node class NodeImpl : public Node
{ {
private: private:
@ -172,14 +183,18 @@ public:
} }
return false; return false;
} }
std::vector<ExternalSigner> externalSigners() override std::vector<std::unique_ptr<interfaces::ExternalSigner>> listExternalSigners() override
{ {
#ifdef ENABLE_EXTERNAL_SIGNER #ifdef ENABLE_EXTERNAL_SIGNER
std::vector<ExternalSigner> signers = {}; std::vector<ExternalSigner> signers = {};
const std::string command = gArgs.GetArg("-signer", ""); const std::string command = gArgs.GetArg("-signer", "");
if (command == "") return signers; if (command == "") return {};
ExternalSigner::Enumerate(command, signers, Params().NetworkIDString()); ExternalSigner::Enumerate(command, signers, Params().NetworkIDString());
return signers; std::vector<std::unique_ptr<interfaces::ExternalSigner>> result;
for (auto& signer : signers) {
result.emplace_back(std::make_unique<ExternalSignerImpl>(std::move(signer)));
}
return result;
#else #else
// This result is indistinguishable from a successful call that returns // This result is indistinguishable from a successful call that returns
// no signers. For the current GUI this doesn't matter, because the wallet // no signers. For the current GUI this doesn't matter, because the wallet

View file

@ -6,7 +6,7 @@
#include <config/bitcoin-config.h> #include <config/bitcoin-config.h>
#endif #endif
#include <external_signer.h> #include <interfaces/node.h>
#include <qt/createwalletdialog.h> #include <qt/createwalletdialog.h>
#include <qt/forms/ui_createwalletdialog.h> #include <qt/forms/ui_createwalletdialog.h>
@ -113,7 +113,7 @@ CreateWalletDialog::~CreateWalletDialog()
delete ui; delete ui;
} }
void CreateWalletDialog::setSigners(const std::vector<ExternalSigner>& signers) void CreateWalletDialog::setSigners(const std::vector<std::unique_ptr<interfaces::ExternalSigner>>& signers)
{ {
m_has_signers = !signers.empty(); m_has_signers = !signers.empty();
if (m_has_signers) { if (m_has_signers) {
@ -126,7 +126,7 @@ void CreateWalletDialog::setSigners(const std::vector<ExternalSigner>& signers)
ui->blank_wallet_checkbox->setChecked(false); ui->blank_wallet_checkbox->setChecked(false);
ui->disable_privkeys_checkbox->setEnabled(false); ui->disable_privkeys_checkbox->setEnabled(false);
ui->disable_privkeys_checkbox->setChecked(true); ui->disable_privkeys_checkbox->setChecked(true);
const std::string label = signers[0].m_name; const std::string label = signers[0]->getName();
ui->wallet_name_line_edit->setText(QString::fromStdString(label)); ui->wallet_name_line_edit->setText(QString::fromStdString(label));
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true); ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true);
} else { } else {

View file

@ -7,7 +7,12 @@
#include <QDialog> #include <QDialog>
#include <memory>
namespace interfaces {
class ExternalSigner; class ExternalSigner;
} // namespace interfaces
class WalletModel; class WalletModel;
namespace Ui { namespace Ui {
@ -24,7 +29,7 @@ public:
explicit CreateWalletDialog(QWidget* parent); explicit CreateWalletDialog(QWidget* parent);
virtual ~CreateWalletDialog(); virtual ~CreateWalletDialog();
void setSigners(const std::vector<ExternalSigner>& signers); void setSigners(const std::vector<std::unique_ptr<interfaces::ExternalSigner>>& signers);
QString walletName() const; QString walletName() const;
bool isEncryptWalletChecked() const; bool isEncryptWalletChecked() const;

View file

@ -274,9 +274,9 @@ void CreateWalletActivity::create()
{ {
m_create_wallet_dialog = new CreateWalletDialog(m_parent_widget); m_create_wallet_dialog = new CreateWalletDialog(m_parent_widget);
std::vector<ExternalSigner> signers; std::vector<std::unique_ptr<interfaces::ExternalSigner>> signers;
try { try {
signers = node().externalSigners(); signers = node().listExternalSigners();
} catch (const std::runtime_error& e) { } catch (const std::runtime_error& e) {
QMessageBox::critical(nullptr, tr("Can't list signers"), e.what()); QMessageBox::critical(nullptr, tr("Can't list signers"), e.what());
} }