From 8cb82d0d31a3a7361cfdc824c1d58dcf71ea7dcc Mon Sep 17 00:00:00 2001 From: Local Dev Date: Wed, 9 Sep 2026 22:57:06 +0200 Subject: [PATCH] Ariadne 0.1.2: install.ps1 no longer dies on PS 5.1 stderr quirk; layered TLD-source cascade install.ps1 root-cause fix - Every `& $node ... 2>&1` had been tripping PS 5.1's "$ErrorActionPreference=Stop + native-command stderr = terminating error" quirk. Trap-and-log added in 0.1.1 EXPOSED the bug (0.1.0 died at the exact same line -- silently). 0.1.2 routes both node calls through a new Invoke-NodeCapture helper that uses Start-Process -RedirectStandardOutput/Error to file, so PS 5.1 never touches the streams. Multi-source TLD cascade with on-disk cache - -Indexer now accepts a comma-separated list; default "https://navigate.st,https://silentmode.st". - Cascade (first hit wins): indexer[s] HTTPS -> local cache (C:\ProgramData\Ariadne\tlds-cache.json) -> electrum WSS (fetchTldList / legacy fetchBcnrTlds) -> bundled ariadne.config.json snapshot -> bootstrap [bch]. - Authoritative fetches (indexer or electrum) refresh the cache. Second install on a machine that has ever succeeded before is instant + always works offline. - Per-source deadlines kept tight (5s for indexer HTTPS) so a slow source can't stall the install. Upgrade over live install - .iss CurStepChanged(ssInstall) stops "BNS Resolver Daemon" + "BNS Sia Bridge" via schtasks + 1.5s pause before file replacement. Fixes "DeleteFile failed; code 5. Access is denied" on runtime\node.exe when upgrading a machine where the daemon is currently running. CA import - Switched Import-Certificate -CertStoreLocation Cert:\... to direct X509Store('Root', 'LocalMachine').Add(). Cert: PSDrive is not always loaded in -NoProfile elevated shells, which had broken the standalone unblock scripts. Verified end-to-end on this box: silent install -> exit 0, clean install.log, BNS Resolver Daemon running, 127.0.0.1:53 open, 9 NRPT rules (all TLDs including .bch), coinspectrum.bch resolves system-wide, tlds-cache.json populated. Deployed - dl.silentmode.st/AriadneResolver-Setup-0.1.2.exe - s3://bns/silentmode/dl/AriadneResolver-Setup-0.1.2.exe - silentmode.st + navigate.st/bns/silentmode.bch manifests advertise 0.1.2 - sha256 5a2c9e4f3c5e1a162008641019f5ffc35968751c0440f94d3c5fe67aafb8cc5e Local Dev --- setup/install.ps1 | 206 ++++++++++++++++++++++++++++++---------------- 1 file changed, 134 insertions(+), 72 deletions(-) diff --git a/setup/install.ps1 b/setup/install.ps1 index e1f5261..d14c6e8 100644 --- a/setup/install.ps1 +++ b/setup/install.ps1 @@ -9,10 +9,11 @@ param( # icann-first : ICANN wins, BCNR fallback on NXDOMAIN. # bns-first is accepted as an alias for bcnr-first. [ValidateSet("bcnr-first", "icann-first", "bns-first")] [string]$Policy = "bcnr-first", - # BNS indexer for the primary TLD discovery source. HTTPS beats WSS-electrum - # from a silent install context because it doesn't need Node, doesn't need - # `ws`, and doesn't get mangled by corporate DPI as easily. - [string]$Indexer = "https://navigate.st", + # BNS indexer(s) for the primary TLD discovery source. Comma-separated list + # so we can fall over between mirrors -- HTTPS beats WSS-electrum from a + # silent-install context (no Node subprocess, no ws dependency, DPI-friendly). + # The first indexer that answers within its per-source deadline wins. + [string]$Indexer = "https://navigate.st,https://silentmode.st", # Opt-in: turn off Firefox DNS-over-HTTPS. Only needed to resolve names that # ALSO exist in ICANN (a reclaimed .de) via BCNR in Firefox -- BCNR-only names # (all .bch, etc.) already work with DoH on, because DoH returns NXDOMAIN and @@ -75,86 +76,140 @@ if (-not (Test-Path $node)) { $daemon = Join-Path $root "src\daemon\bnsd.js" $stateFile = Join-Path $PSScriptRoot "install-state.json" -# Discover the set of currently activated BCNR TLDs. Sources, in order of -# preference: -# 1) BNS indexer HTTPS GET $Indexer/api/tlds -> {advertised:[...]} -# Primary because HTTPS works in a silent-install context that WSS often -# doesn't (no Node subprocess, no `ws` dependency, corporate DPI-friendly). -# The indexer is authoritative -- it mirrors the on-chain TLD beacon. -# 2) Node subprocess: fetchTldList (per-TLD beacon registry, chain-direct). -# 3) Node subprocess: fetchBcnrTlds (legacy tlds.bch list-NFT, chain-direct). -# 4) ariadne.config.json shipped with the installer. -# 5) Built-in bootstrap set [bch]. -# This drives both the CA's nameConstraints extension and the surgical-mode -# NRPT rules below, so adding a new TLD on-chain is picked up by re-running -# this installer (no code release). -$ACTIVATED_TLDS = @() -$tldSource = "" +# TLS 1.2 (PS 5.1 defaults to 1.0/1.1 on older boxes and Invoke-RestMethod fails +# against modern servers). +try { [Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12 } catch {} -# 1) HTTP indexer -- fastest and most reliable path. -try { - $indexerUrl = $Indexer.TrimEnd('/') + "/api/tlds" - Write-Host "[..] fetching TLD list from $indexerUrl" - # TLS 1.2 for Windows PowerShell 5.1 (default is TLS 1.0/1.1 on older boxes). - try { [Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12 } catch {} - $resp = Invoke-RestMethod -Uri $indexerUrl -TimeoutSec 10 -UseBasicParsing -Headers @{ 'User-Agent' = 'AriadneResolverInstaller/1' } - if ($resp -and $resp.advertised -and $resp.advertised.Count -gt 0) { - $ACTIVATED_TLDS = @($resp.advertised | ForEach-Object { [string]$_ }) - $tldSource = "indexer($Indexer)" - } -} catch { - Write-Host "[!] indexer unreachable: $($_.Exception.Message)" -ForegroundColor Yellow -} - -# 2)+3) Node/electrum -- kept as fallback for offline / air-gapped installs. -if ($ACTIVATED_TLDS.Count -eq 0) { - Push-Location $root - $activatedJson = & $node --input-type=module -e "import('./src/lib/resolver-web.js').then(async m=>{const ws=(await import('ws')).default;try{const list=await m.fetchTldList({WebSocket:ws});if(list&&list.length&&!(list.length===1&&list[0]==='bch')){console.log(JSON.stringify(list));return}}catch(e){console.error('fetchTldList:',String(e))}try{const legacy=await m.fetchBcnrTlds({WebSocket:ws});console.log(JSON.stringify(legacy||[]))}catch(e){console.error('fetchBcnrTlds:',String(e));console.log('[]')}}).catch(e=>{console.error(String(e));console.log('[]')})" 2>$null - Pop-Location - try { $ACTIVATED_TLDS = @(($activatedJson | ConvertFrom-Json) | ForEach-Object { [string]$_ }) } catch { $ACTIVATED_TLDS = @() } - if ($ACTIVATED_TLDS.Count -gt 0) { $tldSource = "electrum" } -} - -# 4)+5) Config-shipped list, then bootstrap. -if ($ACTIVATED_TLDS.Count -eq 0) { +# --- helper: run `node --input-type=module -e "