DragonX compatibility: crash fixes, reorg detection, server failover, sync perf
- Fix Rust FFI panics with catch_unwind wrappers and safe CString handling - Handle poisoned mutex/RwLock from prior panics instead of crashing - Add stuck sync detection (10s stall threshold) and chain reorg user prompt - Add "Skip Verification" button to seed phrase wizard - Update payment URIs from hush: to drgx: - Update branding strings throughout UI - Add all 6 lite servers (lite, lite1-5.dragonx.is) with random selection - Add server connectivity probing to skip unreachable servers - Reuse Tokio runtime across block fetch batches to reduce sync overhead - Update Cargo.lock dependencies
This commit is contained in:
@@ -1,194 +1,194 @@
|
||||
// Copyright 2019-2024 The Hush developers
|
||||
// Released under the GPLv3
|
||||
#include "requestdialog.h"
|
||||
#include "ui_requestdialog.h"
|
||||
#include "settings.h"
|
||||
#include "addressbook.h"
|
||||
#include "mainwindow.h"
|
||||
#include "controller.h"
|
||||
#include "settings.h"
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
RequestDialog::RequestDialog(QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::RequestDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
||||
RequestDialog::~RequestDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void RequestDialog::setupDialog(MainWindow* main, QDialog* d, Ui_RequestDialog* req) {
|
||||
req->setupUi(d);
|
||||
Settings::saveRestore(d);
|
||||
|
||||
// Setup
|
||||
req->txtMemo->setLenDisplayLabel(req->lblMemoLen);
|
||||
req->lblAmount->setText(req->lblAmount->text() + Settings::getTokenName());
|
||||
|
||||
if (!main || !main->getRPC())
|
||||
return;
|
||||
|
||||
for (auto addr : main->getRPC()->getModel()->getAllZAddresses()) {
|
||||
auto bal = main->getRPC()->getModel()->getAllBalances().value(addr);
|
||||
if (Settings::getInstance()->isSaplingAddress(addr)) {
|
||||
req->cmbMyAddress->addItem(addr, bal);
|
||||
}
|
||||
}
|
||||
req->cmbMyAddress->setCurrentText(main->getRPC()->getDefaultSaplingAddress());
|
||||
|
||||
QIcon icon(":/icons/res/paymentreq.gif");
|
||||
req->lblPixmap->setPixmap(icon.pixmap(48, 48));
|
||||
}
|
||||
|
||||
// Static method that shows an incoming payment request and prompts the user to pay it
|
||||
void RequestDialog::showPaymentConfirmation(MainWindow* main, QString paymentURI) {
|
||||
PaymentURI payInfo = Settings::parseURI(paymentURI);
|
||||
if (!payInfo.error.isEmpty()) {
|
||||
QMessageBox::critical(main, tr("Error paying DRGX URI"),
|
||||
tr("URI should be of the form 'hush:<addr>?amt=x&memo=y") + "\n" + payInfo.error);
|
||||
return;
|
||||
}
|
||||
|
||||
QDialog d(main);
|
||||
Ui_RequestDialog req;
|
||||
setupDialog(main, &d, &req);
|
||||
|
||||
// In the view mode, all fields are read-only
|
||||
req.txtAmount->setReadOnly(true);
|
||||
req.txtFrom->setReadOnly(true);
|
||||
req.txtMemo->setReadOnly(true);
|
||||
|
||||
// Payment is "to"
|
||||
req.lblAddress->setText(tr("Pay To"));
|
||||
|
||||
// No Addressbook
|
||||
req.btnAddressBook->setVisible(false);
|
||||
|
||||
// No "address is visible" warning
|
||||
req.lblAddressInfo->setVisible(false);
|
||||
|
||||
req.txtFrom->setText(payInfo.addr);
|
||||
req.txtMemo->setPlainText(payInfo.memo);
|
||||
req.txtAmount->setText(payInfo.amt);
|
||||
CAmount amount = CAmount::fromDecimalString(req.txtAmount->text());
|
||||
if (Settings::getInstance()->get_currency_name() == "USD") {
|
||||
req.txtAmountUSD->setText(amount.toDecimalUSDString());
|
||||
} else if (Settings::getInstance()->get_currency_name() == "EUR") {
|
||||
req.txtAmountUSD->setText(amount.toDecimalEURString());
|
||||
} else if (Settings::getInstance()->get_currency_name() == "BTC") {
|
||||
req.txtAmountUSD->setText(amount.toDecimalBTCString());
|
||||
}
|
||||
|
||||
req.buttonBox->button(QDialogButtonBox::Ok)->setText(tr("Pay"));
|
||||
|
||||
req.lblHeader->setText(tr("You are paying a payment request. Your address will not be visible to the person requesting this payment."));
|
||||
|
||||
if (d.exec() == QDialog::Accepted) {
|
||||
main->payhushURI(paymentURI, req.cmbMyAddress->currentText());
|
||||
}
|
||||
}
|
||||
|
||||
// Static method that shows the request dialog
|
||||
void RequestDialog::showRequesthush(MainWindow* main) {
|
||||
QDialog d(main);
|
||||
Ui_RequestDialog req;
|
||||
|
||||
setupDialog(main, &d, &req);
|
||||
|
||||
// Setup the Label completer for the Address
|
||||
req.txtFrom->setCompleter(main->getLabelCompleter());
|
||||
QObject::connect(req.txtFrom, &QLineEdit::textChanged, [=] (auto text) {
|
||||
auto addr = AddressBook::addressFromAddressLabel(text);
|
||||
if (!Settings::getInstance()->isSaplingAddress(addr)) {
|
||||
req.lblSaplingWarning->setText(tr("Can only request from Sapling addresses"));
|
||||
req.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
|
||||
} else {
|
||||
req.lblSaplingWarning->setText("");
|
||||
req.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true);
|
||||
}
|
||||
});
|
||||
|
||||
// Wire up AddressBook button
|
||||
QObject::connect(req.btnAddressBook, &QPushButton::clicked, [=] () {
|
||||
AddressBook::open(main, req.txtFrom);
|
||||
});
|
||||
|
||||
// Amount textbox
|
||||
req.txtAmount->setValidator(main->getAmountValidator());
|
||||
QObject::connect(req.txtAmount, &QLineEdit::textChanged, [=] (auto text) {
|
||||
CAmount amount = CAmount::fromDecimalString(text);
|
||||
if (Settings::getInstance()->get_currency_name() == "USD") {
|
||||
req.txtAmountUSD->setText(amount.toDecimalUSDString());
|
||||
} else if (Settings::getInstance()->get_currency_name() == "EUR") {
|
||||
req.txtAmountUSD->setText(amount.toDecimalEURString());
|
||||
} else if (Settings::getInstance()->get_currency_name() == "BTC") {
|
||||
req.txtAmountUSD->setText(amount.toDecimalBTCString());
|
||||
} else if (Settings::getInstance()->get_currency_name() == "CNY") {
|
||||
req.txtAmountUSD->setText(amount.toDecimalCNYString());
|
||||
} else if (Settings::getInstance()->get_currency_name() == "RUB") {
|
||||
req.txtAmountUSD->setText(amount.toDecimalRUBString());
|
||||
} else if (Settings::getInstance()->get_currency_name() == "CAD") {
|
||||
req.txtAmountUSD->setText(amount.toDecimalCADString());
|
||||
} else if (Settings::getInstance()->get_currency_name() == "SGD") {
|
||||
req.txtAmountUSD->setText(amount.toDecimalSGDString());
|
||||
} else if (Settings::getInstance()->get_currency_name() == "CHF") {
|
||||
req.txtAmountUSD->setText(amount.toDecimalCHFString());
|
||||
} else if (Settings::getInstance()->get_currency_name() == "INR") {
|
||||
req.txtAmountUSD->setText(amount.toDecimalINRString());
|
||||
} else if (Settings::getInstance()->get_currency_name() == "GBP") {
|
||||
req.txtAmountUSD->setText(amount.toDecimalGBPString());
|
||||
} else if (Settings::getInstance()->get_currency_name() == "AUD") {
|
||||
req.txtAmountUSD->setText(amount.toDecimalBTCString());
|
||||
}
|
||||
});
|
||||
CAmount amount = CAmount::fromDecimalString(req.txtAmount->text());
|
||||
if (Settings::getInstance()->get_currency_name() == "USD") {
|
||||
req.txtAmountUSD->setText(amount.toDecimalUSDString());
|
||||
} else if (Settings::getInstance()->get_currency_name() == "EUR") {
|
||||
req.txtAmountUSD->setText(amount.toDecimalEURString());
|
||||
} else if (Settings::getInstance()->get_currency_name() == "BTC") {
|
||||
req.txtAmountUSD->setText(amount.toDecimalBTCString());
|
||||
} else if (Settings::getInstance()->get_currency_name() == "CNY") {
|
||||
req.txtAmountUSD->setText(amount.toDecimalCNYString());
|
||||
} else if (Settings::getInstance()->get_currency_name() == "RUB") {
|
||||
req.txtAmountUSD->setText(amount.toDecimalRUBString());
|
||||
} else if (Settings::getInstance()->get_currency_name() == "CAD") {
|
||||
req.txtAmountUSD->setText(amount.toDecimalCADString());
|
||||
} else if (Settings::getInstance()->get_currency_name() == "SGD") {
|
||||
req.txtAmountUSD->setText(amount.toDecimalSGDString());
|
||||
} else if (Settings::getInstance()->get_currency_name() == "CHF") {
|
||||
req.txtAmountUSD->setText(amount.toDecimalCHFString());
|
||||
} else if (Settings::getInstance()->get_currency_name() == "INR") {
|
||||
req.txtAmountUSD->setText(amount.toDecimalINRString());
|
||||
} else if (Settings::getInstance()->get_currency_name() == "GBP") {
|
||||
req.txtAmountUSD->setText(amount.toDecimalGBPString());
|
||||
} else if (Settings::getInstance()->get_currency_name() == "AUD") {
|
||||
req.txtAmountUSD->setText(amount.toDecimalBTCString());
|
||||
}
|
||||
req.txtMemo->setAcceptButton(req.buttonBox->button(QDialogButtonBox::Ok));
|
||||
req.txtMemo->setLenDisplayLabel(req.lblMemoLen);
|
||||
req.txtMemo->setMaxLen(400);
|
||||
|
||||
req.txtFrom->setFocus();
|
||||
|
||||
if (d.exec() == QDialog::Accepted) {
|
||||
// Construct a hush Payment URI with the data and pay it immediately.
|
||||
CAmount amount = CAmount::fromDecimalString(req.txtAmount->text());
|
||||
QString memoURI = "hush:" + req.cmbMyAddress->currentText()
|
||||
+ "?amt=" + amount.toDecimalString()
|
||||
+ "&memo=" + QUrl::toPercentEncoding(req.txtMemo->toPlainText());
|
||||
|
||||
QString sendURI = "hush:" + AddressBook::addressFromAddressLabel(req.txtFrom->text())
|
||||
+ "?amt=0.0001"
|
||||
+ "&memo=" + QUrl::toPercentEncoding(memoURI);
|
||||
|
||||
// If the disclosed address in the memo doesn't have a balance, it will automatically fallback to the default
|
||||
// sapling address
|
||||
main->payhushURI(sendURI, req.cmbMyAddress->currentText());
|
||||
}
|
||||
}
|
||||
// Copyright 2019-2024 The Hush developers
|
||||
// Released under the GPLv3
|
||||
#include "requestdialog.h"
|
||||
#include "ui_requestdialog.h"
|
||||
#include "settings.h"
|
||||
#include "addressbook.h"
|
||||
#include "mainwindow.h"
|
||||
#include "controller.h"
|
||||
#include "settings.h"
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
RequestDialog::RequestDialog(QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::RequestDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
||||
RequestDialog::~RequestDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void RequestDialog::setupDialog(MainWindow* main, QDialog* d, Ui_RequestDialog* req) {
|
||||
req->setupUi(d);
|
||||
Settings::saveRestore(d);
|
||||
|
||||
// Setup
|
||||
req->txtMemo->setLenDisplayLabel(req->lblMemoLen);
|
||||
req->lblAmount->setText(req->lblAmount->text() + Settings::getTokenName());
|
||||
|
||||
if (!main || !main->getRPC())
|
||||
return;
|
||||
|
||||
for (auto addr : main->getRPC()->getModel()->getAllZAddresses()) {
|
||||
auto bal = main->getRPC()->getModel()->getAllBalances().value(addr);
|
||||
if (Settings::getInstance()->isSaplingAddress(addr)) {
|
||||
req->cmbMyAddress->addItem(addr, bal);
|
||||
}
|
||||
}
|
||||
req->cmbMyAddress->setCurrentText(main->getRPC()->getDefaultSaplingAddress());
|
||||
|
||||
QIcon icon(":/icons/res/paymentreq.gif");
|
||||
req->lblPixmap->setPixmap(icon.pixmap(48, 48));
|
||||
}
|
||||
|
||||
// Static method that shows an incoming payment request and prompts the user to pay it
|
||||
void RequestDialog::showPaymentConfirmation(MainWindow* main, QString paymentURI) {
|
||||
PaymentURI payInfo = Settings::parseURI(paymentURI);
|
||||
if (!payInfo.error.isEmpty()) {
|
||||
QMessageBox::critical(main, tr("Error paying DRGX URI"),
|
||||
tr("URI should be of the form 'drgx:<addr>?amt=x&memo=y") + "\n" + payInfo.error);
|
||||
return;
|
||||
}
|
||||
|
||||
QDialog d(main);
|
||||
Ui_RequestDialog req;
|
||||
setupDialog(main, &d, &req);
|
||||
|
||||
// In the view mode, all fields are read-only
|
||||
req.txtAmount->setReadOnly(true);
|
||||
req.txtFrom->setReadOnly(true);
|
||||
req.txtMemo->setReadOnly(true);
|
||||
|
||||
// Payment is "to"
|
||||
req.lblAddress->setText(tr("Pay To"));
|
||||
|
||||
// No Addressbook
|
||||
req.btnAddressBook->setVisible(false);
|
||||
|
||||
// No "address is visible" warning
|
||||
req.lblAddressInfo->setVisible(false);
|
||||
|
||||
req.txtFrom->setText(payInfo.addr);
|
||||
req.txtMemo->setPlainText(payInfo.memo);
|
||||
req.txtAmount->setText(payInfo.amt);
|
||||
CAmount amount = CAmount::fromDecimalString(req.txtAmount->text());
|
||||
if (Settings::getInstance()->get_currency_name() == "USD") {
|
||||
req.txtAmountUSD->setText(amount.toDecimalUSDString());
|
||||
} else if (Settings::getInstance()->get_currency_name() == "EUR") {
|
||||
req.txtAmountUSD->setText(amount.toDecimalEURString());
|
||||
} else if (Settings::getInstance()->get_currency_name() == "BTC") {
|
||||
req.txtAmountUSD->setText(amount.toDecimalBTCString());
|
||||
}
|
||||
|
||||
req.buttonBox->button(QDialogButtonBox::Ok)->setText(tr("Pay"));
|
||||
|
||||
req.lblHeader->setText(tr("You are paying a payment request. Your address will not be visible to the person requesting this payment."));
|
||||
|
||||
if (d.exec() == QDialog::Accepted) {
|
||||
main->payhushURI(paymentURI, req.cmbMyAddress->currentText());
|
||||
}
|
||||
}
|
||||
|
||||
// Static method that shows the request dialog
|
||||
void RequestDialog::showRequesthush(MainWindow* main) {
|
||||
QDialog d(main);
|
||||
Ui_RequestDialog req;
|
||||
|
||||
setupDialog(main, &d, &req);
|
||||
|
||||
// Setup the Label completer for the Address
|
||||
req.txtFrom->setCompleter(main->getLabelCompleter());
|
||||
QObject::connect(req.txtFrom, &QLineEdit::textChanged, [=] (auto text) {
|
||||
auto addr = AddressBook::addressFromAddressLabel(text);
|
||||
if (!Settings::getInstance()->isSaplingAddress(addr)) {
|
||||
req.lblSaplingWarning->setText(tr("Can only request from Sapling addresses"));
|
||||
req.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
|
||||
} else {
|
||||
req.lblSaplingWarning->setText("");
|
||||
req.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true);
|
||||
}
|
||||
});
|
||||
|
||||
// Wire up AddressBook button
|
||||
QObject::connect(req.btnAddressBook, &QPushButton::clicked, [=] () {
|
||||
AddressBook::open(main, req.txtFrom);
|
||||
});
|
||||
|
||||
// Amount textbox
|
||||
req.txtAmount->setValidator(main->getAmountValidator());
|
||||
QObject::connect(req.txtAmount, &QLineEdit::textChanged, [=] (auto text) {
|
||||
CAmount amount = CAmount::fromDecimalString(text);
|
||||
if (Settings::getInstance()->get_currency_name() == "USD") {
|
||||
req.txtAmountUSD->setText(amount.toDecimalUSDString());
|
||||
} else if (Settings::getInstance()->get_currency_name() == "EUR") {
|
||||
req.txtAmountUSD->setText(amount.toDecimalEURString());
|
||||
} else if (Settings::getInstance()->get_currency_name() == "BTC") {
|
||||
req.txtAmountUSD->setText(amount.toDecimalBTCString());
|
||||
} else if (Settings::getInstance()->get_currency_name() == "CNY") {
|
||||
req.txtAmountUSD->setText(amount.toDecimalCNYString());
|
||||
} else if (Settings::getInstance()->get_currency_name() == "RUB") {
|
||||
req.txtAmountUSD->setText(amount.toDecimalRUBString());
|
||||
} else if (Settings::getInstance()->get_currency_name() == "CAD") {
|
||||
req.txtAmountUSD->setText(amount.toDecimalCADString());
|
||||
} else if (Settings::getInstance()->get_currency_name() == "SGD") {
|
||||
req.txtAmountUSD->setText(amount.toDecimalSGDString());
|
||||
} else if (Settings::getInstance()->get_currency_name() == "CHF") {
|
||||
req.txtAmountUSD->setText(amount.toDecimalCHFString());
|
||||
} else if (Settings::getInstance()->get_currency_name() == "INR") {
|
||||
req.txtAmountUSD->setText(amount.toDecimalINRString());
|
||||
} else if (Settings::getInstance()->get_currency_name() == "GBP") {
|
||||
req.txtAmountUSD->setText(amount.toDecimalGBPString());
|
||||
} else if (Settings::getInstance()->get_currency_name() == "AUD") {
|
||||
req.txtAmountUSD->setText(amount.toDecimalBTCString());
|
||||
}
|
||||
});
|
||||
CAmount amount = CAmount::fromDecimalString(req.txtAmount->text());
|
||||
if (Settings::getInstance()->get_currency_name() == "USD") {
|
||||
req.txtAmountUSD->setText(amount.toDecimalUSDString());
|
||||
} else if (Settings::getInstance()->get_currency_name() == "EUR") {
|
||||
req.txtAmountUSD->setText(amount.toDecimalEURString());
|
||||
} else if (Settings::getInstance()->get_currency_name() == "BTC") {
|
||||
req.txtAmountUSD->setText(amount.toDecimalBTCString());
|
||||
} else if (Settings::getInstance()->get_currency_name() == "CNY") {
|
||||
req.txtAmountUSD->setText(amount.toDecimalCNYString());
|
||||
} else if (Settings::getInstance()->get_currency_name() == "RUB") {
|
||||
req.txtAmountUSD->setText(amount.toDecimalRUBString());
|
||||
} else if (Settings::getInstance()->get_currency_name() == "CAD") {
|
||||
req.txtAmountUSD->setText(amount.toDecimalCADString());
|
||||
} else if (Settings::getInstance()->get_currency_name() == "SGD") {
|
||||
req.txtAmountUSD->setText(amount.toDecimalSGDString());
|
||||
} else if (Settings::getInstance()->get_currency_name() == "CHF") {
|
||||
req.txtAmountUSD->setText(amount.toDecimalCHFString());
|
||||
} else if (Settings::getInstance()->get_currency_name() == "INR") {
|
||||
req.txtAmountUSD->setText(amount.toDecimalINRString());
|
||||
} else if (Settings::getInstance()->get_currency_name() == "GBP") {
|
||||
req.txtAmountUSD->setText(amount.toDecimalGBPString());
|
||||
} else if (Settings::getInstance()->get_currency_name() == "AUD") {
|
||||
req.txtAmountUSD->setText(amount.toDecimalBTCString());
|
||||
}
|
||||
req.txtMemo->setAcceptButton(req.buttonBox->button(QDialogButtonBox::Ok));
|
||||
req.txtMemo->setLenDisplayLabel(req.lblMemoLen);
|
||||
req.txtMemo->setMaxLen(400);
|
||||
|
||||
req.txtFrom->setFocus();
|
||||
|
||||
if (d.exec() == QDialog::Accepted) {
|
||||
// Construct a DRGX Payment URI with the data and pay it immediately.
|
||||
CAmount amount = CAmount::fromDecimalString(req.txtAmount->text());
|
||||
QString memoURI = "drgx:" + req.cmbMyAddress->currentText()
|
||||
+ "?amt=" + amount.toDecimalString()
|
||||
+ "&memo=" + QUrl::toPercentEncoding(req.txtMemo->toPlainText());
|
||||
|
||||
QString sendURI = "drgx:" + AddressBook::addressFromAddressLabel(req.txtFrom->text())
|
||||
+ "?amt=0.0001"
|
||||
+ "&memo=" + QUrl::toPercentEncoding(memoURI);
|
||||
|
||||
// If the disclosed address in the memo doesn't have a balance, it will automatically fallback to the default
|
||||
// sapling address
|
||||
main->payhushURI(sendURI, req.cmbMyAddress->currentText());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user