Browse Source

more debug, free mem, lib update

pull/139/head
Deniod 5 months ago
parent
commit
7863d6ffb2
  1. 2
      lib/Cargo.lock
  2. 2
      lib/Cargo.toml
  3. 45
      lib/src/lib.rs
  4. 22
      src/connection.cpp
  5. 184
      src/controller.cpp
  6. 57
      src/firsttimewizard.cpp

2
lib/Cargo.lock

@ -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",

2
lib/Cargo.toml

@ -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" }

45
lib/src/lib.rs

@ -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 {

22
src/connection.cpp

@ -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) {

184
src/controller.cpp

@ -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,117 +130,124 @@ 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;
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;
}
// Bearbeite die Antwort
for(uint8_t i = 0; i < 8; i++) {
QString randomString;
QRandomGenerator *gen = QRandomGenerator::system();
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()) {
for(int i=0; i<randomStringLength; ++i) {
int index = gen->bounded(0, possibleCharacters.length() - 1);
QChar nextChar = possibleCharacters.at(index);
randomString.append(nextChar);
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;
}
}
}
dust.at(i)["memo"] = randomString.toStdString();
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
// 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();
}
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)
}) ;
}
// Füge Staubtransaktionen einzeln hinzu
for (const auto& dustTransaction : dust) {
allRecepients.push_back(dustTransaction);
}
}
}
void Controller::noConnection()
{

57
src/firsttimewizard.cpp

@ -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;
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();
}
// 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);
}
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;
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;
}
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
{

Loading…
Cancel
Save