From 38c3a3a8164903a8fe17d608830de82c6c542f1f Mon Sep 17 00:00:00 2001 From: tobtoht Date: Thu, 31 Dec 2020 04:26:03 +0100 Subject: [PATCH] Send: don't lose precision --- src/appcontext.cpp | 16 ++++----- src/appcontext.h | 2 +- src/libwalletqt/WalletManager.cpp | 4 +-- src/libwalletqt/WalletManager.h | 4 +-- src/mainwindow.cpp | 2 +- src/sendwidget.cpp | 55 +++++++++++++++++-------------- src/sendwidget.h | 5 +-- 7 files changed, 47 insertions(+), 41 deletions(-) diff --git a/src/appcontext.cpp b/src/appcontext.cpp index 7409e83..65f7a9d 100644 --- a/src/appcontext.cpp +++ b/src/appcontext.cpp @@ -206,10 +206,11 @@ void AppContext::onSweepOutput(const QString &keyImage, QString address, bool ch void AppContext::onCreateTransaction(XmrToOrder *order) { // tx creation via xmr.to const QString description = QString("XmrTo order %1").arg(order->uuid); - this->onCreateTransaction(order->receiving_subaddress, order->incoming_amount_total, description, false); + quint64 amount = WalletManager::amountFromDouble(order->incoming_amount_total); + this->onCreateTransaction(order->receiving_subaddress, amount, description, false); } -void AppContext::onCreateTransaction(const QString &address, const double amount, const QString &description, bool all) { +void AppContext::onCreateTransaction(const QString &address, quint64 amount, const QString &description, bool all) { // tx creation this->tmpTxDescription = description; @@ -218,13 +219,13 @@ void AppContext::onCreateTransaction(const QString &address, const double amount return; } - if (!all && amount <= 0) { + if (!all && amount == 0) { emit createTransactionError("Cannot send nothing"); return; } - auto balance = this->currentWallet->balance() / globals::cdiv; - auto unlocked_balance = this->currentWallet->unlockedBalance() / globals::cdiv; + auto balance = this->currentWallet->balance(); + auto unlocked_balance = this->currentWallet->unlockedBalance(); if(!all && amount > unlocked_balance) { emit createTransactionError("Not enough money to spend"); return; @@ -233,12 +234,11 @@ void AppContext::onCreateTransaction(const QString &address, const double amount return; } - auto amount_num = static_cast(amount * globals::cdiv); qDebug() << "creating tx"; - if(all || amount == balance) + if (all) this->currentWallet->createTransactionAllAsync(address, "", this->tx_mixin, this->tx_priority); else - this->currentWallet->createTransactionAsync(address, "", amount_num, this->tx_mixin, this->tx_priority); + this->currentWallet->createTransactionAsync(address, "", amount, this->tx_mixin, this->tx_priority); emit initiateTransaction(); } diff --git a/src/appcontext.h b/src/appcontext.h index 3ae8c18..4c25a9f 100644 --- a/src/appcontext.h +++ b/src/appcontext.h @@ -109,7 +109,7 @@ public: public slots: void onOpenWallet(const QString& path, const QString &password); - void onCreateTransaction(const QString &address, double amount, const QString &description, bool all); + void onCreateTransaction(const QString &address, quint64 amount, const QString &description, bool all); void onCreateTransaction(XmrToOrder *order); void onCancelTransaction(PendingTransaction *tx, const QString &address); void onSweepOutput(const QString &keyImage, QString address, bool churn, int outputs) const; diff --git a/src/libwalletqt/WalletManager.cpp b/src/libwalletqt/WalletManager.cpp index ce1b99e..fb0b0fc 100644 --- a/src/libwalletqt/WalletManager.cpp +++ b/src/libwalletqt/WalletManager.cpp @@ -255,12 +255,12 @@ QString WalletManager::displayAmount(quint64 amount) return QString::fromStdString(Monero::Wallet::displayAmount(amount)); } -quint64 WalletManager::amountFromString(const QString &amount) const +quint64 WalletManager::amountFromString(const QString &amount) { return Monero::Wallet::amountFromString(amount.toStdString()); } -quint64 WalletManager::amountFromDouble(double amount) const +quint64 WalletManager::amountFromDouble(double amount) { return Monero::Wallet::amountFromDouble(amount); } diff --git a/src/libwalletqt/WalletManager.h b/src/libwalletqt/WalletManager.h index 28c72be..35df670 100644 --- a/src/libwalletqt/WalletManager.h +++ b/src/libwalletqt/WalletManager.h @@ -113,8 +113,8 @@ public: //! since we can't call static method from QML, move it to this class Q_INVOKABLE static QString displayAmount(quint64 amount); - Q_INVOKABLE quint64 amountFromString(const QString &amount) const; - Q_INVOKABLE quint64 amountFromDouble(double amount) const; + Q_INVOKABLE static quint64 amountFromString(const QString &amount); + Q_INVOKABLE static quint64 amountFromDouble(double amount); Q_INVOKABLE quint64 maximumAllowedAmount() const; // QML JS engine doesn't support unsigned integers diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 25cf126..02aecaf 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -149,7 +149,7 @@ MainWindow::MainWindow(AppContext *ctx, QWidget *parent) : ui->fiatTickerLayout->addWidget(m_balanceWidget); // Send widget - connect(ui->sendWidget, &SendWidget::createTransaction, m_ctx, QOverload::of(&AppContext::onCreateTransaction)); + connect(ui->sendWidget, &SendWidget::createTransaction, m_ctx, QOverload::of(&AppContext::onCreateTransaction)); // Nodes connect(m_ctx->nodes, &Nodes::nodeExhausted, this, &MainWindow::showNodeExhaustedMessage); diff --git a/src/sendwidget.cpp b/src/sendwidget.cpp index fe26d16..5e0b883 100644 --- a/src/sendwidget.cpp +++ b/src/sendwidget.cpp @@ -5,6 +5,7 @@ #include "sendwidget.h" #include "mainwindow.h" #include "ui_sendwidget.h" +#include "globals.h" SendWidget::SendWidget(QWidget *parent) : QWidget(parent), @@ -87,7 +88,6 @@ void SendWidget::sendClicked() { return; } - double amount; QString currency = ui->comboCurrencySelection->currentText(); QString recipient = ui->lineAddress->text().simplified().remove(' '); QString description = ui->lineDescription->text(); @@ -96,24 +96,23 @@ void SendWidget::sendClicked() { return; } - if (currency != "XMR") { - amount = this->conversionAmount(); - if(amount <= 0.0) { + quint64 amount; + if (currency == "XMR") { + amount = this->amount(); + bool sendAll = (ui->lineAmount->text() == "all"); + if (amount == 0 && !sendAll) { + QMessageBox::warning(this, "Amount error", "Invalid amount specified."); + return; + } + emit createTransaction(recipient, amount, description, sendAll); + } else { + amount = WalletManager::amountFromDouble(this->conversionAmount()); + if (amount == 0) { QMessageBox::warning(this, "Fiat conversion error", "Could not create transaction."); return; } emit createTransaction(recipient, amount, description, false); - return; } - - amount = this->amount(); - bool sendAll = amount == -1.0; - if(amount == 0.0){ - QMessageBox::warning(this, "Amount error", "Invalid amount specified."); - return; - } - - emit createTransaction(recipient, amount, description, sendAll); } void SendWidget::aliasClicked() { @@ -129,13 +128,14 @@ void SendWidget::clearClicked() { void SendWidget::btnMaxClicked() { ui->lineAmount->setText("all"); + this->updateConversionLabel(); } void SendWidget::updateConversionLabel() { - auto amount = this->amount(); - if(amount == -1) return; + auto amount = this->amountDouble(); + ui->label_conversionAmount->setText(""); - if(amount <= 0) { + if (amount <= 0) { ui->label_conversionAmount->hide(); return; } @@ -147,7 +147,7 @@ void SendWidget::updateConversionLabel() { } else { auto preferredFiatCurrency = config()->get(Config::preferredFiatCurrency).toString(); - double conversionAmount = AppContext::prices->convert("XMR", preferredFiatCurrency, this->amount()); + double conversionAmount = AppContext::prices->convert("XMR", preferredFiatCurrency, this->amountDouble()); return QString("~%1 %2").arg(QString::number(conversionAmount, 'f', 2), preferredFiatCurrency); } }(); @@ -158,18 +158,23 @@ void SendWidget::updateConversionLabel() { double SendWidget::conversionAmount() { QString currency = ui->comboCurrencySelection->currentText(); - return AppContext::prices->convert(currency, "XMR", this->amount()); + return AppContext::prices->convert(currency, "XMR", this->amountDouble()); } -double SendWidget::amount() { +quint64 SendWidget::amount() { // grab amount from "amount" text box QString amount = ui->lineAmount->text(); - if(amount == "all") return -1.0; + if (amount == "all") return 0; + amount.replace(',', '.'); - if(amount.isEmpty()) return 0.0; - auto amount_num = amount.toDouble(); - if(amount_num <= 0) return 0.0; - return amount_num; + if (amount.isEmpty()) return 0; + + return WalletManager::amountFromString(amount); +} + +double SendWidget::amountDouble() { + quint64 amount = this->amount(); + return amount / globals::cdiv; } void SendWidget::onOpenAliasResolved(const QString &address, const QString &openAlias) { diff --git a/src/sendwidget.h b/src/sendwidget.h index 464e2fe..91bac4b 100644 --- a/src/sendwidget.h +++ b/src/sendwidget.h @@ -44,14 +44,15 @@ public slots: signals: void resolveOpenAlias(const QString &address); - void createTransaction(const QString &address, double amount, const QString &description, bool all); + void createTransaction(const QString &address, quint64 amount, const QString &description, bool all); private: void setupComboBox(); + double amountDouble(); Ui::SendWidget *ui; AppContext *m_ctx; - double amount(); + quint64 amount(); double conversionAmount(); };