mirror of
				https://git.wownero.com/wowlet/wowlet.git
				synced 2024-08-15 01:03:14 +00:00 
			
		
		
		
	Allow resending failed transactions
This commit is contained in:
		
							parent
							
								
									15211ce5fa
								
							
						
					
					
						commit
						169d14ab3a
					
				
					 10 changed files with 68 additions and 40 deletions
				
			
		| 
						 | 
				
			
			@ -37,6 +37,7 @@ WalletKeysFilesModel *AppContext::wallets = nullptr;
 | 
			
		|||
TxFiatHistory *AppContext::txFiatHistory = nullptr;
 | 
			
		||||
double AppContext::balance = 0;
 | 
			
		||||
QMap<QString, QString> AppContext::txDescriptionCache;
 | 
			
		||||
QMap<QString, QString> AppContext::txCache;
 | 
			
		||||
 | 
			
		||||
AppContext::AppContext(QCommandLineParser *cmdargs) {
 | 
			
		||||
    this->network = new QNetworkAccessManager();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -86,6 +86,7 @@ public:
 | 
			
		|||
    static WalletKeysFilesModel *wallets;
 | 
			
		||||
    static double balance;
 | 
			
		||||
    static QMap<QString, QString> txDescriptionCache;
 | 
			
		||||
    static QMap<QString, QString> txCache;
 | 
			
		||||
    static TxFiatHistory *txFiatHistory;
 | 
			
		||||
 | 
			
		||||
    // libwalletqt
 | 
			
		||||
| 
						 | 
				
			
			@ -172,7 +173,6 @@ signals:
 | 
			
		|||
    void setTitle(const QString &title); // set window title
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    void sorry();
 | 
			
		||||
    const unsigned int m_donationBoundary = 15;
 | 
			
		||||
    UtilsNetworking *m_utilsNetworkingNodes;
 | 
			
		||||
    QTimer *m_storeTimer = new QTimer(this);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,10 +3,11 @@
 | 
			
		|||
 | 
			
		||||
#include "broadcasttxdialog.h"
 | 
			
		||||
#include "ui_broadcasttxdialog.h"
 | 
			
		||||
#include "utils/nodes.h"
 | 
			
		||||
 | 
			
		||||
#include <QMessageBox>
 | 
			
		||||
 | 
			
		||||
BroadcastTxDialog::BroadcastTxDialog(QWidget *parent, AppContext *ctx)
 | 
			
		||||
BroadcastTxDialog::BroadcastTxDialog(QWidget *parent, AppContext *ctx, const QString &transactionHex)
 | 
			
		||||
        : QDialog(parent)
 | 
			
		||||
        , m_ctx(ctx)
 | 
			
		||||
        , ui(new Ui::BroadcastTxDialog)
 | 
			
		||||
| 
						 | 
				
			
			@ -23,6 +24,10 @@ BroadcastTxDialog::BroadcastTxDialog(QWidget *parent, AppContext *ctx)
 | 
			
		|||
 | 
			
		||||
    connect(m_rpc, &DaemonRpc::ApiResponse, this, &BroadcastTxDialog::onApiResponse);
 | 
			
		||||
 | 
			
		||||
    if (!transactionHex.isEmpty()) {
 | 
			
		||||
        ui->transaction->setPlainText(transactionHex);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    this->adjustSize();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -33,7 +38,7 @@ void BroadcastTxDialog::broadcastTx() {
 | 
			
		|||
        QString node;
 | 
			
		||||
        if (ui->radio_useCustom->isChecked())
 | 
			
		||||
            node = ui->customNode->text();
 | 
			
		||||
        else
 | 
			
		||||
        else if (ui->radio_useDefault->isChecked())
 | 
			
		||||
            node = m_ctx->nodes->connection().full;
 | 
			
		||||
 | 
			
		||||
        if (!node.startsWith("http://"))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -17,7 +17,7 @@ class BroadcastTxDialog : public QDialog
 | 
			
		|||
    Q_OBJECT
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    explicit BroadcastTxDialog(QWidget *parent, AppContext *ctx);
 | 
			
		||||
    explicit BroadcastTxDialog(QWidget *parent, AppContext *ctx, const QString &transactionHex = "");
 | 
			
		||||
    ~BroadcastTxDialog() override;
 | 
			
		||||
 | 
			
		||||
private slots:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -63,16 +63,6 @@
 | 
			
		|||
     </layout>
 | 
			
		||||
    </widget>
 | 
			
		||||
   </item>
 | 
			
		||||
   <item>
 | 
			
		||||
    <widget class="QLabel" name="label_2">
 | 
			
		||||
     <property name="enabled">
 | 
			
		||||
      <bool>false</bool>
 | 
			
		||||
     </property>
 | 
			
		||||
     <property name="text">
 | 
			
		||||
      <string>All transactions are broadcast over Tor</string>
 | 
			
		||||
     </property>
 | 
			
		||||
    </widget>
 | 
			
		||||
   </item>
 | 
			
		||||
   <item>
 | 
			
		||||
    <layout class="QHBoxLayout" name="horizontalLayout">
 | 
			
		||||
     <item>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -51,6 +51,7 @@ TxConfDialog::TxConfDialog(AppContext *ctx, PendingTransaction *tx, const QStrin
 | 
			
		|||
 | 
			
		||||
    connect(ui->btn_Advanced, &QPushButton::clicked, this, &TxConfDialog::setShowAdvanced);
 | 
			
		||||
 | 
			
		||||
    AppContext::txCache[tx->txid()[0]] = tx->signedTxToHex(0);
 | 
			
		||||
    this->adjustSize();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -25,20 +25,9 @@ HistoryWidget::HistoryWidget(QWidget *parent)
 | 
			
		|||
    m_copyMenu->addAction("Transaction ID", this, [this]{copy(copyField::TxID);});
 | 
			
		||||
    m_copyMenu->addAction("Date", this, [this]{copy(copyField::Date);});
 | 
			
		||||
    m_copyMenu->addAction("Amount", this, [this]{copy(copyField::Amount);});
 | 
			
		||||
    auto spendProof = m_copyMenu->addAction("Spend proof", this, &HistoryWidget::getSpendProof);
 | 
			
		||||
 | 
			
		||||
    ui->history->setContextMenuPolicy(Qt::CustomContextMenu);
 | 
			
		||||
    connect(ui->history, &QTreeView::customContextMenuRequested, [=](const QPoint & point){
 | 
			
		||||
        QModelIndex index = ui->history->indexAt(point);
 | 
			
		||||
        if (index.isValid()) {
 | 
			
		||||
            TransactionInfo::Direction direction;
 | 
			
		||||
            m_txHistory->transaction(m_model->mapToSource(index).row(), [&direction](TransactionInfo &tInfo) {
 | 
			
		||||
                direction = tInfo.direction();
 | 
			
		||||
            });
 | 
			
		||||
            spendProof->setVisible(direction == TransactionInfo::Direction_Out);
 | 
			
		||||
            m_contextMenu->exec(ui->history->viewport()->mapToGlobal(point));
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
    connect(ui->history, &QTreeView::customContextMenuRequested, this, &HistoryWidget::showContextMenu);
 | 
			
		||||
    connect(ui->search, &QLineEdit::textChanged, this, &HistoryWidget::setSearchFilter);
 | 
			
		||||
 | 
			
		||||
    connect(ui->history, &QTreeView::doubleClicked, [this](QModelIndex index){
 | 
			
		||||
| 
						 | 
				
			
			@ -50,6 +39,43 @@ HistoryWidget::HistoryWidget(QWidget *parent)
 | 
			
		|||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void HistoryWidget::showContextMenu(const QPoint &point) {
 | 
			
		||||
    QModelIndex index = ui->history->indexAt(point);
 | 
			
		||||
    if (!index.isValid()) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    QMenu menu(this);
 | 
			
		||||
    TransactionInfo::Direction direction;
 | 
			
		||||
    QString txid;
 | 
			
		||||
    bool unconfirmed;
 | 
			
		||||
    m_txHistory->transaction(m_model->mapToSource(index).row(), [&direction, &txid, &unconfirmed](TransactionInfo &tInfo) {
 | 
			
		||||
        direction = tInfo.direction();
 | 
			
		||||
        txid = tInfo.hash();
 | 
			
		||||
        unconfirmed = tInfo.isFailed() || tInfo.isPending();
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    if (AppContext::txCache.contains(txid) && unconfirmed) {
 | 
			
		||||
        menu.addAction(QIcon(":/assets/images/info.png"), "Resend transaction", this, &HistoryWidget::onResendTransaction);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    menu.addMenu(m_copyMenu);
 | 
			
		||||
    menu.addAction(QIcon(":/assets/images/info.png"), "Show details", this, &HistoryWidget::showTxDetails);
 | 
			
		||||
    menu.addAction(QIcon(":/assets/images/network.png"), "View on block explorer", this, &HistoryWidget::onViewOnBlockExplorer);
 | 
			
		||||
 | 
			
		||||
    menu.exec(ui->history->viewport()->mapToGlobal(point));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void HistoryWidget::onResendTransaction() {
 | 
			
		||||
    QModelIndex index = ui->history->currentIndex();
 | 
			
		||||
    QString txid;
 | 
			
		||||
    m_txHistory->transaction(m_model->mapToSource(index).row(), [&txid](TransactionInfo &tInfo) {
 | 
			
		||||
        txid = tInfo.hash();
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    emit resendTransaction(txid);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void HistoryWidget::setModel(TransactionHistoryProxyModel *model, Wallet *wallet)
 | 
			
		||||
{
 | 
			
		||||
    m_model = model;
 | 
			
		||||
| 
						 | 
				
			
			@ -86,14 +112,6 @@ void HistoryWidget::onViewOnBlockExplorer() {
 | 
			
		|||
    emit viewOnBlockExplorer(txid);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void HistoryWidget::getSpendProof() {
 | 
			
		||||
    QModelIndex index = ui->history->currentIndex();
 | 
			
		||||
 | 
			
		||||
    m_txHistory->transaction(m_model->mapToSource(index).row(), [this](TransactionInfo &tInfo) {
 | 
			
		||||
        emit spendProof(tInfo.hash());
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void HistoryWidget::setSearchText(const QString &text) {
 | 
			
		||||
    ui->search->setText(text);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -29,14 +29,14 @@ public slots:
 | 
			
		|||
    void setSearchText(const QString &text);
 | 
			
		||||
 | 
			
		||||
signals:
 | 
			
		||||
    void spendProof(QString txid);
 | 
			
		||||
    void viewOnBlockExplorer(QString txid);
 | 
			
		||||
    void resendTransaction(QString txid);
 | 
			
		||||
 | 
			
		||||
private slots:
 | 
			
		||||
    void showTxDetails();
 | 
			
		||||
    void onViewOnBlockExplorer();
 | 
			
		||||
    void getSpendProof();
 | 
			
		||||
    void setSearchFilter(const QString &filter);
 | 
			
		||||
    void onResendTransaction();
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    enum copyField {
 | 
			
		||||
| 
						 | 
				
			
			@ -46,6 +46,7 @@ private:
 | 
			
		|||
    };
 | 
			
		||||
 | 
			
		||||
    void copy(copyField field);
 | 
			
		||||
    void showContextMenu(const QPoint &point);
 | 
			
		||||
 | 
			
		||||
    Ui::HistoryWidget *ui;
 | 
			
		||||
    QMenu *m_contextMenu;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -289,11 +289,8 @@ MainWindow::MainWindow(AppContext *ctx, QWidget *parent) :
 | 
			
		|||
    });
 | 
			
		||||
 | 
			
		||||
    // History
 | 
			
		||||
    connect(ui->historyWidget, &HistoryWidget::spendProof, [&](const QString &txid){
 | 
			
		||||
        TxProof txproof = m_ctx->currentWallet->getSpendProof(txid, "");
 | 
			
		||||
        Utils::copyToClipboard(txproof.proof);
 | 
			
		||||
    });
 | 
			
		||||
    connect(ui->historyWidget, &HistoryWidget::viewOnBlockExplorer, this, &MainWindow::onViewOnBlockExplorer);
 | 
			
		||||
    connect(ui->historyWidget, &HistoryWidget::resendTransaction, this, &MainWindow::onResendTransaction);
 | 
			
		||||
 | 
			
		||||
    // Contacts
 | 
			
		||||
    connect(ui->contactWidget, &ContactsWidget::addContact, this, &MainWindow::onAddContact);
 | 
			
		||||
| 
						 | 
				
			
			@ -1055,6 +1052,20 @@ void MainWindow::onViewOnBlockExplorer(const QString &txid) {
 | 
			
		|||
    Utils::externalLinkWarning(this, blockExplorerLink);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MainWindow::onResendTransaction(const QString &txid) {
 | 
			
		||||
    if (!AppContext::txCache.contains(txid)) {
 | 
			
		||||
        QMessageBox::warning(this, "Unable to resend transaction", "Transaction was not found in transaction cache. Unable to resend.");
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Connect to a different node so chances of successful relay are higher
 | 
			
		||||
    m_ctx->nodes->autoConnect(true);
 | 
			
		||||
 | 
			
		||||
    auto dialog = new BroadcastTxDialog(this, m_ctx, AppContext::txCache[txid]);
 | 
			
		||||
    dialog->exec();
 | 
			
		||||
    dialog->deleteLater();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MainWindow::onAddContact(const QString &address, const QString &name) {
 | 
			
		||||
    bool addressValid = WalletManager::addressValid(address, m_ctx->currentWallet->nettype());
 | 
			
		||||
    if (!addressValid)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -117,6 +117,7 @@ public slots:
 | 
			
		|||
    void menuWalletOpenClicked();
 | 
			
		||||
    void onWalletOpenPasswordRequired(bool invalidPassword, const QString &path);
 | 
			
		||||
    void onViewOnBlockExplorer(const QString &txid);
 | 
			
		||||
    void onResendTransaction(const QString &txid);
 | 
			
		||||
    void onAddContact(const QString &address, const QString &name);
 | 
			
		||||
    void importContacts();
 | 
			
		||||
    void showRestoreHeightDialog();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue