feather/src/utils/RestoreHeightLookup.h

103 lines
3.1 KiB
C
Raw Normal View History

2021-01-20 21:13:51 +00:00
// SPDX-License-Identifier: BSD-3-Clause
2024-01-01 17:07:58 +00:00
// SPDX-FileCopyrightText: 2020-2024 The Monero Project
2021-01-20 21:13:51 +00:00
#ifndef FEATHER_RESTOREHEIGHTLOOKUP_H
#define FEATHER_RESTOREHEIGHTLOOKUP_H
#include <cstdio>
#include <cstdlib>
2022-12-21 15:15:22 +00:00
#include "monero_seed/monero_seed.hpp"
2021-01-20 21:13:51 +00:00
#include "networktype.h"
2021-07-06 19:36:27 +00:00
#include "utils/Utils.h"
2021-01-20 21:13:51 +00:00
struct RestoreHeightLookup {
NetworkType::Type type;
2022-02-25 15:29:33 +00:00
QMap<time_t, int> data;
2021-01-20 21:13:51 +00:00
explicit RestoreHeightLookup(NetworkType::Type type) : type(type) {}
2022-02-25 15:29:33 +00:00
int dateToHeight(time_t date) {
2021-01-20 21:13:51 +00:00
// restore height based on a given timestamp using a lookup
// table. If it cannot find the date in the lookup table, it
// will calculate the blockheight based off the last known
// date: ((now - lastKnownDate) / blockTime) - clearance
2021-03-12 18:26:48 +00:00
if (this->type == NetworkType::TESTNET) {
return 1;
}
2021-01-20 21:13:51 +00:00
int blockTime = 120;
2022-02-25 15:29:33 +00:00
int blocksPerDay = 720;
2021-01-20 21:13:51 +00:00
int blockCalcClearance = blocksPerDay * 5;
2022-02-25 15:29:33 +00:00
QList<time_t> values = this->data.keys();
// If timestamp is before epoch, return genesis height.
if (date <= values.at(0)) {
return 1;
}
2021-05-18 15:59:18 +00:00
for (int i = 0; i != values.count(); i++) {
2022-02-25 15:29:33 +00:00
if (values[i] > date) {
if (i == 0) {
return 1;
}
return this->data[values[i-1]] - blockCalcClearance;
2021-01-20 21:13:51 +00:00
}
}
// lookup failed, calculate blockheight from last known checkpoint
2022-02-25 15:29:33 +00:00
time_t lastBlockHeightTime = values.last();
2021-01-20 21:13:51 +00:00
int lastBlockHeight = this->data[lastBlockHeightTime];
2022-02-25 15:29:33 +00:00
time_t deltaTime = date - lastBlockHeightTime;
2021-01-20 21:13:51 +00:00
int deltaBlocks = deltaTime / blockTime;
2022-02-25 15:29:33 +00:00
2021-01-20 21:13:51 +00:00
int blockHeight = (lastBlockHeight + deltaBlocks) - blockCalcClearance;
return blockHeight;
}
2022-02-25 15:29:33 +00:00
time_t heightToTimestamp(int height) {
2021-01-20 21:13:51 +00:00
// @TODO: most likely inefficient, refactor
2022-02-25 15:29:33 +00:00
QMap<time_t, int>::iterator i;
time_t timestamp = 0;
2021-03-12 18:26:48 +00:00
int heightData = 1;
2021-01-20 21:13:51 +00:00
for (i = this->data.begin(); i != this->data.end(); ++i) {
2022-02-25 15:29:33 +00:00
time_t ts = i.key();
2021-01-20 21:13:51 +00:00
if (i.value() > height)
return timestamp;
timestamp = ts;
2021-03-12 18:26:48 +00:00
heightData = i.value();
2021-01-20 21:13:51 +00:00
}
2021-03-12 18:26:48 +00:00
while (heightData < height) {
heightData += 720; // blocks per day
timestamp += 86400; // seconds in day
}
2021-01-20 21:13:51 +00:00
return timestamp;
}
2021-05-22 19:32:48 +00:00
QDateTime heightToDate(int height) {
return QDateTime::fromSecsSinceEpoch(this->heightToTimestamp(height));
}
2021-01-20 21:13:51 +00:00
static RestoreHeightLookup *fromFile(const QString &fn, NetworkType::Type type) {
// initialize this class using a lookup table, e.g `:/assets/restore_heights_monero_mainnet.txt`/
auto rtn = new RestoreHeightLookup(type);
2022-02-25 15:29:33 +00:00
auto data= Utils::barrayToString(Utils::fileOpen(fn));
for (const auto &line: data.split('\n')) {
if (line.trimmed().isEmpty()) {
continue;
}
2021-01-20 21:13:51 +00:00
auto spl = line.trimmed().split(':');
2022-02-25 15:29:33 +00:00
rtn->data[(time_t)spl.at(0).toInt()] = spl.at(1).toInt();
2021-01-20 21:13:51 +00:00
}
return rtn;
}
};
#endif //FEATHER_RESTOREHEIGHTLOOKUP_H