mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-11-12 06:58:57 +01:00
Merge bitcoin/bitcoin#23004: multiprocess: add interfaces::ExternalSigner class
a032fa30d2multiprocess: add interfaces::ExternalSigner class (Russell Yanofsky) Pull request description: Add `interfaces::ExternalSigner` class to let signer objects be passed between processes and let signer code run in the original process where the object was created. --- This PR is part of the [process separation project](https://github.com/bitcoin/bitcoin/projects/10). ACKs for top commit: laanwj: Concept and code review ACKa032fa30d2hebasto: re-ACKa032fa30d2Tree-SHA512: 99a729fb3a64d010e142cc778a9f1f358e58345b77faaf2664de7d2277715d59df3352326e8f0f2a6628038670eaa4556310a549079fb28af6d2eeb05aea1460
This commit is contained in:
@@ -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;
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -280,9 +280,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());
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user