Merge pull request 'Allow resending failed transactions' (#212) from tobtoht/feather:black_holed_no_more into master

Reviewed-on: https://git.wownero.com/feather/feather/pulls/212
This commit is contained in:
tobtoht 2020-12-14 22:27:12 +00:00
commit 2217ae602a
10 changed files with 68 additions and 40 deletions

View file

@ -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();

View file

@ -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);

View file

@ -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://"))

View file

@ -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:

View file

@ -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>

View file

@ -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();
}

View file

@ -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);
}

View file

@ -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;

View file

@ -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)

View file

@ -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();