From fcf764e03c3758e753b43723a2e36237f251ce71 Mon Sep 17 00:00:00 2001 From: tobtoht Date: Tue, 16 Mar 2021 04:17:01 +0100 Subject: [PATCH] Multibroadcast transactions --- src/appcontext.cpp | 29 +++ src/appcontext.h | 4 + src/dialog/txconfadvdialog.cpp | 2 +- src/libwalletqt/Wallet.cpp | 9 +- src/mainwindow.cpp | 2 +- src/settings.cpp | 4 + src/settings.ui | 395 +++++++++++++++++---------------- src/utils/config.cpp | 3 +- src/utils/config.h | 3 +- src/utils/nodes.cpp | 4 + src/utils/nodes.h | 6 +- src/widgets/nodewidget.cpp | 2 +- src/wizard/WalletWizard.cpp | 3 +- 13 files changed, 260 insertions(+), 206 deletions(-) diff --git a/src/appcontext.cpp b/src/appcontext.cpp index afa53d0..a8361e6 100644 --- a/src/appcontext.cpp +++ b/src/appcontext.cpp @@ -265,6 +265,35 @@ void AppContext::onAmountPrecisionChanged(int precision) { model->amountPrecision = precision; } +void AppContext::commitTransaction(PendingTransaction *tx) { + // Nodes - even well-connected, properly configured ones - consistently fail to relay transactions + // To mitigate transactions failing we just send the transaction to every node we know about over Tor + if (config()->get(Config::multiBroadcast).toBool()) { + this->onMultiBroadcast(tx); + } + + this->currentWallet->commitTransactionAsync(tx); +} + +void AppContext::onMultiBroadcast(PendingTransaction *tx) { + UtilsNetworking *net = new UtilsNetworking(this->network, this); + DaemonRpc *rpc = new DaemonRpc(this, net, ""); + + int count = tx->txCount(); + for (int i = 0; i < count; i++) { + QString txData = tx->signedTxToHex(i); + + for (const auto& node: this->nodes->websocketNodes()) { + if (!node.online) continue; + + QString address = node.as_url(); + qDebug() << QString("Relaying to: %1").arg(address); + rpc->setDaemonAddress(address); + rpc->sendRawTransaction(txData); + } + } +} + void AppContext::onWalletOpened(Wallet *wallet) { auto state = wallet->status(); if (state != Wallet::Status_Ok) { diff --git a/src/appcontext.h b/src/appcontext.h index 5e185e4..33ebe16 100644 --- a/src/appcontext.h +++ b/src/appcontext.h @@ -18,6 +18,7 @@ #include "utils/wsclient.h" #include "utils/txfiathistory.h" #include "utils/FeatherSeed.h" +#include "utils/daemonrpc.h" #include "widgets/RedditPost.h" #include "widgets/CCSEntry.h" #include "utils/RestoreHeightLookup.h" @@ -66,6 +67,7 @@ public: WSClient *ws; XmRig *XMRig; Nodes *nodes; + DaemonRpc *daemonRpc; static Prices *prices; static WalletKeysFilesModel *wallets; static double balance; @@ -81,6 +83,7 @@ public: void createWallet(FeatherSeed seed, const QString &path, const QString &password, const QString &seedOffset = ""); void createWalletFromKeys(const QString &path, const QString &password, const QString &address, const QString &viewkey, const QString &spendkey, quint64 restoreHeight, bool deterministic = false); void createWalletFinish(const QString &password); + void commitTransaction(PendingTransaction *tx); void syncStatusUpdated(quint64 height, quint64 target); void updateBalance(); void initTor(); @@ -105,6 +108,7 @@ public slots: void onSetRestoreHeight(quint64 height); void onPreferredFiatCurrencyChanged(const QString &symbol); void onAmountPrecisionChanged(int precision); + void onMultiBroadcast(PendingTransaction *tx); private slots: void onWSNodes(const QJsonArray &nodes); diff --git a/src/dialog/txconfadvdialog.cpp b/src/dialog/txconfadvdialog.cpp index cc67e4d..13dfb63 100644 --- a/src/dialog/txconfadvdialog.cpp +++ b/src/dialog/txconfadvdialog.cpp @@ -172,7 +172,7 @@ void TxConfAdvDialog::signedQrCode() { void TxConfAdvDialog::broadcastTransaction() { if (m_tx == nullptr) return; - m_ctx->currentWallet->commitTransactionAsync(m_tx); + m_ctx->commitTransaction(m_tx); QDialog::accept(); } diff --git a/src/libwalletqt/Wallet.cpp b/src/libwalletqt/Wallet.cpp index 0140207..c1ed8e9 100644 --- a/src/libwalletqt/Wallet.cpp +++ b/src/libwalletqt/Wallet.cpp @@ -1286,11 +1286,10 @@ Wallet::~Wallet() //Monero::WalletManagerFactory::getWalletManager()->closeWallet(m_walletImpl); if(status() == Status_Critical) qDebug("Not storing wallet cache"); - // Don't store on wallet close for now -// else if( m_walletImpl->store("")) -// qDebug("Wallet cache stored successfully"); -// else -// qDebug("Error storing wallet cache"); + else if( m_walletImpl->store("")) + qDebug("Wallet cache stored successfully"); + else + qDebug("Error storing wallet cache"); delete m_walletImpl; m_walletImpl = NULL; delete m_walletListener; diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index a9df680..7e0e03c 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -751,7 +751,7 @@ void MainWindow::onCreateTransactionSuccess(PendingTransaction *tx, const QVecto break; } case QDialog::Accepted: - m_ctx->currentWallet->commitTransactionAsync(tx); + m_ctx->commitTransaction(tx); break; } diff --git a/src/settings.cpp b/src/settings.cpp index 295f2f2..cf7d293 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -20,6 +20,9 @@ Settings::Settings(QWidget *parent) : ui->tabWidget->setTabVisible(4, false); connect(ui->btnCopyToClipboard, &QPushButton::clicked, this, &Settings::copyToClipboard); + connect(ui->checkBox_multiBroadcast, &QCheckBox::toggled, [](bool toggled){ + config()->set(Config::multiBroadcast, toggled); + }); connect(ui->checkBox_externalLink, &QCheckBox::clicked, this, &Settings::checkboxExternalLinkWarn); connect(ui->checkBox_hideBalance, &QCheckBox::toggled, [this](bool toggled){ config()->set(Config::hideBalance, toggled); @@ -34,6 +37,7 @@ Settings::Settings(QWidget *parent) : connect(ui->nodeWidget, &NodeWidget::connectToNode, m_ctx->nodes, QOverload::of(&Nodes::connectToNode)); // setup checkboxes + ui->checkBox_multiBroadcast->setChecked(config()->get(Config::multiBroadcast).toBool()); ui->checkBox_externalLink->setChecked(config()->get(Config::warnOnExternalLink).toBool()); ui->checkBox_hideBalance->setChecked(config()->get(Config::hideBalance).toBool()); diff --git a/src/settings.ui b/src/settings.ui index 46b1311..1892866 100644 --- a/src/settings.ui +++ b/src/settings.ui @@ -23,214 +23,225 @@ General - - - + + + + + + + Preferred fiat currency: + + + + + + + + USD + + + + + EUR + + + + + RUB + + + + + GBP + + + + + AUD + + + + + CAD + + + + + CHF + + + + + CNY + + + + + CZK + + + + + JPY + + + + + KRW + + + + + MXN + + + + + NZD + + + + + SEK + + + + + THB + + + + + TRY + + + + + ZAR + + + + + + + + Appearance: + + + + + + + + + + Block explorer: + + + + + + + + exploremonero.com + + + + + xmrchain.net + + + + + moneroblocks.info + + + + + blockchair.com + + + + + + + + Reddit frontend: + + + + + + + + old.reddit.com + + + + + reddit.com + + + + + teddit.net + + + + + + + + Amount precision: + + + + + + + + + + Date format: + + + + + + + + + + Time format: + + + + + + + + + + - Preferred fiat currency: + Multibroadcast outgoing transactions - - - - - USD - - - - - EUR - - - - - RUB - - - - - GBP - - - - - AUD - - - - - CAD - - - - - CHF - - - - - CNY - - - - - CZK - - - - - JPY - - - - - KRW - - - - - MXN - - - - - NZD - - - - - SEK - - - - - THB - - - - - TRY - - - - - ZAR - - - - - - - - Appearance: - - - - - - - - - - Block explorer: - - - - - - - - exploremonero.com - - - - - xmrchain.net - - - - - moneroblocks.info - - - - - blockchair.com - - - - - + Warn before opening external link - + Hide balance - - - - Reddit frontend: - - - - - - - - old.reddit.com - - - - - reddit.com - - - - - teddit.net - - - - - - - - Amount precision: - - - - - - - - - - Date format: - - - - - - - - - - Time format: - - - - - - diff --git a/src/utils/config.cpp b/src/utils/config.cpp index 6bd659e..ce14f97 100644 --- a/src/utils/config.cpp +++ b/src/utils/config.cpp @@ -50,7 +50,8 @@ static const QHash configStrings = { {Config::GUI_HistoryViewState, {QS("GUI_HistoryViewState"), {}}}, {Config::amountPrecision, {QS("amountPrecision"), 4}}, {Config::dateFormat, {QS("dateFormat"), "yyyy-MM-dd"}}, - {Config::timeFormat, {QS("timeFormat"), "HH:mm"}} + {Config::timeFormat, {QS("timeFormat"), "HH:mm"}}, + {Config::multiBroadcast, {QS("multiBroadcast"), true}} }; diff --git a/src/utils/config.h b/src/utils/config.h index 6398d8f..1b0b11e 100644 --- a/src/utils/config.h +++ b/src/utils/config.h @@ -54,7 +54,8 @@ public: amountPrecision, portableMode, dateFormat, - timeFormat + timeFormat, + multiBroadcast }; ~Config() override; diff --git a/src/utils/nodes.cpp b/src/utils/nodes.cpp index f75c520..ade3921 100644 --- a/src/utils/nodes.cpp +++ b/src/utils/nodes.cpp @@ -376,6 +376,10 @@ QList Nodes::customNodes() { return m_customNodes; } +QList Nodes::websocketNodes() { + return m_websocketNodes; +} + FeatherNode Nodes::connection() { return m_connection; } diff --git a/src/utils/nodes.h b/src/utils/nodes.h index 97c8ccb..cc87b97 100644 --- a/src/utils/nodes.h +++ b/src/utils/nodes.h @@ -69,8 +69,8 @@ struct FeatherNode { return QString("%1%2").arg(auth).arg(this->address); } - QString as_url() { - return QString("%1://%2/get_info").arg(this->isHttps ? "https": "http",this->full); + QString as_url() const { + return QString("%1://%2").arg(this->isHttps ? "https": "http",this->full); } bool operator == (const FeatherNode &other) const { @@ -88,7 +88,9 @@ public: NodeSource source(); FeatherNode connection(); + QList customNodes(); + QList websocketNodes(); NodeModel *modelWebsocket; NodeModel *modelCustom; diff --git a/src/widgets/nodewidget.cpp b/src/widgets/nodewidget.cpp index 4fe5056..1f18e89 100644 --- a/src/widgets/nodewidget.cpp +++ b/src/widgets/nodewidget.cpp @@ -94,7 +94,7 @@ void NodeWidget::onContextConnect() { void NodeWidget::onContextStatusURL() { FeatherNode node = this->selectedNode(); if (!node.full.isEmpty()) - Utils::externalLinkWarning(this, node.as_url()); + Utils::externalLinkWarning(this, QString("%1/get_info").arg(node.as_url())); } void NodeWidget::onContextNodeCopy() { diff --git a/src/wizard/WalletWizard.cpp b/src/wizard/WalletWizard.cpp index 2f12bcb..d375dad 100644 --- a/src/wizard/WalletWizard.cpp +++ b/src/wizard/WalletWizard.cpp @@ -69,8 +69,7 @@ WalletWizard::WalletWizard(AppContext *ctx, WalletWizard::Page startPage, QWidge }); connect(openWalletPage, &PageOpenWallet::openWallet, [=](const QString &path){ - const auto walletPassword = this->field("walletPassword").toString(); - emit openWallet(path, walletPassword); + emit openWallet(path, ""); }); }