mirror of
https://github.com/feather-wallet/feather.git
synced 2024-12-23 03:59:29 +00:00
Multibroadcast transactions
This commit is contained in:
parent
858861436b
commit
fcf764e03c
13 changed files with 260 additions and 206 deletions
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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<const FeatherNode&>::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());
|
||||
|
||||
|
|
|
@ -23,7 +23,9 @@
|
|||
<attribute name="title">
|
||||
<string>General</string>
|
||||
</attribute>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout_3">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
|
@ -161,20 +163,6 @@
|
|||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QCheckBox" name="checkBox_externalLink">
|
||||
<property name="text">
|
||||
<string>Warn before opening external link</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<widget class="QCheckBox" name="checkBox_hideBalance">
|
||||
<property name="text">
|
||||
<string>Hide balance</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="text">
|
||||
|
@ -232,6 +220,29 @@
|
|||
<widget class="QComboBox" name="comboBox_timeFormat"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBox_multiBroadcast">
|
||||
<property name="text">
|
||||
<string>Multibroadcast outgoing transactions</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBox_externalLink">
|
||||
<property name="text">
|
||||
<string>Warn before opening external link</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBox_hideBalance">
|
||||
<property name="text">
|
||||
<string>Hide balance</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_node">
|
||||
<attribute name="title">
|
||||
|
|
|
@ -50,7 +50,8 @@ static const QHash<Config::ConfigKey, ConfigDirective> 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}}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -54,7 +54,8 @@ public:
|
|||
amountPrecision,
|
||||
portableMode,
|
||||
dateFormat,
|
||||
timeFormat
|
||||
timeFormat,
|
||||
multiBroadcast
|
||||
};
|
||||
|
||||
~Config() override;
|
||||
|
|
|
@ -376,6 +376,10 @@ QList<FeatherNode> Nodes::customNodes() {
|
|||
return m_customNodes;
|
||||
}
|
||||
|
||||
QList<FeatherNode> Nodes::websocketNodes() {
|
||||
return m_websocketNodes;
|
||||
}
|
||||
|
||||
FeatherNode Nodes::connection() {
|
||||
return m_connection;
|
||||
}
|
||||
|
|
|
@ -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<FeatherNode> customNodes();
|
||||
QList<FeatherNode> websocketNodes();
|
||||
|
||||
NodeModel *modelWebsocket;
|
||||
NodeModel *modelCustom;
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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, "");
|
||||
});
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue