subaddress: cleanup

This commit is contained in:
tobtoht 2025-03-27 09:17:38 +01:00
parent 45f3d89dd3
commit ce2f332114
No known key found for this signature in database
GPG key ID: E45B10DD027D2472
10 changed files with 85 additions and 73 deletions

View file

@ -572,13 +572,12 @@ void MainWindow::onWalletOpened() {
this->setEnabled(true);
// receive page
m_wallet->subaddress()->refresh(m_wallet->currentSubaddressAccount());
m_wallet->subaddress()->refresh();
if (m_wallet->subaddress()->count() == 1) {
for (int i = 0; i < 10; i++) {
m_wallet->subaddress()->addRow(m_wallet->currentSubaddressAccount(), "");
m_wallet->subaddress()->addRow("");
}
}
m_wallet->subaddressModel()->setCurrentSubaddressAccount(m_wallet->currentSubaddressAccount());
// history page
m_wallet->history()->refresh();

View file

@ -236,7 +236,7 @@ void ReceiveWidget::showOnDevice() {
}
void ReceiveWidget::generateSubaddress() {
bool r = m_wallet->subaddress()->addRow(m_wallet->currentSubaddressAccount(), "");
bool r = m_wallet->subaddress()->addRow("");
if (!r) {
Utils::showError(this, "Failed to generate subaddress", m_wallet->subaddress()->getError());
}

View file

@ -43,8 +43,11 @@ AccountSwitcherDialog::AccountSwitcherDialog(Wallet *wallet, QWidget *parent)
connect(ui->accounts, &QTreeView::customContextMenuRequested, this, &AccountSwitcherDialog::showContextMenu);
connect(ui->btn_newAccount, &QPushButton::clicked, [this]{
m_wallet->addSubaddressAccount("New account");
m_wallet->subaddressAccount()->refresh();
m_wallet->addSubaddressAccount("New account");
m_wallet->subaddressAccount()->refresh();
for (int i = 0; i < 10; i ++) {
m_wallet->subaddress()->addRow("");
}
});
connect(m_wallet->subaddressAccount(), &SubaddressAccount::refreshFinished, this, &AccountSwitcherDialog::updateSelection);

View file

@ -18,50 +18,26 @@ Subaddress::Subaddress(Wallet *wallet, tools::wallet2 *wallet2, QObject *parent)
m_hidden = hidden.split(",");
connect(this, &Subaddress::noUnusedSubaddresses, [this] {
this->addRow(m_wallet->currentSubaddressAccount(), "");
this->addRow("");
});
}
bool Subaddress::refresh(quint32 accountIndex)
bool Subaddress::refresh()
{
emit refreshStarted();
m_rows.clear();
bool haveUnused = false;
bool potentialWalletFileCorruption = false;
quint32 accountIndex = m_wallet->currentSubaddressAccount();
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) {
bool r = emplaceRow(i);
if (!r) {
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));
bool used = m_wallet2->get_subaddress_used({accountIndex, (uint32_t)i});
m_rows.emplace_back(
addressStr,
QString::fromStdString(m_wallet2->get_subaddress_label(index)),
used,
this->isHidden(addressStr),
this->isPinned(addressStr)
);
if (!used && i > 0) {
haveUnused = true;
}
}
// Make sure keys are intact. We NEVER want to display incorrect addresses in case of memory corruption.
@ -75,10 +51,6 @@ bool Subaddress::refresh(quint32 accountIndex)
emit refreshFinished();
if (!haveUnused) {
emit noUnusedSubaddresses();
}
return !potentialWalletFileCorruption;
}
@ -125,14 +97,52 @@ const QList<SubaddressRow>& Subaddress::getRows()
return m_rows;
}
bool Subaddress::addRow(quint32 accountIndex, const QString &label)
bool Subaddress::emplaceRow(quint32 addressIndex)
{
cryptonote::subaddress_index index = {m_wallet->currentSubaddressAccount(), addressIndex};
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) {
return false;
}
// Verify mapping
if (idx != index) {
return false;
}
if (m_rows.length() != addressIndex) {
return false;
}
QString addressStr = QString::fromStdString(cryptonote::get_account_address_as_str(m_wallet2->nettype(), !index.is_zero(), address));
bool used = m_wallet2->get_subaddress_used(index);
m_rows.emplace_back(
addressStr,
QString::fromStdString(m_wallet2->get_subaddress_label(index)),
used,
this->isHidden(addressStr),
this->isPinned(addressStr),
index.is_zero()
);
return true;
}
bool Subaddress::addRow(const QString &label)
{
// This can fail if hardware device is unplugged during operating, catch here to prevent crash
// Todo: Notify GUI that it was a device error
try
{
m_wallet2->add_subaddress(accountIndex, label.toStdString());
refresh(accountIndex);
quint32 addressIndex = m_wallet->numSubaddresses(m_wallet->currentSubaddressAccount());
m_wallet2->add_subaddress(m_wallet->currentSubaddressAccount(), label.toStdString());
emit beginAddRow(addressIndex);
emplaceRow(addressIndex);
emit endAddRow();
}
catch (const std::exception& e)
{
@ -145,11 +155,13 @@ bool Subaddress::addRow(quint32 accountIndex, const QString &label)
return true;
}
bool Subaddress::setLabel(quint32 accountIndex, quint32 addressIndex, const QString &label)
bool Subaddress::setLabel(quint32 addressIndex, const QString &label)
{
try {
m_wallet2->set_subaddress_label({accountIndex, addressIndex}, label.toStdString());
refresh(accountIndex);
m_wallet2->set_subaddress_label({m_wallet->currentSubaddressAccount(), addressIndex}, label.toStdString());
SubaddressRow& row = m_rows[addressIndex];
row.label = label;
emit rowUpdated(addressIndex);
}
catch (const std::exception& e)
{
@ -176,7 +188,7 @@ bool Subaddress::setHidden(const QString &address, bool hidden)
bool r = m_wallet->setCacheAttribute("feather.hiddenaddresses", m_hidden.join(","));
refresh(m_wallet->currentSubaddressAccount());
refresh();
return r;
}
@ -197,7 +209,7 @@ bool Subaddress::setPinned(const QString &address, bool pinned)
bool r = m_wallet->setCacheAttribute("feather.pinnedaddresses", m_pinned.join(","));
refresh(m_wallet->currentSubaddressAccount());
refresh();
return r;
}

View file

@ -19,7 +19,7 @@ class Subaddress : public QObject
Q_OBJECT
public:
bool refresh(quint32 accountIndex);
bool refresh();
void updateUsed(quint32 accountIndex);
[[nodiscard]] qsizetype count() const;
@ -27,8 +27,8 @@ public:
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 addRow(const QString &label);
bool setLabel(quint32 addressIndex, const QString &label);
bool setHidden(const QString& address, bool hidden);
bool setPinned(const QString& address, bool pinned);
bool isHidden(const QString& address);
@ -42,8 +42,12 @@ signals:
void rowUpdated(qsizetype index) const;
void corrupted() const;
void noUnusedSubaddresses() const;
void beginAddRow(qsizetype index) const;
void endAddRow() const;
private:
bool emplaceRow(quint32 addressIndex);
explicit Subaddress(Wallet *wallet, tools::wallet2 *wallet2, QObject *parent);
friend class Wallet;

View file

@ -295,10 +295,9 @@ void Wallet::switchSubaddressAccount(quint32 accountIndex) {
{
qWarning() << "failed to set " << ATTRIBUTE_SUBADDRESS_ACCOUNT << " cache attribute";
}
m_subaddress->refresh(m_currentSubaddressAccount);
m_subaddress->refresh();
m_history->refresh();
m_coins->refresh();
this->subaddressModel()->setCurrentSubaddressAccount(m_currentSubaddressAccount);
this->coinsModel()->setCurrentSubaddressAccount(m_currentSubaddressAccount);
this->updateBalance();
this->setSelectedInputs({});
@ -318,18 +317,10 @@ quint32 Wallet::numSubaddresses(quint32 accountIndex) const {
return m_wallet2->get_num_subaddresses(accountIndex);
}
void Wallet::addSubaddress(const QString& label) {
m_wallet2->add_subaddress(currentSubaddressAccount(), label.toStdString());
}
QString Wallet::getSubaddressLabel(quint32 accountIndex, quint32 addressIndex) const {
return QString::fromStdString(m_walletImpl->getSubaddressLabel(accountIndex, addressIndex));
}
void Wallet::setSubaddressLabel(quint32 accountIndex, quint32 addressIndex, const QString &label) {
m_walletImpl->setSubaddressLabel(accountIndex, addressIndex, label.toStdString());
}
void Wallet::deviceShowAddressAsync(quint32 accountIndex, quint32 addressIndex, const QString &paymentId) {
m_scheduler.run([this, accountIndex, addressIndex, paymentId] {
m_walletImpl->deviceShowAddress(accountIndex, addressIndex, paymentId.toStdString());
@ -440,6 +431,7 @@ void Wallet::initAsync(const QString &daemonAddress, bool trustedDaemon, quint64
// #################### Synchronization (Refresh) ####################
void Wallet::startRefresh() {
m_refreshEnabled = true;
m_refreshEnabled = true;
m_refreshNow = true;
}
@ -599,7 +591,7 @@ void Wallet::onRefreshed(bool success, const QString &message) {
void Wallet::refreshModels() {
m_history->refresh();
m_coins->refresh();
this->subaddress()->refresh(this->currentSubaddressAccount());
m_subaddress->refresh();
}
// #################### Hardware wallet ####################
@ -1008,7 +1000,7 @@ void Wallet::onTransactionCommitted(bool success, PendingTransaction *tx, const
this->history()->refresh();
this->coins()->refresh();
this->subaddress()->refresh(this->currentSubaddressAccount());
this->subaddress()->refresh();
this->updateBalance();

View file

@ -170,9 +170,7 @@ public:
void addSubaddressAccount(const QString& label);
quint32 numSubaddressAccounts() const;
quint32 numSubaddresses(quint32 accountIndex) const;
void addSubaddress(const QString& label);
QString getSubaddressLabel(quint32 accountIndex, quint32 addressIndex) const;
void setSubaddressLabel(quint32 accountIndex, quint32 addressIndex, const QString &label);
void deviceShowAddressAsync(quint32 accountIndex, quint32 addressIndex, const QString &paymentId);
QString getSubaddressLookahead() const;

View file

@ -13,13 +13,15 @@ struct SubaddressRow
bool used = false;
bool hidden = false;
bool pinned = false;
bool primary = false;
SubaddressRow(const QString& address, const QString &label, bool used, bool hidden, bool pinned)
SubaddressRow(const QString& address, const QString &label, bool used, bool hidden, bool pinned, bool primary)
: address(address)
, label(label)
, used(used)
, hidden(hidden)
, pinned(pinned) {}
, pinned(pinned)
, primary(primary) {}
};
#endif //FEATHER_SUBADDRESSROW_H

View file

@ -19,6 +19,8 @@ SubaddressModel::SubaddressModel(QObject *parent, Subaddress *subaddress)
{
connect(m_subaddress, &Subaddress::refreshStarted, this, &SubaddressModel::beginResetModel);
connect(m_subaddress, &Subaddress::refreshFinished, this, &SubaddressModel::endResetModel);
connect(m_subaddress, &Subaddress::beginAddRow, this, &SubaddressModel::beginRowAdded);
connect(m_subaddress, &Subaddress::endAddRow, this, &SubaddressModel::endInsertRows);
connect(m_subaddress, &Subaddress::rowUpdated, this, &SubaddressModel::rowUpdated);
}
@ -163,7 +165,7 @@ bool SubaddressModel::setData(const QModelIndex &index, const QVariant &value, i
switch (index.column()) {
case Label:
m_subaddress->setLabel(m_currentSubaddressAccount, row, value.toString());
m_subaddress->setLabel(row, value.toString());
break;
default:
return false;
@ -186,10 +188,6 @@ Qt::ItemFlags SubaddressModel::flags(const QModelIndex &index) const
return QAbstractTableModel::flags(index);
}
void SubaddressModel::setCurrentSubaddressAccount(quint32 accountIndex) {
m_currentSubaddressAccount = accountIndex;
}
const SubaddressRow& SubaddressModel::entryFromIndex(const QModelIndex &index) const {
Q_ASSERT(index.isValid() && index.row() < m_subaddress->count());
return m_subaddress->row(index.row());
@ -199,3 +197,8 @@ void SubaddressModel::rowUpdated(qsizetype index)
{
emit dataChanged(this->index(index, 0), this->index(index, SubaddressModel::COUNT - 1), {Qt::DisplayRole, Qt::EditRole});
}
void SubaddressModel::beginRowAdded(qsizetype index)
{
this->beginInsertRows(this->index(index, 0), index, index);
}

View file

@ -36,9 +36,8 @@ public:
const SubaddressRow& entryFromIndex(const QModelIndex &index) const;
void setCurrentSubaddressAccount(quint32 accountIndex);
void rowUpdated(qsizetype index);
void beginRowAdded(qsizetype index);
private:
Subaddress *m_subaddress;