265 lines
7.9 KiB
Batchfile
265 lines
7.9 KiB
Batchfile
@echo off
|
|
REM Copyright 2024 The Hush Developers
|
|
REM Copyright 2024 The DragonX Developers
|
|
REM Released under the GPLv3
|
|
REM
|
|
REM Download and apply a DRAGONX blockchain bootstrap on Windows.
|
|
REM Safely preserves wallet.dat and configuration files.
|
|
|
|
setlocal enabledelayedexpansion
|
|
|
|
set "BOOTSTRAP_BASE_URL=https://bootstrap.dragonx.is"
|
|
set "BOOTSTRAP_FALLBACK_URL=https://bootstrap2.dragonx.is"
|
|
set "BOOTSTRAP_FILE=DRAGONX.zip"
|
|
set "CHAIN_NAME=DRAGONX"
|
|
|
|
REM Data directory on Windows
|
|
set "DATADIR=%APPDATA%\Hush\%CHAIN_NAME%"
|
|
|
|
REM Find dragonx-cli relative to this script
|
|
set "CLI="
|
|
set "SCRIPT_DIR=%~dp0"
|
|
if exist "%SCRIPT_DIR%dragonx-cli.exe" (
|
|
set "CLI=%SCRIPT_DIR%dragonx-cli.exe"
|
|
)
|
|
|
|
echo ============================================
|
|
echo DragonX Bootstrap Installer
|
|
echo ============================================
|
|
echo.
|
|
echo [INFO] Data directory: %DATADIR%
|
|
echo.
|
|
|
|
REM Step 1: Stop daemon if running
|
|
call :stop_daemon
|
|
if errorlevel 1 goto :error_exit
|
|
|
|
REM Step 2: Clean old chain data
|
|
call :clean_chain_data
|
|
if errorlevel 1 goto :error_exit
|
|
|
|
REM Step 3: Download bootstrap
|
|
call :download_bootstrap
|
|
if errorlevel 1 goto :error_exit
|
|
|
|
REM Step 4: Extract bootstrap
|
|
call :extract_bootstrap
|
|
if errorlevel 1 goto :error_exit
|
|
|
|
echo.
|
|
echo [INFO] Bootstrap installation complete!
|
|
echo [INFO] You can now start DragonX with: dragonxd.exe
|
|
echo.
|
|
goto :EOF
|
|
|
|
REM ============================================
|
|
REM Stop daemon if running
|
|
REM ============================================
|
|
:stop_daemon
|
|
if "%CLI%"=="" (
|
|
echo [WARN] dragonx-cli.exe not found next to this script.
|
|
echo [WARN] Please make sure the DragonX daemon is stopped before continuing.
|
|
set /p "ANSWER=Is the DragonX daemon stopped? (y/N): "
|
|
if /i not "!ANSWER!"=="y" (
|
|
echo [ERROR] Please stop the daemon first and run this script again.
|
|
exit /b 1
|
|
)
|
|
exit /b 0
|
|
)
|
|
|
|
"%CLI%" getinfo >nul 2>&1
|
|
if errorlevel 1 (
|
|
echo [INFO] Daemon is not running.
|
|
exit /b 0
|
|
)
|
|
|
|
echo [INFO] Stopping DragonX daemon...
|
|
"%CLI%" stop >nul 2>&1
|
|
|
|
set "TRIES=0"
|
|
:wait_loop
|
|
"%CLI%" getinfo >nul 2>&1
|
|
if errorlevel 1 goto :daemon_stopped
|
|
timeout /t 2 /nobreak >nul
|
|
set /a TRIES+=1
|
|
if %TRIES% geq 60 (
|
|
echo [ERROR] Daemon did not stop after 120 seconds. Please stop it manually and retry.
|
|
exit /b 1
|
|
)
|
|
goto :wait_loop
|
|
|
|
:daemon_stopped
|
|
echo [INFO] Daemon stopped.
|
|
exit /b 0
|
|
|
|
REM ============================================
|
|
REM Clean blockchain data, preserving wallet and config
|
|
REM ============================================
|
|
:clean_chain_data
|
|
if not exist "%DATADIR%" (
|
|
echo [INFO] Data directory does not exist yet, creating it.
|
|
mkdir "%DATADIR%"
|
|
exit /b 0
|
|
)
|
|
|
|
echo [INFO] Cleaning blockchain data from %DATADIR% ...
|
|
|
|
REM Preserve wallet.dat and config
|
|
set "TMPDIR=%TEMP%\dragonx-bootstrap-%RANDOM%"
|
|
mkdir "%TMPDIR%" 2>nul
|
|
|
|
for %%F in (wallet.dat DRAGONX.conf peers.dat) do (
|
|
if exist "%DATADIR%\%%F" (
|
|
copy /y "%DATADIR%\%%F" "%TMPDIR%\%%F" >nul
|
|
)
|
|
)
|
|
|
|
REM Remove blockchain directories and files
|
|
for %%D in (blocks chainstate notarizations komodo) do (
|
|
if exist "%DATADIR%\%%D" (
|
|
rmdir /s /q "%DATADIR%\%%D" 2>nul
|
|
)
|
|
)
|
|
for %%F in (db.log debug.log fee_estimates.dat banlist.dat) do (
|
|
if exist "%DATADIR%\%%F" (
|
|
del /f /q "%DATADIR%\%%F" 2>nul
|
|
)
|
|
)
|
|
|
|
REM Restore preserved files
|
|
for %%F in (wallet.dat DRAGONX.conf peers.dat) do (
|
|
if exist "%TMPDIR%\%%F" (
|
|
copy /y "%TMPDIR%\%%F" "%DATADIR%\%%F" >nul
|
|
)
|
|
)
|
|
rmdir /s /q "%TMPDIR%" 2>nul
|
|
|
|
echo [INFO] Blockchain data cleaned.
|
|
exit /b 0
|
|
|
|
REM ============================================
|
|
REM Download bootstrap (with fallback)
|
|
REM ============================================
|
|
:download_bootstrap
|
|
echo [INFO] Downloading bootstrap from %BOOTSTRAP_BASE_URL% ...
|
|
echo [INFO] This may take a while depending on your connection speed.
|
|
|
|
REM Try primary URL
|
|
call :do_download "%BOOTSTRAP_BASE_URL%"
|
|
if not errorlevel 1 goto :download_verify
|
|
|
|
echo [WARN] Primary download failed, trying fallback %BOOTSTRAP_FALLBACK_URL% ...
|
|
call :do_download "%BOOTSTRAP_FALLBACK_URL%"
|
|
if errorlevel 1 (
|
|
echo [ERROR] Download failed from both primary and fallback servers.
|
|
exit /b 1
|
|
)
|
|
|
|
:download_verify
|
|
echo [INFO] Bootstrap download complete.
|
|
|
|
REM Verify SHA256 checksum
|
|
echo [INFO] Verifying checksum...
|
|
pushd "%DATADIR%"
|
|
|
|
REM Read expected hash from the .sha256 file (format: "hash filename" or "hash *filename")
|
|
set "EXPECTED_HASH="
|
|
for /f "tokens=1" %%A in (%BOOTSTRAP_FILE%.sha256) do (
|
|
set "EXPECTED_HASH=%%A"
|
|
)
|
|
|
|
if "%EXPECTED_HASH%"=="" (
|
|
echo [WARN] Could not read expected checksum, skipping verification.
|
|
goto :verify_done
|
|
)
|
|
|
|
REM Use certutil to compute SHA256
|
|
certutil -hashfile "%BOOTSTRAP_FILE%" SHA256 > "%TEMP%\dragonx_hash.tmp" 2>nul
|
|
if errorlevel 1 (
|
|
echo [WARN] certutil not available, skipping checksum verification.
|
|
goto :verify_done
|
|
)
|
|
|
|
REM certutil outputs hash on the second line
|
|
set "ACTUAL_HASH="
|
|
set "LINE_NUM=0"
|
|
for /f "skip=1 tokens=*" %%H in (%TEMP%\dragonx_hash.tmp) do (
|
|
if not defined ACTUAL_HASH (
|
|
set "ACTUAL_HASH=%%H"
|
|
)
|
|
)
|
|
REM Remove spaces from certutil output
|
|
set "ACTUAL_HASH=!ACTUAL_HASH: =!"
|
|
del /f /q "%TEMP%\dragonx_hash.tmp" 2>nul
|
|
|
|
if /i "!ACTUAL_HASH!"=="!EXPECTED_HASH!" (
|
|
echo [INFO] SHA256 checksum verified.
|
|
) else (
|
|
echo [ERROR] SHA256 checksum verification failed! The download may be corrupted.
|
|
echo [ERROR] Expected: !EXPECTED_HASH!
|
|
echo [ERROR] Got: !ACTUAL_HASH!
|
|
popd
|
|
exit /b 1
|
|
)
|
|
|
|
:verify_done
|
|
REM Clean up checksum files
|
|
del /f /q "%BOOTSTRAP_FILE%.md5" 2>nul
|
|
del /f /q "%BOOTSTRAP_FILE%.sha256" 2>nul
|
|
popd
|
|
exit /b 0
|
|
|
|
REM ============================================
|
|
REM Download files from a given base URL
|
|
REM Usage: call :do_download "base_url"
|
|
REM ============================================
|
|
:do_download
|
|
set "BASE=%~1"
|
|
|
|
REM Use PowerShell to download (available on all modern Windows)
|
|
echo [INFO] Downloading %BASE%/%BOOTSTRAP_FILE% ...
|
|
powershell -NoProfile -Command ^
|
|
"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; try { (New-Object Net.WebClient).DownloadFile('%BASE%/%BOOTSTRAP_FILE%', '%DATADIR%\%BOOTSTRAP_FILE%') } catch { exit 1 }"
|
|
if errorlevel 1 exit /b 1
|
|
|
|
echo [INFO] Downloading checksums...
|
|
powershell -NoProfile -Command ^
|
|
"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; try { (New-Object Net.WebClient).DownloadFile('%BASE%/%BOOTSTRAP_FILE%.md5', '%DATADIR%\%BOOTSTRAP_FILE%.md5') } catch { exit 1 }"
|
|
if errorlevel 1 exit /b 1
|
|
|
|
powershell -NoProfile -Command ^
|
|
"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; try { (New-Object Net.WebClient).DownloadFile('%BASE%/%BOOTSTRAP_FILE%.sha256', '%DATADIR%\%BOOTSTRAP_FILE%.sha256') } catch { exit 1 }"
|
|
if errorlevel 1 exit /b 1
|
|
|
|
exit /b 0
|
|
|
|
REM ============================================
|
|
REM Extract bootstrap zip
|
|
REM ============================================
|
|
:extract_bootstrap
|
|
echo [INFO] Extracting bootstrap...
|
|
pushd "%DATADIR%"
|
|
|
|
REM Use PowerShell to extract zip, excluding wallet.dat and .conf files
|
|
powershell -NoProfile -Command ^
|
|
"Add-Type -AssemblyName System.IO.Compression.FileSystem; $zip = [System.IO.Compression.ZipFile]::OpenRead('%DATADIR%\%BOOTSTRAP_FILE%'); foreach ($entry in $zip.Entries) { if ($entry.Name -eq 'wallet.dat' -or $entry.Name -like '*.conf') { continue } $dest = Join-Path '%DATADIR%' $entry.FullName; if ($entry.FullName.EndsWith('/')) { New-Item -ItemType Directory -Force -Path $dest | Out-Null } else { $parent = Split-Path $dest -Parent; if (-not (Test-Path $parent)) { New-Item -ItemType Directory -Force -Path $parent | Out-Null } [System.IO.Compression.ZipFileExtensions]::ExtractToFile($entry, $dest, $true) } }; $zip.Dispose()"
|
|
if errorlevel 1 (
|
|
echo [ERROR] Extraction failed.
|
|
popd
|
|
exit /b 1
|
|
)
|
|
|
|
echo [INFO] Bootstrap extracted successfully.
|
|
|
|
REM Clean up archive
|
|
del /f /q "%BOOTSTRAP_FILE%" 2>nul
|
|
echo [INFO] Removed downloaded archive to save disk space.
|
|
|
|
popd
|
|
exit /b 0
|
|
|
|
:error_exit
|
|
echo.
|
|
echo [ERROR] Bootstrap installation failed.
|
|
exit /b 1
|