Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -161,3 +161,5 @@ dist/
osx_volname
dist/
src/test/runtest.sh
configure~
src/dashbls/configure~
2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,7 @@ if test "$CXXFLAGS_overridden" = "no"; then
AX_CHECK_COMPILE_FLAG([-Wduplicated-branches], [WARN_CXXFLAGS="$WARN_CXXFLAGS -Wduplicated-branches"], [], [$CXXFLAG_WERROR])
AX_CHECK_COMPILE_FLAG([-Wduplicated-cond], [WARN_CXXFLAGS="$WARN_CXXFLAGS -Wduplicated-cond"], [], [$CXXFLAG_WERROR])
AX_CHECK_COMPILE_FLAG([-Wlogical-op], [WARN_CXXFLAGS="$WARN_CXXFLAGS -Wlogical-op"], [], [$CXXFLAG_WERROR])
AX_CHECK_COMPILE_FLAG([-Woverloaded-virtual], [WARN_CXXFLAGS="$WARN_CXXFLAGS -Woverloded-virtual"], [], [$CXXFLAG_WERROR])
AX_CHECK_COMPILE_FLAG([-Woverloaded-virtual], [WARN_CXXFLAGS="$WARN_CXXFLAGS -Woverloaded-virtual"], [], [$CXXFLAG_WERROR])
dnl -Wsuggest-override is broken with GCC before 9.2
dnl https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78010
AX_CHECK_COMPILE_FLAG([-Wsuggest-override], [WARN_CXXFLAGS="$WARN_CXXFLAGS -Wsuggest-override"], [], [$CXXFLAG_WERROR],
Expand Down
3 changes: 2 additions & 1 deletion src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -729,6 +729,7 @@ libraptoreum_util_a_SOURCES = \
threadinterrupt.cpp \
util/bip32.cpp \
util/system.cpp \
bootstrap/bootstrapmanager.cpp \
util/asmap.cpp \
util/moneystr.cpp \
util/spanparsing.cpp \
Expand Down Expand Up @@ -779,7 +780,7 @@ raptoreumd_LDADD = \
$(LIBMEMENV) \
$(LIBSECP256K1)

raptoreumd_LDADD += $(BACKTRACE_LIB) $(BOOST_LIBS) $(BDB_LIBS) $(MINIUPNPC_LIBS) $(NATPMP_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(ZMQ_LIBS) $(LIBDASHBLS) $(GMP_LIBS)
raptoreumd_LDADD += $(BACKTRACE_LIB) $(BOOST_LIBS) $(BDB_LIBS) $(MINIUPNPC_LIBS) $(NATPMP_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(ZMQ_LIBS) $(LIBDASHBLS) $(GMP_LIBS) -lcurl -larchive

# raptoreum-cli binary #
raptoreum_cli_SOURCES = raptoreum-cli.cpp
Expand Down
117 changes: 117 additions & 0 deletions src/bootstrap/bootstrapmanager.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
#include "bootstrapmanager.h"
#include <boost/filesystem.hpp>
#include <curl/curl.h>
#include <archive.h>
#include <archive_entry.h>

static size_t WriteCallback(void* ptr, size_t size, size_t nmemb, FILE* stream) {
return fwrite(ptr, size, nmemb, stream);
}

bool BootstrapManager::DownloadFile(const std::string& url, const std::string& dest, ProgressCallback onProgress) {
CURL* curl = curl_easy_init();
if (!curl) return false;

FILE* fp = fopen(dest.c_str(), "wb");
if (!fp) {
curl_easy_cleanup(curl);
return false;
}

curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);

CURLcode res = curl_easy_perform(curl);
fclose(fp);
curl_easy_cleanup(curl);

return (res == CURLE_OK);
}

bool BootstrapManager::ExtractArchive(const std::string& archivePath, const std::string& destDir, ProgressCallback onProgress) {
struct archive* a = archive_read_new();
struct archive* ext = archive_write_disk_new();
struct archive_entry* entry;

archive_read_support_format_zip(a);
archive_read_support_format_tar(a);
archive_read_support_filter_xz(a);

if (archive_read_open_filename(a, archivePath.c_str(), 10240) != ARCHIVE_OK) {
return false;
}

while (archive_read_next_header(a, &entry) == ARCHIVE_OK) {
// Zieldpfad setzen
std::string fullPath = destDir + "/" + archive_entry_pathname(entry);
archive_entry_set_pathname(entry, fullPath.c_str());
archive_write_header(ext, entry);

const void* buff;
size_t size;
la_int64_t offset;
while (archive_read_data_block(a, &buff, &size, &offset) == ARCHIVE_OK) {
archive_write_data_block(ext, buff, size, offset);
}
}

archive_read_close(a);
archive_read_free(a);
archive_write_close(ext);
archive_write_free(ext);

return true;
}

bool BootstrapManager::RunIfNeeded(const std::string& dataDir, ProgressCallback onProgress) {

// Schritt 1: Bootstrap-Prüfung ankündigen
onProgress("Checking if bootstrap is needed...", 0);

// Schritt 2: Prüfen ob blocks/ Ordner fehlt
if (!IsFirstRun(dataDir)) {
onProgress("Bootstrap not needed, blocks directory already exists.", 100);
return true;
}

onProgress("No blockchain data found, starting bootstrap download...", 5);

// Schritt 3: Download
onProgress("Downloading bootstrap.zip from bootstrap.raptoreum.com...", 10);
std::string zipPath = dataDir + "/bootstrap.zip";
if (!DownloadFile("https://bootstrap.raptoreum.com/bootstraps/bootstrap.zip", zipPath, onProgress)) {
// Schritt 4: Server nicht erreichbar
onProgress("ERROR: Bootstrap server not reachable or download failed!", -1);
return false;
}
onProgress("Download complete.", 70);

// Schritt 5: Entpacken
onProgress("Extracting bootstrap.zip...", 75);
if (!ExtractArchive(zipPath, dataDir, onProgress)) {
onProgress("ERROR: Extraction of bootstrap.zip failed!", -1);
return false;
}
onProgress("Extraction complete.", 85);

// powcache.dat laden
onProgress("Downloading powcache.dat...", 90);
if (!DownloadFile("https://bootstrap.raptoreum.com/bootstraps/powcache.dat",
dataDir + "/powcache.dat", onProgress)) {
onProgress("WARNING: Could not download powcache.dat, continuing without it.", 95);
} else {
onProgress("powcache.dat downloaded successfully.", 95);
}

onProgress("Bootstrap complete! Starting normal sync...", 100);
return true;
}

bool BootstrapManager::IsFirstRun(const std::string& dataDir) {
boost::filesystem::path blockFile(dataDir);
blockFile /= "blocks/blk00000.dat";
// Wenn diese Datei fehlt, ist die Chain leer = Bootstrap nötig
return !boost::filesystem::exists(blockFile);
}
17 changes: 17 additions & 0 deletions src/bootstrap/bootstrapmanager.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#pragma once
#include <string>
#include <functional>

// Callback types for progress bar
using ProgressCallback = std::function<void(const std::string& status, int percent)>;

class BootstrapManager {
public:
// Returns true if bootstrap was necessary and successful, false if not needed or failed
static bool RunIfNeeded(const std::string& dataDir, ProgressCallback onProgress);

private:
static bool IsFirstRun(const std::string& dataDir);
static bool DownloadFile(const std::string& url, const std::string& dest, ProgressCallback onProgress);
static bool ExtractArchive(const std::string& archivePath, const std::string& destDir, ProgressCallback onProgress);
};
16 changes: 16 additions & 0 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <amount.h>
#include <banman.h>
#include <base58.h>
#include <bootstrap/bootstrapmanager.h>
#include <chain.h>
#include <chainparams.h>
#include <checkpoints.h>
Expand Down Expand Up @@ -1836,6 +1837,21 @@ bool AppInitMain(const util::Ref &context, NodeContext &node, interfaces::BlockA
LogPrintf("Config file: %s not found, skipping\n", config_file_path.string());
}

// ********************************************************* Bootstrap
{
std::string dataDir = GetDataDir().string();
BootstrapManager::RunIfNeeded(dataDir, [](const std::string& status, int percent) {
if (percent < 0) {
// Fehler
LogPrintf("Bootstrap ERROR: %s\n", status);
} else {
LogPrintf("Bootstrap [%d%%]: %s\n", percent, status);
}
});
}
// ********************************************************* End Bootstrap


LogPrintf("Using at most %i automatic connections (%i file descriptors available)\n", nMaxConnections, nFD);

// Warn about relative -datadir path.
Expand Down
Loading