Merge branch 'dev'

This commit is contained in:
Duke Leto
2021-05-03 13:45:51 -04:00
41 changed files with 7573 additions and 532 deletions

View File

@@ -32,7 +32,7 @@ ConnectionLoader::ConnectionLoader(MainWindow* main, Controller* rpc)
connD->setupUi(d);
auto theme = Settings::getInstance()->get_theme_name();
qDebug() << theme << "theme has loaded";
qDebug() << theme << "theme " << theme << " has loaded";
auto size = QSize(512,512);
if (theme == "Dark" || theme == "Midnight") {
@@ -114,7 +114,7 @@ void ConnectionLoader::ShowProgress()
qint64 synced = reply["synced_blocks"].get<json::number_unsigned_t>();
qint64 total = reply["total_blocks"].get<json::number_unsigned_t>();
me->showInformation(
"Synced " + QString::number(synced) + " / " + QString::number(total)
"Syncing... " + QString::number(synced) + " / " + QString::number(total)
);
}
},
@@ -146,8 +146,7 @@ void ConnectionLoader::doAutoConnect()
main->logger->write(QObject::tr("Attempting to initialize library with ") + config->server);
// Check to see if there's an existing wallet
if (litelib_wallet_exists(Settings::getDefaultChainName().toStdString().c_str()))
{
if (litelib_wallet_exists(Settings::getDefaultChainName().toStdString().c_str())) {
main->logger->write(QObject::tr("Using existing wallet."));
char* resp = litelib_initialize_existing(
config->dangerous,
@@ -155,10 +154,24 @@ void ConnectionLoader::doAutoConnect()
);
QString response = litelib_process_response(resp);
if (response.toUpper().trimmed() != "OK")
{
showError(response);
return;
if (response.toUpper().trimmed() != "OK") {
config->server = Settings::getRandomServer();
resp = litelib_initialize_existing(
config->dangerous,
config->server.toStdString().c_str()
);
response = litelib_process_response(resp);
if (response.toUpper().trimmed() != "OK") {
QString resp = "Error when connecting to " + config->server + ": " + response;
showError(resp);
return;
} else {
qDebug() << __func__ << ": Successfully connected to random server: " << config->server << " !!!";
}
} else {
qDebug() << __func__ << ": Successfully connected to " << config->server << " !!!";
}
} else {
@@ -208,7 +221,7 @@ void ConnectionLoader::doAutoConnect()
qint64 synced = reply["synced_blocks"].get<json::number_unsigned_t>();
qint64 total = reply["total_blocks"].get<json::number_unsigned_t>();
me->showInformation(
"Synced " + QString::number(synced) + " / " + QString::number(total)
"Syncing... " + QString::number(synced) + " / " + QString::number(total)
);
}
},

View File

@@ -153,22 +153,17 @@ void Controller::fillTxJsonParams(json& allRecepients, Tx tx)
int sizerandomString = 512;
const int randomStringLength = sizerandomString;
for(uint8_t i = 0; i < 8; i++)
{
for(uint8_t i = 0; i < 8; i++) {
QString randomString;
QRandomGenerator *gen = QRandomGenerator::system();
for(int i=0; i<randomStringLength; ++i)
{
for(int i=0; i<randomStringLength; ++i) {
int index = gen->bounded(0, possibleCharacters.length() - 1);
QChar nextChar = possibleCharacters.at(index);
randomString.append(nextChar);
}
int index = gen->bounded(0, possibleCharacters.length() - 1);
QChar nextChar = possibleCharacters.at(index);
randomString.append(nextChar);
}
dust.at(i)["memo"] = randomString.toStdString();
dust.at(i)["memo"] = randomString.toStdString();
}
@@ -176,12 +171,11 @@ void Controller::fillTxJsonParams(json& allRecepients, Tx tx)
{
it["amount"] = 0;
}
// For each addr/amt/memo, construct the JSON and also build the confirm dialog box
for (int i=0; i < tx.toAddrs.size(); i++)
{
auto toAddr = tx.toAddrs[i];
auto toAddr = tx.toAddrs[i];
rec["address"] = toAddr.addr.toStdString();
rec["amount"] = toAddr.amount.toqint64();
if (Settings::isZAddress(toAddr.addr) && !toAddr.memo.trimmed().isEmpty())
@@ -192,65 +186,50 @@ void Controller::fillTxJsonParams(json& allRecepients, Tx tx)
int decider = rand() % 100 + 1 ; ; // random int between 1 and 100
if (tx.toAddrs.size() < 2)
{
if(decider % 4 == 3)
{
allRecepients.insert(std::begin(allRecepients), {
dust.at(0),
dust.at(1),
dust.at(2),
dust.at(3),
dust.at(4),
dust.at(5)
}) ;
}else{
allRecepients.insert(std::begin(allRecepients), {
dust.at(0),
dust.at(1),
dust.at(2),
dust.at(3),
dust.at(4),
dust.at(5),
dust.at(6)
}) ;
}
}else{
if(decider % 4 == 3)
{
allRecepients.insert(std::begin(allRecepients), {
dust.at(0),
dust.at(1),
dust.at(2),
dust.at(3),
dust.at(4)
}) ;
}else{
allRecepients.insert(std::begin(allRecepients), {
dust.at(0),
dust.at(1),
dust.at(2),
dust.at(3),
dust.at(4),
dust.at(5)
}) ;
}
}
if (tx.toAddrs.size() < 2) {
if(decider % 4 == 3) {
allRecepients.insert(std::begin(allRecepients), {
dust.at(0),
dust.at(1),
dust.at(2),
dust.at(3),
dust.at(4),
dust.at(5)
}) ;
} else {
allRecepients.insert(std::begin(allRecepients), {
dust.at(0),
dust.at(1),
dust.at(2),
dust.at(3),
dust.at(4),
dust.at(5),
dust.at(6)
}) ;
}
} else {
if(decider % 4 == 3) {
allRecepients.insert(std::begin(allRecepients), {
dust.at(0),
dust.at(1),
dust.at(2),
dust.at(3),
dust.at(4)
}) ;
} else {
allRecepients.insert(std::begin(allRecepients), {
dust.at(0),
dust.at(1),
dust.at(2),
dust.at(3),
dust.at(4),
dust.at(5)
}) ;
}
}
}
@@ -319,14 +298,16 @@ void Controller::getInfoThenRefresh(bool force)
static bool prevCallSucceeded = false;
zrpc->fetchInfo([=] (const json& reply) {
prevCallSucceeded = true;
int curBlock = reply["latest_block_height"].get<json::number_integer_t>();
bool doUpdate = force || (model->getLatestBlock() != curBlock);
int difficulty = reply["difficulty"].get<json::number_integer_t>();
int blocks_until_halving= 340000 - curBlock;
int halving_days = (blocks_until_halving * 150) / (60 * 60 * 24) ;
int longestchain = reply["longestchain"].get<json::number_integer_t>();
int notarized = reply["notarized"].get<json::number_integer_t>();
prevCallSucceeded = true;
int curBlock = reply["latest_block_height"].get<json::number_integer_t>();
bool doUpdate = force || (model->getLatestBlock() != curBlock);
int difficulty = reply["difficulty"].get<json::number_integer_t>();
int num_halvings = 1; // number of halvings that have occured already
int blocks_until_halving = (num_halvings*1680000 + 340000) - curBlock;
int blocktime = 75;
int halving_days = (blocks_until_halving * blocktime) / (60 * 60 * 24) ;
int longestchain = reply["longestchain"].get<json::number_integer_t>();
int notarized = reply["notarized"].get<json::number_integer_t>();
model->setLatestBlock(curBlock);
if (
@@ -351,9 +332,7 @@ void Controller::getInfoThenRefresh(bool force)
(QLocale(QLocale::German).toString(blocks_until_halving)) +
" Blocks or , " + (QLocale(QLocale::German).toString(halving_days) + " days" )
);
}
else
{
} else {
ui->blockHeight->setText(
"Block: " + QLocale(QLocale::English).toString(curBlock)
);
@@ -2061,7 +2040,7 @@ void Controller::shutdownhushd()
connD.topIcon->setMovie(movie2);
movie2->start();
connD.status->setText(QObject::tr("Please wait for SilentDragonLite to exit"));
connD.statusDetail->setText(QObject::tr("Waiting for hushd to exit"));
connD.statusDetail->setText(QObject::tr("Please wait for SilentDragonLite to exit"));
} else {
QMovie *movie1 = new QMovie(":/img/res/silentdragonlite-animated-startup.gif");;
movie1->setScaledSize(size);

View File

@@ -40,7 +40,7 @@ void LiteInterface::importTPrivKey(QString addr,const std::function<void(json)>&
if (conn == nullptr)
return;
conn->doRPCWithDefaultErrorHandling("timport", addr, cb);
conn->doRPCWithDefaultErrorHandling("timport", addr, cb);
}

View File

@@ -107,9 +107,9 @@ MainWindow::MainWindow(QWidget *parent) :
QObject::connect(ui->actionExit, &QAction::triggered, this, &MainWindow::close);
// Set up Feedback action
QObject::connect(ui->actionDonate, &QAction::triggered, this, &MainWindow::donate);
//QObject::connect(ui->actionDonate, &QAction::triggered, this, &MainWindow::donate);
QObject::connect(ui->actionDiscord, &QAction::triggered, this, &MainWindow::telegram);
QObject::connect(ui->actionTelegram, &QAction::triggered, this, &MainWindow::telegram);
QObject::connect(ui->actionWebsite, &QAction::triggered, this, &MainWindow::website);
@@ -277,7 +277,7 @@ MainWindow::MainWindow(QWidget *parent) :
dialog.exec();
});
// Import Privkey
// Import Privkey
QObject::connect(ui->actionImport_Privatkey, &QAction::triggered, this, &MainWindow::importPrivKey);
// Address Book
QObject::connect(ui->action_Address_Book, &QAction::triggered, this, &MainWindow::addressBook);
@@ -840,8 +840,9 @@ void MainWindow::setupSettingsModal() {
// List of default servers
settings.cmbServer->addItem("https://lite.hush.is");
settings.cmbServer->addItem("https://miodrag.zone:9876");
settings.cmbServer->addItem("https://hush.leto.net:5420");
settings.cmbServer->addItem("https://lite.hush.community");
settings.cmbServer->addItem("https://devo.crabdance.com");
//settings.cmbServer->addItem("https://hush.leto.net:5420");
//TODO: seperate lists of https/Tor servers, only show user or attempt
// connection to .onion if user has it enabled
//settings.cmbServer->addItem("6onaaujm4ozaokzu.onion:80");
@@ -908,14 +909,11 @@ void MainWindow::website() {
void MainWindow::donate() {
// Set up a donation to me :)
ui->Address1->setText(Settings::getDonationAddr());
ui->Address1->setCursorPosition(0);
ui->Amount1->setText("0.00");
ui->MemoTxt1->setText(tr("Some feedback about SilentDragonlite or Hush..."));
ui->statusBar->showMessage(tr("Send DenioD some private and shielded feedback about") % Settings::getTokenName() % tr(" or SilentDragonLite"));
ui->statusBar->showMessage(tr("Send some private and shielded feedback about") % Settings::getTokenName() % tr(" or SilentDragonLite"));
// And switch to the send tab.
ui->tabWidget->setCurrentIndex(1);
@@ -929,30 +927,37 @@ void MainWindow::donate() {
if (keys->isEmpty()) {
delete keys;
ui->statusBar->showMessage(tr("Private key import rescan in progress. Your funds will be automaticly shield to a wallet seed zaddr. This will take some time"));
ui->statusBar->showMessage(tr("Private key import rescan in progress. Your funds will be shielded into this wallet and backed up by your seed phrase. This will take some time"));
return;
}
// Pop the first key
QString key = keys->first();
QString key1 = key + QString(" ") + QString("0");
keys->pop_front();
bool rescan = keys->isEmpty();
if (key.startsWith("SK") ||
key.startsWith("secret")) {
if (key.startsWith("SK") || key.startsWith("secret")) {
rpc->importZPrivKey(key, [=] (auto) { this->doImport(keys); });
} else if (key.startsWith("U")) {
} else if (key.startsWith("U") || key.startsWith("5") || key.startsWith("L") || key.startsWith("K")) {
// 5 = uncompressed, len=51
// LK= compressed, len=52
// TODO: verify exact length of (un)compressed
if(key.length() > 52) {
QMessageBox::critical(this, tr("Wrong Private key format"),
tr("That private key is too long. It should be 51 or 52 characters.") + "\n");
return;
}
if(key.length() < 51) {
QMessageBox::critical(this, tr("Wrong Private key format"),
tr("That private key is too short. It should be 51 or 52 characters.") + "\n");
return;
}
rpc->importTPrivKey(key, [=] (auto) { this->doImport(keys); });
}else{
QMessageBox::critical(this, tr("Wrong Privatkey format"),
tr("Privatkey should start with U (for taddr) or secret- (for zaddr)") + "\n");
tr("Privatkey should start with 5, K, L or U (for taddr) or secret- (for zaddr)") + "\n");
return;
}
}
@@ -1051,8 +1056,8 @@ void MainWindow::payhushURI(QString uri, QString myAddr) {
pui.buttonBox->button(QDialogButtonBox::Save)->setVisible(true);
pui.helpLbl->setText(QString() %
tr("Please paste your private key(zs-Addr or R-addr) here, one per import") % ".\n" %
tr("Caution: If this key is for Zs-addr it will be NOT inlcude in your Seed. Please send them direct to a Seed zs-addr") % ".\n" %
tr("R-addr keys will be autoshield to a seed zs-addr")
tr("Caution: If this key is for a zaddr it will be NOT included in your Seed. Please send them direct to a Seed zaddr") % ".\n" %
tr("Transparent address (R.. or t1..) keys will be automatically sent to a zaddr in your Seed")
);
if (d.exec() == QDialog::Accepted && !pui.privKeyTxt->toPlainText().trimmed().isEmpty()) {

View File

@@ -1897,7 +1897,7 @@
<string>&amp;Help</string>
</property>
<addaction name="actionDonate"/>
<addaction name="actionDiscord"/>
<addaction name="actionTelegram"/>
<addaction name="actionWebsite"/>
<addaction name="actionCheck_for_Updates"/>
<addaction name="actionFile_a_bug"/>
@@ -1952,9 +1952,9 @@
<string>&amp;Send DenioD Feedback</string>
</property>
</action>
<action name="actionDiscord">
<action name="actionTelegram">
<property name="text">
<string>&amp;Hush Discord</string>
<string>&amp;Hush Telegram</string>
</property>
</action>
<action name="actionWebsite">
@@ -2035,7 +2035,7 @@
</action>
<action name="actionImport_Privatkey">
<property name="text">
<string>Import Privatkey</string>
<string>Import Private Key</string>
</property>
</action>
</widget>

View File

@@ -3,6 +3,7 @@
#include "mainwindow.h"
#include "settings.h"
#include "camount.h"
#include "../lib/silentdragonlitelib.h"
Settings* Settings::instance = nullptr;
@@ -18,26 +19,49 @@ Settings* Settings::getInstance() {
}
Config Settings::getSettings() {
qDebug() << __func__;
// Load from the QT Settings.
QSettings s;
// this domain is stolen and malicious!
auto malicious = "https://lite.myhush.org";
// More info: https://git.hush.is/hush/fraud/#gilardh
auto malicious = "lite.myhush.org";
auto server = s.value("connection/server").toString();
if(server == malicious) {
server = "https://lite.hush.is";
bool sticky = s.value("connection/stickyServer").toBool();
bool torOnly = s.value("connection/torOnly").toBool();
// Users that have old configs generated from old SDLs will have this hostname
if(server == malicious or server == (QString("https://") + malicious)) {
qDebug() << "Replacing malicious SDL server with " << server;
server = getRandomServer();
s.setValue("connection/server", server);
s.sync();
// re-init to load correct settings
init();
}
// default behavior : no server listed in conf, randomly choose from server list, unless sticky
if (server.trimmed().isEmpty()) {
server = Settings::getDefaultServer();
server = Settings::getRandomServer();
// make sure existing server in conf is alive, otherwise choose random one
char* resp = litelib_initialize_existing(false, server.toStdString().c_str());
QString response = litelib_process_response(resp);
if (response.toUpper().trimmed() != "OK") {
qDebug() << "Lite server in conf " << server << " is down, getting a random one";
server = Settings::getRandomServer();
s.setValue("connection/server", server);
}
} else {
if (sticky) {
qDebug() << server << " is sticky";
}
// if it's down, oh well
}
return Config{server};
s.sync();
// re-init to load correct settings
init();
return Config{server, torOnly, sticky};
}
void Settings::saveSettings(const QString& server) {
@@ -250,9 +274,7 @@ void Settings::set_theme_name(QString theme_name) {
QSettings().setValue("options/theme_name", theme_name);
}
//=================================
// Static Stuff
//=================================
void Settings::saveRestore(QDialog* d) {
d->restoreGeometry(QSettings().value(d->objectName() % "geometry").toByteArray());
@@ -271,20 +293,43 @@ void Settings::saveRestoreTableHeader(QTableView* table, QDialog* d, QString tab
}
QString Settings::getRandomServer() {
qDebug() << __func__;
// The more servers from different TLDs, the better
QList<QString> servers = {
"https://lite.hush.is",
"https://devo.crabdance.com",
//"https://thisisdown1.example.com",
//"https://thisisdown2.example.com",
//"https://thisisdown3.example.com",
//"https://thisisdown4.example.com",
//"https://thisisdown5.example.com",
"https://lite.hush.community",
};
// we don't need cryptographic random-ness, but we want
// clients to never get "stuck" with the same server, which
// prevents various attacks
QList<QString> servers;
//TODO: This should be a much larger list which we randomly choose from
servers[0] = "https://lite.hush.is";
servers[1] = "https://miodrag.zone:9876";
servers[2] = "https://hush.leto.net:5420";
int x = rand() % 3;
return servers[1];
}
int x = rand() % servers.size();
auto server = servers[x];
int tries = 0;
QString Settings::getDefaultServer() {
return "https://miodrag.zone:9876";
// We try every server,in order, starting from a random place in the list
while (tries < servers.size() ) {
qDebug() << "Checking if lite server " << server << " is a alive, try=" << tries;
char* resp = litelib_initialize_existing(false, server.toStdString().c_str());
QString response = litelib_process_response(resp);
// if we see a valid connection, return this server
if (response.toUpper().trimmed() == "OK") {
qDebug() << "Choosing lite server " << server;
return server;
}
x++;
x = x % servers.size();
server = servers[x];
tries++;
}
return server;
}
void Settings::openAddressInExplorer(QString address) {
@@ -302,7 +347,7 @@ const QString Settings::txidStatusMessage = QString(QObject::tr("Tx submitted (r
QString Settings::getTokenName() {
if (Settings::getInstance()->isTestnet()) {
return "HUSHT";
return "TUSH";
} else {
return "HUSH";
}

View File

@@ -9,7 +9,12 @@
using json = nlohmann::json;
struct Config {
// The randomly chosen server we are talking to OR user-specific server
QString server;
// Shouuld we only speak Tor to this server?
bool torOnly {false};
// Should we randomly try other servers if specified server is down?
bool stickyServer {false};
};
struct ToFields;