]> Nutra Git (v1) - gamesguru/feather.git/commitdiff
libwalletqt: cleanup
authortobtoht <tob@featherwallet.org>
Wed, 12 Mar 2025 10:23:03 +0000 (11:23 +0100)
committertobtoht <tob@featherwallet.org>
Wed, 12 Mar 2025 10:23:03 +0000 (11:23 +0100)
33 files changed:
src/MainWindow.cpp
src/dialog/TxConfAdvDialog.cpp
src/dialog/TxInfoDialog.cpp
src/dialog/TxProofDialog.cpp
src/libwalletqt/AddressBook.cpp
src/libwalletqt/AddressBook.h
src/libwalletqt/Coins.cpp
src/libwalletqt/Coins.h
src/libwalletqt/PassphraseHelper.h
src/libwalletqt/PendingTransaction.h
src/libwalletqt/Subaddress.cpp
src/libwalletqt/Subaddress.h
src/libwalletqt/SubaddressAccount.cpp
src/libwalletqt/SubaddressAccount.h
src/libwalletqt/TransactionHistory.cpp
src/libwalletqt/TransactionHistory.h
src/libwalletqt/Transfer.h [deleted file]
src/libwalletqt/UnsignedTransaction.cpp
src/libwalletqt/UnsignedTransaction.h
src/libwalletqt/Wallet.h
src/libwalletqt/WalletListenerImpl.h
src/libwalletqt/WalletManager.h
src/libwalletqt/rows/AccountRow.h
src/libwalletqt/rows/ConstructionInfo.cpp [moved from src/libwalletqt/ConstructionInfo.cpp with 94% similarity]
src/libwalletqt/rows/ConstructionInfo.h [moved from src/libwalletqt/ConstructionInfo.h with 91% similarity]
src/libwalletqt/rows/ContactRow.h
src/libwalletqt/rows/Input.h [moved from src/libwalletqt/Input.h with 64% similarity]
src/libwalletqt/rows/Output.h [new file with mode: 0644]
src/libwalletqt/rows/PendingTransactionInfo.cpp [moved from src/libwalletqt/PendingTransactionInfo.cpp with 100% similarity]
src/libwalletqt/rows/PendingTransactionInfo.h [moved from src/libwalletqt/PendingTransactionInfo.h with 96% similarity]
src/libwalletqt/rows/SubaddressRow.h
src/libwalletqt/rows/TransactionRow.cpp
src/libwalletqt/rows/TransactionRow.h

index d1bc2901bb68993e9caa2879f7398c41b971b8d7..28cb8f8dc0e8e00e96ff8f01fcf4b0f4fb4428e2 100644 (file)
@@ -26,7 +26,7 @@
 #include "dialog/WalletCacheDebugDialog.h"
 #include "libwalletqt/AddressBook.h"
 #include "libwalletqt/rows/CoinsInfo.h"
-#include "libwalletqt/Transfer.h"
+#include "libwalletqt/rows/Output.h"
 #include "libwalletqt/TransactionHistory.h"
 #include "model/AddressBookModel.h"
 #include "plugins/PluginRegistry.h"
index b9d72600f7ead670d874bb2025420f2b4329cbfe..39fecac7ead8e8095a1ad733d68d8e14b0dd0a57 100644 (file)
@@ -10,8 +10,8 @@
 
 #include "constants.h"
 #include "dialog/QrCodeDialog.h"
-#include "libwalletqt/Input.h"
-#include "libwalletqt/Transfer.h"
+#include "libwalletqt/rows/Input.h"
+#include "libwalletqt/rows/Output.h"
 #include "libwalletqt/WalletManager.h"
 #include "qrcode/QrCode.h"
 #include "utils/AppData.h"
index f3b53e6e1d90656ba98b1495910c9881ad0898cb..32e7d887b951e32b7f9122271df33ae7b1dd0f7a 100644 (file)
@@ -12,7 +12,7 @@
 #include "libwalletqt/Coins.h"
 #include "libwalletqt/rows/CoinsInfo.h"
 #include "libwalletqt/TransactionHistory.h"
-#include "libwalletqt/Transfer.h"
+#include "libwalletqt/rows/Output.h"
 #include "libwalletqt/WalletManager.h"
 #include "utils/Icons.h"
 #include "utils/Utils.h"
index d56bf3526da7a824a2b73d9b2091de2aca55c066..b441ab85cfee4cd2b5d6cfc259e4d31e736ea712 100644 (file)
@@ -6,7 +6,7 @@
 
 #include <QMessageBox>
 
-#include "libwalletqt/Transfer.h"
+#include "libwalletqt/rows/Output.h"
 #include "utils/Icons.h"
 #include "utils/Utils.h"
 
index 2d2ea204700846fdf15c35f5389a186b907b7000..71de9ced744f3633d73fa1a97431cea59d2a8b11 100644 (file)
@@ -13,21 +13,11 @@ AddressBook::AddressBook(tools::wallet2 *wallet2, QObject *parent)
     this->refresh();
 }
 
-QString AddressBook::errorString() const
-{
-    return m_errorString;
-}
-
-AddressBook::ErrorCode AddressBook::errorCode() const
-{
-    return m_errorCode;
-}
-
 void AddressBook::refresh()
 {
     emit refreshStarted();
 
-    clearRows();
+    m_rows.clear();
 
     for (const auto &row : m_wallet2->get_address_book()) {
         std::string address;
@@ -42,17 +32,22 @@ void AddressBook::refresh()
     emit refreshFinished();
 }
 
-const QList<ContactRow>& AddressBook::getRows()
+qsizetype AddressBook::count() const
 {
-    return m_rows;
+    return m_rows.length();
 }
 
-const ContactRow& AddressBook::getRow(const qsizetype i)
+const ContactRow& AddressBook::getRow(const qsizetype index)
 {
-    if (i < 0 || i >= m_rows.size()) {
+    if (index < 0 || index >= m_rows.size()) {
         throw std::out_of_range("Index out of range");
     }
-    return m_rows[i];
+    return m_rows[index];
+}
+
+const QList<ContactRow>& AddressBook::getRows()
+{
+    return m_rows;
 }
 
 bool AddressBook::addRow(const QString &address, const QString &description)
@@ -74,7 +69,7 @@ bool AddressBook::addRow(const QString &address, const QString &description)
     return r;
 }
 
-bool AddressBook::setDescription(int index, const QString &description) {
+bool AddressBook::setDescription(qsizetype index, const QString &description) {
     m_errorString = "";
 
     const auto ab = m_wallet2->get_address_book();
@@ -92,20 +87,20 @@ bool AddressBook::setDescription(int index, const QString &description) {
     return r;
 }
 
-bool AddressBook::deleteRow(int rowId)
+bool AddressBook::deleteRow(qsizetype index)
 {
-    bool r = m_wallet2->delete_address_book_row(rowId);
+    bool r = m_wallet2->delete_address_book_row(index);
     if (r)
         refresh();
     return r;
 }
 
-qsizetype AddressBook::count() const
+QString AddressBook::errorString() const
 {
-    return m_rows.length();
+    return m_errorString;
 }
 
-void AddressBook::clearRows()
+AddressBook::ErrorCode AddressBook::errorCode() const
 {
-    m_rows.clear();
+    return m_errorCode;
 }
index 25ac1e2fb99a680d7f34337c451e7e0249d79d97..dc66881fc778b6919a6ba10538abcc4891b939b8 100644 (file)
@@ -1,8 +1,8 @@
 // SPDX-License-Identifier: BSD-3-Clause
 // SPDX-FileCopyrightText: The Monero Project
 
-#ifndef ADDRESSBOOK_H
-#define ADDRESSBOOK_H
+#ifndef FEATHER_ADDRESSBOOK_H
+#define FEATHER_ADDRESSBOOK_H
 
 #include <QObject>
 #include <QList>
@@ -31,23 +31,22 @@ public:
     };
     Q_ENUM(ErrorCode);
 
+    void refresh();
+    qsizetype count() const;
+
+    const ContactRow& getRow(qsizetype index);
     const QList<ContactRow>& getRows();
-    const ContactRow& getRow(qsizetype i);
 
     bool addRow(const QString &address, const QString &description);
-    bool deleteRow(int rowId);
-    bool setDescription(int index, const QString &label);
-    qsizetype count() const;
+    bool setDescription(qsizetype index, const QString &description);
+    bool deleteRow(qsizetype index);
+
     QString errorString() const;
     ErrorCode errorCode() const;
 
-    void refresh();
-    void clearRows();
-
 signals:
     void refreshStarted() const;
     void refreshFinished() const;
-    void descriptionChanged() const;
 
 private:
     explicit AddressBook(tools::wallet2 *wallet2, QObject *parent);
@@ -60,4 +59,4 @@ private:
     ErrorCode m_errorCode;
 };
 
-#endif // ADDRESSBOOK_H
+#endif // FEATHER_ADDRESSBOOK_H
index 5ffbaab531895641d7492ce2b606532c4e1f4a63..f5540a295e2b59746992f36b0f80b2a35e54309e 100644 (file)
@@ -3,6 +3,7 @@
 
 #include "Coins.h"
 #include "rows/CoinsInfo.h"
+#include "Wallet.h"
 #include <wallet/wallet2.h>
 
 Coins::Coins(Wallet *wallet, tools::wallet2 *wallet2, QObject *parent)
@@ -13,19 +14,6 @@ Coins::Coins(Wallet *wallet, tools::wallet2 *wallet2, QObject *parent)
 
 }
 
-const QList<CoinsInfo>& Coins::getRows()
-{
-    return m_rows;
-}
-
-const CoinsInfo& Coins::getRow(const qsizetype i)
-{
-    if (i < 0 || i >= m_rows.size()) {
-        throw std::out_of_range("Index out of range");
-    }
-    return m_rows[i];
-}
-
 void Coins::refresh()
 {
     qDebug() << Q_FUNC_INFO;
@@ -34,47 +22,41 @@ void Coins::refresh()
 
     boost::shared_lock<boost::shared_mutex> transfers_lock(m_wallet2->m_transfers_mutex);
 
+    m_rows.clear();
+    for (size_t i = 0; i < m_wallet2->get_num_transfer_details(); ++i)
     {
-        QWriteLocker locker(&m_lock);
-
-        clearRows();
-        uint32_t account = m_wallet->currentSubaddressAccount();
+        const tools::wallet2::transfer_details &td = m_wallet2->get_transfer_details(i);
 
-        for (size_t i = 0; i < m_wallet2->get_num_transfer_details(); ++i)
-        {
-            const tools::wallet2::transfer_details &td = m_wallet2->get_transfer_details(i);
-
-            if (td.m_subaddr_index.major != account) {
-                continue;
-            }
-
-            CoinsInfo ci;
-            ci.blockHeight = td.m_block_height;
-            ci.hash = QString::fromStdString(epee::string_tools::pod_to_hex(td.m_txid));
-            ci.internalOutputIndex = td.m_internal_output_index;
-            ci.globalOutputIndex = td.m_global_output_index;
-            ci.spent = td.m_spent;
-            ci.frozen = td.m_frozen;
-            ci.spentHeight = td.m_spent_height;
-            ci.amount = td.m_amount;
-            ci.rct = td.m_rct;
-            ci.keyImageKnown = td.m_key_image_known;
-            ci.pkIndex = td.m_pk_index;
-            ci.subaddrIndex = td.m_subaddr_index.minor;
-            ci.subaddrAccount = td.m_subaddr_index.major;
-            ci.address = QString::fromStdString(m_wallet2->get_subaddress_as_str(td.m_subaddr_index)); // todo: this is expensive, cache maybe?
-            ci.addressLabel = QString::fromStdString(m_wallet2->get_subaddress_label(td.m_subaddr_index));
-            ci.txNote = QString::fromStdString(m_wallet2->get_tx_note(td.m_txid));
-            ci.keyImage = QString::fromStdString(epee::string_tools::pod_to_hex(td.m_key_image));
-            ci.unlockTime = td.m_tx.unlock_time;
-            ci.unlocked = m_wallet2->is_transfer_unlocked(td);
-            ci.pubKey = QString::fromStdString(epee::string_tools::pod_to_hex(td.get_public_key()));
-            ci.coinbase = td.m_tx.vin.size() == 1 && td.m_tx.vin[0].type() == typeid(cryptonote::txin_gen);
-            ci.description = m_wallet->getCacheAttribute(QString("coin.description:%1").arg(ci.pubKey));
-            ci.change = m_wallet2->is_change(td);
-
-            m_rows.push_back(ci);
+        if (td.m_subaddr_index.major != m_wallet->currentSubaddressAccount()) {
+            continue;
         }
+
+        CoinsInfo ci;
+        ci.blockHeight = td.m_block_height;
+        ci.hash = QString::fromStdString(epee::string_tools::pod_to_hex(td.m_txid));
+        ci.internalOutputIndex = td.m_internal_output_index;
+        ci.globalOutputIndex = td.m_global_output_index;
+        ci.spent = td.m_spent;
+        ci.frozen = td.m_frozen;
+        ci.spentHeight = td.m_spent_height;
+        ci.amount = td.m_amount;
+        ci.rct = td.m_rct;
+        ci.keyImageKnown = td.m_key_image_known;
+        ci.pkIndex = td.m_pk_index;
+        ci.subaddrIndex = td.m_subaddr_index.minor;
+        ci.subaddrAccount = td.m_subaddr_index.major;
+        ci.address = QString::fromStdString(m_wallet2->get_subaddress_as_str(td.m_subaddr_index)); // todo: this is expensive, cache maybe?
+        ci.addressLabel = QString::fromStdString(m_wallet2->get_subaddress_label(td.m_subaddr_index));
+        ci.txNote = QString::fromStdString(m_wallet2->get_tx_note(td.m_txid));
+        ci.keyImage = QString::fromStdString(epee::string_tools::pod_to_hex(td.m_key_image));
+        ci.unlockTime = td.m_tx.unlock_time;
+        ci.unlocked = m_wallet2->is_transfer_unlocked(td);
+        ci.pubKey = QString::fromStdString(epee::string_tools::pod_to_hex(td.get_public_key()));
+        ci.coinbase = td.m_tx.vin.size() == 1 && td.m_tx.vin[0].type() == typeid(cryptonote::txin_gen);
+        ci.description = m_wallet->getCacheAttribute(QString("coin.description:%1").arg(ci.pubKey));
+        ci.change = m_wallet2->is_change(td);
+
+        m_rows.push_back(ci);
     }
 
     emit refreshFinished();
@@ -82,8 +64,6 @@ void Coins::refresh()
 
 void Coins::refreshUnlocked()
 {
-    QWriteLocker locker(&m_lock);
-
     for (CoinsInfo& c : m_rows) {
         if (!c.unlocked) {
             bool unlocked = m_wallet2->is_transfer_unlocked(c.unlockTime, c.blockHeight);
@@ -94,11 +74,29 @@ void Coins::refreshUnlocked()
 
 quint64 Coins::count() const
 {
-    QReadLocker locker(&m_lock);
-
     return m_rows.length();
 }
 
+const CoinsInfo& Coins::getRow(const qsizetype i)
+{
+    if (i < 0 || i >= m_rows.size()) {
+        throw std::out_of_range("Index out of range");
+    }
+    return m_rows[i];
+}
+
+const QList<CoinsInfo>& Coins::getRows()
+{
+    return m_rows;
+}
+
+void Coins::setDescription(const QString &publicKey, quint32 accountIndex, const QString &description)
+{
+    m_wallet->setCacheAttribute(QString("coin.description:%1").arg(publicKey), description);
+    this->refresh();
+    emit descriptionChanged();
+}
+
 void Coins::freeze(QStringList &publicKeys)
 {
     crypto::public_key pk;
@@ -163,14 +161,3 @@ quint64 Coins::sumAmounts(const QStringList &keyImages) {
 
     return amount;
 }
-
-void Coins::setDescription(const QString &publicKey, quint32 accountIndex, const QString &description)
-{
-    m_wallet->setCacheAttribute(QString("coin.description:%1").arg(publicKey), description);
-    this->refresh();
-    emit descriptionChanged();
-}
-
-void Coins::clearRows() {
-    m_rows.clear();
-}
index a967c47b4a77eea4c71c6ef1841244da4c53672f..a07ad8762a2a94ba3caec30218d25d8c9c260429 100644 (file)
@@ -8,8 +8,6 @@
 #include <QList>
 #include <QReadWriteLock>
 
-#include "Wallet.h"
-
 namespace Monero {
     struct TransactionHistory;
 }
@@ -19,28 +17,24 @@ namespace tools {
 }
 
 class CoinsInfo;
-
+class Wallet;
 class Coins : public QObject
 {
 Q_OBJECT
 
 public:
-    const QList<CoinsInfo>& getRows();
-    const CoinsInfo& getRow(qsizetype i);
-
     void refresh();
     void refreshUnlocked();
+    quint64 count() const;
+
+    const CoinsInfo& getRow(qsizetype i);
+    const QList<CoinsInfo>& getRows();
 
+    void setDescription(const QString &publicKey, quint32 accountIndex, const QString &description);
     void freeze(QStringList &publicKeys);
     void thaw(QStringList &publicKeys);
-
     quint64 sumAmounts(const QStringList &keyImages);
 
-    void setDescription(const QString &publicKey, quint32 accountIndex, const QString &description);
-
-    quint64 count() const;
-    void clearRows();
-
 signals:
     void refreshStarted() const;
     void refreshFinished() const;
@@ -48,15 +42,11 @@ signals:
 
 private:
     explicit Coins(Wallet *wallet, tools::wallet2 *wallet2, QObject *parent = nullptr);
-
-private:
     friend class Wallet;
 
     Wallet *m_wallet;
     tools::wallet2 *m_wallet2;
     QList<CoinsInfo> m_rows;
-
-    mutable QReadWriteLock m_lock;
 };
 
 #endif //FEATHER_COINS_H
index 1c091f6cbccf8074332bd1b87692d18d12dea5ec..d9b8b45068115e1722c88cad0680313077437b48 100644 (file)
@@ -1,8 +1,8 @@
 // SPDX-License-Identifier: BSD-3-Clause
 // SPDX-FileCopyrightText: The Monero Project
 
-#ifndef MONERO_GUI_PASSPHRASEHELPER_H
-#define MONERO_GUI_PASSPHRASEHELPER_H
+#ifndef FEATHER_PASSPHRASEHELPER_H
+#define FEATHER_PASSPHRASEHELPER_H
 
 #include <QMutex>
 #include <QPointer>
@@ -43,4 +43,4 @@ private:
 
 };
 
-#endif //MONERO_GUI_PASSPHRASEHELPER_H
+#endif //FEATHER_PASSPHRASEHELPER_H
index e62fc68a09e26d62f35a77f66056dedea2c46fb5..500fb3075298a27a8c73f92aa959a888341c9172 100644 (file)
@@ -1,13 +1,13 @@
 // SPDX-License-Identifier: BSD-3-Clause
 // SPDX-FileCopyrightText: The Monero Project
 
-#ifndef PENDINGTRANSACTION_H
-#define PENDINGTRANSACTION_H
+#ifndef FEATHER_PENDINGTRANSACTION_H
+#define FEATHER_PENDINGTRANSACTION_H
 
 #include <QObject>
 #include <QList>
 
-#include "PendingTransactionInfo.h"
+#include "rows/PendingTransactionInfo.h"
 
 namespace Monero {
     class PendingTransaction;
@@ -53,4 +53,4 @@ private:
     mutable QList<PendingTransactionInfo> m_pending_tx_info;
 };
 
-#endif // PENDINGTRANSACTION_H
+#endif // FEATHER_PENDINGTRANSACTION_H
index 89f96a21b12e753ff151ddd50e9edce34658d246..e9985203d4354c986b6ac314c43da4b97c48e4de 100644 (file)
@@ -3,6 +3,7 @@
 
 #include "Subaddress.h"
 
+#include "Wallet.h"
 #include <wallet/wallet2.h>
 
 Subaddress::Subaddress(Wallet *wallet, tools::wallet2 *wallet2, QObject *parent)
@@ -17,9 +18,65 @@ Subaddress::Subaddress(Wallet *wallet, tools::wallet2 *wallet2, QObject *parent)
     m_hidden = hidden.split(",");
 }
 
-const QList<SubaddressRow>& Subaddress::getRows()
+bool Subaddress::refresh(quint32 accountIndex)
 {
-    return m_rows;
+    emit refreshStarted();
+
+    m_rows.clear();
+
+    bool potentialWalletFileCorruption = false;
+
+    for (quint32 i = 0; i < m_wallet2->get_num_subaddresses(accountIndex); ++i)
+    {
+        cryptonote::subaddress_index index = {accountIndex, i};
+        cryptonote::account_public_address address = m_wallet2->get_subaddress(index);
+
+        // Make sure we have previously generated Di
+        auto idx =  m_wallet2->get_subaddress_index(address);
+        if (!idx) {
+            potentialWalletFileCorruption = true;
+            break;
+        }
+
+        // Verify mapping
+        if (idx != index) {
+            potentialWalletFileCorruption = true;
+            break;
+        }
+
+        QString addressStr = QString::fromStdString(cryptonote::get_account_address_as_str(m_wallet2->nettype(), !index.is_zero(), address));
+
+        m_rows.emplace_back(
+            addressStr,
+            QString::fromStdString(m_wallet2->get_subaddress_label(index)),
+            m_wallet2->get_subaddress_used({accountIndex, (uint32_t)i}),
+            this->isHidden(addressStr),
+            this->isPinned(addressStr)
+        );
+    }
+
+    // Make sure keys are intact. We NEVER want to display incorrect addresses in case of memory corruption.
+    potentialWalletFileCorruption = potentialWalletFileCorruption || (m_wallet2->get_device_type() == hw::device::SOFTWARE && !m_wallet2->verify_keys());
+
+    if (potentialWalletFileCorruption) {
+        LOG_ERROR("KEY INCONSISTENCY DETECTED, WALLET IS IN CORRUPT STATE.");
+        m_rows.clear();
+        emit corrupted();
+    }
+
+    emit refreshFinished();
+
+    return !potentialWalletFileCorruption;
+}
+
+qsizetype Subaddress::count() const
+{
+    return m_rows.length();
+}
+
+const SubaddressRow& Subaddress::row(int index) const
+{
+    return m_rows[index];
 }
 
 const SubaddressRow& Subaddress::getRow(const qsizetype i)
@@ -30,6 +87,11 @@ const SubaddressRow& Subaddress::getRow(const qsizetype i)
     return m_rows[i];
 }
 
+const QList<SubaddressRow>& Subaddress::getRows()
+{
+    return m_rows;
+}
+
 bool Subaddress::addRow(quint32 accountIndex, const QString &label)
 {
     // This can fail if hardware device is unplugged during operating, catch here to prevent crash
@@ -85,12 +147,7 @@ bool Subaddress::setHidden(const QString &address, bool hidden)
     return r;
 }
 
-bool Subaddress::isHidden(const QString &address) 
-{
-    return m_hidden.contains(address);
-}
-
-bool Subaddress::setPinned(const QString &address, bool pinned) 
+bool Subaddress::setPinned(const QString &address, bool pinned)
 {
     if (pinned) {
         if (m_pinned.contains(address)) {
@@ -104,80 +161,21 @@ bool Subaddress::setPinned(const QString &address, bool pinned)
         }
         m_pinned.removeAll(address);
     }
-    
+
     bool r = m_wallet->setCacheAttribute("feather.pinnedaddresses", m_pinned.join(","));
 
     refresh(m_wallet->currentSubaddressAccount());
     return r;
 }
 
-bool Subaddress::isPinned(const QString &address)
-{
-    return m_pinned.contains(address);
-}
-
-bool Subaddress::refresh(quint32 accountIndex)
+bool Subaddress::isHidden(const QString &address) 
 {
-    emit refreshStarted();
-    
-    this->clearRows();
-
-    bool potentialWalletFileCorruption = false;
-
-    for (quint32 i = 0; i < m_wallet2->get_num_subaddresses(accountIndex); ++i)
-    {
-        cryptonote::subaddress_index index = {accountIndex, i};
-        cryptonote::account_public_address address = m_wallet2->get_subaddress(index);
-
-        // Make sure we have previously generated Di
-        auto idx =  m_wallet2->get_subaddress_index(address);
-        if (!idx) {
-            potentialWalletFileCorruption = true;
-            break;
-        }
-
-        // Verify mapping
-        if (idx != index) {
-            potentialWalletFileCorruption = true;
-            break;
-        }
-
-        QString addressStr = QString::fromStdString(cryptonote::get_account_address_as_str(m_wallet2->nettype(), !index.is_zero(), address));
-
-        m_rows.emplace_back(
-            addressStr,
-            QString::fromStdString(m_wallet2->get_subaddress_label(index)),
-            m_wallet2->get_subaddress_used({accountIndex, (uint32_t)i}),
-            this->isHidden(addressStr),
-            this->isPinned(addressStr)
-        );
-    }
-
-    // Make sure keys are intact. We NEVER want to display incorrect addresses in case of memory corruption.
-    potentialWalletFileCorruption = potentialWalletFileCorruption || (m_wallet2->get_device_type() == hw::device::SOFTWARE && !m_wallet2->verify_keys());
-
-    if (potentialWalletFileCorruption) {
-        LOG_ERROR("KEY INCONSISTENCY DETECTED, WALLET IS IN CORRUPT STATE.");
-        clearRows();
-        emit corrupted();
-    }
-
-    emit refreshFinished();
-
-    return !potentialWalletFileCorruption;
+    return m_hidden.contains(address);
 }
 
-qsizetype Subaddress::count() const
+bool Subaddress::isPinned(const QString &address)
 {
-    return m_rows.length();
-}
-
-void Subaddress::clearRows() {
-    m_rows.clear();
-}
-
-const SubaddressRow& Subaddress::row(int index) const {
-    return m_rows[index];
+    return m_pinned.contains(address);
 }
 
 QString Subaddress::getError() const {
index 80bdb2c85ff015214bec3e9365d91b76b259a4f7..b57d2370b86da9f591ae1e28eecd32d5ef74da51 100644 (file)
@@ -5,42 +5,33 @@
 #define SUBADDRESS_H
 
 #include <QObject>
-#include <QReadWriteLock>
-#include <QList>
-#include <QDateTime>
+#include <QString>
 
-#include "Wallet.h"
 #include "rows/SubaddressRow.h"
 
 namespace tools {
     class wallet2;
 }
 
+class Wallet;
 class Subaddress : public QObject
 {
     Q_OBJECT
 
 public:
-    const QList<SubaddressRow>& getRows();
+    bool refresh(quint32 accountIndex);
+    [[nodiscard]] qsizetype count() const;
+
+    const SubaddressRow& row(int index) const;
     const SubaddressRow& getRow(qsizetype i);
+    const QList<SubaddressRow>& getRows();
 
     bool addRow(quint32 accountIndex, const QString &label);
-    
     bool setLabel(quint32 accountIndex, quint32 addressIndex, const QString &label);
-
     bool setHidden(const QString& address, bool hidden);
-    bool isHidden(const QString& address);
-    bool isHidden(const SubaddressRow& row);
-
     bool setPinned(const QString& address, bool pinned);
+    bool isHidden(const QString& address);
     bool isPinned(const QString& address);
-    
-    bool refresh(quint32 accountIndex);
-    
-    [[nodiscard]] qsizetype count() const;
-    void clearRows();
-
-    const SubaddressRow& row(int index) const;
 
     QString getError() const;
 
index 7d5f0bbcc04fc0b10333eadb4da835279d437cc0..15faa51a67902f6bd836a87221cda2192270ba37 100644 (file)
@@ -10,23 +10,11 @@ SubaddressAccount::SubaddressAccount(tools::wallet2 *wallet2, QObject *parent)
 {
 }
 
-void SubaddressAccount::addRow(const QString &label)
-{
-    m_wallet2->add_subaddress_account(label.toStdString());
-    refresh();
-}
-
-void SubaddressAccount::setLabel(quint32 accountIndex, const QString &label)
-{
-    m_wallet2->set_subaddress_label({accountIndex, 0}, label.toStdString());
-    refresh();
-}
-
 void SubaddressAccount::refresh()
 {
     emit refreshStarted();
 
-    this->clearRows();
+    m_rows.clear();
 
     for (uint32_t i = 0; i < m_wallet2->get_num_subaddress_accounts(); ++i)
     {
@@ -45,9 +33,12 @@ qsizetype SubaddressAccount::count() const
     return m_rows.length();
 }
 
-void SubaddressAccount::clearRows()
+const AccountRow& SubaddressAccount::row(const int index) const
 {
-    m_rows.clear();
+    if (index < 0 || index >= m_rows.size()) {
+        throw std::out_of_range("Index out of range");
+    }
+    return m_rows[index];
 }
 
 const QList<AccountRow>& SubaddressAccount::getRows()
@@ -55,10 +46,14 @@ const QList<AccountRow>& SubaddressAccount::getRows()
     return m_rows;
 }
 
-const AccountRow& SubaddressAccount::row(const int index) const
+void SubaddressAccount::addRow(const QString &label)
 {
-    if (index < 0 || index >= m_rows.size()) {
-        throw std::out_of_range("Index out of range");
-    }
-    return m_rows[index];
+    m_wallet2->add_subaddress_account(label.toStdString());
+    refresh();
+}
+
+void SubaddressAccount::setLabel(quint32 accountIndex, const QString &label)
+{
+    m_wallet2->set_subaddress_label({accountIndex, 0}, label.toStdString());
+    refresh();
 }
index 65e2cea4b68adf9c286030660ed79a0222f5628d..c3c879904c7eb8849d238d1f6050bf83ac2f47d1 100644 (file)
@@ -1,8 +1,8 @@
 // SPDX-License-Identifier: BSD-3-Clause
 // SPDX-FileCopyrightText: The Monero Project
 
-#ifndef SUBADDRESSACCOUNT_H
-#define SUBADDRESSACCOUNT_H
+#ifndef FEATHER_SUBADDRESSACCOUNT_H
+#define FEATHER_SUBADDRESSACCOUNT_H
 
 #include <QObject>
 #include <QList>
@@ -18,15 +18,14 @@ class SubaddressAccount : public QObject
     Q_OBJECT
 
 public:
-    const QList<AccountRow>& getRows();
+    void refresh();
+    qsizetype count() const;
+
     const AccountRow& row(int index) const;
+    const QList<AccountRow>& getRows();
 
     void addRow(const QString &label);
     void setLabel(quint32 accountIndex, const QString &label);
-    qsizetype count() const;
-
-    void refresh();
-    void clearRows();
 
 signals:
     void refreshStarted() const;
@@ -40,4 +39,4 @@ private:
     QList<AccountRow> m_rows;
 };
 
-#endif // SUBADDRESSACCOUNT_H
+#endif // FEATHER_SUBADDRESSACCOUNT_H
index 9b2a8efa7f90442247b07247e681107d157b734c..f72964765994f79b3fbd44b2899063f8e2f9b45b 100644 (file)
@@ -6,10 +6,20 @@
 #include "utils/AppData.h"
 #include "utils/config.h"
 #include "constants.h"
+#include "Wallet.h"
 #include "WalletManager.h"
-#include "Transfer.h"
+#include "rows/Output.h"
 #include "wallet/wallet2.h"
 
+TransactionHistory::TransactionHistory(Wallet *wallet, tools::wallet2 *wallet2, QObject *parent)
+    : QObject(parent)
+    , m_wallet(wallet)
+    , m_wallet2(wallet2)
+    , m_locked(false)
+{
+
+}
+
 QString description(tools::wallet2 *wallet2, const tools::wallet2::payment_details &pd)
 {
     QString description = QString::fromStdString(wallet2->get_tx_note(pd.m_tx_hash));
@@ -27,37 +37,20 @@ QString description(tools::wallet2 *wallet2, const tools::wallet2::payment_detai
     return description;
 }
 
-const TransactionRow& TransactionHistory::transaction(int index)
-{
-    if (index < 0 || index >= m_rows.size()) {
-        throw std::out_of_range("Index out of range");
-    }
-    return m_rows[index];
-}
-
-const QList<TransactionRow>& TransactionHistory::getRows()
-{
-    return m_rows;
-}
-
 void TransactionHistory::refresh()
 {
     qDebug() << Q_FUNC_INFO;
 
-    QDateTime firstDateTime = QDate(2014, 4, 18).startOfDay();
-    QDateTime lastDateTime  = QDateTime::currentDateTime().addDays(1); // tomorrow (guard against jitter and timezones)
-
     emit refreshStarted();
 
     {
         QWriteLocker locker(&m_lock);
 
-        clearRows();
+        m_rows.clear();
 
         quint64 lastTxHeight = 0;
         bool hasFakePaymentId = m_wallet->isTrezor();
         m_locked = false;
-        m_minutesToUnlock = 0;
 
         uint64_t min_height = 0;
         uint64_t max_height = (uint64_t)-1;
@@ -264,20 +257,6 @@ void TransactionHistory::refresh()
     emit refreshFinished();
 }
 
-void TransactionHistory::setTxNote(const QString &txid, const QString &note)
-{
-    cryptonote::blobdata txid_data;
-    if (!epee::string_tools::parse_hexstr_to_binbuff(txid.toStdString(), txid_data) || txid_data.size() != sizeof(crypto::hash)) {
-        qDebug() << Q_FUNC_INFO << "invalid txid";
-        return;
-    }
-
-    const crypto::hash htxid = *reinterpret_cast<const crypto::hash*>(txid_data.data());
-
-    m_wallet2->set_tx_note(htxid, note.toStdString());
-    emit txNoteChanged();
-}
-
 quint64 TransactionHistory::count() const
 {
     QReadLocker locker(&m_lock);
@@ -285,44 +264,36 @@ quint64 TransactionHistory::count() const
     return m_rows.length();
 }
 
-QDateTime TransactionHistory::firstDateTime() const
-{
-    return m_firstDateTime;
-}
-
-QDateTime TransactionHistory::lastDateTime() const
+const TransactionRow& TransactionHistory::transaction(int index)
 {
-    return m_lastDateTime;
+    if (index < 0 || index >= m_rows.size()) {
+        throw std::out_of_range("Index out of range");
+    }
+    return m_rows[index];
 }
 
-quint64 TransactionHistory::minutesToUnlock() const
+const QList<TransactionRow>& TransactionHistory::getRows()
 {
-    return m_minutesToUnlock;
+    return m_rows;
 }
 
-bool TransactionHistory::TransactionHistory::locked() const
+void TransactionHistory::setTxNote(const QString &txid, const QString &note)
 {
-    return m_locked;
-}
+    cryptonote::blobdata txid_data;
+    if (!epee::string_tools::parse_hexstr_to_binbuff(txid.toStdString(), txid_data) || txid_data.size() != sizeof(crypto::hash)) {
+        qDebug() << Q_FUNC_INFO << "invalid txid";
+        return;
+    }
 
+    const crypto::hash htxid = *reinterpret_cast<const crypto::hash*>(txid_data.data());
 
-TransactionHistory::TransactionHistory(Wallet *wallet, tools::wallet2 *wallet2, QObject *parent)
-    : QObject(parent)
-    , m_wallet(wallet)
-    , m_wallet2(wallet2)
-    , m_minutesToUnlock(0)
-    , m_locked(false)
-{
-#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
-    m_firstDateTime = QDate(2014, 4, 18).startOfDay();
-#else
-    m_firstDateTime  = QDateTime(QDate(2014, 4, 18)); // the genesis block
-#endif
-    m_lastDateTime = QDateTime::currentDateTime().addDays(1); // tomorrow (guard against jitter and timezones)
+    m_wallet2->set_tx_note(htxid, note.toStdString());
+    emit txNoteChanged();
 }
 
-void TransactionHistory::clearRows() {
-    m_rows.clear();
+bool TransactionHistory::locked() const
+{
+    return m_locked;
 }
 
 QStringList parseCSVLine(const QString &line) {
index c07a4af51d7e8b203ba23349421ad288aeb099b7..2a26286c779544fa2d6bcaba3db6d370571dbbf2 100644 (file)
@@ -1,18 +1,12 @@
 // SPDX-License-Identifier: BSD-3-Clause
 // SPDX-FileCopyrightText: The Monero Project
 
-#ifndef TRANSACTIONHISTORY_H
-#define TRANSACTIONHISTORY_H
+#ifndef FEATHER_TRANSACTIONHISTORY_H
+#define FEATHER_TRANSACTIONHISTORY_H
 
-#include <functional>
-
-#include <QObject>
-#include <QList>
 #include <QReadWriteLock>
-#include <QDateTime>
 
 #include "rows/TransactionRow.h"
-#include "Wallet.h"
 
 namespace tools {
     class wallet2;
@@ -23,23 +17,20 @@ struct TransactionHistory;
 }
 
 class TransactionInfo;
-
+class Wallet;
 class TransactionHistory : public QObject
 {
     Q_OBJECT
 
 public:
+    void refresh();
+    quint64 count() const;
+
     const TransactionRow& transaction(int index);
     const QList<TransactionRow>& getRows();
 
-    void refresh();
     void setTxNote(const QString &txid, const QString &note);
-    quint64 count() const;
-    QDateTime firstDateTime() const;
-    QDateTime lastDateTime() const;
-    quint64 minutesToUnlock() const;
     bool locked() const;
-    void clearRows();
 
     QString importLabelsFromCSV(const QString &fileName);
 
@@ -70,4 +61,4 @@ private:
     quint32 lastAccountIndex = 0;
 };
 
-#endif // TRANSACTIONHISTORY_H
+#endif // FEATHER_TRANSACTIONHISTORY_H
diff --git a/src/libwalletqt/Transfer.h b/src/libwalletqt/Transfer.h
deleted file mode 100644 (file)
index 486054e..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-// SPDX-License-Identifier: BSD-3-Clause
-// SPDX-FileCopyrightText: The Monero Project
-
-#ifndef TRANSFER_H
-#define TRANSFER_H
-
-struct Transfer
-{
-    QString address;
-    quint64 amount;
-
-    explicit Transfer(uint64_t amount_, QString address_)
-        : address(std::move(address_))
-        , amount(amount_) {}
-};
-
-#endif // TRANSFER_H
index 543d6b56f1fc36a2267000a7ebd6f6811cdd29eb..02206dde573a3f4593faaac66e9627a0a20ddc8c 100644 (file)
@@ -3,7 +3,7 @@
 
 #include "UnsignedTransaction.h"
 
-#include "ConstructionInfo.h"
+#include "rows/ConstructionInfo.h"
 #include <wallet/api/wallet2_api.h>
 
 UnsignedTransaction::Status UnsignedTransaction::status() const
index a81970c4b46b54a24f59bbf4bcff57677df34230..cac1a003c0b1a72156b29867870bc694c46508e0 100644 (file)
@@ -1,8 +1,8 @@
 // SPDX-License-Identifier: BSD-3-Clause
 // SPDX-FileCopyrightText: The Monero Project
 
-#ifndef UNSIGNEDTRANSACTION_H
-#define UNSIGNEDTRANSACTION_H
+#ifndef FEATHER_UNSIGNEDTRANSACTION_H
+#define FEATHER_UNSIGNEDTRANSACTION_H
 
 #include <QObject>
 
@@ -54,4 +54,4 @@ private:
     mutable QList<ConstructionInfo> m_construction_info;
 };
 
-#endif // UNSIGNEDTRANSACTION_H
+#endif // FEATHER_UNSIGNEDTRANSACTION_H
index d7273f91625990a3d42808caa34b29dd082063f6..74838c67891471d5e69b58a2ac4b0ae694086406 100644 (file)
@@ -1,8 +1,8 @@
 // SPDX-License-Identifier: BSD-3-Clause
 // SPDX-FileCopyrightText: The Monero Project
 
-#ifndef WALLET_H
-#define WALLET_H
+#ifndef FEATHER_WALLET_H
+#define FEATHER_WALLET_H
 
 #include <QObject>
 #include <QMutex>
@@ -533,4 +533,4 @@ private:
     std::set<std::string> m_selectedInputs;
 };
 
-#endif // WALLET_H
+#endif // FEATHER_WALLET_H
index e63d40cd4fb992948b265cfce9edd308d60fe939..c5416c0c6cf62b1a2c2f0e9a4e3c068156e01660 100644 (file)
@@ -1,8 +1,8 @@
 // SPDX-License-Identifier: BSD-3-Clause
 // SPDX-FileCopyrightText: The Monero Project
 
-#ifndef MONERO_GUI_WALLETLISTENERIMPL_H
-#define MONERO_GUI_WALLETLISTENERIMPL_H
+#ifndef FEATHER_WALLETLISTENERIMPL_H
+#define FEATHER_WALLETLISTENERIMPL_H
 
 #include "wallet/api/wallet2_api.h"
 #include "PassphraseHelper.h"
@@ -14,32 +14,32 @@ class WalletListenerImpl : public Monero::WalletListener, public PassphraseRecei
 public:
     WalletListenerImpl(Wallet * w);
 
-    virtual void moneySpent(const std::string &txId, uint64_t amount) override;
+    void moneySpent(const std::string &txId, uint64_t amount) override;
 
-    virtual void moneyReceived(const std::string &txId, uint64_t amount, bool coinbase) override;
+    void moneyReceived(const std::string &txId, uint64_t amount, bool coinbase) override;
 
-    virtual void unconfirmedMoneyReceived(const std::string &txId, uint64_t amount) override;
+    void unconfirmedMoneyReceived(const std::string &txId, uint64_t amount) override;
 
-    virtual void newBlock(uint64_t height) override;
+    void newBlock(uint64_t height) override;
 
-    virtual void updated() override;
+    void updated() override;
 
     // called when wallet refreshed by background thread or explicitly
-    virtual void refreshed(bool success) override;
+    void refreshed(bool success) override;
 
-    virtual void onDeviceButtonRequest(uint64_t code) override;
+    void onDeviceButtonRequest(uint64_t code) override;
 
-    virtual void onDeviceButtonPressed() override;
+    void onDeviceButtonPressed() override;
 
-    virtual void onDeviceError(const std::string &message, unsigned int error_code) override;
+    void onDeviceError(const std::string &message, unsigned int error_code) override;
 
-    virtual void onPassphraseEntered(const QString &passphrase, bool enter_on_device, bool entry_abort) override;
+    void onPassphraseEntered(const QString &passphrase, bool enter_on_device, bool entry_abort) override;
 
-    virtual std::optional<std::string> onDevicePassphraseRequest(bool & on_device) override;
+    std::optional<std::string> onDevicePassphraseRequest(bool & on_device) override;
 
 private:
     Wallet * m_wallet;
     PassphraseHelper m_phelper;
 };
 
-#endif //MONERO_GUI_WALLETLISTENERIMPL_H
+#endif //FEATHER_WALLETLISTENERIMPL_H
index 21de94ea2333e73990aecc5be61beb5aeabbbafb..c95895ae031b346d8c0c241d4471429a79632388 100644 (file)
@@ -1,8 +1,8 @@
 // SPDX-License-Identifier: BSD-3-Clause
 // SPDX-FileCopyrightText: The Monero Project
 
-#ifndef WALLETMANAGER_H
-#define WALLETMANAGER_H
+#ifndef FEATHER_WALLETMANAGER_H
+#define FEATHER_WALLETMANAGER_H
 
 #include <QObject>
 #include <QMutex>
@@ -138,4 +138,4 @@ private:
     FutureScheduler m_scheduler;
 };
 
-#endif // WALLETMANAGER_H
+#endif // FEATHER_WALLETMANAGER_H
index 499ddacc8caaa8f6402a6bd1659fb8d3e32a5ef8..c1f3a46fddf183e8c057f9a2d4cf81183396b9db 100644 (file)
@@ -13,11 +13,11 @@ struct AccountRow
     quint64 balance;
     quint64 unlockedBalance;
 
-    AccountRow(const QString& address_, const QString &label_, uint64_t balance_, uint64_t unlockedBalance_)
-            : address(address_)
-            , label(label_)
-            , balance(balance_)
-            , unlockedBalance(unlockedBalance_) {}
+    AccountRow(const QString& address, const QString &label, uint64_t balance, uint64_t unlockedBalance)
+            : address(address)
+            , label(label)
+            , balance(balance)
+            , unlockedBalance(unlockedBalance) {}
 };
 
 #endif //FEATHER_ACCOUNTROW_H
similarity index 94%
rename from src/libwalletqt/ConstructionInfo.cpp
rename to src/libwalletqt/rows/ConstructionInfo.cpp
index 0aa33cfa21e3130cbb380cdb36fd6f29a9d57516..a3fa6783fdf0d433e93d9d104d60e10d83e934f2 100644 (file)
@@ -2,9 +2,6 @@
 // SPDX-FileCopyrightText: The Monero Project
 
 #include "ConstructionInfo.h"
-
-#include "Input.h"
-#include "Transfer.h"
 #include <wallet/api/wallet2_api.h>
 
 ConstructionInfo::ConstructionInfo(const Monero::TransactionConstructionInfo *pimpl)
similarity index 91%
rename from src/libwalletqt/ConstructionInfo.h
rename to src/libwalletqt/rows/ConstructionInfo.h
index 28e21b2ed794382b8bb40e181ae8bfa4e779e922..b88d20b2dcddb2f5e908bc3446ee058b945beff5 100644 (file)
@@ -6,7 +6,7 @@
 
 #include <QSet>
 
-#include "Transfer.h"
+#include "Output.h"
 #include "Input.h"
 
 namespace Monero {
@@ -20,7 +20,7 @@ struct ConstructionInfo
     QVector<QString> subaddresses;
     quint64 minMixinCount;
     QList<Input> inputs;
-    QList<Transfer> outputs;
+    QList<Output> outputs;
 
     explicit ConstructionInfo(const Monero::TransactionConstructionInfo *pimpl);
 };
index 214d80fc67b51aa759f9bbfb4176cbfbeaed7873..ed5ee2b757857e80ccf4e422e9de6f6dc4ff0107 100644 (file)
@@ -11,9 +11,9 @@ struct ContactRow
     QString address;
     QString label;
 
-    ContactRow(const QString address_, const QString &label_)
-        : address(address_)
-        , label(label_) {}
+    ContactRow(const QString address, const QString& label)
+        : address(address)
+        , label(label) {}
 };
 
 #endif //FEATHER_CONTACTROW_H
similarity index 64%
rename from src/libwalletqt/Input.h
rename to src/libwalletqt/rows/Input.h
index b98cf70e4142e4e027d2e52fd99ff7c677273ebb..0b16cbdb99e2e094feec66c89896930af551cc42 100644 (file)
@@ -9,9 +9,9 @@ struct Input
     QString pubKey;
     quint64 amount;
 
-    explicit Input(uint64_t _amount, QString _pubkey)
-        : pubKey(std::move(_pubkey))
-        , amount(_amount) {}
+    explicit Input(uint64_t amount, QString pubkey)
+        : pubKey(std::move(pubkey))
+        , amount(amount) {}
 };
 
 #endif //FEATHER_INPUT_H
diff --git a/src/libwalletqt/rows/Output.h b/src/libwalletqt/rows/Output.h
new file mode 100644 (file)
index 0000000..c35e81c
--- /dev/null
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: BSD-3-Clause
+// SPDX-FileCopyrightText: The Monero Project
+
+#ifndef FEATHER_TRANSFER_H
+#define FEATHER_TRANSFER_H
+
+struct Output
+{
+    QString address;
+    quint64 amount;
+
+    explicit Output(uint64_t amount, QString address)
+        : address(std::move(address))
+        , amount(amount) {}
+};
+
+#endif // FEATHER_TRANSFER_H
similarity index 96%
rename from src/libwalletqt/PendingTransactionInfo.h
rename to src/libwalletqt/rows/PendingTransactionInfo.h
index 540a4e588c752c6924a1cf9349294a96e6ba4eab..cd7763477dd13162512bdfe291b2aa2a9df22202 100644 (file)
@@ -6,7 +6,7 @@
 
 #include "ConstructionInfo.h"
 
-#include <QObject>
+#include <QString>
 
 namespace Monero {
     class PendingTransactionInfo;
index 01777d28d9464cc502436233f7e2fdb0ae0342ba..3669507f12953a9da94a7f665696eee442bb323d 100644 (file)
@@ -14,12 +14,12 @@ struct SubaddressRow
     bool hidden = false;
     bool pinned = false;
 
-    SubaddressRow(const QString& address_, const QString &label_, bool used_, bool hidden_, bool pinned_)
-        : address(address_)
-        , label(label_)
-        , used(used_)
-        , hidden(hidden_)
-        , pinned(pinned_) {}
+    SubaddressRow(const QString& address, const QString &label, bool used, bool hidden, bool pinned)
+        : address(address)
+        , label(label)
+        , used(used)
+        , hidden(hidden)
+        , pinned(pinned) {}
 };
 
 #endif //FEATHER_SUBADDRESSROW_H
index 523bccf78daff59e124cdff6230be809c1e42ff7..cabd004701b6f5090374167048ddcf634b022a3d 100644 (file)
@@ -3,7 +3,7 @@
 
 #include "TransactionRow.h"
 #include "WalletManager.h"
-#include "Transfer.h"
+#include "Output.h"
 
 TransactionRow::TransactionRow()
         : amount(0)
index 1501e00a96772699e3641b610df243d7880bc5a0..db5a466073dcc24d63d01d5c127de42d9978cac0 100644 (file)
@@ -12,11 +12,11 @@ struct Ring
     QString keyImage;
     std::vector<uint64_t> ringMembers;
 
-    explicit Ring(QString _keyImage, std::vector<uint64_t> _ringMembers)
-        : keyImage(std::move(_keyImage))
-        , ringMembers(std::move(_ringMembers)) {}
+    explicit Ring(QString keyImage, std::vector<uint64_t> ringMembers)
+        : keyImage(std::move(keyImage))
+        , ringMembers(std::move(ringMembers)) {}
 };
-struct Transfer;
+struct Output;
 
 struct TransactionRow
 {
@@ -26,7 +26,7 @@ struct TransactionRow
         Direction_Both // invalid direction value, used for filtering
     };
 
-    QList<Transfer> transfers;
+    QList<Output> transfers;
     QList<Ring> rings;
     qint64 amount; // Amount that was sent (to destinations) or received, excludes tx fee
     qint64 balanceDelta; // How much the total balance was mutated as a result of this tx (includes tx fee)