diff --git a/doc/release-notes-27217.md b/doc/release-notes-27217.md new file mode 100644 index 00000000000..ab1452fc942 --- /dev/null +++ b/doc/release-notes-27217.md @@ -0,0 +1,6 @@ +Wallet +------ + +* Address Purposes strings are now restricted to the currently known values of "send", "receive", and "refund". + Wallets that have unrecognized purpose strings will have loading warnings, and the `listlabels` + RPC will raise an error if an unrecognized purpose is requested. diff --git a/src/Makefile.am b/src/Makefile.am index 444480f824a..1d7004ac863 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -329,7 +329,6 @@ BITCOIN_CORE_H = \ wallet/external_signer_scriptpubkeyman.h \ wallet/feebumper.h \ wallet/fees.h \ - wallet/ismine.h \ wallet/load.h \ wallet/receive.h \ wallet/rpc/util.h \ @@ -339,6 +338,7 @@ BITCOIN_CORE_H = \ wallet/spend.h \ wallet/sqlite.h \ wallet/transaction.h \ + wallet/types.h \ wallet/wallet.h \ wallet/walletdb.h \ wallet/wallettool.h \ diff --git a/src/interfaces/wallet.h b/src/interfaces/wallet.h index b37763e6865..8c31112fc94 100644 --- a/src/interfaces/wallet.h +++ b/src/interfaces/wallet.h @@ -35,6 +35,7 @@ struct bilingual_str; namespace wallet { class CCoinControl; class CWallet; +enum class AddressPurpose; enum isminetype : unsigned int; struct CRecipient; struct WalletContext; @@ -103,7 +104,7 @@ public: virtual bool haveWatchOnly() = 0; //! Add or update address. - virtual bool setAddressBook(const CTxDestination& dest, const std::string& name, const std::string& purpose) = 0; + virtual bool setAddressBook(const CTxDestination& dest, const std::string& name, const std::optional& purpose) = 0; // Remove address. virtual bool delAddressBook(const CTxDestination& dest) = 0; @@ -112,7 +113,7 @@ public: virtual bool getAddress(const CTxDestination& dest, std::string* name, wallet::isminetype* is_mine, - std::string* purpose) = 0; + wallet::AddressPurpose* purpose) = 0; //! Get wallet address list. virtual std::vector getAddresses() const = 0; @@ -293,7 +294,7 @@ public: using AddressBookChangedFn = std::function; virtual std::unique_ptr handleAddressBookChanged(AddressBookChangedFn fn) = 0; @@ -352,11 +353,11 @@ struct WalletAddress { CTxDestination dest; wallet::isminetype is_mine; + wallet::AddressPurpose purpose; std::string name; - std::string purpose; - WalletAddress(CTxDestination dest, wallet::isminetype is_mine, std::string name, std::string purpose) - : dest(std::move(dest)), is_mine(is_mine), name(std::move(name)), purpose(std::move(purpose)) + WalletAddress(CTxDestination dest, wallet::isminetype is_mine, wallet::AddressPurpose purpose, std::string name) + : dest(std::move(dest)), is_mine(is_mine), purpose(std::move(purpose)), name(std::move(name)) { } }; diff --git a/src/qt/addresstablemodel.cpp b/src/qt/addresstablemodel.cpp index e402c51ac4c..0d0f1a4d154 100644 --- a/src/qt/addresstablemodel.cpp +++ b/src/qt/addresstablemodel.cpp @@ -8,6 +8,7 @@ #include #include +#include #include #include @@ -52,17 +53,16 @@ struct AddressTableEntryLessThan }; /* Determine address type from address purpose */ -static AddressTableEntry::Type translateTransactionType(const QString &strPurpose, bool isMine) +static AddressTableEntry::Type translateTransactionType(wallet::AddressPurpose purpose, bool isMine) { - AddressTableEntry::Type addressType = AddressTableEntry::Hidden; // "refund" addresses aren't shown, and change addresses aren't returned by getAddresses at all. - if (strPurpose == "send") - addressType = AddressTableEntry::Sending; - else if (strPurpose == "receive") - addressType = AddressTableEntry::Receiving; - else if (strPurpose == "unknown" || strPurpose == "") // if purpose not set, guess - addressType = (isMine ? AddressTableEntry::Receiving : AddressTableEntry::Sending); - return addressType; + switch (purpose) { + case wallet::AddressPurpose::SEND: return AddressTableEntry::Sending; + case wallet::AddressPurpose::RECEIVE: return AddressTableEntry::Receiving; + case wallet::AddressPurpose::REFUND: return AddressTableEntry::Hidden; + // No default case to allow for compiler to warn + } + assert(false); } // Private implementation @@ -85,7 +85,7 @@ public: continue; } AddressTableEntry::Type addressType = translateTransactionType( - QString::fromStdString(address.purpose), address.is_mine); + address.purpose, address.is_mine); cachedAddressTable.append(AddressTableEntry(addressType, QString::fromStdString(address.name), QString::fromStdString(EncodeDestination(address.dest)))); @@ -97,7 +97,7 @@ public: std::sort(cachedAddressTable.begin(), cachedAddressTable.end(), AddressTableEntryLessThan()); } - void updateEntry(const QString &address, const QString &label, bool isMine, const QString &purpose, int status) + void updateEntry(const QString &address, const QString &label, bool isMine, wallet::AddressPurpose purpose, int status) { // Find address / label in model QList::iterator lower = std::lower_bound( @@ -239,7 +239,7 @@ bool AddressTableModel::setData(const QModelIndex &index, const QVariant &value, if(!index.isValid()) return false; AddressTableEntry *rec = static_cast(index.internalPointer()); - std::string strPurpose = (rec->type == AddressTableEntry::Sending ? "send" : "receive"); + wallet::AddressPurpose purpose = rec->type == AddressTableEntry::Sending ? wallet::AddressPurpose::SEND : wallet::AddressPurpose::RECEIVE; editStatus = OK; if(role == Qt::EditRole) @@ -253,7 +253,7 @@ bool AddressTableModel::setData(const QModelIndex &index, const QVariant &value, editStatus = NO_CHANGES; return false; } - walletModel->wallet().setAddressBook(curAddress, value.toString().toStdString(), strPurpose); + walletModel->wallet().setAddressBook(curAddress, value.toString().toStdString(), purpose); } else if(index.column() == Address) { CTxDestination newAddress = DecodeDestination(value.toString().toStdString()); // Refuse to set invalid address, set error status and return false @@ -282,7 +282,7 @@ bool AddressTableModel::setData(const QModelIndex &index, const QVariant &value, // Remove old entry walletModel->wallet().delAddressBook(curAddress); // Add new entry with new address - walletModel->wallet().setAddressBook(newAddress, value.toString().toStdString(), strPurpose); + walletModel->wallet().setAddressBook(newAddress, value.toString().toStdString(), purpose); } } return true; @@ -334,7 +334,7 @@ QModelIndex AddressTableModel::index(int row, int column, const QModelIndex &par } void AddressTableModel::updateEntry(const QString &address, - const QString &label, bool isMine, const QString &purpose, int status) + const QString &label, bool isMine, wallet::AddressPurpose purpose, int status) { // Update address book model from Bitcoin core priv->updateEntry(address, label, isMine, purpose, status); @@ -365,7 +365,7 @@ QString AddressTableModel::addRow(const QString &type, const QString &label, con } // Add entry - walletModel->wallet().setAddressBook(DecodeDestination(strAddress), strLabel, "send"); + walletModel->wallet().setAddressBook(DecodeDestination(strAddress), strLabel, wallet::AddressPurpose::SEND); } else if(type == Receive) { @@ -416,18 +416,18 @@ QString AddressTableModel::labelForAddress(const QString &address) const return QString(); } -QString AddressTableModel::purposeForAddress(const QString &address) const +std::optional AddressTableModel::purposeForAddress(const QString &address) const { - std::string purpose; + wallet::AddressPurpose purpose; if (getAddressData(address, /* name= */ nullptr, &purpose)) { - return QString::fromStdString(purpose); + return purpose; } - return QString(); + return std::nullopt; } bool AddressTableModel::getAddressData(const QString &address, std::string* name, - std::string* purpose) const { + wallet::AddressPurpose* purpose) const { CTxDestination destination = DecodeDestination(address.toStdString()); return walletModel->wallet().getAddress(destination, name, /* is_mine= */ nullptr, purpose); } diff --git a/src/qt/addresstablemodel.h b/src/qt/addresstablemodel.h index 6cc14654ef4..599aa89cadd 100644 --- a/src/qt/addresstablemodel.h +++ b/src/qt/addresstablemodel.h @@ -5,6 +5,8 @@ #ifndef BITCOIN_QT_ADDRESSTABLEMODEL_H #define BITCOIN_QT_ADDRESSTABLEMODEL_H +#include + #include #include @@ -16,6 +18,9 @@ class WalletModel; namespace interfaces { class Wallet; } +namespace wallet { +enum class AddressPurpose; +} // namespace wallet /** Qt model of the address book in the core. This allows views to access and modify the address book. @@ -71,7 +76,7 @@ public: QString labelForAddress(const QString &address) const; /** Look up purpose for address in address book, if not found return empty string. */ - QString purposeForAddress(const QString &address) const; + std::optional purposeForAddress(const QString &address) const; /* Look up row index of an address in the model. Return -1 if not found. @@ -89,7 +94,7 @@ private: EditStatus editStatus = OK; /** Look up address book data given an address string. */ - bool getAddressData(const QString &address, std::string* name, std::string* purpose) const; + bool getAddressData(const QString &address, std::string* name, wallet::AddressPurpose* purpose) const; /** Notify listeners that data changed. */ void emitDataChanged(int index); @@ -97,7 +102,7 @@ private: public Q_SLOTS: /* Update address list from core. */ - void updateEntry(const QString &address, const QString &label, bool isMine, const QString &purpose, int status); + void updateEntry(const QString &address, const QString &label, bool isMine, wallet::AddressPurpose purpose, int status); friend class AddressTablePriv; }; diff --git a/src/qt/editaddressdialog.cpp b/src/qt/editaddressdialog.cpp index 9b3319415d2..092a89fa116 100644 --- a/src/qt/editaddressdialog.cpp +++ b/src/qt/editaddressdialog.cpp @@ -8,6 +8,8 @@ #include #include +#include + #include #include @@ -137,9 +139,9 @@ QString EditAddressDialog::getDuplicateAddressWarning() const { QString dup_address = ui->addressEdit->text(); QString existing_label = model->labelForAddress(dup_address); - QString existing_purpose = model->purposeForAddress(dup_address); + auto existing_purpose = model->purposeForAddress(dup_address); - if (existing_purpose == "receive" && + if (existing_purpose == wallet::AddressPurpose::RECEIVE && (mode == NewSendingAddress || mode == EditSendingAddress)) { return tr( "Address \"%1\" already exists as a receiving address with label " diff --git a/src/qt/test/addressbooktests.cpp b/src/qt/test/addressbooktests.cpp index d005e08d14d..5706964cc9a 100644 --- a/src/qt/test/addressbooktests.cpp +++ b/src/qt/test/addressbooktests.cpp @@ -113,8 +113,8 @@ void TestAddAddressesToSendBook(interfaces::Node& node) { LOCK(wallet->cs_wallet); - wallet->SetAddressBook(r_key_dest, r_label.toStdString(), "receive"); - wallet->SetAddressBook(s_key_dest, s_label.toStdString(), "send"); + wallet->SetAddressBook(r_key_dest, r_label.toStdString(), wallet::AddressPurpose::RECEIVE); + wallet->SetAddressBook(s_key_dest, s_label.toStdString(), wallet::AddressPurpose::SEND); } auto check_addbook_size = [&wallet](int expected_size) { diff --git a/src/qt/test/wallettests.cpp b/src/qt/test/wallettests.cpp index eb7bf33a325..072718fe151 100644 --- a/src/qt/test/wallettests.cpp +++ b/src/qt/test/wallettests.cpp @@ -221,7 +221,7 @@ std::shared_ptr SetupDescriptorsWallet(interfaces::Node& node, TestChai WalletDescriptor w_desc(std::move(desc), 0, 0, 1, 1); if (!wallet->AddWalletDescriptor(w_desc, provider, "", false)) assert(false); CTxDestination dest = GetDestinationForKey(test.coinbaseKey.GetPubKey(), wallet->m_default_address_type); - wallet->SetAddressBook(dest, "", "receive"); + wallet->SetAddressBook(dest, "", wallet::AddressPurpose::RECEIVE); wallet->SetLastBlockProcessed(105, WITH_LOCK(node.context()->chainman->GetMutex(), return node.context()->chainman->ActiveChain().Tip()->GetBlockHash())); SyncUpWallet(wallet, node); wallet->SetBroadcastTransactions(true); diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp index 057e4a7f559..2461a069307 100644 --- a/src/qt/transactiondesc.cpp +++ b/src/qt/transactiondesc.cpp @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include #include diff --git a/src/qt/transactionrecord.cpp b/src/qt/transactionrecord.cpp index 5f981ea250d..1d2f6484fba 100644 --- a/src/qt/transactionrecord.cpp +++ b/src/qt/transactionrecord.cpp @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index 565b732bf0c..fdd96c664a3 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -138,7 +138,7 @@ void WalletModel::updateTransaction() } void WalletModel::updateAddressBook(const QString &address, const QString &label, - bool isMine, const QString &purpose, int status) + bool isMine, wallet::AddressPurpose purpose, int status) { if(addressTableModel) addressTableModel->updateEntry(address, label, isMine, purpose, status); @@ -280,11 +280,11 @@ void WalletModel::sendCoins(WalletModelTransaction& transaction) if (!m_wallet->getAddress( dest, &name, /* is_mine= */ nullptr, /* purpose= */ nullptr)) { - m_wallet->setAddressBook(dest, strLabel, "send"); + m_wallet->setAddressBook(dest, strLabel, wallet::AddressPurpose::SEND); } else if (name != strLabel) { - m_wallet->setAddressBook(dest, strLabel, ""); // "" means don't change purpose + m_wallet->setAddressBook(dest, strLabel, {}); // {} means don't change purpose } } } @@ -377,18 +377,17 @@ static void NotifyKeyStoreStatusChanged(WalletModel *walletmodel) static void NotifyAddressBookChanged(WalletModel *walletmodel, const CTxDestination &address, const std::string &label, bool isMine, - const std::string &purpose, ChangeType status) + wallet::AddressPurpose purpose, ChangeType status) { QString strAddress = QString::fromStdString(EncodeDestination(address)); QString strLabel = QString::fromStdString(label); - QString strPurpose = QString::fromStdString(purpose); - qDebug() << "NotifyAddressBookChanged: " + strAddress + " " + strLabel + " isMine=" + QString::number(isMine) + " purpose=" + strPurpose + " status=" + QString::number(status); + qDebug() << "NotifyAddressBookChanged: " + strAddress + " " + strLabel + " isMine=" + QString::number(isMine) + " purpose=" + QString::number(static_cast(purpose)) + " status=" + QString::number(status); bool invoked = QMetaObject::invokeMethod(walletmodel, "updateAddressBook", Q_ARG(QString, strAddress), Q_ARG(QString, strLabel), Q_ARG(bool, isMine), - Q_ARG(QString, strPurpose), + Q_ARG(wallet::AddressPurpose, purpose), Q_ARG(int, status)); assert(invoked); } diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h index 17a39349f3f..4f75d41404a 100644 --- a/src/qt/walletmodel.h +++ b/src/qt/walletmodel.h @@ -236,7 +236,7 @@ public Q_SLOTS: /* New transaction, or transaction changed status */ void updateTransaction(); /* New, updated or removed address book entry */ - void updateAddressBook(const QString &address, const QString &label, bool isMine, const QString &purpose, int status); + void updateAddressBook(const QString &address, const QString &label, bool isMine, wallet::AddressPurpose purpose, int status); /* Watch-only added */ void updateWatchOnlyFlag(bool fHaveWatchonly); /* Current, immature or unconfirmed balance might have changed - emit 'balanceChanged' if so */ diff --git a/src/wallet/interfaces.cpp b/src/wallet/interfaces.cpp index df1eb19a339..086f6d9de85 100644 --- a/src/wallet/interfaces.cpp +++ b/src/wallet/interfaces.cpp @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include #include #include @@ -179,7 +179,7 @@ public: } return false; }; - bool setAddressBook(const CTxDestination& dest, const std::string& name, const std::string& purpose) override + bool setAddressBook(const CTxDestination& dest, const std::string& name, const std::optional& purpose) override { return m_wallet->SetAddressBook(dest, name, purpose); } @@ -190,7 +190,7 @@ public: bool getAddress(const CTxDestination& dest, std::string* name, isminetype* is_mine, - std::string* purpose) override + AddressPurpose* purpose) override { LOCK(m_wallet->cs_wallet); const auto& entry = m_wallet->FindAddressBookEntry(dest, /*allow_change=*/false); @@ -198,11 +198,16 @@ public: if (name) { *name = entry->GetLabel(); } + std::optional dest_is_mine; + if (is_mine || purpose) { + dest_is_mine = m_wallet->IsMine(dest); + } if (is_mine) { - *is_mine = m_wallet->IsMine(dest); + *is_mine = *dest_is_mine; } if (purpose) { - *purpose = entry->purpose; + // In very old wallets, address purpose may not be recorded so we derive it from IsMine + *purpose = entry->purpose.value_or(*dest_is_mine ? AddressPurpose::RECEIVE : AddressPurpose::SEND); } return true; } @@ -210,9 +215,11 @@ public: { LOCK(m_wallet->cs_wallet); std::vector result; - m_wallet->ForEachAddrBookEntry([&](const CTxDestination& dest, const std::string& label, const std::string& purpose, bool is_change) EXCLUSIVE_LOCKS_REQUIRED(m_wallet->cs_wallet) { + m_wallet->ForEachAddrBookEntry([&](const CTxDestination& dest, const std::string& label, bool is_change, const std::optional& purpose) EXCLUSIVE_LOCKS_REQUIRED(m_wallet->cs_wallet) { if (is_change) return; - result.emplace_back(dest, m_wallet->IsMine(dest), label, purpose); + isminetype is_mine = m_wallet->IsMine(dest); + // In very old wallets, address purpose may not be recorded so we derive it from IsMine + result.emplace_back(dest, is_mine, purpose.value_or(is_mine ? AddressPurpose::RECEIVE : AddressPurpose::SEND), label); }); return result; } @@ -519,7 +526,7 @@ public: { return MakeSignalHandler(m_wallet->NotifyAddressBookChanged.connect( [fn](const CTxDestination& address, const std::string& label, bool is_mine, - const std::string& purpose, ChangeType status) { fn(address, label, is_mine, purpose, status); })); + AddressPurpose purpose, ChangeType status) { fn(address, label, is_mine, purpose, status); })); } std::unique_ptr handleTransactionChanged(TransactionChangedFn fn) override { diff --git a/src/wallet/receive.h b/src/wallet/receive.h index 87be0fc2aeb..d50644b4cf9 100644 --- a/src/wallet/receive.h +++ b/src/wallet/receive.h @@ -6,8 +6,8 @@ #define BITCOIN_WALLET_RECEIVE_H #include -#include #include +#include #include namespace wallet { diff --git a/src/wallet/rpc/addresses.cpp b/src/wallet/rpc/addresses.cpp index da63d45d118..838d66c1e18 100644 --- a/src/wallet/rpc/addresses.cpp +++ b/src/wallet/rpc/addresses.cpp @@ -141,9 +141,9 @@ RPCHelpMan setlabel() const std::string label{LabelFromValue(request.params[1])}; if (pwallet->IsMine(dest)) { - pwallet->SetAddressBook(dest, label, "receive"); + pwallet->SetAddressBook(dest, label, AddressPurpose::RECEIVE); } else { - pwallet->SetAddressBook(dest, label, "send"); + pwallet->SetAddressBook(dest, label, AddressPurpose::SEND); } return UniValue::VNULL; @@ -285,7 +285,7 @@ RPCHelpMan addmultisigaddress() // Construct using pay-to-script-hash: CScript inner; CTxDestination dest = AddAndGetMultisigDestination(required, pubkeys, output_type, spk_man, inner); - pwallet->SetAddressBook(dest, label, "send"); + pwallet->SetAddressBook(dest, label, AddressPurpose::SEND); // Make the descriptor std::unique_ptr descriptor = InferDescriptor(GetScriptForDestination(dest), spk_man); @@ -663,7 +663,7 @@ RPCHelpMan getaddressesbylabel() // Find all addresses that have the given label UniValue ret(UniValue::VOBJ); std::set addresses; - pwallet->ForEachAddrBookEntry([&](const CTxDestination& _dest, const std::string& _label, const std::string& _purpose, bool _is_change) { + pwallet->ForEachAddrBookEntry([&](const CTxDestination& _dest, const std::string& _label, bool _is_change, const std::optional& _purpose) { if (_is_change) return; if (_label == label) { std::string address = EncodeDestination(_dest); @@ -677,7 +677,7 @@ RPCHelpMan getaddressesbylabel() // std::set in O(log(N))), UniValue::__pushKV is used instead, // which currently is O(1). UniValue value(UniValue::VOBJ); - value.pushKV("purpose", _purpose); + value.pushKV("purpose", _purpose ? PurposeToString(*_purpose) : "unknown"); ret.__pushKV(address, value); } }); @@ -721,9 +721,15 @@ RPCHelpMan listlabels() LOCK(pwallet->cs_wallet); - std::string purpose; + std::optional purpose; if (!request.params[0].isNull()) { - purpose = request.params[0].get_str(); + std::string purpose_str = request.params[0].get_str(); + if (!purpose_str.empty()) { + purpose = PurposeFromString(purpose_str); + if (!purpose) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid 'purpose' argument, must be a known purpose string, typically 'send', or 'receive'."); + } + } } // Add to a set to sort by label name, then insert into Univalue array diff --git a/src/wallet/rpc/backup.cpp b/src/wallet/rpc/backup.cpp index f4ea66c8334..31a8954259c 100644 --- a/src/wallet/rpc/backup.cpp +++ b/src/wallet/rpc/backup.cpp @@ -188,7 +188,7 @@ RPCHelpMan importprivkey() // label was passed. for (const auto& dest : GetAllDestinationsForKey(pubkey)) { if (!request.params[1].isNull() || !pwallet->FindAddressBookEntry(dest)) { - pwallet->SetAddressBook(dest, strLabel, "receive"); + pwallet->SetAddressBook(dest, strLabel, AddressPurpose::RECEIVE); } } @@ -608,7 +608,7 @@ RPCHelpMan importwallet() } if (has_label) - pwallet->SetAddressBook(PKHash(keyid), label, "receive"); + pwallet->SetAddressBook(PKHash(keyid), label, AddressPurpose::RECEIVE); progress++; } for (const auto& script_pair : scripts) { diff --git a/src/wallet/rpc/transactions.cpp b/src/wallet/rpc/transactions.cpp index 3bfe296d90d..5c9de7de47c 100644 --- a/src/wallet/rpc/transactions.cpp +++ b/src/wallet/rpc/transactions.cpp @@ -134,7 +134,7 @@ static UniValue ListReceived(const CWallet& wallet, const UniValue& params, cons UniValue ret(UniValue::VARR); std::map label_tally; - const auto& func = [&](const CTxDestination& address, const std::string& label, const std::string& purpose, bool is_change) { + const auto& func = [&](const CTxDestination& address, const std::string& label, bool is_change, const std::optional& purpose) { if (is_change) return; // no change addresses auto it = mapTally.find(address); @@ -175,7 +175,7 @@ static UniValue ListReceived(const CWallet& wallet, const UniValue& params, cons if (filtered_address) { const auto& entry = wallet.FindAddressBookEntry(*filtered_address, /*allow_change=*/false); - if (entry) func(*filtered_address, entry->GetLabel(), entry->purpose, /*is_change=*/false); + if (entry) func(*filtered_address, entry->GetLabel(), entry->IsChange(), entry->purpose); } else { // No filtered addr, walk-through the addressbook entry wallet.ForEachAddrBookEntry(func); diff --git a/src/wallet/scriptpubkeyman.h b/src/wallet/scriptpubkeyman.h index 42407173c3f..22b67c88e95 100644 --- a/src/wallet/scriptpubkeyman.h +++ b/src/wallet/scriptpubkeyman.h @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include diff --git a/src/wallet/test/ismine_tests.cpp b/src/wallet/test/ismine_tests.cpp index 90f369b22a1..f6f2d423e4b 100644 --- a/src/wallet/test/ismine_tests.cpp +++ b/src/wallet/test/ismine_tests.cpp @@ -8,7 +8,7 @@ #include