more debug, free mem, lib update
This commit is contained in:
2
lib/Cargo.lock
generated
2
lib/Cargo.lock
generated
@@ -1849,7 +1849,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "silentdragonlitelib"
|
||||
version = "0.1.0"
|
||||
source = "git+https://git.hush.is/lucretius/silentdragonlite-cli?rev=eff5dd7b6dbcfd7e4db6fdba423399337b590722#eff5dd7b6dbcfd7e4db6fdba423399337b590722"
|
||||
source = "git+https://git.hush.is/lucretius/silentdragonlite-cli?rev=2483d4f372079ee8cb00a61caba74b53e4fcf1e3#2483d4f372079ee8cb00a61caba74b53e4fcf1e3"
|
||||
dependencies = [
|
||||
"base58",
|
||||
"bellman",
|
||||
|
||||
@@ -12,4 +12,4 @@ crate-type = ["staticlib"]
|
||||
libc = "0.2.58"
|
||||
lazy_static = "1.4.0"
|
||||
blake3 = "0.3.4"
|
||||
silentdragonlitelib = { git = "https://git.hush.is/lucretius/silentdragonlite-cli", rev = "eff5dd7b6dbcfd7e4db6fdba423399337b590722" }
|
||||
silentdragonlitelib = { git = "https://git.hush.is/lucretius/silentdragonlite-cli", rev = "2483d4f372079ee8cb00a61caba74b53e4fcf1e3" }
|
||||
|
||||
@@ -6,6 +6,7 @@ use libc::{c_char};
|
||||
use std::ffi::{CStr, CString};
|
||||
use std::sync::{Mutex, Arc};
|
||||
use std::cell::RefCell;
|
||||
use std::ptr;
|
||||
|
||||
use silentdragonlitelib::{commands, lightclient::{LightClient, LightClientConfig}};
|
||||
|
||||
@@ -109,33 +110,44 @@ pub extern fn litelib_initialize_new(dangerous: bool,server: *const c_char) -> *
|
||||
|
||||
/// Restore a wallet from the seed phrase
|
||||
#[no_mangle]
|
||||
pub extern fn litelib_initialize_new_from_phrase(dangerous: bool,server: *const c_char,
|
||||
pub extern "C" fn litelib_initialize_new_from_phrase(dangerous: bool, server: *const c_char,
|
||||
seed: *const c_char, birthday: u64, number: u64, overwrite: bool) -> *mut c_char {
|
||||
let server_str = unsafe {
|
||||
assert!(!server.is_null());
|
||||
// Prüfen auf null-Pointer
|
||||
if server.is_null() || seed.is_null() {
|
||||
println!("Server or seed is null");
|
||||
return ptr::null_mut();
|
||||
}
|
||||
|
||||
let server_str = unsafe {
|
||||
CStr::from_ptr(server).to_string_lossy().into_owned()
|
||||
};
|
||||
|
||||
let seed_str = unsafe {
|
||||
assert!(!seed.is_null());
|
||||
|
||||
CStr::from_ptr(seed).to_string_lossy().into_owned()
|
||||
};
|
||||
|
||||
println!("Initializing with server: {}, seed: {}", server_str, seed_str);
|
||||
|
||||
let server = LightClientConfig::get_server_or_default(Some(server_str));
|
||||
let (config, _latest_block_height) = match LightClientConfig::create(server,dangerous) {
|
||||
Ok((c, h)) => (c, h),
|
||||
let (config, _latest_block_height) = match LightClientConfig::create(server, dangerous) {
|
||||
Ok((c, h)) => {
|
||||
println!("Config created successfully");
|
||||
(c, h)
|
||||
},
|
||||
Err(e) => {
|
||||
let e_str = CString::new(format!("Error: {}", e)).unwrap();
|
||||
println!("Error creating config: {}", e);
|
||||
let e_str = CString::new(format!("Error: {}", e)).unwrap_or_else(|_| CString::new("Error creating CString").unwrap());
|
||||
return e_str.into_raw();
|
||||
}
|
||||
};
|
||||
|
||||
let lightclient = match LightClient::new_from_phrase(seed_str, &config, birthday, number, overwrite) {
|
||||
Ok(l) => l,
|
||||
Ok(l) => {
|
||||
println!("LightClient created successfully");
|
||||
l
|
||||
},
|
||||
Err(e) => {
|
||||
let e_str = CString::new(format!("Error: {}", e)).unwrap();
|
||||
println!("Error creating LightClient: {}", e);
|
||||
let e_str = CString::new(format!("Error: {}", e)).unwrap_or_else(|_| CString::new("Error creating CString").unwrap());
|
||||
return e_str.into_raw();
|
||||
}
|
||||
};
|
||||
@@ -145,18 +157,17 @@ pub extern fn litelib_initialize_new_from_phrase(dangerous: bool,server: *const
|
||||
|
||||
let lc = Arc::new(lightclient);
|
||||
match LightClient::start_mempool_monitor(lc.clone()) {
|
||||
Ok(_) => {println!("Starting Mempool")},
|
||||
Err(e) => {
|
||||
println!("Couldnt start mempool {}",e)
|
||||
}
|
||||
Ok(_) => println!("Starting Mempool"),
|
||||
Err(e) => println!("Could not start mempool: {}", e)
|
||||
}
|
||||
|
||||
LIGHTCLIENT.lock().unwrap().replace(Some(lc));
|
||||
|
||||
let c_str = CString::new("OK").unwrap();
|
||||
|
||||
let c_str = CString::new("OK").unwrap_or_else(|_| CString::new("CString creation failed").unwrap());
|
||||
return c_str.into_raw();
|
||||
}
|
||||
|
||||
|
||||
// Initialize a new lightclient and store its value
|
||||
#[no_mangle]
|
||||
pub extern fn litelib_initialize_existing(dangerous: bool, server: *const c_char) -> *mut c_char {
|
||||
|
||||
@@ -105,15 +105,15 @@ void ConnectionLoader::ShowProgress()
|
||||
DEBUG("server=" << config->server << " connection=" << connection << " me=" << me);
|
||||
|
||||
isSyncing = new QAtomicInteger<bool>();
|
||||
isSyncing->store(true);
|
||||
isSyncing->storeRelaxed(true);
|
||||
DEBUG("isSyncing");
|
||||
|
||||
// Do a sync after import
|
||||
syncTimer = new QTimer(main);
|
||||
DEBUG("Beginning sync after import wif");
|
||||
connection->doRPC("sync", "", [=](auto) {
|
||||
DEBUG("finished syncing");
|
||||
isSyncing->store(false);
|
||||
qDebug()<< "finished syncing";
|
||||
isSyncing->storeRelaxed(false);
|
||||
// Cancel the timer
|
||||
syncTimer->deleteLater();
|
||||
// When sync is done, set the connection
|
||||
@@ -125,7 +125,7 @@ void ConnectionLoader::ShowProgress()
|
||||
// While it is syncing, we'll show the status updates while it is alive.
|
||||
QObject::connect(syncTimer, &QTimer::timeout, [=]() {
|
||||
DEBUG("Check the sync status");
|
||||
if (isSyncing != nullptr && isSyncing->load()) {
|
||||
if (isSyncing != nullptr && isSyncing->loadRelaxed()) {
|
||||
DEBUG("Get the sync status");
|
||||
try {
|
||||
connection->doRPC("syncstatus", "", [=](json reply) {
|
||||
@@ -220,7 +220,7 @@ void ConnectionLoader::doAutoConnect()
|
||||
auto connection = makeConnection(config);
|
||||
auto me = this;
|
||||
qDebug() << __func__ << ": server=" << config->server
|
||||
<< " connection=" << connection << " me=" << me << endl;
|
||||
<< " connection=" << connection << " me=" << me << Qt::endl;
|
||||
|
||||
// After the lib is initialized, try to do get info
|
||||
connection->doRPC("info", "", [=](auto reply) {
|
||||
@@ -229,15 +229,15 @@ void ConnectionLoader::doAutoConnect()
|
||||
connection->setInfo(reply);
|
||||
DEBUG("getting Connection reply");
|
||||
isSyncing = new QAtomicInteger<bool>();
|
||||
isSyncing->store(true);
|
||||
isSyncing->storeRelaxed(true);
|
||||
DEBUG("isSyncing");
|
||||
|
||||
// Do a sync at startup
|
||||
syncTimer = new QTimer(main);
|
||||
DEBUG("Beginning sync");
|
||||
connection->doRPC("sync", "", [=](auto) {
|
||||
DEBUG("finished syncing");
|
||||
isSyncing->store(false);
|
||||
qDebug()<<"finished syncing startup";
|
||||
isSyncing->storeRelaxed(false);
|
||||
// Cancel the timer
|
||||
syncTimer->deleteLater();
|
||||
// When sync is done, set the connection
|
||||
@@ -252,9 +252,9 @@ void ConnectionLoader::doAutoConnect()
|
||||
// auto connection = makeConnection(config);
|
||||
// DEBUG("changed server to " << config->server);
|
||||
connection->doRPC("sync", "", [=](auto) mutable {
|
||||
DEBUG("sync success with server=" << config->server);
|
||||
qDebug()<<"sync success with server=" << config->server;
|
||||
failed = false;
|
||||
isSyncing->store(false);
|
||||
isSyncing->storeRelaxed(false);
|
||||
// Cancel the timer
|
||||
syncTimer->deleteLater();
|
||||
// When sync is done, set the connection
|
||||
@@ -268,7 +268,7 @@ void ConnectionLoader::doAutoConnect()
|
||||
// While it is syncing, we'll show the status updates while it is alive.
|
||||
QObject::connect(syncTimer, &QTimer::timeout, [=]() {
|
||||
DEBUG("Check the sync status");
|
||||
if (isSyncing != nullptr && isSyncing->load()) {
|
||||
if (isSyncing != nullptr && isSyncing->loadRelaxed()) {
|
||||
DEBUG("Getting the sync status");
|
||||
try {
|
||||
connection->doRPC("syncstatus", "", [=](json reply) {
|
||||
|
||||
@@ -9,6 +9,9 @@
|
||||
#include "camount.h"
|
||||
#include "Model/ChatItem.h"
|
||||
#include "DataStore/DataStore.h"
|
||||
#include <future>
|
||||
#include <vector>
|
||||
#include <thread>
|
||||
|
||||
ChatModel *chatModel = new ChatModel();
|
||||
Chat *chat = new Chat();
|
||||
@@ -127,118 +130,125 @@ void Controller::setConnection(Connection* c)
|
||||
// Build the RPC JSON Parameters for this tx
|
||||
void Controller::fillTxJsonParams(json& allRecepients, Tx tx)
|
||||
{
|
||||
Q_ASSERT(allRecepients.is_array());
|
||||
Q_ASSERT(allRecepients.is_array());
|
||||
|
||||
// Construct the JSON params
|
||||
json rec = json::object();
|
||||
// Variablen zur Speicherung der Adresse mit dem höchsten Gesamtwert
|
||||
std::string addressWithMaxValue;
|
||||
int maxValue = 0;
|
||||
std::map<std::string, int> addressValues;
|
||||
|
||||
//creating the JSON dust parameters in a std::vector to iterate over there during tx
|
||||
std::vector<json> dust(8);
|
||||
dust.resize(8, json::object());
|
||||
// Zähle die Anzahl der spendablen Notizen mit einem Wert über 10.000
|
||||
int spendableNotesCount = 0;
|
||||
bool replaceDustTransaction = false; // Standardmäßig keine Ersetzung
|
||||
|
||||
// Create Sietch zdust addr again to not use it twice.
|
||||
// Using DataStore singelton, to store the data outside of lambda, bing bada boom :D
|
||||
for(uint8_t i = 0; i < 8; i++)
|
||||
{
|
||||
zrpc->createNewSietchZaddr( [=] (json reply) {
|
||||
QString zdust = QString::fromStdString(reply.get<json::array_t>()[0]);
|
||||
DataStore::getSietchDataStore()->setData(QString("Sietch") + QString(i), zdust.toUtf8());
|
||||
} );
|
||||
}
|
||||
// Set sietch zdust addr to json.
|
||||
// Using DataStore singelton, to store the data into the dust.
|
||||
for(uint8_t i = 0; i < 8; i++)
|
||||
{
|
||||
dust.at(i)["address"] = DataStore::getSietchDataStore()->getData(QString("Sietch" + QString(i))).toStdString();
|
||||
}
|
||||
std::promise<void> fetchPromise;
|
||||
std::future<void> fetchFuture = fetchPromise.get_future();
|
||||
|
||||
DataStore::getSietchDataStore()->clear(); // clears the datastore
|
||||
|
||||
const QString possibleCharacters("0123456789abcdef");
|
||||
int sizerandomString = 512;
|
||||
const int randomStringLength = sizerandomString;
|
||||
|
||||
for(uint8_t i = 0; i < 8; i++) {
|
||||
QString randomString;
|
||||
QRandomGenerator *gen = QRandomGenerator::system();
|
||||
|
||||
for(int i=0; i<randomStringLength; ++i) {
|
||||
int index = gen->bounded(0, possibleCharacters.length() - 1);
|
||||
QChar nextChar = possibleCharacters.at(index);
|
||||
randomString.append(nextChar);
|
||||
zrpc->fetchUnspent([=, &spendableNotesCount, &replaceDustTransaction, &addressValues, &addressWithMaxValue, &maxValue, &fetchPromise] (json reply) {
|
||||
// Fehlerbehandlung hinzugefügt
|
||||
if (reply.find("unspent_notes") == reply.end() || !reply["unspent_notes"].is_array()) {
|
||||
qDebug() << "Fehler: 'unspent_notes' fehlt oder ist kein Array";
|
||||
fetchPromise.set_value();
|
||||
return;
|
||||
}
|
||||
|
||||
dust.at(i)["memo"] = randomString.toStdString();
|
||||
// Bearbeite die Antwort
|
||||
|
||||
for (const auto& note : reply["unspent_notes"]) {
|
||||
if (note.find("spendable") != note.end() && note.find("value") != note.end() &&
|
||||
note["spendable"].is_boolean() && note["value"].is_number_integer()) {
|
||||
|
||||
if (note["spendable"] && note["value"] >= 10000) {
|
||||
spendableNotesCount++;
|
||||
}
|
||||
|
||||
std::string address = note["address"];
|
||||
int value = note["value"];
|
||||
addressValues[address] += value;
|
||||
if (addressValues[address] > maxValue) {
|
||||
maxValue = addressValues[address];
|
||||
addressWithMaxValue = address;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
replaceDustTransaction = spendableNotesCount < 10;
|
||||
qDebug() << "Nutzbare Notes Anzahl : " << spendableNotesCount;
|
||||
fetchPromise.set_value();
|
||||
});
|
||||
|
||||
fetchFuture.wait(); // Warte auf die Fertigstellung des fetchUnspent-Aufrufs
|
||||
|
||||
// Erstelle die Staubtransaktionen
|
||||
std::vector<json> dust(8, json::object());
|
||||
|
||||
// Promises und Futures für die asynchronen Aufrufe
|
||||
std::vector<std::promise<json>> promises(8);
|
||||
std::vector<std::future<json>> futures;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
futures.push_back(promises[i].get_future());
|
||||
|
||||
zrpc->createNewSietchZaddr([=, &promises] (json reply) {
|
||||
promises[i].set_value(reply);
|
||||
});
|
||||
}
|
||||
|
||||
for(auto &it: dust)
|
||||
{
|
||||
// Warte auf die Fertigstellung aller Futures
|
||||
for (auto& future : futures) {
|
||||
future.wait();
|
||||
}
|
||||
|
||||
// Verarbeite die Ergebnisse der Futures
|
||||
for (int i = 0; i < 8; i++) {
|
||||
json reply = futures[i].get(); // Hier erhalten wir das Ergebnis
|
||||
std::string zdust = reply[0];
|
||||
dust.at(i)["address"] = zdust;
|
||||
}
|
||||
|
||||
// Setze Staubtransaktionen
|
||||
for(auto &it: dust) {
|
||||
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];
|
||||
|
||||
// Generiere zufälliges Memo
|
||||
const QString possibleCharacters("0123456789abcdef");
|
||||
const int randomStringLength = 512; // Länge des zufälligen Strings
|
||||
QString randomString;
|
||||
|
||||
for(int i = 0; i < randomStringLength; ++i) {
|
||||
int index = QRandomGenerator::global()->bounded(possibleCharacters.length());
|
||||
randomString.append(possibleCharacters.at(index));
|
||||
}
|
||||
|
||||
// Füge Transaktionen hinzu
|
||||
json rec = json::object();
|
||||
for (int i = 0; i < tx.toAddrs.size(); i++) {
|
||||
auto toAddr = tx.toAddrs[i];
|
||||
rec["address"] = toAddr.addr.toStdString();
|
||||
rec["amount"] = toAddr.amount.toqint64();
|
||||
rec["amount"] = toAddr.amount.toqint64();
|
||||
if (Settings::isZAddress(toAddr.addr) && !toAddr.memo.trimmed().isEmpty())
|
||||
rec["memo"] = toAddr.memo.toStdString();
|
||||
|
||||
allRecepients.push_back(rec);
|
||||
}
|
||||
|
||||
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)
|
||||
}) ;
|
||||
}
|
||||
// Entscheide, ob eine Staubtransaktion ersetzt werden soll
|
||||
if (replaceDustTransaction) {
|
||||
int dustIndexToReplace = rand() % dust.size(); // Zufälliger Index
|
||||
auto& dustTransactionToReplace = dust.at(dustIndexToReplace);
|
||||
dustTransactionToReplace["address"] = addressWithMaxValue; // Adresse mit dem höchsten Gesamtwert
|
||||
dustTransactionToReplace["amount"] = 10000;
|
||||
dustTransactionToReplace["memo"] = randomString.toStdString();
|
||||
}
|
||||
|
||||
|
||||
// Füge Staubtransaktionen einzeln hinzu
|
||||
for (const auto& dustTransaction : dust) {
|
||||
allRecepients.push_back(dustTransaction);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Controller::noConnection()
|
||||
{
|
||||
qDebug()<< __func__;
|
||||
|
||||
@@ -725,41 +725,40 @@ bool RestoreSeedPage::validatePage() {
|
||||
return false;
|
||||
}
|
||||
|
||||
///Number
|
||||
QString number_str = form.number->text();
|
||||
qint64 number = number_str.toUInt();
|
||||
// 3. Attempt to restore wallet with the seed phrase
|
||||
{
|
||||
QString reply = "";
|
||||
try {
|
||||
char* resp = litelib_initialize_new_from_phrase(parent->dangerous, parent->server.toStdString().c_str(),
|
||||
seed.toStdString().c_str(), birthday, number);
|
||||
reply = litelib_process_response(resp);
|
||||
} catch (const std::exception& e) {
|
||||
qDebug() << __func__ << ": caught an exception, ignoring: " << e.what();
|
||||
}
|
||||
// 3. Initialize wallet with number
|
||||
QString number_str = form.number->text();
|
||||
qint64 number = number_str.toUInt();
|
||||
qDebug() << __func__ << ": Initializing wallet with number: " << number;
|
||||
|
||||
qDebug() << __func__ << ": reply=" << reply;
|
||||
QString reply = "";
|
||||
try {
|
||||
char *resp = litelib_initialize_new_from_phrase(parent->dangerous, parent->server.toStdString().c_str(),
|
||||
seed.toStdString().c_str(), birthday, number);
|
||||
|
||||
if (reply.toUpper().trimmed() != "OK") {
|
||||
qDebug() << "Lite server " << parent->server << " is down, getting a random one";
|
||||
parent->server = Settings::getRandomServer();
|
||||
qDebug() << __func__ << ": new server is " << parent->server;
|
||||
|
||||
// retry with the new server
|
||||
char* resp = litelib_initialize_new_from_phrase(parent->dangerous, parent->server.toStdString().c_str(),
|
||||
seed.toStdString().c_str(), birthday, number);
|
||||
reply = litelib_process_response(resp);
|
||||
}
|
||||
|
||||
|
||||
if (reply.toUpper().trimmed() != "OK") {
|
||||
QMessageBox::warning(this, tr("Failed to restore wallet"),
|
||||
tr("Couldn't restore the wallet") + "\n" + "server=" + parent->server + "\n" + reply,
|
||||
QMessageBox::Ok);
|
||||
return false;
|
||||
}
|
||||
if (resp != nullptr) {
|
||||
reply = litelib_process_response(resp);
|
||||
} else {
|
||||
qDebug() << __func__ << ": Null response from litelib_initialize_new_from_phrase";
|
||||
}
|
||||
} catch (const std::exception &e) {
|
||||
qDebug() << __func__ << ": caught an exception, ignoring: " << e.what();
|
||||
}
|
||||
|
||||
qDebug() << __func__ << ": reply=" << reply;
|
||||
|
||||
if (reply.toUpper().trimmed() != "OK") {
|
||||
qDebug() << "Lite server " << parent->server << " is down, getting a random one";
|
||||
parent->server = Settings::getRandomServer();
|
||||
qDebug() << __func__ << ": new server is " << parent->server;
|
||||
|
||||
char *resp = litelib_initialize_new_from_phrase(parent->dangerous, parent->server.toStdString().c_str(),
|
||||
seed.toStdString().c_str(), birthday, number);
|
||||
if (resp != nullptr) {
|
||||
reply = litelib_process_response(resp);
|
||||
} else {
|
||||
qDebug() << __func__ << ": Null response on retry from litelib_initialize_new_from_phrase";
|
||||
}
|
||||
}
|
||||
|
||||
// 4. Finally attempt to save the wallet
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user