Skip to content

Commit 4357158

Browse files
committed
wallet: return and display signer error
Both RPC and GUI now render a useful error message instead of (silently) failing. Replace bool with util::Result<void> to clarify that this either succeeds or returns an error message.
1 parent dc55531 commit 4357158

File tree

12 files changed

+40
-22
lines changed

12 files changed

+40
-22
lines changed

src/interfaces/wallet.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ class Wallet
127127
virtual bool setAddressReceiveRequest(const CTxDestination& dest, const std::string& id, const std::string& value) = 0;
128128

129129
//! Display address on external signer
130-
virtual bool displayAddress(const CTxDestination& dest) = 0;
130+
virtual util::Result<void> displayAddress(const CTxDestination& dest) = 0;
131131

132132
//! Lock coin.
133133
virtual bool lockCoin(const COutPoint& output, const bool write_to_db) = 0;

src/qt/walletmodel.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -569,16 +569,17 @@ bool WalletModel::bumpFee(uint256 hash, uint256& new_hash)
569569
return true;
570570
}
571571

572-
bool WalletModel::displayAddress(std::string sAddress) const
572+
void WalletModel::displayAddress(std::string sAddress) const
573573
{
574574
CTxDestination dest = DecodeDestination(sAddress);
575-
bool res = false;
576575
try {
577-
res = m_wallet->displayAddress(dest);
576+
util::Result<void> result = m_wallet->displayAddress(dest);
577+
if (!result) {
578+
QMessageBox::warning(nullptr, tr("Signer error"), QString::fromStdString(util::ErrorString(result).translated));
579+
}
578580
} catch (const std::runtime_error& e) {
579581
QMessageBox::critical(nullptr, tr("Can't display address"), e.what());
580582
}
581-
return res;
582583
}
583584

584585
bool WalletModel::isWalletEnabled()

src/qt/walletmodel.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ class WalletModel : public QObject
130130
UnlockContext requestUnlock();
131131

132132
bool bumpFee(uint256 hash, uint256& new_hash);
133-
bool displayAddress(std::string sAddress) const;
133+
void displayAddress(std::string sAddress) const;
134134

135135
static bool isWalletEnabled();
136136

src/wallet/external_signer_scriptpubkeyman.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <memory>
1414
#include <stdexcept>
1515
#include <string>
16+
#include <univalue.h>
1617
#include <utility>
1718
#include <vector>
1819

@@ -52,7 +53,7 @@ ExternalSigner ExternalSignerScriptPubKeyMan::GetExternalSigner() {
5253
return signers[0];
5354
}
5455

55-
bool ExternalSignerScriptPubKeyMan::DisplayAddress(const CTxDestination& dest, const ExternalSigner &signer) const
56+
util::Result<void> ExternalSignerScriptPubKeyMan::DisplayAddress(const CTxDestination& dest, const ExternalSigner &signer) const
5657
{
5758
// TODO: avoid the need to infer a descriptor from inside a descriptor wallet
5859
const CScript& scriptPubKey = GetScriptForDestination(dest);
@@ -61,10 +62,17 @@ bool ExternalSignerScriptPubKeyMan::DisplayAddress(const CTxDestination& dest, c
6162

6263
const UniValue& result = signer.DisplayAddress(descriptor->ToString());
6364

65+
const UniValue& error = result.find_value("error");
66+
if (error.isStr()) return util::Error{strprintf(_("Signer returned error: %s"), error.getValStr())};
67+
6468
const UniValue& ret_address = result.find_value("address");
65-
if (!ret_address.isStr()) return false;
69+
if (!ret_address.isStr()) return util::Error{_("Signer did not echo address")};
70+
71+
if (ret_address.getValStr() != EncodeDestination(dest)) {
72+
return util::Error{strprintf(_("Signer echoed unexpected address %s"), ret_address.getValStr())};
73+
}
6674

67-
return ret_address.getValStr() == EncodeDestination(dest);
75+
return util::Result<void>();
6876
}
6977

7078
// If sign is true, transaction must previously have been filled

src/wallet/external_signer_scriptpubkeyman.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99

1010
#include <memory>
1111

12+
struct bilingual_str;
13+
1214
namespace wallet {
1315
class ExternalSignerScriptPubKeyMan : public DescriptorScriptPubKeyMan
1416
{
@@ -27,7 +29,11 @@ class ExternalSignerScriptPubKeyMan : public DescriptorScriptPubKeyMan
2729

2830
static ExternalSigner GetExternalSigner();
2931

30-
bool DisplayAddress(const CTxDestination& dest, const ExternalSigner &signer) const;
32+
/**
33+
* Display address on the device and verify that the returned value matches.
34+
* @returns nothing or an error message
35+
*/
36+
util::Result<void> DisplayAddress(const CTxDestination& dest, const ExternalSigner& signer) const;
3137

3238
TransactionError FillPSBT(PartiallySignedTransaction& psbt, const PrecomputedTransactionData& txdata, int sighash_type = 1 /* SIGHASH_ALL */, bool sign = true, bool bip32derivs = false, int* n_signed = nullptr, bool finalize = true) const override;
3339
};

src/wallet/interfaces.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ class WalletImpl : public Wallet
247247
return value.empty() ? m_wallet->EraseAddressReceiveRequest(batch, dest, id)
248248
: m_wallet->SetAddressReceiveRequest(batch, dest, id, value);
249249
}
250-
bool displayAddress(const CTxDestination& dest) override
250+
util::Result<void> displayAddress(const CTxDestination& dest) override
251251
{
252252
LOCK(m_wallet->cs_wallet);
253253
return m_wallet->DisplayAddress(dest);

src/wallet/rpc/addresses.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -789,9 +789,8 @@ RPCHelpMan walletdisplayaddress()
789789
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address");
790790
}
791791

792-
if (!pwallet->DisplayAddress(dest)) {
793-
throw JSONRPCError(RPC_MISC_ERROR, "Failed to display address");
794-
}
792+
util::Result<void> res = pwallet->DisplayAddress(dest);
793+
if (!res) throw JSONRPCError(RPC_MISC_ERROR, util::ErrorString(res).original);
795794

796795
UniValue result(UniValue::VOBJ);
797796
result.pushKV("address", request.params[0].get_str());

src/wallet/scriptpubkeyman.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
#include <unordered_map>
2828

2929
enum class OutputType;
30-
struct bilingual_str;
3130

3231
namespace wallet {
3332
struct MigrationData;

src/wallet/wallet.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2667,7 +2667,7 @@ void ReserveDestination::ReturnDestination()
26672667
address = CNoDestination();
26682668
}
26692669

2670-
bool CWallet::DisplayAddress(const CTxDestination& dest)
2670+
util::Result<void> CWallet::DisplayAddress(const CTxDestination& dest)
26712671
{
26722672
CScript scriptPubKey = GetScriptForDestination(dest);
26732673
for (const auto& spk_man : GetScriptPubKeyMans(scriptPubKey)) {
@@ -2678,7 +2678,7 @@ bool CWallet::DisplayAddress(const CTxDestination& dest)
26782678
ExternalSigner signer = ExternalSignerScriptPubKeyMan::GetExternalSigner();
26792679
return signer_spk_man->DisplayAddress(dest, signer);
26802680
}
2681-
return false;
2681+
return util::Error{_("There is no ScriptPubKeyManager for this address")};
26822682
}
26832683

26842684
bool CWallet::LockCoin(const COutPoint& output, WalletBatch* batch)

src/wallet/wallet.h

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -537,11 +537,8 @@ class CWallet final : public WalletStorage, public interfaces::Chain::Notificati
537537
bool IsSpentKey(const CScript& scriptPubKey) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
538538
void SetSpentKeyState(WalletBatch& batch, const uint256& hash, unsigned int n, bool used, std::set<CTxDestination>& tx_destinations) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
539539

540-
/** Display address on an external signer.
541-
* Returns false if the signer does not respond with a matching address.
542-
* Returns false if external signer support is not compiled.
543-
*/
544-
bool DisplayAddress(const CTxDestination& dest) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
540+
/** Display address on an external signer. */
541+
util::Result<void> DisplayAddress(const CTxDestination& dest) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
545542

546543
bool IsLockedCoin(const COutPoint& output) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
547544
bool LockCoin(const COutPoint& output, WalletBatch* batch = nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);

0 commit comments

Comments
 (0)