common: Add PSBTError enum
Add separate PSBTError enum instead of reusing TransactionError enum for PSBT operations, and drop unused error codes. The error codes returned by PSBT operations and transaction broadcast functions mostly do not overlap, so using an unified enum makes it harder to call any of these functions and know which errors actually need to be handled. Define PSBTError in the common library because PSBT functionality is implemented in the common library and used by both the node (for rawtransaction RPCs) and the wallet.
This commit is contained in:
1 parent
0d44c44ae3
commit
02e62c6c9a
25 files changed
+156
-97
No files matched your search
@@ -13,6 +13,7 @@
|
||||
#include <qt/forms/ui_psbtoperationsdialog.h>
|
||||
#include <qt/guiutil.h>
|
||||
#include <qt/optionsmodel.h>
|
||||
#include <util/error.h>
|
||||
#include <util/fs.h>
|
||||
#include <util/strencodings.h>
|
||||
|
||||
@@ -55,10 +56,10 @@ void PSBTOperationsDialog::openWithPSBT(PartiallySignedTransaction psbtx)
|
||||
bool complete = FinalizePSBT(psbtx); // Make sure all existing signatures are fully combined before checking for completeness.
|
||||
if (m_wallet_model) {
|
||||
size_t n_could_sign;
|
||||
TransactionError err = m_wallet_model->wallet().fillPSBT(SIGHASH_ALL, /*sign=*/false, /*bip32derivs=*/true, &n_could_sign, m_transaction_data, complete);
|
||||
if (err != TransactionError::OK) {
|
||||
const auto err{m_wallet_model->wallet().fillPSBT(SIGHASH_ALL, /*sign=*/false, /*bip32derivs=*/true, &n_could_sign, m_transaction_data, complete)};
|
||||
if (err) {
|
||||
showStatus(tr("Failed to load transaction: %1")
|
||||
.arg(QString::fromStdString(TransactionErrorString(err).translated)),
|
||||
.arg(QString::fromStdString(PSBTErrorString(*err).translated)),
|
||||
StatusLevel::ERR);
|
||||
return;
|
||||
}
|
||||
@@ -79,11 +80,11 @@ void PSBTOperationsDialog::signTransaction()
|
||||
|
||||
WalletModel::UnlockContext ctx(m_wallet_model->requestUnlock());
|
||||
|
||||
TransactionError err = m_wallet_model->wallet().fillPSBT(SIGHASH_ALL, /*sign=*/true, /*bip32derivs=*/true, &n_signed, m_transaction_data, complete);
|
||||
const auto err{m_wallet_model->wallet().fillPSBT(SIGHASH_ALL, /*sign=*/true, /*bip32derivs=*/true, &n_signed, m_transaction_data, complete)};
|
||||
|
||||
if (err != TransactionError::OK) {
|
||||
if (err) {
|
||||
showStatus(tr("Failed to sign transaction: %1")
|
||||
.arg(QString::fromStdString(TransactionErrorString(err).translated)), StatusLevel::ERR);
|
||||
.arg(QString::fromStdString(PSBTErrorString(*err).translated)), StatusLevel::ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -247,9 +248,9 @@ size_t PSBTOperationsDialog::couldSignInputs(const PartiallySignedTransaction &p
|
||||
|
||||
size_t n_signed;
|
||||
bool complete;
|
||||
TransactionError err = m_wallet_model->wallet().fillPSBT(SIGHASH_ALL, /*sign=*/false, /*bip32derivs=*/false, &n_signed, m_transaction_data, complete);
|
||||
const auto err{m_wallet_model->wallet().fillPSBT(SIGHASH_ALL, /*sign=*/false, /*bip32derivs=*/false, &n_signed, m_transaction_data, complete)};
|
||||
|
||||
if (err != TransactionError::OK) {
|
||||
if (err) {
|
||||
return 0;
|
||||
}
|
||||
return n_signed;
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include <QSettings>
|
||||
#include <QTextDocument>
|
||||
|
||||
using common::PSBTError;
|
||||
using wallet::CCoinControl;
|
||||
using wallet::DEFAULT_PAY_TX_FEE;
|
||||
|
||||
@@ -442,26 +443,26 @@ void SendCoinsDialog::presentPSBT(PartiallySignedTransaction& psbtx)
|
||||
}
|
||||
|
||||
bool SendCoinsDialog::signWithExternalSigner(PartiallySignedTransaction& psbtx, CMutableTransaction& mtx, bool& complete) {
|
||||
TransactionError err;
|
||||
std::optional<PSBTError> err;
|
||||
try {
|
||||
err = model->wallet().fillPSBT(SIGHASH_ALL, /*sign=*/true, /*bip32derivs=*/true, /*n_signed=*/nullptr, psbtx, complete);
|
||||
} catch (const std::runtime_error& e) {
|
||||
QMessageBox::critical(nullptr, tr("Sign failed"), e.what());
|
||||
return false;
|
||||
}
|
||||
if (err == TransactionError::EXTERNAL_SIGNER_NOT_FOUND) {
|
||||
if (err == PSBTError::EXTERNAL_SIGNER_NOT_FOUND) {
|
||||
//: "External signer" means using devices such as hardware wallets.
|
||||
const QString msg = tr("External signer not found");
|
||||
QMessageBox::critical(nullptr, msg, msg);
|
||||
return false;
|
||||
}
|
||||
if (err == TransactionError::EXTERNAL_SIGNER_FAILED) {
|
||||
if (err == PSBTError::EXTERNAL_SIGNER_FAILED) {
|
||||
//: "External signer" means using devices such as hardware wallets.
|
||||
const QString msg = tr("External signer failure");
|
||||
QMessageBox::critical(nullptr, msg, msg);
|
||||
return false;
|
||||
}
|
||||
if (err != TransactionError::OK) {
|
||||
if (err) {
|
||||
tfm::format(std::cerr, "Failed to sign PSBT");
|
||||
processSendCoinsReturn(WalletModel::TransactionCreationFailed);
|
||||
return false;
|
||||
@@ -501,9 +502,9 @@ void SendCoinsDialog::sendButtonClicked([[maybe_unused]] bool checked)
|
||||
PartiallySignedTransaction psbtx(mtx);
|
||||
bool complete = false;
|
||||
// Fill without signing
|
||||
TransactionError err = model->wallet().fillPSBT(SIGHASH_ALL, /*sign=*/false, /*bip32derivs=*/true, /*n_signed=*/nullptr, psbtx, complete);
|
||||
const auto err{model->wallet().fillPSBT(SIGHASH_ALL, /*sign=*/false, /*bip32derivs=*/true, /*n_signed=*/nullptr, psbtx, complete)};
|
||||
assert(!complete);
|
||||
assert(err == TransactionError::OK);
|
||||
assert(!err);
|
||||
|
||||
// Copy PSBT to clipboard and offer to save
|
||||
presentPSBT(psbtx);
|
||||
@@ -517,9 +518,9 @@ void SendCoinsDialog::sendButtonClicked([[maybe_unused]] bool checked)
|
||||
bool complete = false;
|
||||
// Always fill without signing first. This prevents an external signer
|
||||
// from being called prematurely and is not expensive.
|
||||
TransactionError err = model->wallet().fillPSBT(SIGHASH_ALL, /*sign=*/false, /*bip32derivs=*/true, /*n_signed=*/nullptr, psbtx, complete);
|
||||
const auto err{model->wallet().fillPSBT(SIGHASH_ALL, /*sign=*/false, /*bip32derivs=*/true, /*n_signed=*/nullptr, psbtx, complete)};
|
||||
assert(!complete);
|
||||
assert(err == TransactionError::OK);
|
||||
assert(!err);
|
||||
send_failure = !signWithExternalSigner(psbtx, mtx, complete);
|
||||
// Don't broadcast when user rejects it on the device or there's a failure:
|
||||
broadcast = complete && !send_failure;
|
||||
|
||||
@@ -534,8 +534,8 @@ bool WalletModel::bumpFee(uint256 hash, uint256& new_hash)
|
||||
// "Create Unsigned" clicked
|
||||
PartiallySignedTransaction psbtx(mtx);
|
||||
bool complete = false;
|
||||
const TransactionError err = wallet().fillPSBT(SIGHASH_ALL, /*sign=*/false, /*bip32derivs=*/true, nullptr, psbtx, complete);
|
||||
if (err != TransactionError::OK || complete) {
|
||||
const auto err{wallet().fillPSBT(SIGHASH_ALL, /*sign=*/false, /*bip32derivs=*/true, nullptr, psbtx, complete)};
|
||||
if (err || complete) {
|
||||
QMessageBox::critical(nullptr, tr("Fee bump error"), tr("Can't draft transaction."));
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user