#!/usr/bin/env bash # Copyright 2024 The Hush Developers # Copyright 2024 The DragonX Developers # Released under the GPLv3 # # Download and apply a DRAGONX blockchain bootstrap. # Safely preserves wallet.dat and configuration files. set -euo pipefail BOOTSTRAP_BASE_URL="https://bootstrap.dragonx.is" BOOTSTRAP_FILE="DRAGONX.zip" CHAIN_NAME="DRAGONX" # Determine data directory if [[ "$OSTYPE" == "darwin"* ]]; then DATADIR="$HOME/Library/Application Support/Hush/$CHAIN_NAME" else DATADIR="$HOME/.hush/$CHAIN_NAME" fi CLI="dragonx-cli" # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # No Color info() { echo -e "${GREEN}[INFO]${NC} $*" >&2; } warn() { echo -e "${YELLOW}[WARN]${NC} $*" >&2; } error() { echo -e "${RED}[ERROR]${NC} $*" >&2; exit 1; } # Find dragonx-cli in PATH or relative to this script find_cli() { if command -v "$CLI" &>/dev/null; then CLI=$(command -v "$CLI") elif [[ -x "$(dirname "$0")/../../src/$CLI" ]]; then CLI="$(dirname "$0")/../../src/$CLI" else CLI="" fi } # Stop the daemon if running stop_daemon() { find_cli if [[ -n "$CLI" ]]; then if "$CLI" getinfo &>/dev/null 2>&1; then info "Stopping DragonX daemon..." "$CLI" stop 2>/dev/null || true # Wait for daemon to exit local tries=0 while "$CLI" getinfo &>/dev/null 2>&1; do sleep 2 tries=$((tries + 1)) if [[ $tries -ge 60 ]]; then error "Daemon did not stop after 120 seconds. Please stop it manually and retry." fi done info "Daemon stopped." else info "Daemon is not running." fi else warn "dragonx-cli not found. Please make sure the daemon is stopped before continuing." read -rp "Is the DragonX daemon stopped? (y/N): " answer if [[ "${answer,,}" != "y" ]]; then error "Please stop the daemon first and run this script again." fi fi } # Files/dirs to preserve (never delete these) PRESERVE_LIST=( "wallet.dat" "DRAGONX.conf" "peers.dat" ) # Remove blockchain data while preserving wallet and config clean_chain_data() { if [[ ! -d "$DATADIR" ]]; then info "Data directory does not exist yet, creating it." mkdir -p "$DATADIR" return fi info "Cleaning blockchain data from $DATADIR ..." # Move preserved files to a temp location local tmpdir tmpdir=$(mktemp -d) for f in "${PRESERVE_LIST[@]}"; do if [[ -e "$DATADIR/$f" ]]; then cp -a "$DATADIR/$f" "$tmpdir/" fi done # Remove blockchain directories local dirs_to_remove=("blocks" "chainstate" "notarizations" "komodo" "db.log" "debug.log" "fee_estimates.dat" "banlist.dat") for d in "${dirs_to_remove[@]}"; do if [[ -e "$DATADIR/$d" ]]; then rm -rf "$DATADIR/$d" fi done # Restore preserved files for f in "${PRESERVE_LIST[@]}"; do if [[ -e "$tmpdir/$f" ]]; then cp -a "$tmpdir/$f" "$DATADIR/" fi done rm -rf "$tmpdir" info "Blockchain data cleaned." } # Download a file via wget or curl download_file() { local url="$1" local outfile="$2" if command -v wget &>/dev/null; then wget --progress=bar:force -O "$outfile" "$url" || error "Download failed: $url" elif command -v curl &>/dev/null; then curl -L --progress-bar -o "$outfile" "$url" || error "Download failed: $url" else error "Neither wget nor curl found. Please install one and retry." fi } # Download the bootstrap and verify checksums download_bootstrap() { local outfile="$DATADIR/$BOOTSTRAP_FILE" local md5file="$DATADIR/${BOOTSTRAP_FILE}.md5" local sha256file="$DATADIR/${BOOTSTRAP_FILE}.sha256" info "Downloading bootstrap from $BOOTSTRAP_BASE_URL ..." info "This may take a while depending on your connection speed." download_file "$BOOTSTRAP_BASE_URL/$BOOTSTRAP_FILE" "$outfile" info "Bootstrap download complete." info "Downloading checksums..." download_file "$BOOTSTRAP_BASE_URL/${BOOTSTRAP_FILE}.md5" "$md5file" download_file "$BOOTSTRAP_BASE_URL/${BOOTSTRAP_FILE}.sha256" "$sha256file" # Verify checksums info "Verifying checksums..." cd "$DATADIR" if command -v md5sum &>/dev/null; then if md5sum -c "$md5file" >&2; then info "MD5 checksum verified." else error "MD5 checksum verification failed! The download may be corrupted." fi else warn "md5sum not found, skipping MD5 verification." fi if command -v sha256sum &>/dev/null; then if sha256sum -c "$sha256file" >&2; then info "SHA256 checksum verified." else error "SHA256 checksum verification failed! The download may be corrupted." fi else warn "sha256sum not found, skipping SHA256 verification." fi # Clean up checksum files rm -f "$md5file" "$sha256file" echo "$outfile" } # Extract the bootstrap extract_bootstrap() { local archive="$1" info "Extracting bootstrap..." cd "$DATADIR" # Extract zip, but never overwrite wallet.dat or config unzip -o "$archive" -x 'wallet.dat' '*.conf' || error "Extraction failed. Please install unzip and retry." info "Bootstrap extracted successfully." # Clean up the downloaded archive rm -f "$archive" info "Removed downloaded archive to save disk space." } main() { echo "============================================" echo " DragonX Bootstrap Installer" echo "============================================" echo "" info "Data directory: $DATADIR" echo "" # Step 1: Stop daemon stop_daemon # Step 2: Clean old chain data clean_chain_data # Step 3: Download bootstrap local archive archive=$(download_bootstrap) # Step 4: Extract bootstrap extract_bootstrap "$archive" echo "" info "Bootstrap installation complete!" info "You can now start DragonX with: dragonxd" echo "" } main "$@"