#!/bin/bash set -euo pipefail # Script de mise à jour du Bitcoin Signet Custom # Auteur: Équipe 4NK # Date: 2026-01-09 SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" cd "$SCRIPT_DIR" # Couleurs pour les messages RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Fonction d'affichage info() { echo -e "${BLUE}[INFO]${NC} $1" } success() { echo -e "${GREEN}[SUCCESS]${NC} $1" } warning() { echo -e "${YELLOW}[WARNING]${NC} $1" } error() { echo -e "${RED}[ERROR]${NC} $1" } # Vérification des prérequis check_prerequisites() { info "Vérification des prérequis..." if ! command -v docker &> /dev/null; then error "Docker n'est pas installé" exit 1 fi if ! sudo docker ps &> /dev/null; then error "Impossible d'accéder à Docker. Vérifiez les permissions." exit 1 fi if [ ! -f ".env" ]; then error "Le fichier .env n'existe pas" exit 1 fi success "Prérequis vérifiés" } # Récupération de la version actuelle get_current_version() { if [ -f ".bitcoin-version" ]; then cat .bitcoin-version else grep -oP 'BITCOIN_VERSION=\$\{BITCOIN_VERSION:-?\K[0-9]+\.[0-9]+' Dockerfile | head -1 || echo "unknown" fi } # Récupération de la dernière version disponible get_latest_version() { local version # Essayer plusieurs méthodes pour récupérer la version version=$(curl -s https://api.github.com/repos/bitcoin/bitcoin/releases/latest 2>/dev/null | \ grep -oP '"tag_name": "\Kv?[0-9]+\.[0-9]+\.[0-9]+' | head -1 | sed 's/^v//') if [ -z "$version" ]; then version=$(curl -s https://bitcoincore.org/bin/ 2>/dev/null | \ grep -oP 'bitcoin-core-\K[0-9]+\.[0-9]+\.[0-9]+' | sort -V | tail -1) fi if [ -z "$version" ]; then # Version par défaut si aucune méthode ne fonctionne version="30.2" warning "Impossible de récupérer la version automatiquement, utilisation de la version par défaut: $version" fi echo "$version" } # Sauvegarde avant mise à jour backup_data() { info "Sauvegarde des données avant mise à jour..." local backup_dir="backups" local backup_file="${backup_dir}/signet-backup-$(date +%Y%m%d-%H%M%S).tar.gz" mkdir -p "$backup_dir" if sudo docker ps | grep -q bitcoin-signet-instance; then info "Sauvegarde des données du conteneur..." sudo docker exec bitcoin-signet-instance tar czf /tmp/bitcoin-backup.tar.gz /root/.bitcoin/ 2>/dev/null || true sudo docker cp bitcoin-signet-instance:/tmp/bitcoin-backup.tar.gz "$backup_file" 2>/dev/null || true fi # Sauvegarder le .env cp .env "${backup_dir}/.env.backup-$(date +%Y%m%d-%H%M%S)" success "Sauvegarde effectuée: $backup_file" } # Mise à jour du Dockerfile update_dockerfile() { local new_version=$1 info "Mise à jour du Dockerfile avec Bitcoin Core $new_version..." # Mettre à jour la version dans le Dockerfile sed -i "s/ARG BITCOIN_VERSION=\${BITCOIN_VERSION:-[0-9]\+\.[0-9]\+}/ARG BITCOIN_VERSION=\${BITCOIN_VERSION:-${new_version}}/" Dockerfile success "Dockerfile mis à jour" } # Reconstruction de l'image rebuild_image() { info "Reconstruction de l'image Docker..." if sudo docker build -t bitcoin-signet .; then success "Image reconstruite avec succès" else error "Échec de la reconstruction de l'image" exit 1 fi } # Volume persistant : même que restore-signet-from-backup.sh (une seule chaîne pour Mempool, dashboard, APIs) VOLUME_NAME="signet-bitcoin-data" # Volume contenant la chaîne Signet complète (~11530 blocs). Utilisé par défaut s'il existe pour éviter de repartir sur une chaîne vide. # Voir docs/MAINTENANCE.md et fixKnowledge/dashboard-anchor-wrong-chain-insufficient-balance.md SIGNET_VOLUME_FULL_CHAIN="4b5dca4d940b9f6e5db67b460f40f230a5ef1195a3769e5f91fa02be6edde649" # Redémarrage du conteneur restart_container() { info "Redémarrage du conteneur..." # Arrêter le conteneur existant if sudo docker ps | grep -q bitcoin-signet-instance; then info "Arrêt du conteneur existant..." sudo docker stop bitcoin-signet-instance sudo docker rm bitcoin-signet-instance fi # Utiliser le volume "chaîne complète" s'il existe, sinon le volume nommé (créé si besoin) local volume_to_use="$VOLUME_NAME" if sudo docker volume inspect "$SIGNET_VOLUME_FULL_CHAIN" &>/dev/null; then volume_to_use="$SIGNET_VOLUME_FULL_CHAIN" info "Utilisation du volume chaîne complète (signet ~11530 blocs)" else sudo docker volume create "$VOLUME_NAME" 2>/dev/null || true fi # Démarrer le nouveau conteneur avec volume persistant (une seule chaîne pour tous les services) info "Démarrage du nouveau conteneur (volume $volume_to_use)..." sudo docker run --env-file .env -d \ --name bitcoin-signet-instance \ -v "$volume_to_use":/root/.bitcoin \ -p 38332:38332 \ -p 38333:38333 \ -p 28332:28332 \ -p 28333:28333 \ -p 28334:28334 \ bitcoin-signet success "Conteneur redémarré" } # Vérification post-mise à jour verify_update() { info "Vérification de la mise à jour..." sleep 10 # Vérifier que le conteneur est en cours d'exécution if ! sudo docker ps | grep -q bitcoin-signet-instance; then error "Le conteneur n'est pas en cours d'exécution" return 1 fi # Vérifier la version de Bitcoin (datadir = BITCOIN_DIR du conteneur) local bitcoin_datadir bitcoin_datadir=$(sudo docker exec bitcoin-signet-instance printenv BITCOIN_DIR 2>/dev/null || echo "/root/.bitcoin") local version_info version_info=$(sudo docker exec bitcoin-signet-instance bitcoin-cli -datadir="$bitcoin_datadir" -version 2>/dev/null || \ sudo docker exec bitcoin-signet-instance bitcoin-cli -datadir="$bitcoin_datadir" getnetworkinfo 2>/dev/null | grep -oP '"subversion": "\K[^"]+' || echo "unknown") if [ "$version_info" != "unknown" ]; then success "Version Bitcoin détectée: $version_info" else warning "Impossible de vérifier la version, mais le conteneur fonctionne" fi # Vérifier l'état de la blockchain local blockchain_info blockchain_info=$(sudo docker exec bitcoin-signet-instance bitcoin-cli -datadir="$bitcoin_datadir" getblockchaininfo 2>/dev/null | grep -oP '"chain": "\K[^"]+' || echo "unknown") if [ "$blockchain_info" = "signet" ]; then success "Blockchain signet opérationnelle" else warning "État de la blockchain: $blockchain_info" fi } # Fonction principale main() { local target_version="${1:-}" local current_version local latest_version echo "==========================================" echo " Mise à jour du Bitcoin Signet Custom" echo "==========================================" echo "" check_prerequisites current_version=$(get_current_version) info "Version actuelle: $current_version" if [ -n "$target_version" ]; then latest_version="$target_version" info "Version cible spécifiée: $latest_version" else info "Récupération de la dernière version disponible..." latest_version=$(get_latest_version) info "Dernière version disponible: $latest_version" fi if [ "$current_version" = "$latest_version" ]; then success "Déjà à jour (version $current_version)" exit 0 fi echo "" warning "ATTENTION: Cette mise à jour va:" warning " 1. Arrêter le conteneur actuel" warning " 2. Reconstruire l'image Docker" warning " 3. Redémarrer le conteneur" echo "" read -p "Continuer? (o/N): " -n 1 -r echo "" if [[ ! $REPLY =~ ^[OoYy]$ ]]; then info "Mise à jour annulée" exit 0 fi echo "" backup_data echo "" update_dockerfile "$latest_version" echo "" rebuild_image echo "" restart_container echo "" verify_update echo "" # Enregistrer la nouvelle version echo "$latest_version" > .bitcoin-version success "Version enregistrée: $latest_version" echo "" success "Mise à jour terminée avec succès!" info "Pour voir les logs: sudo docker logs -f bitcoin-signet-instance" info "Pour vérifier l'état: sudo docker exec bitcoin-signet-instance bitcoin-cli -datadir=\$(docker exec bitcoin-signet-instance printenv BITCOIN_DIR 2>/dev/null || echo /root/.bitcoin) getblockchaininfo" } # Gestion des arguments if [ "${1:-}" = "--help" ] || [ "${1:-}" = "-h" ]; then echo "Usage: $0 [VERSION]" echo "" echo "Mise à jour du Bitcoin Signet Custom" echo "" echo "Arguments:" echo " VERSION Version spécifique de Bitcoin Core (ex: 27.0)" echo " Si non spécifié, utilise la dernière version disponible" echo "" echo "Options:" echo " -h, --help Affiche cette aide" echo "" exit 0 fi # Exécution du script principal main "$@"