From f6c3d6248808f0a510a630cc1ed6c1b088514d1e Mon Sep 17 00:00:00 2001 From: Patrick Mulligan Date: Sun, 15 Feb 2026 18:25:32 -0500 Subject: [PATCH] fix(docker): improve channel setup timing for clean slate - Add is_lnd1_wallet_ready() to verify wallet is ready before operations - Mine initial blocks if blockchain has < 101 blocks (fresh regtest) - Wait for lnd-1 to sync to chain before opening channels - Create bitcoind wallet if needed (clean slate) - Increase channel activation wait from 40s to 60s - Add explicit graph propagation check via queryroutes - Wait up to 60s for lnd-3 to find route to lnd-4 before funding This ensures the environment works from a completely clean Docker slate without relying on the scheduled miner. Co-Authored-By: Claude Opus 4.5 --- docker/dev.sh | 82 ++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 71 insertions(+), 11 deletions(-) diff --git a/docker/dev.sh b/docker/dev.sh index 14e5571..b848878 100755 --- a/docker/dev.sh +++ b/docker/dev.sh @@ -116,6 +116,20 @@ is_lnd1_ready() { docker exec lnbits-lnd-1-1 lncli --network=regtest --rpcserver=lnd-1:10009 getinfo &>/dev/null 2>&1 } +is_lnd1_wallet_ready() { + # Check if lnd-1 wallet is ready (can query balance - needed for channel operations) + docker exec lnbits-lnd-1-1 lncli --network=regtest --rpcserver=lnd-1:10009 walletbalance &>/dev/null 2>&1 +} + +wait_for_lnd1_wallet() { + local attempts=0 + while ! is_lnd1_wallet_ready && [[ $attempts -lt 30 ]]; do + sleep 2 + attempts=$((attempts + 1)) + done + is_lnd1_wallet_ready +} + wait_for_lnd1() { log "Waiting for lnd-1 to be ready..." local attempts=0 @@ -145,8 +159,38 @@ ensure_lnd4_channel() { fi success "lnd-1 is ready" - # Give lnd-1 a moment to fully initialize (getinfo succeeds before all subsystems ready) - sleep 5 + # Wait for wallet to be fully initialized (needed for channel operations) + log "Waiting for lnd-1 wallet..." + if ! wait_for_lnd1_wallet; then + error "lnd-1 wallet failed to initialize" + return 1 + fi + success "lnd-1 wallet is ready" + + # From a clean slate, bitcoind may have 0 blocks. Mine some for LND to sync. + local block_count=$(docker exec lnbits-bitcoind-1 bitcoin-cli -regtest getblockcount 2>/dev/null || echo "0") + if [[ "$block_count" -lt 101 ]]; then + log "Mining initial blocks for chain sync..." + local init_addr=$(docker exec lnbits-lnd-1-1 lncli --network=regtest --rpcserver=lnd-1:10009 newaddress p2wkh 2>/dev/null | grep -oP '"address":\s*"\K[^"]+') + if [[ -n "$init_addr" ]]; then + docker exec lnbits-bitcoind-1 bitcoin-cli -regtest generatetoaddress 110 "$init_addr" &>/dev/null + sleep 3 + success "Initial blocks mined" + fi + fi + + # Wait for LND to sync to chain + log "Waiting for lnd-1 to sync..." + local sync_attempts=0 + while [[ $sync_attempts -lt 30 ]]; do + local synced=$(docker exec lnbits-lnd-1-1 lncli --network=regtest --rpcserver=lnd-1:10009 getinfo 2>/dev/null | grep -oP '"synced_to_chain":\s*\K(true|false)') + if [[ "$synced" == "true" ]]; then + break + fi + sleep 2 + sync_attempts=$((sync_attempts + 1)) + done + success "lnd-1 synced to chain" # Check if lnd-1 has funds, if not fund it local lnd1_balance=$(docker exec lnbits-lnd-1-1 lncli --network=regtest --rpcserver=lnd-1:10009 walletbalance 2>/dev/null | grep -oP '"confirmed_balance":\s*"\K[0-9]+' | head -1 || echo "0") @@ -176,8 +220,9 @@ ensure_lnd4_channel() { connect "${lnd4_pubkey}@lnd-4:9735" &>/dev/null || true # Retry loop for opening channels (server may still be initializing) + # From a clean slate, LND needs ~30-60s after getinfo works to fully initialize local result3="" result4="" attempts=0 - while [[ $attempts -lt 5 ]]; do + while [[ $attempts -lt 10 ]]; do # Open channel to lnd-3: 10M sats, push 5M so lnd-3 has sending capacity if [[ -z "$result3" ]] || echo "$result3" | grep -q "still in the process of starting"; then result3=$(docker exec lnbits-lnd-1-1 lncli --network=regtest --rpcserver=lnd-1:10009 \ @@ -196,8 +241,8 @@ ensure_lnd4_channel() { fi attempts=$((attempts + 1)) - if [[ $attempts -lt 5 ]]; then - log "Waiting for LND to be fully ready... (attempt $attempts/5)" + if [[ $attempts -lt 10 ]]; then + log "Waiting for LND to be fully ready... (attempt $attempts/10)" sleep 5 fi done @@ -213,24 +258,39 @@ ensure_lnd4_channel() { if [[ "$channels_opened" == "true" ]]; then log "Mining blocks to confirm channels..." - # Mine 10 blocks to confirm channels and allow graph propagation + # From clean slate, bitcoind may need wallet. Ensure it has one. + docker exec lnbits-bitcoind-1 bitcoin-cli -regtest createwallet "regtest" &>/dev/null 2>&1 || true + + # Mine 10 blocks to confirm channels local addr=$(docker exec lnbits-bitcoind-1 bitcoin-cli -regtest getnewaddress 2>/dev/null) docker exec lnbits-bitcoind-1 bitcoin-cli -regtest generatetoaddress 10 "$addr" &>/dev/null - # Wait for channels to become active + # Wait for channels to become active (may take up to 60s) local attempts=0 - while ! lnd4_has_active_channels && [[ $attempts -lt 20 ]]; do + while ! lnd4_has_active_channels && [[ $attempts -lt 30 ]]; do sleep 2 attempts=$((attempts + 1)) done if lnd4_has_active_channels; then - # Wait a bit more for graph propagation + # Wait for graph propagation (critical for routing payments) log "Waiting for network graph to sync..." - sleep 10 - # Mine a few more blocks to trigger announcements + # Mine more blocks to trigger channel announcements docker exec lnbits-bitcoind-1 bitcoin-cli -regtest generatetoaddress 6 "$addr" &>/dev/null sleep 5 + + # Verify graph has propagated by checking if lnd-3 can route to lnd-4 + local route_attempts=0 + while [[ $route_attempts -lt 12 ]]; do + local route=$(docker exec lnbits-lnd-3-1 lncli --network=regtest --rpcserver=lnd-3:10009 \ + queryroutes --dest "$lnd4_pubkey" --amt 10000 2>&1) + if echo "$route" | grep -q '"total_amt"'; then + break + fi + sleep 5 + route_attempts=$((route_attempts + 1)) + done + success "Channels active - lnd-3 and lnd-4 ready" return 0 else