2026-01-30 21:15:18 +04:00
|
|
|
#pragma once
|
|
|
|
|
#include "logos_api.h"
|
|
|
|
|
#include "logos_sdk.h"
|
2026-02-19 14:15:16 +04:00
|
|
|
#include <QDir>
|
2026-02-17 11:27:03 +04:00
|
|
|
#include <QFile>
|
2026-01-30 21:15:18 +04:00
|
|
|
#include <QObject>
|
|
|
|
|
#include <QString>
|
|
|
|
|
#include <QStringList>
|
|
|
|
|
#include <QTimer>
|
|
|
|
|
#include <QtQml/qqml.h>
|
|
|
|
|
|
|
|
|
|
static const int RET_OK = 0;
|
2026-02-10 13:27:11 +04:00
|
|
|
static const int RET_PROGRESS = 3;
|
2026-02-20 13:41:07 +04:00
|
|
|
static const QString ECHO_PROVIDER = "https://echo.codex.storage/";
|
2026-02-19 14:15:16 +04:00
|
|
|
static const QString APP_HOME = QDir::homePath() + "/.logos_storage";
|
|
|
|
|
static const QString DEFAULT_DATA_DIR = APP_HOME + "/data";
|
|
|
|
|
static const QString USER_CONFIG_PATH = APP_HOME + "/config.json";
|
2026-01-30 21:15:18 +04:00
|
|
|
|
2026-02-17 11:27:03 +04:00
|
|
|
// Add manual SPR from https://spr.codex.storage/devnet
|
|
|
|
|
static const QStringList BOOTSTRAP_NODES = {
|
|
|
|
|
"spr:CiUIAhIhA-VlcoiRm02KyIzrcTP-ljFpzTljfBRRKTIvhMIwqBqWEgIDARpJCicAJQgCEiED5WVyiJGbTYrIjOtxM_6WMWnNOWN8FFEpMi-"
|
|
|
|
|
"EwjCoGpYQs8n8wQYaCwoJBHTKubmRAnU6GgsKCQR0yrm5kQJ1OipHMEUCIQDwUNsfReB4ty7JFS5WVQ6n1fcko89qVAOfQEHixa03rgIgan2-"
|
|
|
|
|
"uFNDT-r4s9TOkLe9YBkCbsRWYCHGGVJ25rLj0QE",
|
|
|
|
|
"spr:CiUIAhIhApIj9p6zJDRbw2NoCo-"
|
|
|
|
|
"tj98Y760YbppRiEpGIE1yGaMzEgIDARpJCicAJQgCEiECkiP2nrMkNFvDY2gKj62P3xjvrRhumlGISkYgTXIZozMQvcz8wQYaCwoJBAWhF3WRAnVEG"
|
|
|
|
|
"gsKCQQFoRd1kQJ1RCpGMEQCIFZB84O_nzPNuViqEGRL1vJTjHBJ-i5ZDgFL5XZxm4HAAiB8rbLHkUdFfWdiOmlencYVn0noSMRHzn4lJYoShuVzlw",
|
|
|
|
|
"spr:CiUIAhIhApqRgeWRPSXocTS9RFkQmwTZRG-"
|
|
|
|
|
"Cdt7UR2N7POoz606ZEgIDARpJCicAJQgCEiECmpGB5ZE9JehxNL1EWRCbBNlEb4J23tRHY3s86jPrTpkQj8_"
|
|
|
|
|
"8wQYaCwoJBAXfEfiRAnVOGgsKCQQF3xH4kQJ1TipGMEQCIGWJMsF57N1iIEQgTH7IrVOgEgv0J2P2v3jvQr5Cjy-RAiAy4aiZ8QtyDvCfl_K_"
|
|
|
|
|
"w6SyZ9csFGkRNTpirq_M_QNgKw"};
|
|
|
|
|
|
2026-01-30 21:15:18 +04:00
|
|
|
class StorageBackend : public QObject {
|
|
|
|
|
Q_OBJECT
|
|
|
|
|
QML_ELEMENT
|
2026-02-10 13:27:11 +04:00
|
|
|
Q_PROPERTY(QString debugLogs READ debugLogs NOTIFY debugLogsChanged)
|
2026-02-17 11:27:03 +04:00
|
|
|
Q_PROPERTY(StorageStatus status READ status WRITE status NOTIFY statusChanged)
|
2026-02-13 20:16:27 +04:00
|
|
|
Q_PROPERTY(QString cid READ cid NOTIFY cidChanged)
|
2026-02-15 20:14:44 +04:00
|
|
|
Q_PROPERTY(int uploadProgress READ uploadProgress NOTIFY uploadProgressChanged)
|
|
|
|
|
Q_PROPERTY(QString uploadStatus READ uploadStatus NOTIFY uploadStatusChanged)
|
2026-02-17 11:53:47 +04:00
|
|
|
Q_PROPERTY(QVariantList manifests READ manifests NOTIFY manifestsChanged)
|
2026-02-17 13:08:30 +04:00
|
|
|
Q_PROPERTY(qint64 quotaMaxBytes READ quotaMaxBytes NOTIFY quotaChanged)
|
|
|
|
|
Q_PROPERTY(qint64 quotaUsedBytes READ quotaUsedBytes NOTIFY quotaChanged)
|
|
|
|
|
Q_PROPERTY(qint64 quotaReservedBytes READ quotaReservedBytes NOTIFY quotaChanged)
|
2026-01-30 21:15:18 +04:00
|
|
|
|
|
|
|
|
public:
|
2026-02-19 14:15:16 +04:00
|
|
|
enum StorageStatus {
|
|
|
|
|
// Stopped means that the context is created but the module is not started
|
|
|
|
|
Stopped = 0,
|
|
|
|
|
|
|
|
|
|
Starting,
|
|
|
|
|
|
|
|
|
|
// Running means the module is started
|
|
|
|
|
Running,
|
|
|
|
|
|
|
|
|
|
Stopping,
|
|
|
|
|
|
|
|
|
|
// Destroyed means the context is not created (or has been destroyed).
|
|
|
|
|
Destroyed
|
|
|
|
|
};
|
2026-01-30 21:15:18 +04:00
|
|
|
Q_ENUM(StorageStatus)
|
|
|
|
|
|
2026-02-13 20:16:27 +04:00
|
|
|
QString cid() const;
|
2026-02-10 13:27:11 +04:00
|
|
|
QString debugLogs() const;
|
2026-02-13 20:16:27 +04:00
|
|
|
StorageStatus status() const;
|
2026-02-15 20:14:44 +04:00
|
|
|
int uploadProgress() const;
|
|
|
|
|
QString uploadStatus() const;
|
2026-02-17 11:53:47 +04:00
|
|
|
QVariantList manifests() const;
|
2026-02-17 13:08:30 +04:00
|
|
|
qint64 quotaMaxBytes() const;
|
|
|
|
|
qint64 quotaUsedBytes() const;
|
|
|
|
|
qint64 quotaReservedBytes() const;
|
2026-01-30 21:15:18 +04:00
|
|
|
|
2026-02-19 14:15:16 +04:00
|
|
|
static QJsonDocument defaultConfig();
|
2026-02-17 11:27:03 +04:00
|
|
|
|
2026-01-30 21:15:18 +04:00
|
|
|
explicit StorageBackend(LogosAPI* logosAPI = nullptr, QObject* parent = nullptr);
|
|
|
|
|
~StorageBackend();
|
|
|
|
|
|
|
|
|
|
public slots:
|
2026-02-13 20:16:27 +04:00
|
|
|
LogosResult start(const QString& configJson = "");
|
2026-01-30 21:15:18 +04:00
|
|
|
void destroy();
|
|
|
|
|
void stop();
|
2026-02-13 20:16:27 +04:00
|
|
|
void tryPeerConnect(const QString& peerId);
|
2026-02-10 13:27:11 +04:00
|
|
|
void tryDebug();
|
|
|
|
|
void tryUpload();
|
|
|
|
|
void tryUploadFinalize();
|
|
|
|
|
void exists(const QString& cid);
|
|
|
|
|
void remove(const QString& cid);
|
|
|
|
|
void fetch(const QString& cid);
|
|
|
|
|
void tryUploadFile(const QUrl& url);
|
|
|
|
|
void tryDownloadFile(const QString& cid, const QUrl& url);
|
|
|
|
|
void dataDir();
|
|
|
|
|
void version();
|
|
|
|
|
void spr();
|
|
|
|
|
void showPeerId();
|
|
|
|
|
void downloadManifest(const QString& cid);
|
|
|
|
|
void downloadManifests();
|
|
|
|
|
void space();
|
2026-02-13 20:16:27 +04:00
|
|
|
LogosResult init(const QString& configJson);
|
2026-02-10 13:27:11 +04:00
|
|
|
void updateLogLevel(const QString& logLevel);
|
2026-02-17 11:27:03 +04:00
|
|
|
void status(StorageStatus status);
|
2026-02-19 14:15:16 +04:00
|
|
|
|
|
|
|
|
// Save the user config passed in parameter
|
|
|
|
|
// into the user config json.
|
2026-02-17 21:57:31 +04:00
|
|
|
void saveUserConfig(const QString& configJson);
|
2026-02-10 13:27:11 +04:00
|
|
|
|
2026-02-19 14:15:16 +04:00
|
|
|
// Save the current config object
|
|
|
|
|
// into the user config json.
|
|
|
|
|
void saveCurrentConfig();
|
|
|
|
|
|
|
|
|
|
// Load the user config saved previously
|
|
|
|
|
void loadUserConfig();
|
|
|
|
|
|
|
|
|
|
// Take a new config json and reload the Storage context
|
|
|
|
|
// if the configuration has changed.
|
|
|
|
|
//
|
|
|
|
|
// This method cannot be used if the Storage Module
|
|
|
|
|
// is running, starting or stopping.
|
|
|
|
|
//
|
|
|
|
|
// If the Storage Module was already created,
|
|
|
|
|
// it will be destroyed first.
|
|
|
|
|
//
|
|
|
|
|
// On success, the status will be set to Stopped.
|
|
|
|
|
//
|
|
|
|
|
// Emit initCompleted on success.
|
|
|
|
|
// Emit initFailed on failure.
|
|
|
|
|
void reloadIfChanged(const QString& configJson);
|
|
|
|
|
|
|
|
|
|
// Enables the upnp in the config
|
|
|
|
|
// and re-create a context with the new configuration
|
|
|
|
|
void enableUpnpConfig();
|
|
|
|
|
|
|
|
|
|
// Enables the net external in the config
|
|
|
|
|
// and re-create a context with the new configuration
|
|
|
|
|
void enableNatExtConfig(int tcpPort);
|
|
|
|
|
|
2026-02-19 17:44:49 +04:00
|
|
|
// This method will ensure that the node is ready to be used.
|
2026-02-20 13:41:07 +04:00
|
|
|
//
|
2026-02-19 17:44:49 +04:00
|
|
|
// 1- Make a call to debug function in the storage module and
|
|
|
|
|
// make sure that the node has peer. If not, the UI should suggest
|
|
|
|
|
// to modifiy the discovery port (8090) in the advance settings (to come).
|
2026-02-20 13:41:07 +04:00
|
|
|
//
|
2026-02-19 17:44:49 +04:00
|
|
|
// 2- Ensure that the tcp port is open to remote connection. If not,
|
|
|
|
|
// the UI should suggest to change go back and try another port and double
|
|
|
|
|
// check that the port forwarding is enabled on the router.
|
2026-02-20 13:41:07 +04:00
|
|
|
//
|
|
|
|
|
// Emit nodeIsUp() on success
|
|
|
|
|
// Emit nodeIsntUp(error) on failure
|
2026-02-19 17:44:49 +04:00
|
|
|
void checkNodeIsUp();
|
|
|
|
|
|
2026-01-30 21:15:18 +04:00
|
|
|
signals:
|
2026-02-19 14:15:16 +04:00
|
|
|
void ready();
|
2026-02-17 11:27:03 +04:00
|
|
|
void startCompleted();
|
|
|
|
|
void startFailed(const QString& error);
|
2026-01-30 21:15:18 +04:00
|
|
|
void statusChanged();
|
2026-02-10 13:27:11 +04:00
|
|
|
void debugLogsChanged();
|
2026-02-17 11:27:03 +04:00
|
|
|
void stopCompleted();
|
2026-02-13 20:16:27 +04:00
|
|
|
void cidChanged();
|
2026-02-15 20:14:44 +04:00
|
|
|
void uploadProgressChanged();
|
|
|
|
|
void uploadStatusChanged();
|
2026-02-17 11:53:47 +04:00
|
|
|
void manifestsChanged();
|
2026-02-17 13:08:30 +04:00
|
|
|
void quotaChanged();
|
2026-02-17 21:57:31 +04:00
|
|
|
void initCompleted();
|
2026-02-19 14:15:16 +04:00
|
|
|
void natExtConfigCompleted();
|
2026-02-19 17:44:49 +04:00
|
|
|
void error(const QString& message);
|
2026-01-30 21:15:18 +04:00
|
|
|
|
2026-02-20 13:41:07 +04:00
|
|
|
// Emitted when the node port is reachable from the internet
|
|
|
|
|
void nodeIsUp();
|
|
|
|
|
|
|
|
|
|
// Emitted when the node port is not reachable, with a reason
|
|
|
|
|
void nodeIsntUp(const QString& reason);
|
|
|
|
|
|
2026-01-30 21:15:18 +04:00
|
|
|
private slots:
|
|
|
|
|
|
|
|
|
|
private:
|
2026-02-13 20:16:27 +04:00
|
|
|
void setStatus(StorageStatus newStatus);
|
2026-02-10 13:27:11 +04:00
|
|
|
void peerConnect(const QString& peerId);
|
|
|
|
|
void debug(const QString& log);
|
2026-02-19 17:44:49 +04:00
|
|
|
void reportError(const QString& message);
|
2026-01-30 21:15:18 +04:00
|
|
|
|
|
|
|
|
LogosAPI* m_logosAPI;
|
|
|
|
|
LogosModules* m_logos;
|
2026-02-13 20:16:27 +04:00
|
|
|
StorageStatus m_status;
|
2026-02-10 13:27:11 +04:00
|
|
|
QString m_debugLogs;
|
2026-02-13 20:16:27 +04:00
|
|
|
QString m_cid;
|
2026-02-15 20:14:44 +04:00
|
|
|
int m_uploadProgress = 0;
|
|
|
|
|
QString m_uploadStatus = "";
|
|
|
|
|
qint64 m_uploadTotalBytes = 0;
|
|
|
|
|
qint64 m_uploadedBytes = 0;
|
2026-02-17 11:53:47 +04:00
|
|
|
QVariantList m_manifests;
|
2026-02-17 13:08:30 +04:00
|
|
|
qint64 m_quotaMaxBytes = 0;
|
|
|
|
|
qint64 m_quotaUsedBytes = 0;
|
|
|
|
|
qint64 m_quotaReservedBytes = 0;
|
2026-02-19 14:15:16 +04:00
|
|
|
QJsonDocument m_config;
|
2026-01-30 21:15:18 +04:00
|
|
|
};
|