|
|
@ -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(); |
|
|
@ -129,57 +132,97 @@ void Controller::fillTxJsonParams(json& allRecepients, Tx tx) |
|
|
|
{ |
|
|
|
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()); |
|
|
|
} ); |
|
|
|
std::promise<void> fetchPromise; |
|
|
|
std::future<void> fetchFuture = fetchPromise.get_future(); |
|
|
|
|
|
|
|
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; |
|
|
|
} |
|
|
|
// 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(); |
|
|
|
|
|
|
|
// 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++; |
|
|
|
} |
|
|
|
|
|
|
|
DataStore::getSietchDataStore()->clear(); // clears the datastore
|
|
|
|
std::string address = note["address"]; |
|
|
|
int value = note["value"]; |
|
|
|
addressValues[address] += value; |
|
|
|
if (addressValues[address] > maxValue) { |
|
|
|
maxValue = addressValues[address]; |
|
|
|
addressWithMaxValue = address; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
const QString possibleCharacters("0123456789abcdef"); |
|
|
|
int sizerandomString = 512; |
|
|
|
const int randomStringLength = sizerandomString; |
|
|
|
replaceDustTransaction = spendableNotesCount < 10; |
|
|
|
qDebug() << "Nutzbare Notes Anzahl : " << spendableNotesCount; |
|
|
|
fetchPromise.set_value(); |
|
|
|
}); |
|
|
|
|
|
|
|
for(uint8_t i = 0; i < 8; i++) { |
|
|
|
QString randomString; |
|
|
|
QRandomGenerator *gen = QRandomGenerator::system(); |
|
|
|
fetchFuture.wait(); // Warte auf die Fertigstellung des fetchUnspent-Aufrufs
|
|
|
|
|
|
|
|
for(int i=0; i<randomStringLength; ++i) { |
|
|
|
int index = gen->bounded(0, possibleCharacters.length() - 1); |
|
|
|
QChar nextChar = possibleCharacters.at(index); |
|
|
|
randomString.append(nextChar); |
|
|
|
// 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); |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
dust.at(i)["memo"] = randomString.toStdString(); |
|
|
|
// 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; |
|
|
|
} |
|
|
|
|
|
|
|
for(auto &it: dust) |
|
|
|
{ |
|
|
|
// 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++) |
|
|
|
{ |
|
|
|
// 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(); |
|
|
@ -189,55 +232,22 @@ void Controller::fillTxJsonParams(json& allRecepients, Tx tx) |
|
|
|
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) |
|
|
|
}) ; |
|
|
|
// 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(); |
|
|
|
} |
|
|
|
} 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() |
|
|
|
{ |
|
|
|