diff --git a/.conf.model b/.conf.model index 71fba0e..3061fcd 100644 --- a/.conf.model +++ b/.conf.model @@ -2,14 +2,14 @@ core_url="http://bitcoin:38332" ws_url="0.0.0.0:8090" wallet_name="default" network="signet" -blindbit_url="http://blindbit:8000" +blindbit_url="http://blindbit-proxy:8000" zmq_url="tcp://bitcoin:29000" -storage="https://demo.4nkweb.com/storage" +storage="https://dev4.4nkweb.com/storage" data_dir="/home/bitcoin/.4nk" bitcoin_data_dir="/home/bitcoin/.bitcoin" -bootstrap_url="wss://dev3.4nkweb.com/ws/" +bootstrap_url="ws://dev3.4nkweb.com:8090" bootstrap_faucet=true -RUST_LOG="DEBUG" +RUST_LOG="DEBUG,reqwest=DEBUG,tokio_tungstenite=DEBUG" NODE_OPTIONS="--max-old-space-size=2048" SIGNER_API_KEY="your-api-key-change-this" diff --git a/.env b/.env index 140b9ff..2754674 100644 --- a/.env +++ b/.env @@ -1,17 +1,15 @@ -RUN_WS_TEST=0 core_url=http://bitcoin:38332 ws_url=0.0.0.0:8090 wallet_name=default network=signet -blindbit_url=http://blindbit:8000 +blindbit_url=http://localhost:8000 zmq_url=tcp://bitcoin:29000 storage=https://dev4.4nkweb.com/storage data_dir=/home/bitcoin/.4nk bitcoin_data_dir=/home/bitcoin/.bitcoin -bootstrap_url=wss://dev3.4nkweb.com/ws/ +bootstrap_url=ws://dev3.4nkweb.com:8090 bootstrap_faucet=true -HOME=/home/bitcoin -RUST_LOG=DEBUG +RUST_LOG=DEBUG,reqwest=DEBUG,tokio_tungstenite=DEBUG NODE_OPTIONS=--max-old-space-size=2048 SIGNER_API_KEY=your-api-key-change-this diff --git a/.env.exemple b/.env.exemple index 1f5aab1..2754674 100644 --- a/.env.exemple +++ b/.env.exemple @@ -1,18 +1,16 @@ -RUN_WS_TEST=0 core_url=http://bitcoin:38332 ws_url=0.0.0.0:8090 wallet_name=default network=signet -blindbit_url=http://blindbit:8000 +blindbit_url=http://localhost:8000 zmq_url=tcp://bitcoin:29000 storage=https://dev4.4nkweb.com/storage data_dir=/home/bitcoin/.4nk bitcoin_data_dir=/home/bitcoin/.bitcoin -bootstrap_url=wss://dev3.4nkweb.com/ws/ +bootstrap_url=ws://dev3.4nkweb.com:8090 bootstrap_faucet=true -HOME=/home/bitcoin -RUST_LOG=DEBUG -NODE_OPTIONS=--max-old-space-size=2048. +RUST_LOG=DEBUG,reqwest=DEBUG,tokio_tungstenite=DEBUG +NODE_OPTIONS=--max-old-space-size=2048 SIGNER_API_KEY=your-api-key-change-this VITE_JWT_SECRET_KEY=52b3d77617bb00982dfee15b08effd52cfe5b2e69b2f61cc4848cfe1e98c0bc9 diff --git a/Dockerfile b/Dockerfile index a268c1e..62bfa84 100644 --- a/Dockerfile +++ b/Dockerfile @@ -16,7 +16,7 @@ RUN --mount=type=ssh cargo build --release # ---- image finale ---- FROM debian:bookworm-slim -RUN apt-get update && apt-get install -y ca-certificates strace curl +RUN apt-get update && apt-get install -y ca-certificates strace curl dnsutils jq git wget telnet # Créer l'utilisateur bitcoin RUN useradd -m -d /home/bitcoin -u 1000 bitcoin diff --git a/IMPROVEMENTS.md b/IMPROVEMENTS.md new file mode 100644 index 0000000..064c4c1 --- /dev/null +++ b/IMPROVEMENTS.md @@ -0,0 +1,170 @@ +# Améliorations de la séquence de démarrage de sdk_relay + +## Problème actuel +- Le serveur WebSocket ne démarre qu'après le scan complet des blocs +- Les services dépendants (ihm_client, etc.) ne peuvent pas se connecter pendant le scan +- Le scan peut prendre plusieurs minutes et bloquer complètement le service + +## Solutions proposées + +### 1. Démarrage immédiat des serveurs (Recommandé) +```rust +// Dans main.rs, démarrer les serveurs AVANT le scan +async fn main() -> Result<(), Box> { + // ... configuration ... + + // DÉMARRER LES SERVEURS IMMÉDIATEMENT + let try_socket = TcpListener::bind(config.ws_url).await?; + let listener = try_socket; + + // Démarrer le serveur de santé immédiatement + tokio::spawn(start_health_server(8091)); + + // Démarrer le serveur WebSocket dans une tâche séparée + let ws_handle = tokio::spawn(async move { + while let Ok((stream, addr)) = listener.accept().await { + tokio::spawn(handle_connection(stream, addr, our_sp_address)); + } + }); + + // FAIRE LE SCAN EN ARRIÈRE-PLAN + tokio::spawn(async move { + if let Err(e) = scan_blocks(current_tip - last_scan, &config.blindbit_url).await { + eprintln!("Scan error: {}", e); + } + }); + + // Attendre que le serveur WebSocket soit prêt + ws_handle.await?; + Ok(()) +} +``` + +### 2. Mode "dégradé" pendant le scan +```rust +// Ajouter un état de service +enum ServiceState { + Starting, + Scanning, + Ready, + Error, +} + +// Le serveur WebSocket accepte les connexions mais répond avec un état +async fn handle_connection(stream: TcpStream, addr: SocketAddr, state: Arc>) { + let current_state = state.lock().await; + match *current_state { + ServiceState::Scanning => { + // Répondre avec un message indiquant que le service est en cours de scan + send_message(stream, json!({ + "status": "scanning", + "message": "Service is scanning blocks, please wait..." + })).await; + }, + ServiceState::Ready => { + // Traitement normal des messages + handle_normal_connection(stream).await; + }, + _ => { + // Répondre avec une erreur + send_error(stream, "Service not ready").await; + } + } +} +``` + +### 3. Scan incrémental en arrière-plan +```rust +// Modifier le scan pour qu'il soit non-bloquant +async fn start_background_scan(start_block: u32, end_block: u32, blindbit_url: &str) { + let mut current = start_block; + while current <= end_block { + match scan_single_block(current, blindbit_url).await { + Ok(_) => { + current += 1; + // Mettre à jour le last_scan dans le wallet + update_last_scan(current).await; + }, + Err(e) => { + eprintln!("Error scanning block {}: {}", current, e); + // Attendre un peu avant de réessayer + tokio::time::sleep(Duration::from_secs(5)).await; + } + } + } +} +``` + +### 4. Healthcheck amélioré +```rust +async fn start_health_server(port: u16) { + let listener = TcpListener::bind(format!("0.0.0.0:{}", port)).await.unwrap(); + + while let Ok((stream, _)) = listener.accept().await { + tokio::spawn(async move { + let response = match get_service_state().await { + ServiceState::Ready => json!({"status": "ok", "scan_complete": true}), + ServiceState::Scanning => json!({"status": "ok", "scan_complete": false, "message": "Scanning in progress"}), + ServiceState::Starting => json!({"status": "starting", "scan_complete": false}), + ServiceState::Error => json!({"status": "error", "scan_complete": false}), + }; + + let response_str = response.to_string(); + let http_response = format!( + "HTTP/1.1 200 OK\r\nContent-Length: {}\r\nContent-Type: application/json\r\n\r\n{}", + response_str.len(), + response_str + ); + + let _ = stream.write_all(http_response.as_bytes()).await; + }); + } +} +``` + +## Implémentation recommandée + +### Étape 1 : Modifier main.rs +1. Démarrer les serveurs WebSocket et de santé immédiatement +2. Faire le scan en arrière-plan dans une tâche séparée +3. Ajouter un état de service partagé + +### Étape 2 : Modifier le healthcheck +1. Retourner l'état du scan dans la réponse +2. Permettre aux services de savoir si le scan est terminé + +### Étape 3 : Modifier docker-compose.yml +```yaml +sdk_relay: + # ... configuration existante ... + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:8091/"] + interval: 10s + timeout: 5s + retries: 3 + start_period: 30s # Donner plus de temps pour le démarrage initial +``` + +### Étape 4 : Modifier les services dépendants +```yaml +ihm_client: + depends_on: + sdk_relay: + condition: service_healthy + # Ajouter une vérification de l'état du scan + environment: + - SDK_RELAY_SCAN_TIMEOUT=300 # 5 minutes max d'attente +``` + +## Avantages +- ✅ Services disponibles immédiatement +- ✅ Scan non-bloquant +- ✅ Meilleure expérience utilisateur +- ✅ Monitoring de l'état du scan +- ✅ Récupération d'erreur améliorée + +## Migration +1. Implémenter les changements dans sdk_relay +2. Tester avec un scan réduit +3. Déployer en production +4. Surveiller les logs et métriques