create migration plan
This commit is contained in:
@@ -1,14 +1,125 @@
|
||||
#include "turnstile.h"
|
||||
|
||||
#include "rpc.h"
|
||||
#include "utils.h"
|
||||
#include "settings.h"
|
||||
|
||||
Turnstile::Turnstile() {
|
||||
#include "precompiled.h"
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
Turnstile::Turnstile(RPC* _rpc) {
|
||||
this->rpc = _rpc;
|
||||
}
|
||||
|
||||
|
||||
Turnstile::~Turnstile() {
|
||||
}
|
||||
|
||||
QString Turnstile::writeableFile() {
|
||||
auto filename = QStringLiteral("turnstilemigrationplan.dat");
|
||||
|
||||
auto dir = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation));
|
||||
if (!dir.exists())
|
||||
QDir().mkpath(dir.absolutePath());
|
||||
|
||||
if (Settings::getInstance()->isTestnet()) {
|
||||
return dir.filePath("testnet-" % filename);
|
||||
} else {
|
||||
return dir.filePath(filename);
|
||||
}
|
||||
}
|
||||
|
||||
// Data stream write/read methods for migration items
|
||||
QDataStream &operator<<(QDataStream& ds, const TurnstileMigrationItem& item) {
|
||||
return ds << "v1" << item.fromAddr << item.intTAddr
|
||||
<< item.destAddr << item.amount << item.blockNumber << item.chaff;
|
||||
}
|
||||
|
||||
QDataStream &operator>>(QDataStream& ds, TurnstileMigrationItem& item) {
|
||||
QString version;
|
||||
return ds >> version >> item.fromAddr >> item.intTAddr
|
||||
>> item.destAddr >> item.amount >> item.blockNumber >> item.chaff;
|
||||
}
|
||||
|
||||
void Turnstile::writeMigrationPlan(QList<TurnstileMigrationItem> plan) {
|
||||
QFile file(writeableFile());
|
||||
file.open(QIODevice::WriteOnly);
|
||||
QDataStream out(&file); // we will serialize the data into the file
|
||||
out << plan;
|
||||
}
|
||||
|
||||
QList<TurnstileMigrationItem> Turnstile::readMigrationPlan() {
|
||||
QFile file(writeableFile());
|
||||
|
||||
QList<TurnstileMigrationItem> plan;
|
||||
if (!file.exists()) return plan;
|
||||
|
||||
file.open(QIODevice::ReadOnly);
|
||||
QDataStream in(&file); // read the data serialized from the file
|
||||
in >> plan;
|
||||
|
||||
return plan;
|
||||
}
|
||||
|
||||
void Turnstile::planMigration(QString zaddr, QString destAddr) {
|
||||
// First, get the balance and split up the amounts
|
||||
auto bal = rpc->getAllBalances()->value(zaddr);
|
||||
auto splits = splitAmount(bal+2354, 5);
|
||||
|
||||
// Then, generate an intermediate t-Address for each part using getBatchRPC
|
||||
rpc->getBatchRPC<double>(splits,
|
||||
[=] (double /*unused*/) {
|
||||
json payload = {
|
||||
{"jsonrpc", "1.0"},
|
||||
{"id", "someid"},
|
||||
{"method", "getnewaddress"},
|
||||
};
|
||||
return payload;
|
||||
},
|
||||
[=] (QMap<double, json>* newAddrs) {
|
||||
// Get block numbers
|
||||
auto curBlock = Settings::getInstance()->getBlockNumber();
|
||||
auto blockNumbers = getBlockNumbers(curBlock, curBlock + 10, splits.size());
|
||||
|
||||
// Assign the amounts to the addresses.
|
||||
QList<TurnstileMigrationItem> migItems;
|
||||
|
||||
for (int i=0; i < splits.size(); i++) {
|
||||
auto tAddr = newAddrs->values()[i].get<json::string_t>();
|
||||
auto item = TurnstileMigrationItem { zaddr, QString::fromStdString(tAddr), destAddr,
|
||||
blockNumbers[i], splits[i], i == splits.size() -1 };
|
||||
migItems.push_back(item);
|
||||
}
|
||||
|
||||
std::sort(migItems.begin(), migItems.end(), [&] (auto a, auto b) {
|
||||
return a.blockNumber < b.blockNumber;
|
||||
});
|
||||
|
||||
// The first migration is shifted to the current block, so the user sees something
|
||||
// happening immediately
|
||||
migItems[0].blockNumber = curBlock;
|
||||
|
||||
writeMigrationPlan(migItems);
|
||||
auto readPlan = readMigrationPlan();
|
||||
|
||||
for (auto item : readPlan) {
|
||||
qDebug() << item.fromAddr << item.intTAddr
|
||||
<< item.destAddr << item.amount << item.blockNumber << item.chaff;
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
QList<int> Turnstile::getBlockNumbers(int start, int end, int count) {
|
||||
QList<int> blocks;
|
||||
// Generate 'count' numbers between [start, end]
|
||||
for (int i=0; i < count; i++) {
|
||||
auto blk = (std::rand() % (end - start)) + start;
|
||||
blocks.push_back(blk);
|
||||
}
|
||||
|
||||
return blocks;
|
||||
}
|
||||
|
||||
QList<double> Turnstile::splitAmount(double amount, int parts) {
|
||||
QList<double> amounts;
|
||||
// Need at least 0.0004 ZEC for this
|
||||
|
||||
Reference in New Issue
Block a user