diff --git a/.github/ci-groups.yml b/.github/ci-groups.yml index 8265011c0..288e4703b 100644 --- a/.github/ci-groups.yml +++ b/.github/ci-groups.yml @@ -10,6 +10,7 @@ groups: spv: - dash-spv + - dash-network-seeds wallet: - key-wallet @@ -27,3 +28,4 @@ groups: excluded: - integration_test # Requires live Dash node - dash-fuzz # Honggfuzz binary targets, tested by fuzz.yml + - masternode-seeds-fetcher # Tooling binary; needs live dashd RPC, exercised by update-masternode-seeds.yml diff --git a/.github/workflows/update-masternode-seeds.yml b/.github/workflows/update-masternode-seeds.yml new file mode 100644 index 000000000..7c32b6d8d --- /dev/null +++ b/.github/workflows/update-masternode-seeds.yml @@ -0,0 +1,82 @@ +name: Update masternode seeds + +# Refreshes the hardcoded masternode IP lists shipped in `dash-network-seeds` +# by connecting to the Dash P2P network, discovering a recent chain tip via a +# new-block announcement, issuing a `getmnlistd` request, and writing the +# resulting masternode IP list (differentiated by regular/evo type). Opens a +# pull request if any seed file changed. +# +# Runs fully self-contained: no RPC credentials or repository secrets needed. +# The fetcher bootstraps peers from DNS seeds and the existing seed files. + +on: + schedule: + # Every Monday at 06:00 UTC. + - cron: '0 6 * * 1' + workflow_dispatch: + +permissions: + contents: write + pull-requests: write + +jobs: + refresh: + name: Refresh masternode seed files + runs-on: ubuntu-latest + timeout-minutes: 60 + steps: + - uses: actions/checkout@v6 + + - uses: dtolnay/rust-toolchain@stable + + - uses: Swatinem/rust-cache@v2 + with: + shared-key: "masternode-seeds-fetcher" + + - name: Build fetcher + run: cargo build --release -p masternode-seeds-fetcher + + - name: Refresh mainnet seeds (with probes) + env: + RUST_LOG: info + run: | + ./target/release/masternode-seeds-fetcher \ + --network mainnet \ + --out dash-network-seeds/seeds/mainnet.txt \ + --max-peers 16 \ + --probe-concurrency 100 + + - name: Refresh testnet seeds (with probes) + env: + RUST_LOG: info + run: | + ./target/release/masternode-seeds-fetcher \ + --network testnet \ + --out dash-network-seeds/seeds/testnet.txt \ + --max-peers 16 \ + --probe-concurrency 64 + + - name: Verify parsed seed files still build + run: cargo test -p dash-network-seeds --lib + + - name: Open pull request on change + uses: peter-evans/create-pull-request@v7 + with: + commit-message: "chore(dash-spv): refresh masternode seed files" + title: "chore(dash-spv): refresh masternode seed files" + body: | + Weekly automated refresh of the hardcoded masternode IP lists + embedded in `dash-spv` (`dash-network-seeds/seeds/mainnet.txt`, + `dash-network-seeds/seeds/testnet.txt`). + + Generated by `.github/workflows/update-masternode-seeds.yml` + via the `masternode-seeds-fetcher` crate, which fetches the + current masternode list from the Dash P2P network using a + `getmnlistd` request against a peer discovered through DNS + seeds and the existing seed files. + branch: chore/refresh-masternode-seeds + delete-branch: true + add-paths: | + dash-network-seeds/seeds/mainnet.txt + dash-network-seeds/seeds/testnet.txt + labels: automated diff --git a/Cargo.toml b/Cargo.toml index dc4ad6587..5491e2f88 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [workspace] -members = ["dash", "dash-network", "hashes", "internals", "fuzz", "rpc-client", "rpc-json", "rpc-integration-test", "key-wallet", "key-wallet-manager", "key-wallet-ffi", "dash-spv", "dash-spv-ffi"] +members = ["dash", "dash-network", "hashes", "internals", "fuzz", "rpc-client", "rpc-json", "rpc-integration-test", "key-wallet", "key-wallet-manager", "key-wallet-ffi", "dash-spv", "dash-spv-ffi", "dash-network-seeds", "masternode-seeds-fetcher"] resolver = "2" [workspace.package] diff --git a/dash-network-seeds/Cargo.toml b/dash-network-seeds/Cargo.toml new file mode 100644 index 000000000..a5ce9bff8 --- /dev/null +++ b/dash-network-seeds/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "dash-network-seeds" +version = { workspace = true } +edition = "2024" +authors = ["Dash Core Team"] +description = "Hardcoded masternode IP seed lists for Dash mainnet and testnet, differentiated by regular/evo type. Refreshed weekly via CI from the live Dash P2P network." +license = "MIT" +repository = "https://github.com/dashpay/rust-dashcore" + +[dependencies] +dash-network = { path = "../dash-network" } diff --git a/dash-network-seeds/seeds/mainnet.txt b/dash-network-seeds/seeds/mainnet.txt new file mode 100644 index 000000000..e1adb2e85 --- /dev/null +++ b/dash-network-seeds/seeds/mainnet.txt @@ -0,0 +1,2044 @@ +# Auto-generated by masternode-seeds-fetcher on 2026-04-23T09:43:50Z for mainnet +# Source: Dash P2P network (mnlistdiff) +# Primary peer: 135.181.53.196:9999 +# Tip block hash: 0000000000000032859abaadd7d3a1e63c960b579b6b59f783af122859ab642c +# Tip block height: 2459693 +# 2034 seeds (1674 regular + 360 evo) of 2934 total masternodes, valid-only +# Probe summary: core_reachable=1987/2034 platform_reachable=352/360 ssl_valid=294/360 +# Columns: +# Values: core_reach/plat_reach=ok|timeout|refused|error|?, core_sync=sync|-N|+N|?, plat_live=ok|none|?|-, plat_ssl=valid|expired|self-signed|untrusted|no-handshake|?|- +# Do not edit manually — refreshed weekly by .github/workflows/update-masternode-seeds.yml +regular 2.56.213.218:9999 - ok sync - - - +regular 2.56.213.221:9999 - ok sync - - - +regular 2.57.241.155:9999 - ok sync - - - +regular 2.57.241.178:9999 - ok sync - - - +evo 2.59.156.192:9999 443 ok sync ok ok valid +regular 2.59.219.54:9999 - ok sync - - - +regular 2.233.120.35:9999 - ok sync - - - +regular 5.2.67.190:9999 - error ? - - - +regular 5.2.73.58:9999 - error ? - - - +regular 5.9.237.32:9999 - ok sync - - - +regular 5.9.237.37:9999 - ok sync - - - +regular 5.35.103.19:9999 - ok sync - - - +regular 5.35.103.25:9999 - ok sync - - - +regular 5.35.103.26:9999 - ok sync - - - +regular 5.35.103.123:9999 - ok sync - - - +regular 5.39.10.23:9999 - ok sync - - - +regular 5.39.11.80:9999 - ok sync - - - +evo 5.39.27.224:9999 443 ok sync ok ok valid +regular 5.53.124.120:9999 - ok sync - - - +evo 5.75.133.148:9999 443 ok sync ok ok valid +regular 5.161.110.79:9999 - ok sync - - - +evo 5.189.145.80:9999 443 ok sync ok ok valid +evo 5.189.151.7:9999 443 ok sync ok ok valid +evo 5.189.164.253:9999 443 ok sync ok ok valid +regular 5.230.228.238:9999 - ok sync - - - +regular 5.230.228.239:9999 - timeout ? - - - +regular 5.230.229.1:9999 - timeout ? - - - +regular 5.230.229.2:9999 - ok sync - - - +regular 5.230.229.3:9999 - ok sync - - - +regular 5.230.229.4:9999 - timeout ? - - - +regular 5.230.229.5:9999 - timeout ? - - - +regular 5.230.229.6:9999 - timeout ? - - - +regular 5.230.229.7:9999 - ok sync - - - +regular 5.230.229.8:9999 - timeout ? - - - +regular 5.230.229.9:9999 - timeout ? - - - +regular 5.230.229.10:9999 - timeout ? - - - +regular 5.230.229.11:9999 - timeout ? - - - +regular 5.230.229.12:9999 - ok sync - - - +regular 5.230.229.13:9999 - timeout ? - - - +regular 5.230.229.14:9999 - ok sync - - - +regular 5.230.229.15:9999 - timeout ? - - - +regular 5.230.229.16:9999 - ok sync - - - +regular 5.230.229.17:9999 - timeout ? - - - +regular 5.230.229.18:9999 - ok sync - - - +regular 5.230.229.19:9999 - timeout ? - - - +regular 5.230.229.20:9999 - ok sync - - - +regular 5.230.229.21:9999 - ok sync - - - +regular 5.230.229.22:9999 - timeout ? - - - +regular 5.230.229.23:9999 - timeout ? - - - +regular 5.230.229.24:9999 - ok sync - - - +regular 5.230.229.25:9999 - timeout ? - - - +regular 5.230.229.27:9999 - timeout ? - - - +regular 8.219.0.187:9999 - ok sync - - - +regular 8.219.1.166:9999 - ok sync - - - +regular 8.219.4.138:9999 - ok sync - - - +regular 8.219.5.90:9999 - ok sync - - - +regular 8.219.12.154:9999 - ok sync - - - +regular 8.219.51.144:9999 - ok sync - - - +regular 8.219.52.8:9999 - ok sync - - - +regular 8.219.54.127:9999 - ok sync - - - +regular 8.219.56.203:9999 - ok sync - - - +regular 8.219.67.30:9999 - ok sync - - - +regular 8.219.68.85:9999 - ok sync - - - +regular 8.219.69.81:9999 - ok sync - - - +regular 8.219.83.30:9999 - ok sync - - - +regular 8.219.90.201:9999 - ok sync - - - +regular 8.219.93.245:9999 - ok sync - - - +regular 8.219.103.216:9999 - ok sync - - - +regular 8.219.104.151:9999 - ok sync - - - +regular 8.219.108.248:9999 - ok sync - - - +regular 8.219.110.74:9999 - ok sync - - - +regular 8.219.110.226:9999 - ok sync - - - +regular 8.219.113.65:9999 - ok sync - - - +regular 8.219.126.185:9999 - ok sync - - - +regular 8.219.129.23:9999 - ok sync - - - +regular 8.219.129.70:9999 - ok sync - - - +regular 8.219.134.65:9999 - ok sync - - - +regular 8.219.134.88:9999 - ok sync - - - +regular 8.219.135.18:9999 - ok sync - - - +regular 8.219.136.60:9999 - ok sync - - - +regular 8.219.140.82:9999 - ok sync - - - +regular 8.219.141.238:9999 - ok sync - - - +regular 8.219.143.36:9999 - ok sync - - - +regular 8.219.143.214:9999 - ok sync - - - +regular 8.219.145.115:9999 - ok sync - - - +regular 8.219.152.91:9999 - ok sync - - - +regular 8.219.153.43:9999 - ok sync - - - +regular 8.219.154.12:9999 - ok sync - - - +regular 8.219.155.151:9999 - ok sync - - - +regular 8.219.160.147:9999 - ok sync - - - +regular 8.219.170.241:9999 - ok sync - - - +regular 8.219.173.78:9999 - ok sync - - - +regular 8.219.175.17:9999 - ok sync - - - +regular 8.219.175.64:9999 - ok sync - - - +regular 8.219.177.137:9999 - ok sync - - - +regular 8.219.178.166:9999 - ok sync - - - +regular 8.219.185.232:9999 - ok sync - - - +regular 8.219.187.175:9999 - ok sync - - - +regular 8.219.190.253:9999 - ok sync - - - +regular 8.219.192.108:9999 - ok sync - - - +regular 8.219.193.162:9999 - ok sync - - - +regular 8.219.196.16:9999 - ok sync - - - +regular 8.219.200.247:9999 - ok sync - - - +regular 8.219.201.242:9999 - ok sync - - - +regular 8.219.204.148:9999 - ok sync - - - +regular 8.219.205.129:9999 - ok sync - - - +regular 8.219.206.45:9999 - ok sync - - - +regular 8.219.210.37:9999 - ok sync - - - +regular 8.219.212.26:9999 - ok sync - - - +regular 8.219.215.184:9999 - ok sync - - - +regular 8.219.217.58:9999 - ok sync - - - +regular 8.219.219.186:9999 - ok sync - - - +regular 8.219.220.92:9999 - ok sync - - - +regular 8.219.220.160:9999 - ok sync - - - +regular 8.219.221.32:9999 - ok sync - - - +regular 8.219.223.98:9999 - ok sync - - - +regular 8.219.223.247:9999 - ok sync - - - +regular 8.219.228.99:9999 - ok sync - - - +regular 8.219.229.197:9999 - ok sync - - - +regular 8.219.229.220:9999 - ok sync - - - +regular 8.219.230.37:9999 - ok sync - - - +regular 8.219.234.92:9999 - ok sync - - - +regular 8.219.234.148:9999 - ok sync - - - +regular 8.219.234.202:9999 - ok sync - - - +regular 8.219.238.104:9999 - ok sync - - - +regular 8.219.239.63:9999 - ok sync - - - +regular 8.219.240.153:9999 - ok sync - - - +regular 8.219.241.180:9999 - ok sync - - - +regular 8.219.242.77:9999 - ok sync - - - +regular 8.219.243.178:9999 - ok sync - - - +regular 8.219.244.159:9999 - ok sync - - - +regular 8.219.245.11:9999 - ok sync - - - +regular 8.219.246.164:9999 - ok sync - - - +regular 8.219.249.223:9999 - ok sync - - - +regular 8.219.251.8:9999 - ok sync - - - +regular 8.219.253.60:9999 - ok sync - - - +regular 8.219.253.196:9999 - ok sync - - - +regular 8.222.128.127:9999 - ok sync - - - +regular 8.222.128.182:9999 - ok sync - - - +regular 8.222.129.74:9999 - ok sync - - - +regular 8.222.130.18:9999 - ok sync - - - +regular 8.222.130.91:9999 - ok sync - - - +regular 8.222.130.119:9999 - ok sync - - - +regular 8.222.130.123:9999 - ok sync - - - +regular 8.222.130.131:9999 - ok sync - - - +regular 8.222.131.209:9999 - ok sync - - - +regular 8.222.131.215:9999 - ok sync - - - +regular 8.222.132.84:9999 - ok sync - - - +regular 8.222.132.173:9999 - ok sync - - - +regular 8.222.133.79:9999 - ok sync - - - +regular 8.222.134.37:9999 - ok sync - - - +regular 8.222.134.134:9999 - ok sync - - - +regular 8.222.134.140:9999 - ok sync - - - +regular 8.222.135.8:9999 - ok sync - - - +regular 8.222.135.26:9999 - ok sync - - - +regular 8.222.135.69:9999 - ok sync - - - +regular 8.222.135.84:9999 - ok sync - - - +regular 8.222.136.138:9999 - ok sync - - - +regular 8.222.137.45:9999 - ok sync - - - +regular 8.222.137.173:9999 - ok sync - - - +regular 8.222.137.204:9999 - ok sync - - - +regular 8.222.138.140:9999 - ok sync - - - +regular 8.222.138.235:9999 - ok sync - - - +regular 8.222.139.20:9999 - ok sync - - - +regular 8.222.139.231:9999 - ok sync - - - +regular 8.222.140.21:9999 - ok sync - - - +regular 8.222.140.126:9999 - ok sync - - - +regular 8.222.140.161:9999 - ok sync - - - +regular 8.222.141.118:9999 - ok sync - - - +regular 8.222.144.32:9999 - ok sync - - - +regular 8.222.145.72:9999 - ok sync - - - +regular 8.222.145.160:9999 - ok sync - - - +regular 8.222.145.217:9999 - ok sync - - - +regular 8.222.146.30:9999 - ok sync - - - +regular 8.222.146.67:9999 - ok sync - - - +regular 8.222.146.149:9999 - ok sync - - - +regular 8.222.147.108:9999 - ok sync - - - +regular 8.222.147.169:9999 - ok sync - - - +regular 8.222.147.207:9999 - ok sync - - - +regular 8.222.147.225:9999 - ok sync - - - +regular 8.222.148.109:9999 - ok sync - - - +regular 8.222.148.183:9999 - ok sync - - - +regular 8.222.148.255:9999 - ok sync - - - +regular 8.222.149.162:9999 - ok sync - - - +regular 8.222.149.195:9999 - ok sync - - - +regular 8.222.150.74:9999 - ok sync - - - +regular 8.222.151.173:9999 - ok sync - - - +evo 15.235.102.215:9999 443 ok sync refused none no-handshake +evo 15.235.102.216:9999 443 ok sync refused none no-handshake +regular 23.88.22.66:9999 - ok sync - - - +regular 23.88.22.67:9999 - ok sync - - - +regular 23.88.22.68:9999 - ok sync - - - +evo 23.88.63.58:9999 443 ok sync ok ok valid +regular 23.95.186.248:9999 - ok sync - - - +regular 23.163.0.174:9999 - ok sync - - - +regular 31.10.97.36:9999 - ok sync - - - +regular 31.56.38.0:9999 - ok sync - - - +regular 31.56.38.185:9999 - ok sync - - - +regular 31.58.170.16:9999 - ok sync - - - +regular 31.58.170.130:9999 - ok sync - - - +regular 31.58.170.139:9999 - ok sync - - - +regular 31.58.170.180:9999 - ok sync - - - +regular 31.58.170.181:9999 - ok sync - - - +regular 31.58.170.213:9999 - ok sync - - - +regular 31.58.170.230:9999 - ok sync - - - +regular 31.148.99.148:9999 - ok sync - - - +evo 31.220.77.84:9999 443 ok sync ok ok valid +evo 31.220.84.93:9999 443 ok sync ok ok valid +evo 31.220.91.43:9999 443 ok sync ok ok valid +evo 31.220.91.60:9999 443 ok sync ok ok valid +regular 34.209.37.222:9999 - ok sync - - - +regular 34.246.176.25:9999 - ok sync - - - +regular 35.174.217.98:9999 - ok sync - - - +evo 37.27.67.154:9999 443 ok sync ok ok expired +evo 37.27.67.156:9999 443 ok sync ok ok expired +evo 37.27.67.159:9999 443 ok sync ok ok expired +evo 37.27.67.163:9999 443 ok sync ok ok expired +evo 37.27.67.164:9999 443 ok sync ok ok expired +evo 37.27.83.17:9999 443 ok sync ok ok valid +regular 37.27.193.211:9999 - ok sync - - - +regular 37.27.199.15:9999 - ok sync - - - +evo 37.60.234.168:9999 443 ok sync ok ok valid +evo 37.60.234.205:9999 443 ok sync ok ok valid +evo 37.60.235.24:9999 443 ok sync ok ok valid +evo 37.60.235.39:9999 443 ok sync ok ok valid +evo 37.60.235.89:9999 443 ok sync ok ok valid +evo 37.60.235.205:9999 443 ok sync ok ok valid +evo 37.60.235.218:9999 443 ok sync ok ok valid +evo 37.60.235.224:9999 443 ok sync ok ok valid +evo 37.60.236.41:9999 443 ok sync ok ok valid +evo 37.60.236.230:9999 443 ok sync ok ok valid +evo 37.60.243.59:9999 443 ok sync ok ok valid +evo 37.60.244.35:9999 443 ok sync ok ok valid +evo 37.60.244.87:9999 443 ok sync ok ok valid +evo 37.60.244.253:9999 443 ok sync ok ok valid +evo 37.60.246.228:9999 443 ok sync ok ok valid +evo 37.60.254.201:9999 443 ok sync ok ok valid +evo 37.60.254.202:9999 443 ok sync ok ok valid +evo 37.60.254.205:9999 443 ok sync ok ok valid +evo 37.60.254.211:9999 443 ok sync ok ok valid +evo 37.60.254.213:9999 443 ok sync ok ok valid +evo 37.60.255.160:9999 443 ok sync ok ok valid +regular 37.97.227.21:9999 - ok sync - - - +regular 37.139.5.159:9999 - ok sync - - - +regular 37.139.6.204:9999 - ok sync - - - +regular 37.139.10.249:9999 - ok sync - - - +regular 37.139.11.82:9999 - ok sync - - - +regular 37.139.29.66:9999 - ok sync - - - +regular 38.54.12.111:9999 - ok sync - - - +regular 38.102.125.108:9999 - ok sync - - - +evo 38.242.145.178:9999 443 ok sync ok ok valid +evo 38.242.197.189:9999 443 ok sync ok ok valid +evo 38.242.200.227:9999 443 ok sync ok ok valid +evo 38.242.206.56:9999 443 ok sync ok ok valid +evo 38.242.206.103:9999 443 ok sync ok ok valid +regular 38.242.211.123:9999 - ok sync - - - +evo 38.242.218.26:9999 443 ok sync ok ok valid +evo 43.133.171.101:9999 443 ok sync ok ok valid +regular 43.134.180.113:9999 - ok sync - - - +evo 43.167.239.145:9999 443 ok sync ok ok valid +evo 43.167.244.109:9999 443 ok sync ok ok valid +regular 43.224.35.163:9999 - error ? - - - +regular 43.229.77.46:9999 - ok sync - - - +evo 44.240.99.214:9999 443 ok sync ok ok valid +regular 45.32.35.170:9999 - ok sync - - - +evo 45.32.70.131:9999 443 ok sync ok ok valid +regular 45.32.74.179:9999 - ok sync - - - +regular 45.32.74.201:9999 - ok sync - - - +regular 45.32.115.119:9999 - error ? - - - +regular 45.32.146.196:9999 - ok sync - - - +regular 45.32.150.129:9999 - ok sync - - - +regular 45.32.156.167:9999 - ok sync - - - +regular 45.32.199.30:9999 - ok sync - - - +regular 45.32.207.17:9999 - ok sync - - - +regular 45.32.241.67:9999 - ok sync - - - +regular 45.58.52.179:9999 - ok sync - - - +regular 45.58.52.232:9999 - ok sync - - - +regular 45.58.52.247:9999 - ok sync - - - +regular 45.58.56.79:9999 - ok sync - - - +regular 45.58.56.82:9999 - ok sync - - - +regular 45.58.56.87:9999 - ok sync - - - +regular 45.61.186.121:9999 - ok sync - - - +regular 45.63.21.44:9999 - ok sync - - - +regular 45.63.116.79:9999 - ok sync - - - +regular 45.63.120.66:9999 - ok sync - - - +regular 45.76.29.241:9999 - ok sync - - - +evo 45.76.36.241:9999 443 ok sync ok ok valid +regular 45.76.42.151:9999 - ok sync - - - +regular 45.76.64.242:9999 - ok sync - - - +regular 45.76.84.108:9999 - ok sync - - - +regular 45.76.111.111:9999 - ok sync - - - +regular 45.76.116.16:9999 - error ? - - - +evo 45.76.141.74:9999 443 ok sync ok ok valid +regular 45.76.205.140:9999 - ok sync - - - +regular 45.76.236.39:9999 - ok sync - - - +evo 45.77.11.194:9999 443 ok sync ok ok valid +regular 45.77.15.33:9999 - ok sync - - - +regular 45.77.33.239:9999 - ok sync - - - +regular 45.77.117.182:9999 - ok sync - - - +evo 45.77.129.235:9999 443 ok sync ok ok valid +regular 45.77.171.78:9999 - ok sync - - - +regular 45.79.18.106:9999 - ok sync - - - +evo 45.85.147.192:9999 443 ok sync ok ok valid +regular 45.91.94.217:9999 - ok sync - - - +evo 45.94.58.58:9999 443 ok sync ok ok valid +regular 45.128.156.30:9999 - ok sync - - - +regular 45.135.180.68:9999 - ok sync - - - +evo 45.135.180.70:9999 443 ok sync ok ok valid +evo 45.135.180.79:9999 443 ok sync ok ok valid +evo 45.135.180.114:9999 443 ok sync ok ok valid +evo 45.135.180.130:9999 443 ok sync ok ok valid +regular 45.140.19.201:9999 - ok sync - - - +regular 45.149.154.194:9999 - ok sync - - - +regular 45.151.70.202:9999 - ok sync - - - +regular 45.153.186.100:9999 - ok sync - - - +regular 46.4.162.96:9999 - ok sync - - - +regular 46.4.162.98:9999 - ok sync - - - +regular 46.4.162.99:9999 - ok sync - - - +regular 46.4.162.100:9999 - ok sync - - - +regular 46.4.162.101:9999 - ok sync - - - +regular 46.4.162.102:9999 - ok sync - - - +regular 46.4.162.103:9999 - ok sync - - - +regular 46.4.162.104:9999 - ok sync - - - +regular 46.4.162.106:9999 - ok sync - - - +regular 46.4.162.109:9999 - ok sync - - - +regular 46.4.162.110:9999 - ok sync - - - +regular 46.4.162.112:9999 - ok sync - - - +regular 46.4.162.113:9999 - ok sync - - - +regular 46.4.162.114:9999 - ok sync - - - +regular 46.4.162.115:9999 - ok sync - - - +regular 46.4.162.116:9999 - ok sync - - - +regular 46.4.162.117:9999 - ok sync - - - +regular 46.4.162.118:9999 - ok sync - - - +regular 46.4.162.119:9999 - ok sync - - - +regular 46.4.162.122:9999 - ok sync - - - +regular 46.4.162.124:9999 - ok sync - - - +regular 46.4.162.125:9999 - ok sync - - - +regular 46.4.162.127:9999 - ok sync - - - +regular 46.4.217.227:9999 - ok sync - - - +regular 46.4.217.230:9999 - ok sync - - - +regular 46.4.217.231:9999 - ok sync - - - +regular 46.4.217.232:9999 - ok sync - - - +regular 46.4.217.233:9999 - ok sync - - - +regular 46.4.217.234:9999 - ok sync - - - +regular 46.4.217.238:9999 - ok sync - - - +regular 46.4.217.239:9999 - ok sync - - - +regular 46.4.217.241:9999 - ok sync - - - +regular 46.4.217.242:9999 - ok sync - - - +regular 46.4.217.244:9999 - ok sync - - - +regular 46.4.217.245:9999 - ok sync - - - +regular 46.4.217.246:9999 - ok sync - - - +regular 46.4.217.250:9999 - ok sync - - - +regular 46.4.217.251:9999 - ok sync - - - +regular 46.4.217.252:9999 - ok sync - - - +regular 46.4.217.254:9999 - ok sync - - - +regular 46.30.189.187:9999 - ok sync - - - +regular 46.30.189.213:9999 - ok sync - - - +regular 46.30.189.251:9999 - ok sync - - - +regular 46.36.40.242:9999 - ok sync - - - +regular 46.62.132.144:9999 - ok sync - - - +regular 46.62.245.210:9999 - ok sync - - - +evo 46.62.250.247:9999 443 ok sync ok ok valid +regular 46.101.37.234:9999 - ok sync - - - +regular 46.101.60.13:9999 - ok sync - - - +regular 46.101.84.163:9999 - ok sync - - - +regular 46.101.108.68:9999 - ok sync - - - +regular 46.101.110.82:9999 - ok sync - - - +regular 46.101.118.96:9999 - ok sync - - - +regular 46.101.129.63:9999 - ok sync - - - +regular 46.101.195.230:9999 - ok sync - - - +regular 46.101.240.34:9999 - ok sync - - - +regular 46.148.231.121:9999 - ok sync - - - +regular 46.224.50.151:9999 - ok sync - - - +regular 46.250.254.10:9999 - ok sync - - - +regular 49.12.1.250:9999 - ok sync - - - +evo 49.12.102.105:9999 443 ok sync ok ok valid +regular 49.12.189.12:9999 - ok sync - - - +regular 49.12.198.203:9999 - ok sync - - - +regular 49.13.27.107:9999 - ok sync - - - +evo 49.13.28.255:9999 443 ok sync ok ok valid +regular 49.13.140.167:9999 - ok sync - - - +evo 49.13.154.121:9999 443 ok sync ok ok expired +evo 49.13.193.251:9999 443 ok sync ok ok valid +regular 49.13.209.157:9999 - ok sync - - - +regular 49.13.212.202:9999 - ok sync - - - +regular 49.13.212.210:9999 - ok sync - - - +regular 49.13.221.33:9999 - ok sync - - - +evo 49.13.237.193:9999 443 ok sync ok ok valid +evo 50.116.28.103:9999 443 ok sync ok ok expired +regular 51.38.27.202:9999 - ok sync - - - +evo 51.68.3.29:9999 443 ok sync ok ok valid +evo 51.68.35.98:9999 443 ok sync ok ok valid +evo 51.79.109.182:9999 443 ok sync refused none no-handshake +regular 51.158.167.31:9999 - ok sync - - - +evo 51.158.169.237:9999 443 ok sync ok ok valid +regular 51.158.188.88:9999 - ok sync - - - +evo 51.195.47.118:9999 443 ok sync ok ok valid +evo 51.195.235.166:9999 443 ok sync ok ok valid +evo 52.10.213.198:9999 443 ok sync ok ok valid +evo 52.33.9.172:9999 443 ok sync ok ok valid +evo 52.36.102.91:9999 443 ok sync ok ok valid +evo 54.69.95.118:9999 443 ok sync ok ok valid +evo 57.128.212.163:9999 443 ok sync ok ok expired +evo 57.131.28.197:9999 443 ok sync ok ok valid +regular 62.60.244.174:9999 - ok sync - - - +evo 62.171.133.125:9999 443 ok sync ok none expired +evo 62.171.136.93:9999 443 ok sync ok ok valid +evo 62.171.136.245:9999 443 ok sync ok ok valid +evo 62.171.138.186:9999 443 ok sync ok ok valid +evo 62.171.144.159:9999 443 ok sync ok ok expired +evo 62.171.144.192:9999 443 ok sync ok ok valid +evo 62.171.145.24:9999 443 ok sync ok ok valid +evo 62.171.145.234:9999 443 ok sync ok ok valid +regular 62.171.149.86:9999 - ok sync - - - +evo 62.171.150.24:9999 443 ok sync ok ok valid +evo 62.171.168.4:9999 443 ok sync ok ok valid +evo 62.171.168.44:9999 443 ok sync ok ok valid +evo 62.171.170.14:9999 443 ok sync ok ok valid +evo 62.171.170.222:9999 443 ok sync ok ok valid +evo 62.171.171.253:9999 443 ok sync ok ok valid +evo 62.171.174.123:9999 443 ok sync ok ok valid +evo 62.171.176.79:9999 443 ok sync ok ok valid +evo 62.171.178.71:9999 443 ok sync ok ok valid +evo 62.171.189.0:9999 443 ok sync ok ok valid +regular 62.171.189.217:9999 - ok sync - - - +evo 64.176.10.71:9999 443 ok sync ok ok valid +evo 64.176.35.235:9999 443 ok sync ok ok valid +regular 64.176.68.150:9999 - ok sync - - - +regular 64.225.96.193:9999 - ok sync - - - +regular 64.226.66.91:9999 - ok sync - - - +regular 64.226.81.185:9999 - ok sync - - - +regular 64.227.32.83:9999 - ok sync - - - +regular 64.227.122.247:9999 - ok sync - - - +regular 64.227.139.86:9999 - ok sync - - - +regular 64.227.165.75:9999 - ok sync - - - +regular 65.20.101.115:9999 - ok sync - - - +regular 65.20.102.188:9999 - ok sync - - - +regular 65.21.183.4:9999 - ok sync - - - +evo 65.21.237.222:9999 443 ok sync ok ok expired +evo 65.21.237.223:9999 443 ok sync ok ok expired +evo 65.21.237.224:9999 443 ok sync ok ok expired +evo 65.21.237.225:9999 443 ok sync ok ok expired +evo 65.21.237.231:9999 443 ok sync ok ok expired +evo 65.108.0.149:9999 443 ok sync ok ok expired +evo 65.108.0.150:9999 443 ok sync ok ok expired +evo 65.108.0.151:9999 443 ok sync ok ok expired +evo 65.108.0.153:9999 443 ok sync ok ok expired +evo 65.108.0.158:9999 443 ok sync ok ok expired +evo 65.108.4.194:9999 443 ok sync ok ok expired +evo 65.108.4.195:9999 443 ok sync ok ok expired +evo 65.108.4.196:9999 443 ok sync ok ok expired +evo 65.108.4.213:9999 443 ok sync ok ok expired +evo 65.108.74.75:9999 443 ok sync ok ok expired +evo 65.108.74.78:9999 443 ok sync ok ok expired +evo 65.108.74.79:9999 443 ok sync ok ok expired +evo 65.108.74.95:9999 443 ok sync ok ok expired +evo 65.108.74.109:9999 443 ok sync ok ok expired +regular 65.108.145.8:9999 - ok sync - - - +regular 65.108.150.87:9999 - ok sync - - - +regular 65.108.221.24:9999 - ok sync - - - +evo 65.108.246.145:9999 443 ok sync ok ok valid +evo 65.109.84.203:9999 443 ok sync ok ok expired +evo 65.109.84.204:9999 443 ok sync ok ok expired +regular 65.109.93.110:9999 - ok sync - - - +evo 65.109.108.138:9999 443 ok sync ok ok expired +evo 65.109.108.139:9999 443 ok sync ok ok expired +evo 65.109.108.141:9999 443 ok sync ok ok expired +evo 65.109.108.142:9999 443 ok sync ok ok expired +evo 65.109.108.150:9999 443 ok sync ok ok expired +evo 65.109.114.210:9999 443 ok sync ok ok expired +evo 65.109.114.211:9999 443 ok sync ok ok expired +evo 65.109.114.212:9999 443 ok sync ok ok expired +evo 65.109.114.215:9999 443 ok sync ok ok expired +evo 65.109.114.236:9999 443 ok sync ok ok expired +evo 66.29.147.83:9999 443 ok sync ok ok valid +regular 66.42.84.27:9999 - error ? - - - +regular 66.42.105.227:9999 - ok sync - - - +regular 66.163.113.7:9999 - ok sync - - - +regular 66.163.113.91:9999 - ok sync - - - +regular 66.163.113.113:9999 - ok sync - - - +regular 66.244.243.70:9999 - ok sync - - - +evo 66.245.196.52:9999 443 ok sync ok ok valid +regular 68.183.2.66:9999 - ok sync - - - +regular 68.183.36.87:9999 - ok sync - - - +regular 68.183.75.121:9999 - ok sync - - - +regular 68.183.80.227:9999 - ok sync - - - +regular 68.183.92.68:9999 - ok sync - - - +regular 68.183.188.215:9999 - ok sync - - - +regular 68.183.192.117:9999 - ok sync - - - +regular 68.183.199.77:9999 - ok sync - - - +regular 68.183.201.176:9999 - ok sync - - - +regular 68.183.207.246:9999 - ok sync - - - +regular 68.183.208.90:9999 - ok sync - - - +regular 68.183.235.156:9999 - ok sync - - - +regular 68.183.236.118:9999 - ok sync - - - +regular 69.61.107.215:9999 - ok sync - - - +regular 70.34.198.26:9999 - ok sync - - - +regular 70.34.203.203:9999 - ok sync - - - +evo 70.34.206.123:9999 443 ok sync ok ok valid +regular 70.34.210.105:9999 - ok sync - - - +evo 72.60.38.160:9999 443 ok sync ok ok valid +evo 72.62.58.108:9999 443 ok sync ok ok valid +regular 74.50.90.113:9999 - ok sync - - - +evo 75.119.128.71:9999 443 ok sync ok ok valid +regular 75.119.134.20:9999 - ok sync - - - +evo 75.119.137.66:9999 443 ok sync ok ok valid +evo 75.119.138.9:9999 443 ok sync ok ok valid +evo 75.119.152.219:9999 443 ok sync ok ok valid +evo 75.119.153.10:9999 443 ok sync ok ok valid +evo 75.119.156.254:9999 443 ok sync ok ok valid +regular 77.42.16.46:9999 - ok sync - - - +regular 77.42.65.17:9999 - ok sync - - - +evo 77.42.74.68:9999 443 ok sync ok ok valid +regular 77.42.91.72:9999 - ok sync - - - +evo 77.221.148.204:9999 443 ok sync ok ok valid +regular 77.223.99.4:9999 - ok sync - - - +regular 77.237.235.0:9999 - ok sync - - - +regular 77.237.236.66:9999 - ok sync - - - +regular 77.237.236.214:9999 - ok sync - - - +regular 78.47.119.20:9999 - ok sync - - - +regular 78.83.19.0:9999 - ok sync - - - +evo 78.141.225.100:9999 443 ok sync ok ok valid +regular 78.141.240.214:9999 - ok sync - - - +regular 80.208.230.144:9999 - ok sync - - - +regular 80.209.233.182:9999 - ok sync - - - +regular 80.209.239.129:9999 - error ? - - - +evo 80.240.19.200:9999 443 error ? timeout none no-handshake +regular 80.240.132.231:9999 - ok sync - - - +regular 80.240.135.83:9999 - ok sync - - - +regular 80.249.147.8:9999 - ok sync - - - +regular 81.227.250.51:9999 - ok sync - - - +regular 82.180.146.192:9999 - ok sync - - - +regular 82.180.149.107:9999 - ok sync - - - +regular 82.196.1.10:9999 - ok sync - - - +regular 82.202.230.83:9999 - ok sync - - - +evo 82.208.20.153:9999 443 ok sync ok ok valid +regular 83.239.99.40:9999 - ok sync - - - +regular 84.9.50.17:9999 - ok sync - - - +regular 84.98.12.196:9999 - ok sync - - - +regular 84.242.179.204:9999 - ok sync - - - +regular 84.247.132.230:9999 - error ? - - - +regular 84.247.137.20:9999 - ok sync - - - +evo 84.247.180.190:9999 443 ok sync ok ok valid +evo 84.247.180.198:9999 443 ok sync ok ok valid +evo 84.247.180.200:9999 443 ok sync ok ok valid +evo 84.247.180.201:9999 443 ok sync ok ok valid +evo 84.247.180.205:9999 443 ok sync ok ok valid +evo 84.247.187.76:9999 443 ok sync ok ok valid +regular 85.155.188.138:9999 - ok sync - - - +evo 85.190.243.3:9999 443 ok sync ok ok valid +regular 85.209.241.2:9999 - ok sync - - - +regular 85.209.241.3:9999 - ok sync - - - +regular 85.209.241.4:9999 - ok sync - - - +regular 85.209.241.5:9999 - ok sync - - - +regular 85.209.241.6:9999 - ok sync - - - +regular 85.209.241.7:9999 - ok sync - - - +regular 85.209.241.8:9999 - ok sync - - - +regular 85.209.241.10:9999 - ok sync - - - +regular 85.209.241.11:9999 - ok sync - - - +regular 85.209.241.12:9999 - ok sync - - - +regular 85.209.241.13:9999 - ok sync - - - +regular 85.209.241.14:9999 - ok sync - - - +regular 85.209.241.16:9999 - ok sync - - - +regular 85.209.241.17:9999 - ok sync - - - +regular 85.209.241.19:9999 - ok sync - - - +regular 85.209.241.22:9999 - ok sync - - - +regular 85.209.241.23:9999 - ok sync - - - +regular 85.209.241.24:9999 - ok sync - - - +regular 85.209.241.25:9999 - ok sync - - - +regular 85.209.241.26:9999 - ok sync - - - +regular 85.209.241.27:9999 - ok sync - - - +regular 85.209.241.28:9999 - ok sync - - - +regular 85.209.241.30:9999 - ok sync - - - +regular 85.209.241.33:9999 - ok sync - - - +regular 85.209.241.34:9999 - ok sync - - - +regular 85.209.241.36:9999 - ok sync - - - +regular 85.209.241.42:9999 - ok sync - - - +regular 85.209.241.43:9999 - ok sync - - - +regular 85.209.241.45:9999 - ok sync - - - +regular 85.209.241.46:9999 - ok sync - - - +regular 85.209.241.48:9999 - ok sync - - - +regular 85.209.241.49:9999 - ok sync - - - +regular 85.209.241.50:9999 - ok sync - - - +regular 85.209.241.51:9999 - ok sync - - - +regular 85.209.241.52:9999 - ok sync - - - +regular 85.209.241.53:9999 - ok sync - - - +regular 85.209.241.54:9999 - ok sync - - - +regular 85.209.241.57:9999 - ok sync - - - +regular 85.209.241.58:9999 - ok sync - - - +regular 85.209.241.59:9999 - ok sync - - - +regular 85.209.241.60:9999 - ok sync - - - +regular 85.209.241.61:9999 - ok sync - - - +regular 85.209.241.62:9999 - ok sync - - - +regular 85.209.241.63:9999 - ok sync - - - +regular 85.209.241.65:9999 - ok sync - - - +regular 85.209.241.66:9999 - ok sync - - - +regular 85.209.241.67:9999 - ok sync - - - +regular 85.209.241.68:9999 - ok sync - - - +regular 85.209.241.73:9999 - ok sync - - - +regular 85.209.241.74:9999 - ok sync - - - +regular 85.209.241.78:9999 - ok sync - - - +regular 85.209.241.79:9999 - ok sync - - - +regular 85.209.241.80:9999 - ok sync - - - +regular 85.209.241.81:9999 - ok sync - - - +regular 85.209.241.82:9999 - ok sync - - - +regular 85.209.241.83:9999 - ok sync - - - +regular 85.209.241.84:9999 - ok sync - - - +regular 85.209.241.85:9999 - ok sync - - - +regular 85.209.241.86:9999 - ok sync - - - +regular 85.209.241.87:9999 - ok sync - - - +regular 85.209.241.88:9999 - ok sync - - - +regular 85.209.241.89:9999 - ok sync - - - +regular 85.209.241.90:9999 - ok sync - - - +regular 85.209.241.91:9999 - ok sync - - - +regular 85.209.241.92:9999 - ok sync - - - +regular 85.209.241.93:9999 - ok sync - - - +regular 85.209.241.94:9999 - ok sync - - - +regular 85.209.241.102:9999 - ok sync - - - +regular 85.209.241.103:9999 - ok sync - - - +regular 85.209.241.104:9999 - ok sync - - - +regular 85.209.241.105:9999 - ok sync - - - +regular 85.209.241.121:9999 - ok sync - - - +regular 85.209.241.127:9999 - ok sync - - - +regular 85.209.241.137:9999 - ok sync - - - +regular 85.209.241.146:9999 - ok sync - - - +regular 85.209.241.150:9999 - ok sync - - - +regular 85.209.241.156:9999 - ok sync - - - +regular 85.209.241.164:9999 - ok sync - - - +regular 85.209.241.167:9999 - ok sync - - - +regular 85.209.241.172:9999 - ok sync - - - +regular 85.209.241.177:9999 - ok sync - - - +regular 85.209.241.179:9999 - ok sync - - - +regular 85.209.241.185:9999 - ok sync - - - +regular 85.209.241.187:9999 - ok sync - - - +regular 85.209.241.198:9999 - ok sync - - - +regular 85.209.241.200:9999 - ok sync - - - +regular 85.209.241.207:9999 - ok sync - - - +regular 85.209.241.208:9999 - ok sync - - - +regular 85.209.241.211:9999 - ok sync - - - +regular 85.209.241.212:9999 - ok sync - - - +regular 85.209.241.213:9999 - ok sync - - - +regular 85.209.241.214:9999 - ok sync - - - +regular 85.209.241.215:9999 - ok sync - - - +regular 85.209.241.216:9999 - ok sync - - - +regular 85.209.241.217:9999 - ok sync - - - +regular 85.209.241.218:9999 - ok sync - - - +regular 85.209.241.219:9999 - ok sync - - - +regular 85.209.241.220:9999 - ok sync - - - +regular 85.209.241.221:9999 - ok sync - - - +regular 85.209.241.223:9999 - ok sync - - - +regular 85.209.241.224:9999 - ok sync - - - +regular 85.209.241.225:9999 - ok sync - - - +regular 85.209.241.226:9999 - ok sync - - - +regular 85.209.241.228:9999 - ok sync - - - +regular 85.209.241.229:9999 - ok sync - - - +regular 85.209.241.231:9999 - ok sync - - - +regular 85.209.241.233:9999 - ok sync - - - +regular 85.209.241.234:9999 - ok sync - - - +regular 85.209.241.235:9999 - ok sync - - - +regular 85.209.241.236:9999 - ok sync - - - +regular 85.209.241.238:9999 - ok sync - - - +regular 85.209.241.239:9999 - ok sync - - - +regular 85.209.241.240:9999 - ok sync - - - +regular 85.209.241.242:9999 - ok sync - - - +regular 85.209.241.243:9999 - ok sync - - - +regular 85.209.241.244:9999 - ok sync - - - +regular 85.209.241.245:9999 - ok sync - - - +regular 85.209.241.246:9999 - ok sync - - - +regular 85.209.241.247:9999 - ok sync - - - +regular 85.209.241.248:9999 - ok sync - - - +regular 85.209.241.249:9999 - ok sync - - - +regular 85.209.242.250:9999 - ok sync - - - +evo 87.228.24.64:9999 443 ok sync ok ok valid +regular 88.99.11.2:9999 - ok sync - - - +regular 88.99.11.3:9999 - ok sync - - - +regular 88.99.11.7:9999 - ok sync - - - +regular 88.99.11.10:9999 - ok sync - - - +regular 88.99.11.12:9999 - ok sync - - - +regular 88.99.11.14:9999 - ok sync - - - +regular 88.99.11.15:9999 - ok sync - - - +regular 88.99.11.16:9999 - ok sync - - - +regular 88.99.11.17:9999 - ok sync - - - +regular 88.99.11.20:9999 - ok sync - - - +regular 88.99.11.21:9999 - ok sync - - - +regular 88.99.11.22:9999 - ok sync - - - +regular 88.99.11.23:9999 - ok sync - - - +regular 88.99.11.24:9999 - ok sync - - - +regular 88.99.11.25:9999 - ok sync - - - +regular 88.99.11.26:9999 - ok sync - - - +regular 88.99.11.27:9999 - ok sync - - - +regular 88.99.11.29:9999 - ok sync - - - +regular 88.99.11.30:9999 - ok sync - - - +regular 88.99.11.31:9999 - ok sync - - - +regular 88.99.38.175:9999 - ok sync - - - +evo 89.35.131.23:9999 443 ok sync ok ok valid +evo 89.35.131.39:9999 443 ok sync ok ok valid +evo 89.35.131.61:9999 443 ok sync ok ok expired +evo 89.35.131.149:9999 443 ok sync ok ok valid +evo 89.35.131.158:9999 443 ok sync ok ok valid +evo 89.35.131.218:9999 443 ok sync ok ok valid +evo 89.35.131.219:9999 443 ok sync ok ok valid +regular 89.40.15.222:9999 - ok sync - - - +regular 89.46.42.216:9999 - ok sync - - - +regular 89.46.42.218:9999 - ok sync - - - +regular 89.47.167.131:9999 - ok sync - - - +regular 89.117.3.242:9999 - ok sync - - - +evo 89.117.57.27:9999 443 ok sync ok ok expired +evo 89.125.50.14:9999 443 ok sync ok ok valid +evo 89.125.50.206:9999 443 ok sync ok ok valid +evo 89.125.209.27:9999 443 ok sync ok ok valid +evo 89.125.209.69:9999 443 ok sync ok ok valid +evo 89.125.209.106:9999 443 ok sync ok ok valid +evo 89.125.209.110:9999 443 ok sync ok ok valid +evo 89.125.209.120:9999 443 ok sync ok ok valid +evo 89.125.209.133:9999 443 ok sync ok ok valid +evo 89.125.209.152:9999 443 ok sync ok ok valid +evo 89.125.209.156:9999 443 ok sync ok ok valid +evo 89.125.209.178:9999 443 ok sync ok ok valid +evo 89.125.209.195:9999 443 ok sync ok ok valid +evo 89.125.209.234:9999 443 ok sync ok ok valid +regular 89.179.73.96:9999 - ok sync - - - +regular 91.98.160.22:9999 - ok sync - - - +regular 91.99.169.186:9999 - ok sync - - - +evo 91.198.108.35:9999 443 ok sync ok ok valid +evo 91.198.108.36:9999 443 ok sync ok ok valid +evo 91.198.108.37:9999 443 ok sync ok ok valid +evo 91.198.108.38:9999 443 ok sync ok ok valid +regular 91.198.108.39:9999 - ok sync - - - +regular 91.198.108.40:9999 - ok sync - - - +evo 91.199.149.177:9999 443 ok sync ok ok expired +evo 93.95.115.187:9999 443 error ? ok ok valid +evo 93.115.172.36:9999 443 ok sync ok ok valid +evo 93.115.172.37:9999 443 ok sync ok ok valid +evo 93.115.172.38:9999 443 ok sync ok ok valid +evo 93.115.172.39:9999 443 ok sync ok ok valid +regular 93.190.140.98:9999 - ok sync - - - +regular 93.190.140.101:9999 - ok sync - - - +regular 93.190.140.162:9999 - ok sync - - - +regular 95.85.1.147:9999 - ok sync - - - +regular 95.85.1.197:9999 - ok sync - - - +regular 95.85.12.33:9999 - ok sync - - - +regular 95.85.21.42:9999 - ok sync - - - +regular 95.85.32.155:9999 - ok sync - - - +regular 95.85.37.225:9999 - ok sync - - - +regular 95.85.48.49:9999 - ok sync - - - +regular 95.85.54.64:9999 - ok sync - - - +evo 95.111.232.18:9999 443 ok sync ok ok valid +evo 95.111.233.139:9999 443 ok sync ok ok valid +evo 95.111.239.54:9999 443 ok sync ok ok valid +evo 95.111.241.20:9999 443 ok sync ok ok valid +evo 95.111.242.220:9999 443 ok sync ok ok valid +evo 95.179.139.125:9999 443 ok sync ok ok expired +regular 95.179.152.242:9999 - ok sync - - - +evo 95.179.159.65:9999 443 ok sync ok ok valid +regular 95.179.213.67:9999 - ok sync - - - +regular 95.179.240.114:9999 - ok sync - - - +evo 95.179.241.182:9999 443 ok sync ok ok valid +regular 95.179.243.76:9999 - ok sync - - - +regular 95.216.79.224:9999 - ok sync - - - +regular 95.216.79.228:9999 - ok sync - - - +regular 95.216.84.33:9999 - ok sync - - - +regular 95.216.84.35:9999 - ok sync - - - +regular 95.216.84.36:9999 - ok sync - - - +regular 95.216.84.39:9999 - ok sync - - - +regular 95.216.84.42:9999 - ok sync - - - +regular 95.216.84.43:9999 - ok sync - - - +regular 95.216.84.45:9999 - ok sync - - - +regular 95.216.109.130:9999 - ok sync - - - +regular 95.216.109.131:9999 - ok sync - - - +regular 95.216.109.133:9999 - ok sync - - - +regular 95.216.109.134:9999 - ok sync - - - +regular 95.216.109.135:9999 - ok sync - - - +regular 95.216.109.136:9999 - ok sync - - - +regular 95.216.126.32:9999 - ok sync - - - +regular 95.216.126.34:9999 - ok sync - - - +regular 95.216.126.38:9999 - ok sync - - - +regular 95.216.126.39:9999 - ok sync - - - +regular 95.216.126.45:9999 - ok sync - - - +regular 95.216.126.46:9999 - ok sync - - - +evo 95.216.146.18:9999 443 ok sync ok ok valid +regular 95.216.230.97:9999 - ok sync - - - +regular 95.216.230.98:9999 - ok sync - - - +regular 95.216.230.101:9999 - ok sync - - - +regular 95.216.230.102:9999 - ok sync - - - +regular 95.216.230.103:9999 - ok sync - - - +regular 95.216.255.64:9999 - ok sync - - - +regular 95.216.255.67:9999 - ok sync - - - +regular 95.216.255.68:9999 - ok sync - - - +regular 95.216.255.69:9999 - ok sync - - - +regular 95.216.255.70:9999 - ok sync - - - +regular 95.216.255.71:9999 - ok sync - - - +regular 95.216.255.78:9999 - ok sync - - - +regular 95.217.48.96:9999 - ok sync - - - +regular 95.217.48.97:9999 - ok sync - - - +regular 95.217.48.100:9999 - ok sync - - - +regular 95.217.71.192:9999 - ok sync - - - +regular 95.217.71.194:9999 - ok sync - - - +regular 95.217.71.197:9999 - ok sync - - - +regular 95.217.71.198:9999 - ok sync - - - +regular 95.217.71.202:9999 - ok sync - - - +regular 95.217.71.203:9999 - ok sync - - - +regular 95.217.71.204:9999 - ok sync - - - +regular 95.217.71.207:9999 - ok sync - - - +regular 95.217.71.209:9999 - ok sync - - - +regular 95.217.71.211:9999 - ok sync - - - +regular 95.217.125.97:9999 - ok sync - - - +regular 95.217.125.98:9999 - ok sync - - - +regular 95.217.125.101:9999 - ok sync - - - +regular 95.217.125.103:9999 - ok sync - - - +regular 96.30.194.83:9999 - ok sync - - - +regular 100.42.182.181:9999 - ok sync - - - +evo 103.214.68.30:9999 443 ok sync timeout none no-handshake +evo 103.214.68.131:9999 443 ok sync timeout none no-handshake +regular 104.128.239.50:9999 - ok sync - - - +regular 104.128.239.123:9999 - ok sync - - - +regular 104.129.51.151:9999 - ok sync - - - +regular 104.129.51.152:9999 - ok sync - - - +regular 104.131.134.41:9999 - ok sync - - - +regular 104.131.134.62:9999 - ok sync - - - +regular 104.131.143.9:9999 - ok sync - - - +regular 104.131.160.119:9999 - ok sync - - - +regular 104.131.180.71:9999 - ok sync - - - +regular 104.131.193.7:9999 - ok sync - - - +regular 104.131.236.114:9999 - ok sync - - - +evo 104.156.154.179:9999 443 ok sync ok ok valid +regular 104.156.237.196:9999 - ok sync - - - +regular 104.168.46.54:9999 - ok sync - - - +regular 104.207.130.246:9999 - ok sync - - - +regular 104.207.130.255:9999 - ok sync - - - +regular 104.207.131.17:9999 - error ? - - - +regular 104.234.167.115:9999 - ok sync - - - +regular 104.236.58.131:9999 - ok sync - - - +regular 104.236.183.29:9999 - ok sync - - - +regular 104.238.159.13:9999 - ok sync - - - +regular 104.238.167.102:9999 - ok sync - - - +regular 104.238.176.125:9999 - ok sync - - - +regular 104.238.176.179:9999 - ok sync - - - +regular 104.248.40.20:9999 - ok sync - - - +regular 104.248.46.23:9999 - ok sync - - - +regular 104.248.137.183:9999 - ok sync - - - +regular 104.248.138.204:9999 - ok sync - - - +regular 104.248.159.169:9999 - ok sync - - - +regular 104.248.167.243:9999 - ok sync - - - +regular 104.248.172.106:9999 - ok sync - - - +regular 106.55.9.22:9999 - ok sync - - - +regular 107.170.7.146:9999 - ok sync - - - +regular 107.170.13.222:9999 - ok sync - - - +regular 107.170.120.125:9999 - ok sync - - - +regular 107.170.157.166:9999 - ok sync - - - +regular 107.170.165.78:9999 - ok sync - - - +regular 107.170.171.115:9999 - ok sync - - - +regular 107.170.196.35:9999 - ok sync - - - +regular 107.170.223.74:9999 - ok sync - - - +regular 107.170.238.241:9999 - error ? - - - +regular 107.170.242.110:9999 - ok sync - - - +regular 107.170.254.160:9999 - ok sync - - - +regular 107.172.78.198:9999 - ok sync - - - +regular 107.173.28.208:9999 - ok sync - - - +regular 107.174.204.232:9999 - ok sync - - - +regular 107.175.206.17:9999 - ok sync - - - +regular 107.175.206.125:9999 - ok sync - - - +regular 107.179.202.74:9999 - ok sync - - - +regular 107.189.3.74:9999 - ok sync - - - +regular 107.191.58.41:9999 - ok sync - - - +evo 108.61.165.170:9999 443 ok sync ok ok valid +regular 108.61.171.85:9999 - ok sync - - - +regular 108.61.189.92:9999 - ok sync - - - +regular 108.61.210.143:9999 - ok sync - - - +regular 108.160.131.192:9999 - ok sync - - - +regular 108.160.134.116:9999 - ok sync - - - +regular 108.160.140.103:9999 - ok sync - - - +evo 109.123.244.131:9999 443 ok sync ok ok valid +regular 109.173.240.233:9999 - ok sync - - - +regular 109.199.96.61:9999 - ok sync - - - +evo 109.199.97.144:9999 443 ok sync ok ok valid +evo 109.199.105.14:9999 443 ok sync ok ok valid +regular 109.199.105.203:9999 - ok sync - - - +evo 109.199.107.155:9999 443 ok sync ok ok valid +evo 109.199.108.223:9999 443 ok sync ok ok valid +evo 109.199.108.234:9999 443 ok sync ok ok valid +evo 109.199.109.39:9999 443 ok sync ok ok valid +evo 109.199.119.192:9999 443 ok sync ok ok valid +evo 109.199.120.79:9999 443 ok sync ok ok valid +evo 109.199.124.30:9999 443 ok sync ok ok valid +evo 109.199.124.135:9999 443 ok sync ok ok valid +regular 109.235.67.246:9999 - ok sync - - - +evo 114.132.172.215:9999 443 ok sync ok ok valid +regular 115.120.238.240:9999 - error ? - - - +regular 115.190.248.57:9999 - error ? - - - +regular 116.203.244.222:9999 - ok sync - - - +regular 123.193.64.166:9999 - ok sync - - - +regular 128.140.7.186:9999 - ok sync - - - +regular 128.140.58.30:9999 - ok sync - - - +regular 128.199.17.79:9999 - ok sync - - - +regular 128.199.22.78:9999 - ok sync - - - +regular 128.199.38.246:9999 - ok sync - - - +regular 128.199.42.44:9999 - ok sync - - - +regular 128.199.59.124:9999 - ok sync - - - +regular 128.199.82.102:9999 - ok sync - - - +regular 128.199.134.235:9999 - ok sync - - - +regular 128.199.137.10:9999 - ok sync - - - +regular 128.199.232.212:9999 - ok sync - - - +regular 129.212.233.191:9999 - ok sync - - - +evo 130.162.233.186:9999 443 ok sync ok ok expired +evo 130.185.118.3:9999 443 ok sync ok ok valid +regular 130.255.155.163:9999 - ok sync - - - +regular 132.243.197.2:9999 - ok sync - - - +regular 132.243.197.3:9999 - ok sync - - - +regular 132.243.197.4:9999 - ok sync - - - +regular 132.243.197.6:9999 - ok sync - - - +regular 132.243.197.7:9999 - ok sync - - - +regular 132.243.197.8:9999 - ok sync - - - +regular 132.243.197.9:9999 - ok sync - - - +regular 132.243.197.10:9999 - ok sync - - - +regular 132.243.197.11:9999 - ok sync - - - +regular 132.243.197.12:9999 - ok sync - - - +regular 132.243.197.13:9999 - ok sync - - - +regular 132.243.197.14:9999 - ok sync - - - +regular 132.243.197.15:9999 - ok sync - - - +evo 132.243.197.16:9999 443 ok sync ok ok valid +regular 132.243.197.17:9999 - ok sync - - - +evo 132.243.197.18:9999 443 ok sync ok ok valid +regular 132.243.197.19:9999 - ok sync - - - +regular 132.243.197.20:9999 - ok sync - - - +regular 132.243.197.21:9999 - ok sync - - - +regular 132.243.197.22:9999 - ok sync - - - +regular 132.243.197.23:9999 - ok sync - - - +regular 132.243.197.24:9999 - ok sync - - - +regular 132.243.197.25:9999 - ok sync - - - +regular 132.243.197.26:9999 - ok sync - - - +regular 132.243.197.28:9999 - ok sync - - - +regular 132.243.197.29:9999 - ok sync - - - +regular 132.243.197.30:9999 - ok sync - - - +regular 132.243.197.31:9999 - ok sync - - - +regular 132.243.197.32:9999 - ok sync - - - +regular 132.243.197.33:9999 - ok sync - - - +regular 132.243.197.34:9999 - ok sync - - - +regular 132.243.197.35:9999 - ok sync - - - +regular 132.243.197.36:9999 - ok sync - - - +regular 132.243.197.37:9999 - ok sync - - - +evo 132.243.197.38:9999 443 ok sync ok ok valid +regular 132.243.197.39:9999 - ok sync - - - +evo 132.243.197.40:9999 443 ok sync ok ok valid +regular 132.243.197.41:9999 - ok sync - - - +regular 132.243.197.42:9999 - ok sync - - - +regular 132.243.197.43:9999 - ok sync - - - +regular 132.243.197.44:9999 - ok sync - - - +regular 132.243.197.45:9999 - ok sync - - - +regular 132.243.197.46:9999 - ok sync - - - +regular 132.243.197.47:9999 - ok sync - - - +regular 132.243.197.48:9999 - ok sync - - - +regular 132.243.197.49:9999 - ok sync - - - +regular 132.243.197.50:9999 - ok sync - - - +regular 132.243.197.51:9999 - ok sync - - - +regular 132.243.197.52:9999 - ok sync - - - +regular 132.243.197.53:9999 - ok sync - - - +regular 132.243.197.54:9999 - ok sync - - - +regular 132.243.197.55:9999 - ok sync - - - +regular 132.243.197.56:9999 - ok sync - - - +regular 132.243.197.57:9999 - ok sync - - - +regular 132.243.197.58:9999 - ok sync - - - +regular 132.243.197.59:9999 - ok sync - - - +regular 132.243.197.61:9999 - ok sync - - - +regular 132.243.197.62:9999 - ok sync - - - +regular 132.243.197.63:9999 - ok sync - - - +regular 132.243.197.64:9999 - ok sync - - - +regular 132.243.197.65:9999 - ok sync - - - +regular 132.243.197.66:9999 - ok sync - - - +regular 132.243.197.67:9999 - ok sync - - - +regular 132.243.197.68:9999 - ok sync - - - +regular 132.243.197.70:9999 - ok sync - - - +regular 132.243.197.71:9999 - ok sync - - - +regular 132.243.197.72:9999 - ok sync - - - +regular 132.243.197.73:9999 - ok sync - - - +regular 132.243.197.74:9999 - ok sync - - - +regular 132.243.197.75:9999 - ok sync - - - +regular 132.243.197.76:9999 - ok sync - - - +regular 132.243.197.77:9999 - ok sync - - - +regular 132.243.197.78:9999 - ok sync - - - +regular 132.243.197.79:9999 - ok sync - - - +regular 132.243.197.80:9999 - ok sync - - - +regular 132.243.197.81:9999 - ok sync - - - +regular 132.243.197.82:9999 - ok sync - - - +regular 132.243.197.83:9999 - ok sync - - - +regular 132.243.197.84:9999 - ok sync - - - +regular 132.243.197.85:9999 - ok sync - - - +regular 132.243.197.87:9999 - ok sync - - - +regular 132.243.197.88:9999 - ok sync - - - +regular 132.243.197.89:9999 - ok sync - - - +regular 132.243.197.90:9999 - ok sync - - - +regular 132.243.197.91:9999 - ok sync - - - +regular 132.243.197.92:9999 - ok sync - - - +regular 132.243.197.93:9999 - ok sync - - - +regular 132.243.197.94:9999 - ok sync - - - +regular 132.243.197.95:9999 - ok sync - - - +regular 132.243.197.96:9999 - ok sync - - - +regular 132.243.197.97:9999 - ok sync - - - +regular 132.243.197.98:9999 - ok sync - - - +regular 132.243.197.99:9999 - ok sync - - - +regular 132.243.197.100:9999 - ok sync - - - +regular 132.243.197.102:9999 - ok sync - - - +regular 132.243.197.103:9999 - ok sync - - - +regular 132.243.197.104:9999 - ok sync - - - +regular 132.243.197.105:9999 - ok sync - - - +regular 132.243.197.107:9999 - ok sync - - - +regular 132.243.197.108:9999 - ok sync - - - +regular 132.243.197.109:9999 - ok sync - - - +regular 132.243.197.110:9999 - ok sync - - - +regular 132.243.197.111:9999 - ok sync - - - +regular 132.243.197.112:9999 - ok sync - - - +regular 132.243.197.113:9999 - ok sync - - - +regular 132.243.197.114:9999 - ok sync - - - +regular 132.243.197.115:9999 - ok sync - - - +regular 132.243.197.116:9999 - ok sync - - - +regular 132.243.197.117:9999 - ok sync - - - +regular 132.243.197.118:9999 - ok sync - - - +regular 132.243.197.127:9999 - ok sync - - - +regular 132.243.197.130:9999 - ok sync - - - +regular 132.243.197.131:9999 - ok sync - - - +regular 132.243.197.132:9999 - ok sync - - - +regular 132.243.197.137:9999 - ok sync - - - +regular 132.243.197.138:9999 - ok sync - - - +regular 132.243.197.139:9999 - ok sync - - - +regular 132.243.197.140:9999 - ok sync - - - +regular 132.243.197.142:9999 - ok sync - - - +regular 132.243.197.143:9999 - ok sync - - - +regular 132.243.197.144:9999 - ok sync - - - +regular 132.243.197.145:9999 - ok sync - - - +regular 132.243.197.155:9999 - ok sync - - - +regular 132.243.197.160:9999 - ok sync - - - +regular 132.243.197.161:9999 - ok sync - - - +regular 132.243.197.175:9999 - ok sync - - - +regular 132.243.197.176:9999 - ok sync - - - +regular 132.243.197.177:9999 - ok sync - - - +regular 132.243.197.178:9999 - ok sync - - - +regular 132.243.197.179:9999 - ok sync - - - +regular 132.243.197.182:9999 - ok sync - - - +regular 132.243.197.184:9999 - ok sync - - - +regular 132.243.197.185:9999 - ok sync - - - +regular 132.243.197.187:9999 - ok sync - - - +regular 132.243.197.188:9999 - ok sync - - - +regular 132.243.197.189:9999 - ok sync - - - +regular 132.243.197.190:9999 - ok sync - - - +regular 132.243.197.216:9999 - ok sync - - - +regular 132.243.197.220:9999 - ok sync - - - +regular 132.243.197.224:9999 - ok sync - - - +regular 132.243.197.225:9999 - ok sync - - - +regular 132.243.197.226:9999 - ok sync - - - +regular 132.243.197.227:9999 - ok sync - - - +regular 132.243.197.228:9999 - ok sync - - - +regular 132.243.197.229:9999 - ok sync - - - +regular 132.243.197.230:9999 - ok sync - - - +regular 132.243.197.231:9999 - ok sync - - - +regular 132.243.197.233:9999 - ok sync - - - +regular 132.243.197.234:9999 - ok sync - - - +regular 132.243.197.236:9999 - ok sync - - - +regular 132.243.197.237:9999 - ok sync - - - +regular 132.243.197.238:9999 - ok sync - - - +regular 132.243.197.239:9999 - ok sync - - - +regular 132.243.197.240:9999 - ok sync - - - +regular 132.243.197.241:9999 - ok sync - - - +regular 132.243.197.242:9999 - ok sync - - - +regular 132.243.197.243:9999 - ok sync - - - +regular 132.243.197.244:9999 - ok sync - - - +regular 132.243.197.245:9999 - ok sync - - - +regular 132.243.197.246:9999 - ok sync - - - +regular 132.243.197.247:9999 - ok sync - - - +regular 132.243.197.248:9999 - ok sync - - - +evo 132.243.197.249:9999 443 ok sync ok ok valid +evo 132.243.197.250:9999 443 ok sync ok ok valid +evo 132.243.197.251:9999 443 ok sync ok ok valid +evo 132.243.197.252:9999 443 ok sync ok ok valid +regular 133.18.97.226:9999 - ok sync - - - +regular 134.122.32.152:9999 - ok sync - - - +regular 134.122.32.230:9999 - ok sync - - - +regular 134.122.37.115:9999 - ok sync - - - +regular 134.122.38.28:9999 - ok sync - - - +regular 134.122.45.173:9999 - ok sync - - - +regular 134.209.80.187:9999 - ok sync - - - +regular 134.209.88.181:9999 - ok sync - - - +regular 134.209.92.57:9999 - ok sync - - - +regular 134.209.96.96:9999 - ok sync - - - +regular 134.209.105.161:9999 - ok sync - - - +regular 134.209.146.189:9999 - ok sync - - - +regular 134.209.156.141:9999 - ok sync - - - +regular 134.209.158.119:9999 - ok sync - - - +regular 134.209.176.109:9999 - ok sync - - - +regular 134.209.185.24:9999 - ok sync - - - +regular 134.209.197.15:9999 - ok sync - - - +regular 134.209.207.71:9999 - ok sync - - - +evo 134.255.182.185:9999 443 ok sync ok ok valid +evo 134.255.182.186:9999 443 ok sync ok ok valid +regular 135.181.8.66:9999 - ok sync - - - +regular 135.181.8.68:9999 - ok sync - - - +regular 135.181.8.69:9999 - ok sync - - - +regular 135.181.8.70:9999 - ok sync - - - +regular 135.181.8.72:9999 - ok sync - - - +regular 135.181.8.73:9999 - ok sync - - - +regular 135.181.8.74:9999 - ok sync - - - +regular 135.181.8.81:9999 - ok sync - - - +regular 135.181.8.82:9999 - ok sync - - - +regular 135.181.8.83:9999 - ok sync - - - +regular 135.181.15.224:9999 - ok sync - - - +regular 135.181.15.228:9999 - ok sync - - - +regular 135.181.15.229:9999 - ok sync - - - +regular 135.181.15.233:9999 - ok sync - - - +regular 135.181.15.234:9999 - ok sync - - - +regular 135.181.15.235:9999 - ok sync - - - +regular 135.181.50.36:9999 - ok sync - - - +regular 135.181.50.38:9999 - ok sync - - - +regular 135.181.50.45:9999 - ok sync - - - +regular 135.181.52.129:9999 - ok sync - - - +regular 135.181.52.140:9999 - ok sync - - - +regular 135.181.52.145:9999 - ok sync - - - +regular 135.181.52.148:9999 - ok sync - - - +regular 135.181.52.153:9999 - ok sync - - - +regular 135.181.52.159:9999 - ok sync - - - +regular 135.181.53.132:9999 - ok sync - - - +regular 135.181.53.133:9999 - ok sync - - - +regular 135.181.53.134:9999 - ok sync - - - +regular 135.181.53.192:9999 - ok sync - - - +regular 135.181.53.193:9999 - ok sync - - - +regular 135.181.53.194:9999 - ok sync - - - +regular 135.181.53.195:9999 - ok sync - - - +regular 135.181.53.196:9999 - ok sync - - - +regular 135.181.53.197:9999 - ok sync - - - +regular 135.181.53.198:9999 - ok sync - - - +regular 135.181.53.199:9999 - ok sync - - - +regular 135.181.53.227:9999 - ok sync - - - +regular 135.181.53.228:9999 - ok sync - - - +regular 135.181.53.229:9999 - ok sync - - - +regular 135.181.53.230:9999 - ok sync - - - +regular 135.181.53.231:9999 - ok sync - - - +regular 135.181.54.96:9999 - ok sync - - - +regular 135.181.54.98:9999 - ok sync - - - +regular 135.181.54.101:9999 - ok sync - - - +regular 135.181.54.103:9999 - ok sync - - - +regular 135.181.54.104:9999 - ok sync - - - +evo 135.181.110.216:9999 443 ok sync ok ok valid +regular 135.181.174.222:9999 - ok sync - - - +regular 135.181.177.53:9999 - ok sync - - - +evo 135.181.229.49:9999 443 ok sync ok ok valid +regular 136.243.29.193:9999 - ok sync - - - +regular 136.243.29.194:9999 - ok sync - - - +regular 136.243.29.195:9999 - ok sync - - - +regular 136.243.29.196:9999 - ok sync - - - +regular 136.243.29.197:9999 - ok sync - - - +regular 136.243.29.199:9999 - ok sync - - - +regular 136.243.29.201:9999 - ok sync - - - +regular 136.243.29.205:9999 - ok sync - - - +regular 136.243.29.206:9999 - ok sync - - - +regular 136.243.29.207:9999 - ok sync - - - +regular 136.243.29.208:9999 - ok sync - - - +regular 136.243.29.212:9999 - ok sync - - - +regular 136.243.29.215:9999 - ok sync - - - +regular 136.243.29.216:9999 - ok sync - - - +regular 136.243.29.220:9999 - ok sync - - - +regular 136.243.115.128:9999 - ok sync - - - +regular 136.243.115.130:9999 - ok sync - - - +regular 136.243.115.133:9999 - ok sync - - - +regular 136.243.115.134:9999 - ok sync - - - +regular 136.243.115.136:9999 - ok sync - - - +regular 136.243.115.138:9999 - ok sync - - - +regular 136.243.115.139:9999 - ok sync - - - +regular 136.243.115.140:9999 - ok sync - - - +regular 136.243.115.141:9999 - ok sync - - - +regular 136.243.115.142:9999 - ok sync - - - +regular 136.243.138.106:9999 - ok sync - - - +regular 136.243.142.32:9999 - ok sync - - - +regular 136.243.142.33:9999 - ok sync - - - +regular 136.243.142.41:9999 - ok sync - - - +evo 136.244.99.17:9999 443 ok sync ok ok valid +regular 136.244.103.110:9999 - ok sync - - - +regular 136.244.105.174:9999 - ok sync - - - +regular 137.184.5.78:9999 - ok sync - - - +regular 137.184.175.173:9999 - ok sync - - - +regular 137.220.38.255:9999 - error ? - - - +regular 138.68.68.160:9999 - ok sync - - - +regular 138.68.149.239:9999 - ok sync - - - +regular 138.68.157.15:9999 - ok sync - - - +regular 138.197.128.77:9999 - ok sync - - - +regular 138.197.130.116:9999 - ok sync - - - +regular 138.197.131.126:9999 - ok sync - - - +regular 138.197.147.28:9999 - ok sync - - - +regular 138.197.161.208:9999 - ok sync - - - +regular 139.28.97.2:9999 - ok sync - - - +regular 139.59.0.167:9999 - ok sync - - - +regular 139.59.3.197:9999 - ok sync - - - +regular 139.59.4.172:9999 - ok sync - - - +regular 139.59.22.95:9999 - ok sync - - - +regular 139.59.29.173:9999 - ok sync - - - +regular 139.59.30.197:9999 - ok sync - - - +regular 139.59.39.142:9999 - ok sync - - - +regular 139.59.56.7:9999 - ok sync - - - +regular 139.59.102.0:9999 - ok sync - - - +regular 139.59.120.106:9999 - ok sync - - - +regular 139.59.137.155:9999 - ok sync - - - +regular 139.59.138.149:9999 - ok sync - - - +regular 139.59.144.169:9999 - ok sync - - - +regular 139.59.156.27:9999 - ok sync - - - +regular 139.59.178.169:9999 - ok sync - - - +regular 139.59.179.170:9999 - ok sync - - - +regular 139.59.231.57:9999 - ok sync - - - +regular 139.59.243.139:9999 - ok sync - - - +evo 139.84.137.143:9999 443 ok sync ok ok valid +evo 139.84.170.10:9999 443 ok sync ok ok valid +evo 139.84.231.221:9999 443 ok sync ok ok valid +evo 139.84.232.129:9999 443 ok sync ok ok valid +evo 139.84.236.208:9999 443 ok sync ok ok valid +evo 139.99.201.103:9999 443 ok sync ok ok valid +regular 139.162.211.76:9999 - ok sync - - - +regular 139.162.215.169:9999 - ok sync - - - +evo 139.180.143.115:9999 443 ok sync ok ok valid +regular 139.180.208.106:9999 - ok sync - - - +evo 142.44.136.69:9999 443 ok sync ok ok valid +regular 142.93.38.4:9999 - ok sync - - - +regular 142.93.98.38:9999 - ok sync - - - +regular 142.93.143.137:9999 - ok sync - - - +regular 142.93.154.186:9999 - ok sync - - - +regular 142.93.157.112:9999 - ok sync - - - +regular 142.93.215.115:9999 - ok sync - - - +regular 142.93.216.91:9999 - ok sync - - - +regular 143.110.156.147:9999 - ok sync - - - +regular 143.110.183.99:9999 - ok sync - - - +regular 143.110.189.48:9999 - ok sync - - - +regular 143.110.191.135:9999 - ok sync - - - +regular 143.110.248.96:9999 - ok sync - - - +regular 143.110.250.48:9999 - ok sync - - - +regular 143.110.250.167:9999 - ok sync - - - +regular 143.198.42.189:9999 - ok sync - - - +regular 143.198.74.32:9999 - ok sync - - - +regular 143.198.104.135:9999 - ok sync - - - +evo 143.198.145.184:9999 443 ok sync ok ok valid +regular 143.244.131.179:9999 - ok sync - - - +regular 144.24.238.178:9999 - ok sync - - - +evo 144.91.87.82:9999 443 ok sync ok ok valid +evo 144.91.99.105:9999 443 ok sync ok ok valid +evo 144.91.105.209:9999 443 ok sync ok ok valid +evo 144.91.106.188:9999 443 ok sync ok ok valid +evo 144.91.121.81:9999 443 ok sync ok ok valid +evo 144.126.141.62:9999 443 ok sync ok ok valid +regular 144.126.143.197:9999 - ok sync - - - +regular 144.126.203.253:9999 - ok sync - - - +regular 144.202.19.42:9999 - ok sync - - - +regular 144.202.37.1:9999 - error ? - - - +regular 144.202.72.211:9999 - error ? - - - +regular 144.202.101.45:9999 - error ? - - - +regular 145.239.92.115:9999 - ok sync - - - +evo 146.59.45.235:9999 443 ok sync ok ok valid +regular 146.185.131.124:9999 - ok sync - - - +regular 146.185.139.109:9999 - ok sync - - - +regular 146.185.140.22:9999 - ok sync - - - +regular 146.185.150.204:9999 - ok sync - - - +regular 146.185.153.111:9999 - ok sync - - - +regular 146.185.158.188:9999 - ok sync - - - +regular 146.185.180.40:9999 - ok sync - - - +regular 146.185.182.189:9999 - ok sync - - - +regular 146.190.33.135:9999 - ok sync - - - +regular 147.45.41.210:9999 - ok sync - - - +regular 147.93.131.52:9999 - ok sync - - - +regular 147.93.132.12:9999 - ok sync - - - +regular 147.182.146.51:9999 - ok sync - - - +regular 147.182.147.0:9999 - ok sync - - - +regular 148.113.202.169:9999 - ok sync - - - +regular 148.251.73.224:9999 - ok sync - - - +regular 148.251.73.232:9999 - ok sync - - - +regular 148.251.73.235:9999 - ok sync - - - +regular 148.251.73.238:9999 - ok sync - - - +regular 149.28.58.97:9999 - ok sync - - - +regular 149.28.85.41:9999 - ok sync - - - +regular 149.28.112.102:9999 - error ? - - - +regular 149.28.174.121:9999 - ok sync - - - +evo 149.28.223.171:9999 443 ok sync ok ok valid +regular 149.28.225.54:9999 - error ? - - - +evo 149.28.241.190:9999 443 ok sync ok ok expired +evo 149.28.247.165:9999 443 ok sync ok ok expired +evo 149.102.140.101:9999 443 ok sync ok ok valid +regular 149.248.3.156:9999 - ok sync - - - +regular 149.248.53.48:9999 - ok sync - - - +regular 151.244.85.0:9999 - ok sync - - - +regular 151.244.85.1:9999 - ok sync - - - +regular 151.244.85.7:9999 - ok sync - - - +regular 151.244.85.8:9999 - ok sync - - - +regular 151.244.85.9:9999 - ok sync - - - +regular 151.244.85.15:9999 - ok sync - - - +regular 151.244.85.31:9999 - ok sync - - - +regular 151.244.85.45:9999 - ok sync - - - +regular 151.244.85.47:9999 - ok sync - - - +regular 151.244.85.48:9999 - ok sync - - - +regular 151.244.85.64:9999 - ok sync - - - +regular 151.244.85.67:9999 - ok sync - - - +regular 151.244.85.68:9999 - ok sync - - - +regular 151.244.85.69:9999 - ok sync - - - +regular 151.244.85.70:9999 - ok sync - - - +regular 151.244.85.80:9999 - ok sync - - - +regular 151.244.85.81:9999 - ok sync - - - +regular 151.244.85.88:9999 - ok sync - - - +regular 151.244.85.96:9999 - ok sync - - - +regular 151.244.85.98:9999 - ok sync - - - +regular 151.244.85.111:9999 - ok sync - - - +regular 151.244.85.123:9999 - ok sync - - - +regular 151.244.85.131:9999 - ok sync - - - +regular 151.244.85.135:9999 - ok sync - - - +regular 151.244.85.141:9999 - ok sync - - - +regular 151.244.85.143:9999 - ok sync - - - +regular 151.244.85.147:9999 - ok sync - - - +regular 151.244.85.166:9999 - ok sync - - - +regular 151.244.85.178:9999 - ok sync - - - +regular 151.244.85.179:9999 - ok sync - - - +regular 151.244.85.181:9999 - ok sync - - - +regular 151.244.85.187:9999 - ok sync - - - +regular 151.244.85.190:9999 - ok sync - - - +regular 151.244.85.195:9999 - ok sync - - - +regular 151.244.85.197:9999 - ok sync - - - +regular 151.244.85.203:9999 - ok sync - - - +regular 151.244.85.205:9999 - ok sync - - - +regular 151.244.85.212:9999 - ok sync - - - +regular 151.244.85.213:9999 - ok sync - - - +regular 151.244.85.214:9999 - ok sync - - - +regular 151.244.85.217:9999 - ok sync - - - +regular 151.244.85.219:9999 - ok sync - - - +regular 151.244.85.220:9999 - ok sync - - - +regular 151.244.85.228:9999 - ok sync - - - +regular 151.244.85.229:9999 - ok sync - - - +regular 151.244.85.236:9999 - ok sync - - - +regular 151.244.85.244:9999 - ok sync - - - +regular 151.244.85.245:9999 - ok sync - - - +regular 151.244.85.255:9999 - ok sync - - - +regular 152.42.253.148:9999 - ok sync - - - +regular 152.67.95.184:9999 - ok sync - - - +regular 154.16.63.112:9999 - ok sync - - - +evo 155.133.26.122:9999 443 ok sync ok ok valid +regular 155.138.154.140:9999 - error ? - - - +evo 156.67.29.45:9999 443 ok sync ok ok valid +regular 157.90.150.75:9999 - ok sync - - - +evo 157.90.238.161:9999 443 ok sync ok ok valid +evo 157.173.122.20:9999 443 ok sync ok ok valid +evo 157.173.122.21:9999 443 ok sync ok ok valid +evo 157.173.122.25:9999 443 ok sync ok ok valid +evo 157.173.122.26:9999 443 ok sync ok ok valid +regular 157.180.91.78:9999 - ok sync - - - +regular 157.230.24.176:9999 - ok sync - - - +regular 157.230.113.158:9999 - ok sync - - - +regular 157.230.119.39:9999 - ok sync - - - +regular 157.230.244.227:9999 - ok sync - - - +regular 157.245.32.45:9999 - ok sync - - - +regular 157.245.34.149:9999 - ok sync - - - +regular 157.245.76.255:9999 - ok sync - - - +regular 157.245.158.11:9999 - ok sync - - - +regular 157.245.193.129:9999 - ok sync - - - +evo 158.220.101.10:9999 443 ok sync ok ok valid +evo 158.220.101.28:9999 443 ok sync ok ok valid +evo 158.247.208.247:9999 443 ok sync ok ok valid +evo 158.247.247.241:9999 443 ok sync ok ok valid +regular 159.65.2.7:9999 - ok sync - - - +regular 159.65.11.8:9999 - ok sync - - - +regular 159.65.21.48:9999 - ok sync - - - +regular 159.65.59.244:9999 - ok sync - - - +regular 159.65.81.125:9999 - ok sync - - - +regular 159.65.147.79:9999 - ok sync - - - +regular 159.65.155.91:9999 - ok sync - - - +evo 159.69.204.162:9999 443 ok sync ok ok expired +regular 159.75.121.163:9999 - ok sync - - - +regular 159.89.113.202:9999 - ok sync - - - +regular 159.89.122.128:9999 - ok sync - - - +regular 159.89.123.69:9999 - ok sync - - - +regular 159.89.174.239:9999 - ok sync - - - +regular 159.203.2.128:9999 - ok sync - - - +regular 159.203.4.177:9999 - ok sync - - - +regular 159.203.8.95:9999 - ok sync - - - +regular 159.203.33.3:9999 - ok sync - - - +regular 159.203.33.254:9999 - ok sync - - - +regular 159.203.39.201:9999 - ok sync - - - +regular 159.203.61.192:9999 - ok sync - - - +regular 159.223.60.121:9999 - ok sync - - - +regular 159.223.218.14:9999 - ok sync - - - +regular 159.223.218.50:9999 - ok sync - - - +regular 159.223.228.209:9999 - ok sync - - - +regular 161.35.17.210:9999 - ok sync - - - +regular 161.35.69.134:9999 - ok sync - - - +regular 161.35.94.177:9999 - ok sync - - - +regular 161.35.150.124:9999 - ok sync - - - +regular 161.35.168.34:9999 - ok sync - - - +regular 161.35.207.170:9999 - ok sync - - - +regular 161.35.213.210:9999 - ok sync - - - +regular 161.35.247.75:9999 - ok sync - - - +evo 161.97.66.31:9999 443 ok sync ok ok valid +regular 161.97.69.219:9999 - ok sync - - - +evo 161.97.70.66:9999 443 ok sync ok ok valid +evo 161.97.74.173:9999 443 ok sync ok ok valid +evo 161.97.75.36:9999 443 ok sync ok ok valid +evo 161.97.83.102:9999 443 ok sync ok ok valid +evo 161.97.85.159:9999 443 ok sync ok ok valid +evo 161.97.85.182:9999 443 ok sync ok ok valid +evo 161.97.88.199:9999 443 ok sync ok ok valid +evo 161.97.88.219:9999 443 ok sync ok ok valid +evo 161.97.91.68:9999 443 error ? timeout none no-handshake +evo 161.97.91.217:9999 443 ok sync ok ok valid +evo 161.97.96.120:9999 443 ok sync ok ok valid +evo 161.97.102.156:9999 443 ok sync ok ok valid +evo 161.97.104.37:9999 443 ok sync ok ok valid +evo 161.97.106.14:9999 443 ok sync ok ok valid +evo 161.97.106.164:9999 443 ok sync ok ok valid +evo 161.97.117.125:9999 443 ok sync ok ok valid +evo 161.97.120.156:9999 443 ok sync ok ok valid +regular 161.97.124.111:9999 - ok sync - - - +evo 161.97.142.210:9999 443 ok sync ok ok valid +evo 161.97.153.122:9999 443 ok sync ok ok valid +evo 161.97.159.172:9999 443 ok sync ok ok valid +evo 161.97.163.75:9999 443 ok sync ok ok valid +evo 161.97.165.115:9999 443 ok sync ok ok valid +evo 161.97.166.49:9999 443 ok sync ok ok valid +evo 161.97.173.67:9999 443 ok sync ok ok valid +evo 161.97.175.233:9999 443 ok sync ok ok valid +evo 161.97.176.38:9999 443 ok sync ok ok valid +evo 161.97.179.214:9999 443 ok sync ok ok valid +evo 161.97.180.105:9999 443 error ? timeout none no-handshake +evo 161.97.180.182:9999 443 ok sync ok ok valid +regular 162.212.35.99:9999 - ok sync - - - +evo 162.212.35.100:9999 443 ok sync ok ok valid +regular 162.212.35.101:9999 - error ? - - - +regular 162.212.35.102:9999 - error ? - - - +regular 162.212.35.103:9999 - error ? - - - +regular 162.212.35.104:9999 - error ? - - - +regular 162.212.35.105:9999 - error ? - - - +regular 162.212.35.106:9999 - error ? - - - +regular 162.212.35.107:9999 - ok sync - - - +regular 162.212.35.108:9999 - ok sync - - - +regular 162.212.35.109:9999 - ok sync - - - +regular 162.243.59.230:9999 - ok sync - - - +regular 162.243.76.23:9999 - ok sync - - - +regular 162.243.136.66:9999 - ok sync - - - +regular 162.243.205.212:9999 - ok sync - - - +regular 162.243.219.25:9999 - ok sync - - - +regular 163.172.66.41:9999 - ok sync - - - +evo 164.68.114.36:9999 443 ok sync ok ok valid +evo 164.68.118.37:9999 443 ok sync ok ok valid +regular 164.90.221.233:9999 - ok sync - - - +regular 164.92.160.130:9999 - ok sync - - - +regular 164.92.164.29:9999 - ok sync - - - +regular 164.92.175.210:9999 - ok sync - - - +regular 164.92.204.214:9999 - ok sync - - - +regular 164.92.249.64:9999 - ok sync - - - +regular 165.22.30.195:9999 - ok sync - - - +regular 165.22.62.28:9999 - ok sync - - - +regular 165.22.65.68:9999 - ok sync - - - +regular 165.22.107.61:9999 - ok sync - - - +regular 165.22.194.80:9999 - ok sync - - - +regular 165.22.208.146:9999 - ok sync - - - +regular 165.22.221.97:9999 - ok sync - - - +regular 165.22.227.208:9999 - ok sync - - - +regular 165.22.234.135:9999 - ok sync - - - +regular 165.22.236.90:9999 - ok sync - - - +regular 165.227.35.129:9999 - ok sync - - - +regular 165.227.43.54:9999 - ok sync - - - +regular 165.227.46.145:9999 - ok sync - - - +regular 165.227.166.196:9999 - ok sync - - - +regular 165.232.33.54:9999 - ok sync - - - +regular 165.232.95.72:9999 - ok sync - - - +regular 165.232.114.131:9999 - ok sync - - - +regular 165.232.187.22:9999 - ok sync - - - +regular 167.71.75.173:9999 - ok sync - - - +regular 167.71.76.44:9999 - ok sync - - - +regular 167.71.133.157:9999 - ok sync - - - +regular 167.71.143.5:9999 - ok sync - - - +regular 167.71.227.82:9999 - ok sync - - - +regular 167.71.228.155:9999 - ok sync - - - +regular 167.71.229.90:9999 - ok sync - - - +evo 167.86.77.58:9999 443 ok sync ok ok valid +evo 167.86.93.21:9999 443 ok sync ok ok valid +evo 167.86.94.138:9999 443 ok sync ok ok valid +evo 167.88.169.16:9999 443 ok sync ok ok valid +regular 167.99.73.247:9999 - ok sync - - - +regular 167.99.74.32:9999 - ok sync - - - +regular 167.99.177.115:9999 - ok sync - - - +regular 167.99.178.147:9999 - ok sync - - - +regular 167.99.182.250:9999 - ok sync - - - +regular 167.99.185.82:9999 - ok sync - - - +regular 167.99.199.59:9999 - ok sync - - - +regular 167.99.205.145:9999 - ok sync - - - +evo 167.114.153.110:9999 443 ok sync ok ok valid +regular 167.114.185.96:9999 - ok sync - - - +regular 167.172.45.235:9999 - ok sync - - - +regular 167.172.65.155:9999 - ok sync - - - +regular 167.172.67.55:9999 - ok sync - - - +regular 167.172.70.187:9999 - ok sync - - - +regular 167.172.87.128:9999 - ok sync - - - +regular 167.172.94.148:9999 - ok sync - - - +regular 167.172.183.190:9999 - ok sync - - - +evo 167.235.102.194:9999 443 ok sync ok ok valid +regular 167.235.132.126:9999 - ok sync - - - +regular 168.119.57.12:9999 - ok sync - - - +regular 168.119.80.0:9999 - ok sync - - - +regular 168.119.80.1:9999 - ok sync - - - +regular 168.119.80.3:9999 - ok sync - - - +regular 168.119.80.4:9999 - ok sync - - - +regular 168.119.80.5:9999 - ok sync - - - +regular 168.119.80.6:9999 - ok sync - - - +regular 168.119.80.7:9999 - ok sync - - - +regular 168.119.80.10:9999 - ok sync - - - +regular 168.119.80.12:9999 - ok sync - - - +regular 168.119.80.13:9999 - ok sync - - - +regular 168.119.80.15:9999 - ok sync - - - +regular 168.119.83.0:9999 - ok sync - - - +regular 168.119.83.2:9999 - ok sync - - - +regular 168.119.83.3:9999 - ok sync - - - +regular 168.119.83.6:9999 - ok sync - - - +regular 168.119.83.7:9999 - ok sync - - - +regular 168.119.83.8:9999 - ok sync - - - +regular 168.119.83.9:9999 - ok sync - - - +regular 168.119.83.10:9999 - ok sync - - - +regular 168.119.83.12:9999 - ok sync - - - +regular 168.119.83.13:9999 - ok sync - - - +regular 168.119.83.14:9999 - ok sync - - - +regular 168.119.83.17:9999 - ok sync - - - +regular 168.119.83.19:9999 - ok sync - - - +regular 168.119.87.129:9999 - ok sync - - - +regular 168.119.87.130:9999 - ok sync - - - +regular 168.119.87.131:9999 - ok sync - - - +regular 168.119.87.133:9999 - ok sync - - - +regular 168.119.87.134:9999 - ok sync - - - +regular 168.119.87.136:9999 - ok sync - - - +regular 168.119.87.137:9999 - ok sync - - - +regular 168.119.87.138:9999 - ok sync - - - +regular 168.119.87.146:9999 - ok sync - - - +regular 168.119.87.147:9999 - ok sync - - - +regular 168.119.87.149:9999 - ok sync - - - +regular 168.119.87.150:9999 - ok sync - - - +regular 168.119.87.152:9999 - ok sync - - - +regular 168.119.87.193:9999 - ok sync - - - +regular 168.119.87.194:9999 - ok sync - - - +regular 168.119.87.195:9999 - ok sync - - - +regular 168.119.87.196:9999 - ok sync - - - +regular 168.119.87.197:9999 - ok sync - - - +regular 168.119.87.198:9999 - ok sync - - - +regular 168.119.87.199:9999 - ok sync - - - +regular 168.119.87.202:9999 - ok sync - - - +regular 168.119.87.203:9999 - ok sync - - - +regular 168.119.87.204:9999 - ok sync - - - +regular 168.119.87.206:9999 - ok sync - - - +evo 168.119.102.10:9999 443 ok sync ok ok valid +regular 172.86.73.160:9999 - ok sync - - - +regular 172.86.91.158:9999 - ok sync - - - +regular 172.104.145.166:9999 - ok sync - - - +evo 172.236.244.81:9999 443 ok sync ok ok valid +evo 172.238.7.25:9999 443 ok sync ok ok valid +regular 172.245.111.223:9999 - ok sync - - - +evo 173.199.71.83:9999 443 ok sync ok ok valid +regular 173.199.119.21:9999 - ok sync - - - +evo 173.212.196.214:9999 443 ok sync ok ok valid +evo 173.212.231.230:9999 443 ok sync ok ok valid +evo 173.212.232.90:9999 443 ok sync ok ok valid +evo 173.212.245.118:9999 443 ok sync ok none valid +evo 173.212.251.130:9999 443 ok sync ok ok valid +regular 173.249.16.95:9999 - ok sync - - - +evo 173.249.21.12:9999 443 ok sync ok ok valid +regular 173.249.31.237:9999 - ok sync - - - +regular 173.249.33.131:9999 - ok sync - - - +regular 173.249.35.151:9999 - ok sync - - - +regular 173.249.40.168:9999 - ok sync - - - +regular 174.138.11.164:9999 - ok sync - - - +regular 174.138.24.25:9999 - ok sync - - - +regular 176.9.145.240:9999 - ok sync - - - +regular 176.9.210.0:9999 - ok sync - - - +regular 176.9.210.3:9999 - ok sync - - - +regular 176.9.210.4:9999 - ok sync - - - +regular 176.9.210.6:9999 - ok sync - - - +regular 176.9.210.9:9999 - ok sync - - - +regular 176.9.210.13:9999 - ok sync - - - +regular 176.9.210.14:9999 - ok sync - - - +regular 176.9.210.15:9999 - ok sync - - - +regular 176.9.210.19:9999 - ok sync - - - +regular 176.9.210.21:9999 - ok sync - - - +regular 176.9.210.22:9999 - ok sync - - - +regular 176.9.210.23:9999 - ok sync - - - +regular 176.102.65.145:9999 - ok sync - - - +evo 177.93.141.60:9999 443 ok sync ok ok expired +regular 177.93.141.86:9999 - ok sync - - - +evo 178.18.244.255:9999 443 ok sync ok ok valid +evo 178.18.254.136:9999 443 ok sync ok ok valid +regular 178.62.10.124:9999 - ok sync - - - +regular 178.62.45.13:9999 - ok sync - - - +regular 178.62.128.50:9999 - ok sync - - - +regular 178.62.128.51:9999 - ok sync - - - +regular 178.62.128.168:9999 - ok sync - - - +regular 178.62.129.5:9999 - ok sync - - - +regular 178.62.129.7:9999 - ok sync - - - +regular 178.62.149.161:9999 - ok sync - - - +regular 178.62.149.233:9999 - ok sync - - - +regular 178.62.152.222:9999 - ok sync - - - +regular 178.62.159.73:9999 - ok sync - - - +regular 178.62.159.196:9999 - ok sync - - - +regular 178.62.159.218:9999 - ok sync - - - +regular 178.62.159.219:9999 - ok sync - - - +regular 178.62.160.29:9999 - ok sync - - - +regular 178.62.161.176:9999 - ok sync - - - +regular 178.62.163.205:9999 - ok sync - - - +regular 178.62.165.80:9999 - ok sync - - - +regular 178.62.166.18:9999 - ok sync - - - +regular 178.62.171.16:9999 - ok sync - - - +regular 178.62.171.56:9999 - ok sync - - - +regular 178.62.171.57:9999 - ok sync - - - +regular 178.62.171.58:9999 - ok sync - - - +regular 178.62.171.59:9999 - ok sync - - - +regular 178.62.171.60:9999 - ok sync - - - +regular 178.62.171.69:9999 - ok sync - - - +regular 178.62.171.227:9999 - ok sync - - - +regular 178.62.172.188:9999 - ok sync - - - +regular 178.62.172.195:9999 - ok sync - - - +regular 178.62.172.196:9999 - ok sync - - - +regular 178.62.172.197:9999 - ok sync - - - +regular 178.62.180.8:9999 - ok sync - - - +regular 178.62.183.183:9999 - ok sync - - - +regular 178.62.186.23:9999 - ok sync - - - +regular 178.62.186.39:9999 - ok sync - - - +regular 178.62.192.42:9999 - ok sync - - - +regular 178.62.196.119:9999 - ok sync - - - +regular 178.62.200.153:9999 - ok sync - - - +regular 178.62.207.128:9999 - ok sync - - - +regular 178.62.209.128:9999 - ok sync - - - +regular 178.62.215.116:9999 - ok sync - - - +regular 178.62.220.199:9999 - ok sync - - - +regular 178.62.230.209:9999 - ok sync - - - +regular 178.62.236.233:9999 - ok sync - - - +regular 178.62.241.133:9999 - ok sync - - - +regular 178.62.244.17:9999 - ok sync - - - +regular 178.62.253.170:9999 - ok sync - - - +regular 178.63.121.128:9999 - ok sync - - - +regular 178.63.121.129:9999 - ok sync - - - +regular 178.63.121.132:9999 - ok sync - - - +regular 178.63.121.133:9999 - ok sync - - - +regular 178.63.121.134:9999 - ok sync - - - +regular 178.63.121.135:9999 - ok sync - - - +regular 178.63.121.136:9999 - ok sync - - - +regular 178.63.121.137:9999 - ok sync - - - +regular 178.63.121.140:9999 - ok sync - - - +regular 178.63.121.141:9999 - ok sync - - - +regular 178.63.121.147:9999 - ok sync - - - +regular 178.63.235.192:9999 - ok sync - - - +regular 178.63.235.193:9999 - ok sync - - - +regular 178.63.235.196:9999 - ok sync - - - +regular 178.63.235.197:9999 - ok sync - - - +regular 178.63.235.198:9999 - ok sync - - - +regular 178.63.235.199:9999 - ok sync - - - +regular 178.63.235.201:9999 - ok sync - - - +regular 178.63.236.96:9999 - ok sync - - - +regular 178.63.236.97:9999 - ok sync - - - +regular 178.63.236.99:9999 - ok sync - - - +regular 178.63.236.102:9999 - ok sync - - - +regular 178.63.236.103:9999 - ok sync - - - +regular 178.63.236.104:9999 - ok sync - - - +regular 178.63.236.105:9999 - ok sync - - - +regular 178.63.236.107:9999 - ok sync - - - +regular 178.63.236.108:9999 - ok sync - - - +regular 178.63.236.109:9999 - ok sync - - - +regular 178.63.236.110:9999 - ok sync - - - +regular 178.63.236.112:9999 - ok sync - - - +regular 178.63.236.114:9999 - ok sync - - - +regular 178.63.236.115:9999 - ok sync - - - +regular 178.63.236.116:9999 - ok sync - - - +regular 178.63.236.117:9999 - ok sync - - - +regular 178.63.236.118:9999 - ok sync - - - +regular 178.104.155.5:9999 - ok sync - - - +regular 178.128.40.87:9999 - ok sync - - - +regular 178.128.49.188:9999 - ok sync - - - +regular 178.128.80.241:9999 - ok sync - - - +regular 178.128.107.166:9999 - ok sync - - - +regular 178.128.111.214:9999 - ok sync - - - +regular 178.128.207.85:9999 - ok sync - - - +regular 178.128.207.219:9999 - ok sync - - - +regular 178.128.221.170:9999 - ok sync - - - +regular 178.128.223.175:9999 - ok sync - - - +regular 178.128.229.142:9999 - ok sync - - - +regular 178.128.230.210:9999 - ok sync - - - +regular 178.128.243.194:9999 - ok sync - - - +evo 178.157.91.177:9999 443 ok sync ok ok expired +evo 178.157.91.178:9999 443 ok sync ok ok expired +evo 178.157.91.184:9999 443 ok sync ok ok expired +regular 178.208.87.33:9999 - ok sync - - - +regular 178.208.87.72:9999 - ok sync - - - +regular 178.208.87.163:9999 - ok sync - - - +regular 178.208.87.213:9999 - ok sync - - - +regular 178.208.87.221:9999 - ok sync - - - +regular 178.208.87.225:9999 - ok sync - - - +regular 178.208.87.226:9999 - ok sync - - - +regular 178.208.87.231:9999 - ok sync - - - +regular 178.208.87.233:9999 - ok sync - - - +evo 178.215.237.134:9999 443 ok sync ok ok expired +evo 178.215.237.135:9999 443 ok sync ok ok expired +regular 178.253.253.5:9999 - ok sync - - - +regular 184.107.182.198:9999 - ok sync - - - +regular 185.28.101.145:9999 - ok sync - - - +regular 185.92.220.178:9999 - ok sync - - - +regular 185.112.249.49:9999 - ok sync - - - +regular 185.112.249.50:9999 - ok sync - - - +regular 185.112.249.51:9999 - ok sync - - - +regular 185.112.249.52:9999 - ok sync - - - +regular 185.112.249.53:9999 - ok sync - - - +regular 185.112.249.55:9999 - ok sync - - - +regular 185.164.163.55:9999 - ok sync - - - +regular 185.164.163.59:9999 - ok sync - - - +regular 185.164.163.85:9999 - ok sync - - - +regular 185.164.163.132:9999 - ok sync - - - +regular 185.164.163.133:9999 - ok sync - - - +regular 185.164.163.143:9999 - ok sync - - - +regular 185.164.163.217:9999 - ok sync - - - +regular 185.164.163.218:9999 - ok sync - - - +regular 185.164.163.220:9999 - ok sync - - - +regular 185.165.171.117:9999 - ok sync - - - +evo 185.166.217.154:9999 443 ok sync ok ok valid +regular 185.175.56.212:9999 - ok sync - - - +regular 185.185.40.14:9999 - ok sync - - - +regular 185.185.40.104:9999 - ok sync - - - +regular 185.185.40.115:9999 - ok sync - - - +regular 185.185.40.167:9999 - ok sync - - - +regular 185.185.40.171:9999 - ok sync - - - +evo 185.185.80.117:9999 443 ok sync ok ok valid +regular 185.193.19.214:9999 - ok sync - - - +evo 185.198.234.12:9999 443 ok sync ok ok expired +evo 185.198.234.17:9999 443 ok sync ok ok valid +regular 185.198.234.25:9999 - ok sync - - - +evo 185.202.236.58:9999 443 ok sync ok ok valid +evo 185.209.230.13:9999 443 ok sync ok ok valid +evo 185.215.164.84:9999 443 ok sync ok ok valid +evo 185.215.164.186:9999 443 ok sync ok ok valid +evo 185.215.166.126:9999 443 ok sync ok ok valid +regular 185.228.83.132:9999 - ok sync - - - +regular 185.228.83.156:9999 - ok sync - - - +evo 185.239.208.110:9999 443 ok sync ok ok valid +evo 185.239.209.6:9999 443 ok sync ok ok valid +regular 185.243.115.219:9999 - ok sync - - - +regular 185.252.232.103:9999 - ok sync - - - +evo 185.252.234.238:9999 443 ok sync ok ok valid +regular 188.40.21.227:9999 - ok sync - - - +regular 188.40.21.229:9999 - ok sync - - - +regular 188.40.21.231:9999 - ok sync - - - +regular 188.40.21.233:9999 - ok sync - - - +regular 188.40.21.234:9999 - ok sync - - - +regular 188.40.21.236:9999 - ok sync - - - +regular 188.40.21.237:9999 - ok sync - - - +regular 188.40.21.239:9999 - ok sync - - - +regular 188.40.21.242:9999 - ok sync - - - +regular 188.40.21.243:9999 - ok sync - - - +regular 188.40.21.244:9999 - ok sync - - - +regular 188.40.21.245:9999 - ok sync - - - +regular 188.40.21.246:9999 - ok sync - - - +regular 188.40.21.247:9999 - ok sync - - - +regular 188.40.21.248:9999 - ok sync - - - +regular 188.40.163.0:9999 - ok sync - - - +regular 188.40.163.1:9999 - ok sync - - - +regular 188.40.163.2:9999 - ok sync - - - +regular 188.40.163.3:9999 - ok sync - - - +regular 188.40.163.4:9999 - ok sync - - - +regular 188.40.163.5:9999 - ok sync - - - +regular 188.40.163.6:9999 - ok sync - - - +regular 188.40.163.7:9999 - ok sync - - - +regular 188.40.163.8:9999 - ok sync - - - +regular 188.40.163.9:9999 - ok sync - - - +regular 188.40.163.12:9999 - ok sync - - - +regular 188.40.163.15:9999 - ok sync - - - +regular 188.40.163.21:9999 - ok sync - - - +regular 188.40.163.24:9999 - ok sync - - - +regular 188.40.163.25:9999 - ok sync - - - +regular 188.40.163.26:9999 - ok sync - - - +regular 188.40.163.27:9999 - ok sync - - - +regular 188.40.163.28:9999 - ok sync - - - +regular 188.40.163.30:9999 - ok sync - - - +regular 188.40.163.31:9999 - ok sync - - - +regular 188.40.169.39:9999 - ok sync - - - +regular 188.40.169.44:9999 - ok sync - - - +regular 188.40.175.64:9999 - ok sync - - - +regular 188.40.175.65:9999 - ok sync - - - +regular 188.40.175.67:9999 - ok sync - - - +regular 188.40.175.68:9999 - ok sync - - - +regular 188.40.175.69:9999 - ok sync - - - +regular 188.40.175.71:9999 - ok sync - - - +regular 188.40.178.64:9999 - ok sync - - - +regular 188.40.178.66:9999 - ok sync - - - +regular 188.40.178.67:9999 - ok sync - - - +regular 188.40.178.69:9999 - ok sync - - - +regular 188.40.178.70:9999 - ok sync - - - +regular 188.40.178.71:9999 - ok sync - - - +regular 188.40.178.72:9999 - ok sync - - - +regular 188.40.178.73:9999 - ok sync - - - +regular 188.40.180.128:9999 - ok sync - - - +regular 188.40.180.129:9999 - ok sync - - - +regular 188.40.180.130:9999 - ok sync - - - +regular 188.40.180.132:9999 - ok sync - - - +regular 188.40.180.135:9999 - ok sync - - - +regular 188.40.180.138:9999 - ok sync - - - +regular 188.40.180.139:9999 - ok sync - - - +regular 188.40.180.140:9999 - ok sync - - - +regular 188.40.180.142:9999 - ok sync - - - +regular 188.40.182.192:9999 - ok sync - - - +regular 188.40.182.193:9999 - ok sync - - - +regular 188.40.182.194:9999 - ok sync - - - +regular 188.40.182.195:9999 - ok sync - - - +regular 188.40.182.196:9999 - ok sync - - - +regular 188.40.182.205:9999 - ok sync - - - +regular 188.40.182.207:9999 - ok sync - - - +regular 188.40.182.208:9999 - ok sync - - - +regular 188.40.182.209:9999 - ok sync - - - +regular 188.40.182.210:9999 - ok sync - - - +regular 188.40.182.211:9999 - ok sync - - - +regular 188.40.182.212:9999 - ok sync - - - +regular 188.40.182.213:9999 - ok sync - - - +regular 188.40.182.214:9999 - ok sync - - - +regular 188.40.182.215:9999 - ok sync - - - +regular 188.40.182.216:9999 - ok sync - - - +regular 188.40.182.220:9999 - ok sync - - - +regular 188.40.182.221:9999 - ok sync - - - +regular 188.40.182.222:9999 - ok sync - - - +regular 188.40.184.65:9999 - ok sync - - - +regular 188.40.184.67:9999 - ok sync - - - +regular 188.40.184.68:9999 - ok sync - - - +regular 188.40.184.72:9999 - ok sync - - - +regular 188.40.185.128:9999 - ok sync - - - +regular 188.40.185.129:9999 - ok sync - - - +regular 188.40.185.130:9999 - ok sync - - - +regular 188.40.185.131:9999 - ok sync - - - +regular 188.40.185.132:9999 - ok sync - - - +regular 188.40.185.133:9999 - ok sync - - - +regular 188.40.185.134:9999 - ok sync - - - +regular 188.40.185.137:9999 - ok sync - - - +regular 188.40.185.144:9999 - ok sync - - - +regular 188.40.185.147:9999 - ok sync - - - +regular 188.40.190.38:9999 - ok sync - - - +regular 188.40.190.39:9999 - ok sync - - - +regular 188.40.190.40:9999 - ok sync - - - +regular 188.40.190.41:9999 - ok sync - - - +regular 188.40.190.49:9999 - ok sync - - - +regular 188.40.190.52:9999 - ok sync - - - +regular 188.40.190.55:9999 - ok sync - - - +regular 188.40.190.56:9999 - ok sync - - - +regular 188.40.205.3:9999 - ok sync - - - +regular 188.40.205.5:9999 - ok sync - - - +regular 188.40.205.6:9999 - ok sync - - - +regular 188.40.205.8:9999 - ok sync - - - +regular 188.40.205.10:9999 - ok sync - - - +regular 188.40.205.11:9999 - ok sync - - - +regular 188.40.205.13:9999 - ok sync - - - +regular 188.40.205.18:9999 - ok sync - - - +regular 188.40.205.19:9999 - ok sync - - - +regular 188.40.231.1:9999 - ok sync - - - +regular 188.40.231.2:9999 - ok sync - - - +regular 188.40.231.3:9999 - ok sync - - - +regular 188.40.231.5:9999 - ok sync - - - +regular 188.40.231.8:9999 - ok sync - - - +regular 188.40.231.9:9999 - ok sync - - - +regular 188.40.231.10:9999 - ok sync - - - +regular 188.40.231.12:9999 - ok sync - - - +regular 188.40.231.18:9999 - ok sync - - - +regular 188.40.231.20:9999 - ok sync - - - +regular 188.40.231.22:9999 - ok sync - - - +regular 188.40.241.97:9999 - ok sync - - - +regular 188.40.241.99:9999 - ok sync - - - +regular 188.40.241.101:9999 - ok sync - - - +regular 188.40.241.102:9999 - ok sync - - - +regular 188.40.241.103:9999 - ok sync - - - +regular 188.40.241.104:9999 - ok sync - - - +regular 188.40.241.107:9999 - ok sync - - - +regular 188.40.241.112:9999 - ok sync - - - +regular 188.40.241.114:9999 - ok sync - - - +regular 188.40.241.115:9999 - ok sync - - - +regular 188.40.241.116:9999 - ok sync - - - +regular 188.40.241.117:9999 - ok sync - - - +regular 188.40.241.118:9999 - ok sync - - - +regular 188.40.241.119:9999 - ok sync - - - +regular 188.40.241.122:9999 - ok sync - - - +regular 188.40.251.193:9999 - ok sync - - - +regular 188.40.251.195:9999 - ok sync - - - +regular 188.40.251.196:9999 - ok sync - - - +regular 188.40.251.197:9999 - ok sync - - - +regular 188.40.251.198:9999 - ok sync - - - +regular 188.40.251.200:9999 - ok sync - - - +regular 188.40.251.202:9999 - ok sync - - - +regular 188.40.251.203:9999 - ok sync - - - +regular 188.40.251.204:9999 - ok sync - - - +regular 188.40.251.205:9999 - ok sync - - - +regular 188.40.251.206:9999 - ok sync - - - +regular 188.40.251.207:9999 - ok sync - - - +regular 188.40.251.208:9999 - ok sync - - - +regular 188.40.251.209:9999 - ok sync - - - +regular 188.40.251.211:9999 - ok sync - - - +regular 188.40.251.212:9999 - ok sync - - - +regular 188.40.251.213:9999 - ok sync - - - +regular 188.40.251.214:9999 - ok sync - - - +regular 188.40.251.216:9999 - ok sync - - - +regular 188.40.251.217:9999 - ok sync - - - +regular 188.40.251.218:9999 - ok sync - - - +regular 188.40.251.219:9999 - ok sync - - - +regular 188.40.251.221:9999 - ok sync - - - +regular 188.40.251.223:9999 - ok sync - - - +regular 188.166.0.242:9999 - ok sync - - - +regular 188.166.1.179:9999 - ok sync - - - +regular 188.166.5.179:9999 - ok sync - - - +regular 188.166.5.202:9999 - ok sync - - - +regular 188.166.8.181:9999 - ok sync - - - +regular 188.166.21.185:9999 - ok sync - - - +regular 188.166.30.248:9999 - ok sync - - - +regular 188.166.33.180:9999 - ok sync - - - +regular 188.166.54.247:9999 - ok sync - - - +regular 188.166.56.220:9999 - ok sync - - - +regular 188.166.60.137:9999 - ok sync - - - +regular 188.166.61.118:9999 - ok sync - - - +regular 188.166.73.248:9999 - ok sync - - - +regular 188.166.77.65:9999 - ok sync - - - +regular 188.166.77.93:9999 - ok sync - - - +regular 188.166.85.205:9999 - ok sync - - - +regular 188.166.91.57:9999 - ok sync - - - +regular 188.166.106.130:9999 - ok sync - - - +regular 188.166.160.236:9999 - ok sync - - - +regular 188.166.188.42:9999 - ok sync - - - +regular 188.166.190.208:9999 - ok sync - - - +regular 188.166.218.79:9999 - ok sync - - - +regular 188.226.156.220:9999 - ok sync - - - +regular 188.226.161.128:9999 - ok sync - - - +regular 188.226.180.119:9999 - ok sync - - - +regular 188.226.196.182:9999 - ok sync - - - +regular 188.226.201.140:9999 - ok sync - - - +regular 188.226.210.144:9999 - ok sync - - - +regular 188.226.224.233:9999 - ok sync - - - +regular 188.226.228.88:9999 - ok sync - - - +regular 188.244.117.12:9999 - ok sync - - - +evo 188.245.90.255:9999 443 ok sync ok ok valid +regular 191.101.2.231:9999 - ok sync - - - +evo 192.95.32.205:9999 443 ok sync ok ok expired +regular 192.169.6.87:9999 - ok sync - - - +evo 192.175.127.198:9999 443 ok sync ok ok expired +regular 192.241.194.154:9999 - ok sync - - - +regular 192.241.217.126:9999 - ok sync - - - +regular 192.248.169.180:9999 - ok sync - - - +evo 192.248.175.198:9999 443 ok sync ok ok valid +evo 192.248.178.237:9999 443 ok sync ok ok valid +regular 192.248.189.66:9999 - ok sync - - - +evo 193.70.43.172:9999 443 ok sync ok ok valid +regular 193.160.119.129:9999 - ok sync - - - +regular 194.5.157.214:9999 - ok sync - - - +regular 194.135.80.33:9999 - ok sync - - - +regular 194.135.84.100:9999 - ok sync - - - +regular 194.135.94.228:9999 - ok sync - - - +evo 194.163.156.190:9999 443 ok sync ok ok valid +evo 194.163.159.171:9999 443 ok sync ok ok valid +evo 194.163.166.76:9999 443 ok sync ok ok valid +evo 194.163.172.206:9999 443 ok sync ok ok valid +regular 194.163.183.132:9999 - ok sync - - - +evo 195.26.254.228:9999 443 ok sync ok ok valid +regular 195.98.95.210:9999 - ok sync - - - +regular 195.201.35.7:9999 - ok sync - - - +evo 195.201.238.55:9999 443 ok sync ok ok valid +regular 198.12.92.214:9999 - ok sync - - - +regular 198.199.119.50:9999 - ok sync - - - +regular 198.199.124.50:9999 - ok sync - - - +regular 198.211.119.126:9999 - ok sync - - - +regular 198.244.213.69:9999 - ok sync - - - +regular 198.251.79.146:9999 - ok sync - - - +regular 202.5.16.33:9999 - ok sync - - - +evo 202.71.14.79:9999 443 ok sync ok ok valid +regular 202.182.105.95:9999 - ok sync - - - +regular 202.182.115.161:9999 - ok sync - - - +regular 205.206.173.159:9999 - ok sync - - - +regular 205.206.254.21:9999 - ok sync - - - +regular 205.206.255.206:9999 - ok sync - - - +regular 206.189.21.120:9999 - error ? - - - +regular 206.189.28.109:9999 - ok sync - - - +regular 206.189.112.246:9999 - ok sync - - - +regular 206.189.134.126:9999 - ok sync - - - +regular 206.189.136.218:9999 - ok sync - - - +regular 206.189.143.107:9999 - ok sync - - - +evo 206.245.167.74:9999 443 ok sync ok ok valid +evo 206.245.167.76:9999 443 ok sync ok ok valid +regular 207.148.5.10:9999 - ok sync - - - +regular 207.148.78.131:9999 - ok sync - - - +regular 207.154.204.134:9999 - ok sync - - - +regular 207.154.207.223:9999 - ok sync - - - +regular 207.154.214.156:9999 - ok sync - - - +regular 207.154.226.228:9999 - ok sync - - - +regular 207.154.227.241:9999 - ok sync - - - +regular 207.154.229.81:9999 - ok sync - - - +regular 207.154.235.44:9999 - ok sync - - - +evo 207.180.213.141:9999 443 ok sync ok ok valid +evo 207.180.218.245:9999 443 ok sync ok ok valid +regular 207.180.224.34:9999 - ok sync - - - +evo 207.180.224.96:9999 443 ok sync ok ok valid +regular 207.180.227.146:9999 - ok sync - - - +evo 207.180.233.6:9999 443 ok sync ok ok valid +evo 207.180.233.246:9999 443 ok sync ok ok valid +regular 207.180.237.66:9999 - ok sync - - - +evo 207.180.241.242:9999 443 ok sync ok ok valid +evo 207.244.247.40:9999 443 ok sync ok ok valid +regular 208.87.98.19:9999 - ok sync - - - +regular 208.87.98.21:9999 - ok sync - - - +regular 208.87.102.81:9999 - ok sync - - - +regular 208.87.102.86:9999 - ok sync - - - +regular 208.87.102.89:9999 - ok sync - - - +regular 208.87.102.91:9999 - ok sync - - - +regular 208.87.102.95:9999 - ok sync - - - +regular 209.38.120.93:9999 - ok sync - - - +regular 209.38.217.42:9999 - ok sync - - - +regular 209.38.226.76:9999 - ok sync - - - +regular 209.97.142.65:9999 - ok sync - - - +regular 209.141.36.206:9999 - ok sync - - - +regular 209.250.240.73:9999 - ok sync - - - +regular 212.24.104.225:9999 - ok sync - - - +regular 212.24.109.253:9999 - ok sync - - - +regular 213.136.91.123:9999 - ok sync - - - +evo 213.159.77.221:9999 443 ok sync ok ok valid +evo 213.199.44.112:9999 443 ok sync ok ok valid +evo 213.199.53.161:9999 443 ok sync ok ok valid +evo 213.199.54.34:9999 443 ok sync ok ok valid +evo 213.199.54.35:9999 443 ok sync ok ok valid +evo 213.199.54.37:9999 443 ok sync ok ok valid +evo 213.199.54.171:9999 443 ok sync ok ok valid +regular 213.199.56.113:9999 - ok sync - - - +regular 216.128.177.156:9999 - ok sync - - - +regular 216.128.180.106:9999 - ok sync - - - +regular 216.189.154.44:9999 - ok sync - - - +regular 216.189.154.59:9999 - ok sync - - - +regular 216.189.154.74:9999 - ok sync - - - +regular 216.189.154.76:9999 - ok sync - - - +regular 216.189.157.22:9999 - ok sync - - - +regular 216.189.157.131:9999 - ok sync - - - +regular 216.189.157.210:9999 - ok sync - - - +regular 216.230.232.125:9999 - ok sync - - - +regular 216.238.73.67:9999 - ok sync - - - +evo 216.238.75.46:9999 443 ok sync ok ok valid +regular 216.238.79.28:9999 - ok sync - - - +regular 216.238.82.102:9999 - ok sync - - - +regular 216.238.82.108:9999 - ok sync - - - +regular 216.238.85.93:9999 - ok sync - - - +regular 216.238.85.238:9999 - ok sync - - - +evo 216.238.99.9:9999 443 ok sync ok ok valid +regular 217.69.5.141:9999 - ok sync - - - +evo 217.76.54.175:9999 443 ok sync ok ok valid diff --git a/dash-network-seeds/seeds/testnet.txt b/dash-network-seeds/seeds/testnet.txt new file mode 100644 index 000000000..37c453b77 --- /dev/null +++ b/dash-network-seeds/seeds/testnet.txt @@ -0,0 +1,96 @@ +# Auto-generated by masternode-seeds-fetcher on 2026-04-23T09:36:05Z for testnet +# Source: Dash P2P network (mnlistdiff) +# Primary peer: 68.67.122.21:19999 +# Tip block hash: 00000019c99229ca7308c36585d1986897c1e559c11f257ba3344deadb3aebd9 +# Tip block height: 1463660 +# 86 seeds (55 regular + 31 evo) of 543 total masternodes, valid-only +# Probe summary: core_reachable=85/86 platform_reachable=31/31 ssl_valid=28/31 +# Columns: +# Values: core_reach/plat_reach=ok|timeout|refused|error|?, core_sync=sync|-N|+N|?, plat_live=ok|none|?|-, plat_ssl=valid|expired|self-signed|untrusted|no-handshake|?|- +# Do not edit manually — refreshed weekly by .github/workflows/update-masternode-seeds.yml +evo 68.67.122.1:19999 1443 ok sync ok ok expired +evo 68.67.122.2:19999 1443 ok sync ok ok valid +evo 68.67.122.3:19999 1443 ok sync ok ok valid +evo 68.67.122.4:19999 1443 ok sync ok ok valid +evo 68.67.122.5:19999 1443 ok sync ok ok valid +evo 68.67.122.6:19999 1443 ok sync ok ok valid +evo 68.67.122.7:19999 1443 ok sync ok ok valid +evo 68.67.122.8:19999 1443 ok sync ok ok valid +evo 68.67.122.9:19999 1443 ok sync ok ok valid +evo 68.67.122.10:19999 1443 ok sync ok ok valid +evo 68.67.122.11:19999 1443 ok sync ok ok valid +evo 68.67.122.12:19999 1443 ok sync ok ok valid +evo 68.67.122.13:19999 1443 ok sync ok ok valid +evo 68.67.122.14:19999 1443 ok sync ok ok valid +evo 68.67.122.15:19999 1443 ok sync ok ok valid +evo 68.67.122.16:19999 1443 ok sync ok ok valid +evo 68.67.122.17:19999 1443 ok sync ok ok valid +evo 68.67.122.18:19999 1443 ok sync ok ok valid +evo 68.67.122.19:19999 1443 ok sync ok ok valid +evo 68.67.122.20:19999 1443 ok sync ok ok valid +evo 68.67.122.21:19999 1443 ok sync ok ok valid +evo 68.67.122.22:19999 1443 ok sync ok ok valid +evo 68.67.122.23:19999 1443 ok sync ok ok valid +evo 68.67.122.24:19999 1443 ok sync ok ok valid +evo 68.67.122.25:19999 1443 ok sync ok ok valid +evo 68.67.122.26:19999 1443 ok sync ok ok valid +evo 68.67.122.27:19999 1443 ok sync ok ok valid +evo 68.67.122.28:19999 1443 ok sync ok ok valid +evo 68.67.122.29:19999 1443 ok sync ok ok valid +regular 68.67.122.30:19999 - ok sync - - - +regular 68.67.122.31:19999 - ok sync - - - +regular 68.67.122.32:19999 - ok sync - - - +regular 68.67.122.33:19999 - ok sync - - - +regular 68.67.122.34:19999 - ok sync - - - +regular 68.67.122.35:19999 - ok sync - - - +regular 68.67.122.36:19999 - ok sync - - - +regular 68.67.122.37:19999 - ok sync - - - +regular 68.67.122.38:19999 - ok sync - - - +regular 68.67.122.39:19999 - ok sync - - - +regular 68.67.122.40:19999 - ok sync - - - +regular 68.67.122.41:19999 - ok sync - - - +regular 68.67.122.42:19999 - ok sync - - - +regular 68.67.122.43:19999 - ok sync - - - +regular 68.67.122.44:19999 - ok sync - - - +regular 68.67.122.45:19999 - ok sync - - - +regular 68.67.122.46:19999 - ok sync - - - +regular 68.67.122.47:19999 - ok sync - - - +regular 68.67.122.48:19999 - ok sync - - - +regular 68.67.122.49:19999 - ok sync - - - +regular 68.67.122.50:19999 - ok sync - - - +regular 68.67.122.51:19999 - ok sync - - - +regular 68.67.122.52:19999 - ok sync - - - +regular 68.67.122.53:19999 - ok sync - - - +regular 68.67.122.54:19999 - ok sync - - - +regular 68.67.122.55:19999 - ok sync - - - +regular 68.67.122.56:19999 - timeout ? - - - +regular 68.67.122.57:19999 - ok sync - - - +regular 68.67.122.58:19999 - ok sync - - - +regular 68.67.122.59:19999 - ok sync - - - +regular 68.67.122.60:19999 - ok sync - - - +regular 68.67.122.61:19999 - ok sync - - - +regular 68.67.122.62:19999 - ok sync - - - +regular 68.67.122.63:19999 - ok sync - - - +regular 68.67.122.64:19999 - ok sync - - - +regular 68.67.122.65:19999 - ok sync - - - +regular 68.67.122.66:19999 - ok sync - - - +regular 68.67.122.67:19999 - ok sync - - - +regular 68.67.122.68:19999 - ok sync - - - +regular 68.67.122.69:19999 - ok sync - - - +regular 68.67.122.70:19999 - ok sync - - - +regular 68.67.122.71:19999 - ok sync - - - +regular 68.67.122.72:19999 - ok sync - - - +regular 68.67.122.73:19999 - ok sync - - - +regular 68.67.122.74:19999 - ok sync - - - +regular 68.67.122.75:19999 - ok sync - - - +regular 68.67.122.76:19999 - ok sync - - - +regular 68.67.122.77:19999 - ok sync - - - +regular 68.67.122.78:19999 - ok sync - - - +regular 68.67.122.79:19999 - ok sync - - - +regular 68.67.122.80:19999 - ok sync - - - +regular 68.67.122.81:19999 - ok sync - - - +regular 68.67.122.82:19999 - ok sync - - - +regular 147.93.132.9:19999 - ok sync - - - +regular 185.187.169.193:19999 - ok sync - - - +evo 206.245.167.63:19999 1443 ok sync ok ok self-signed +evo 212.47.68.199:19999 1443 ok sync ok ok expired diff --git a/dash-network-seeds/src/lib.rs b/dash-network-seeds/src/lib.rs new file mode 100644 index 000000000..d3c001ea1 --- /dev/null +++ b/dash-network-seeds/src/lib.rs @@ -0,0 +1,652 @@ +//! Hardcoded masternode seed lists for Dash mainnet and testnet. +//! +//! The seed lists are regenerated weekly by CI from the live Dash P2P network +//! using the `masternode-seeds-fetcher` tool. Alongside each masternode +//! address the file records the type (regular / evo) and best-effort probe +//! results captured at the moment the list was refreshed: +//! +//! * **Core reachability** — TCP + P2P handshake to the advertised Core port. +//! * **Core sync** — the peer's `start_height` compared to a reference tip. +//! * **Platform reachability** — TCP + TLS to the advertised platform HTTP +//! port (Evo nodes only). +//! * **Platform liveness** — whether the platform HTTP endpoint responds to a +//! baseline HTTP request (Evo nodes only). +//! * **Platform SSL** — the health of the presented X.509 certificate +//! (Evo nodes only). +//! +//! Consumers that just need a bootstrap peer list can still ignore the +//! probe fields and treat this crate as a plain `Vec` source +//! via [`addresses`] or [`reachable_addresses`]. +//! +//! # Example +//! +//! ```rust +//! use dash_network_seeds::{MasternodeType, Reachability, reachable_seeds, seeds}; +//! use dash_network::Network; +//! +//! let all = seeds(Network::Mainnet); +//! assert!(!all.is_empty()); +//! // Only entries whose Core port answered our last probe: +//! let live = reachable_seeds(Network::Mainnet); +//! assert!(live.len() <= all.len()); +//! # let _ = (live, MasternodeType::Evo, Reachability::Ok); +//! ``` +//! +//! # File format +//! +//! Plain text, one seed per line. Lines beginning with `#` and blank lines +//! are ignored. Each data line is space-separated with fixed columns: +//! +//! ```text +//! +//! ``` +//! +//! where: +//! +//! | column | values | +//! |--------|--------| +//! | `type` | `regular`, `evo` | +//! | `addr` | `ip:port` for the Core P2P port | +//! | `platform_http_port` | `u16` for Evo; `-` for regular | +//! | `core_reach`, `plat_reach` | `ok`, `timeout`, `refused`, `error`, `?` | +//! | `core_sync` | `sync`, `-N` (behind), `+N` (ahead), `?` | +//! | `plat_live` | `ok`, `none`, `?`, `-` (regular) | +//! | `plat_ssl` | `valid`, `expired`, `self-signed`, `untrusted`, `no-handshake`, `?`, `-` (regular) | +//! +//! Backwards-compatible legacy formats are still accepted on parse: lines +//! with just `` default to regular + unknown status, lines with just +//! ` ` default to unknown status. + +#![forbid(unsafe_code)] + +use dash_network::Network; +use std::fmt; +use std::net::{IpAddr, SocketAddr}; + +/// Raw embedded seed file contents, as a `&'static str`. +pub const fn raw_seed_file(network: &Network) -> &'static str { + match network { + Network::Mainnet => MAINNET_SEED_FILE, + Network::Testnet => TESTNET_SEED_FILE, + _ => "", + } +} + +// ---------- MasternodeType ---------- + +/// Masternode type as encoded in a seed entry. +/// +/// The underlying protocol uses `EntryMasternodeType::HighPerformance` for +/// what Dash Platform documentation, users, and the Dash Core RPC all refer +/// to as an "Evo" or "HPMN". This crate uses "Evo" because that's the +/// ecosystem-facing name. +#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +pub enum MasternodeType { + /// Regular masternode. + Regular, + /// Evo (a.k.a. HPMN) masternode — runs Dash Platform alongside Core. + Evo, +} + +impl MasternodeType { + /// Parse the seed-file token (`"regular"` or `"evo"`, case-insensitive). + pub fn parse(token: &str) -> Option { + match token.to_ascii_lowercase().as_str() { + "regular" => Some(MasternodeType::Regular), + "evo" | "hpmn" | "highperformance" => Some(MasternodeType::Evo), + _ => None, + } + } + + /// The seed-file token for this type. + pub const fn as_str(self) -> &'static str { + match self { + MasternodeType::Regular => "regular", + MasternodeType::Evo => "evo", + } + } +} + +// ---------- Status enums ---------- + +/// Result of a reachability probe. +#[derive(Copy, Clone, Debug, Default, Hash, PartialEq, Eq)] +pub enum Reachability { + /// Not probed. + #[default] + Unknown, + /// TCP (and, where applicable, handshake/TLS) completed successfully. + Ok, + /// Connect attempt did not finish in time. + Timeout, + /// Peer actively refused the connection. + Refused, + /// Other error (protocol, I/O) while probing. + Error, +} + +impl Reachability { + /// Short token used in the seed file. + pub const fn as_str(self) -> &'static str { + match self { + Reachability::Unknown => "?", + Reachability::Ok => "ok", + Reachability::Timeout => "timeout", + Reachability::Refused => "refused", + Reachability::Error => "error", + } + } + + fn parse(token: &str) -> Option { + Some(match token { + "?" => Reachability::Unknown, + "ok" => Reachability::Ok, + "timeout" => Reachability::Timeout, + "refused" => Reachability::Refused, + "error" => Reachability::Error, + _ => return None, + }) + } +} + +/// A peer's chain-tip relationship to a reference height captured during the +/// same run. +/// +/// Only meaningful for Core (we have a reliable tip height from the primary +/// `mnlistdiff` exchange). Platform does not currently support this level +/// of detail in the seed file. +#[derive(Copy, Clone, Debug, Default, Hash, PartialEq, Eq)] +pub enum SyncStatus { + /// Not probed. + #[default] + Unknown, + /// Within a small delta (default ±10 blocks) of the reference tip. + Synced, + /// `n` blocks behind the reference tip. + Behind(u32), + /// `n` blocks ahead of the reference tip (unusual; peer had a fresher + /// block than our reference). + Ahead(u32), +} + +impl SyncStatus { + /// Short token used in the seed file. + pub fn as_string(self) -> String { + match self { + SyncStatus::Unknown => "?".to_string(), + SyncStatus::Synced => "sync".to_string(), + SyncStatus::Behind(n) => format!("-{}", n), + SyncStatus::Ahead(n) => format!("+{}", n), + } + } + + fn parse(token: &str) -> Option { + if token == "?" { + return Some(SyncStatus::Unknown); + } + if token == "sync" { + return Some(SyncStatus::Synced); + } + if let Some(rest) = token.strip_prefix('-') { + return rest.parse().ok().map(SyncStatus::Behind); + } + if let Some(rest) = token.strip_prefix('+') { + return rest.parse().ok().map(SyncStatus::Ahead); + } + None + } +} + +/// Whether the platform HTTP port served *any* HTTP response during the +/// probe. +/// +/// We do not parse the response body. `Ok` just means the server answered +/// with an HTTP status line (2xx/3xx/4xx/5xx); `None` means the TLS layer +/// came up but no HTTP response arrived before the timeout. +#[derive(Copy, Clone, Debug, Default, Hash, PartialEq, Eq)] +pub enum PlatformLiveness { + /// Not probed. + #[default] + Unknown, + /// Server answered with an HTTP status line. + Ok, + /// No HTTP response received. + None, +} + +impl PlatformLiveness { + /// Short token used in the seed file. + pub const fn as_str(self) -> &'static str { + match self { + PlatformLiveness::Unknown => "?", + PlatformLiveness::Ok => "ok", + PlatformLiveness::None => "none", + } + } + + fn parse(token: &str) -> Option { + Some(match token { + "?" => PlatformLiveness::Unknown, + "ok" => PlatformLiveness::Ok, + "none" => PlatformLiveness::None, + _ => return None, + }) + } +} + +/// Platform TLS certificate health. +/// +/// Hostname verification is deliberately **not** performed: seed entries are +/// keyed by IP address, so the presented cert's Subject/SAN almost always +/// doesn't match. The probe instead checks the certificate's self-described +/// validity (expiration, self-signedness, chain trust). +#[derive(Copy, Clone, Debug, Default, Hash, PartialEq, Eq)] +pub enum SslStatus { + /// Not probed. + #[default] + Unknown, + /// Chain verified, not expired. + Valid, + /// Cert is past its `notAfter` timestamp. + Expired, + /// Leaf cert is its own issuer. + SelfSigned, + /// Chain did not verify against the system root store (and is not + /// self-signed). + Untrusted, + /// TLS handshake failed before we could see a certificate. + NoHandshake, +} + +impl SslStatus { + /// Short token used in the seed file. + pub const fn as_str(self) -> &'static str { + match self { + SslStatus::Unknown => "?", + SslStatus::Valid => "valid", + SslStatus::Expired => "expired", + SslStatus::SelfSigned => "self-signed", + SslStatus::Untrusted => "untrusted", + SslStatus::NoHandshake => "no-handshake", + } + } + + fn parse(token: &str) -> Option { + Some(match token { + "?" => SslStatus::Unknown, + "valid" => SslStatus::Valid, + "expired" => SslStatus::Expired, + "self-signed" => SslStatus::SelfSigned, + "untrusted" => SslStatus::Untrusted, + "no-handshake" => SslStatus::NoHandshake, + _ => return None, + }) + } +} + +// ---------- Core / Platform status composites ---------- + +/// Core probe summary. +#[derive(Copy, Clone, Debug, Default, Hash, PartialEq, Eq)] +pub struct CoreStatus { + pub reachable: Reachability, + pub synced: SyncStatus, +} + +/// Platform probe summary (Evo masternodes only). +#[derive(Copy, Clone, Debug, Default, Hash, PartialEq, Eq)] +pub struct PlatformStatus { + pub reachable: Reachability, + pub live: PlatformLiveness, + pub ssl: SslStatus, +} + +// ---------- MasternodeSeed ---------- + +/// A single masternode seed entry. +#[derive(Clone, Debug, Hash, PartialEq, Eq)] +pub struct MasternodeSeed { + /// The masternode's advertised Core P2P service address. + pub address: SocketAddr, + /// Whether this masternode is a regular or Evo (HPMN) node. + pub mn_type: MasternodeType, + /// Evo masternodes advertise a platform HTTP port. `None` for regular. + pub platform_http_port: Option, + /// Result of the most recent Core probe (or all-`Unknown` if not probed). + pub core: CoreStatus, + /// Result of the most recent Platform probe. `None` for regular nodes. + pub platform: Option, +} + +impl MasternodeSeed { + /// Format this seed as a single seed-file line (no trailing newline). + pub fn to_line(&self) -> String { + let http = match self.platform_http_port { + Some(p) => p.to_string(), + None => "-".to_string(), + }; + let (plat_reach, plat_live, plat_ssl) = match self.platform { + Some(p) => ( + p.reachable.as_str().to_string(), + p.live.as_str().to_string(), + p.ssl.as_str().to_string(), + ), + None => ("-".to_string(), "-".to_string(), "-".to_string()), + }; + format!( + "{} {} {} {} {} {} {} {}", + self.mn_type.as_str(), + self.address, + http, + self.core.reachable.as_str(), + self.core.synced.as_string(), + plat_reach, + plat_live, + plat_ssl, + ) + } +} + +impl fmt::Display for MasternodeSeed { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.to_line()) + } +} + +impl PartialOrd for MasternodeSeed { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for MasternodeSeed { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + // Sort primarily by address (stable across probe-result churn) then + // type. Probe fields are deliberately *not* part of the sort so that + // seed-file diffs are dominated by membership churn, not status. + self.address.cmp(&other.address).then_with(|| self.mn_type.cmp(&other.mn_type)) + } +} + +// ---------- Embedded files ---------- + +const MAINNET_SEED_FILE: &str = include_str!("../seeds/mainnet.txt"); +const TESTNET_SEED_FILE: &str = include_str!("../seeds/testnet.txt"); + +// ---------- Public API ---------- + +/// Return all hardcoded masternode seeds for the given network. +pub fn seeds(network: Network) -> Vec { + parse(raw_seed_file(&network), network.default_p2p_port()) +} + +/// Return just the socket addresses for all hardcoded masternode seeds, +/// dropping type and probe information. +pub fn addresses(network: Network) -> Vec { + seeds(network).into_iter().map(|s| s.address).collect() +} + +/// Return only Evo (HPMN) masternode seeds. +pub fn evo_seeds(network: Network) -> Vec { + seeds(network).into_iter().filter(|s| s.mn_type == MasternodeType::Evo).collect() +} + +/// Return only regular masternode seeds. +pub fn regular_seeds(network: Network) -> Vec { + seeds(network).into_iter().filter(|s| s.mn_type == MasternodeType::Regular).collect() +} + +/// Return seeds whose last Core probe reported the node reachable. Useful +/// as a "liveliest" bootstrap list. +pub fn reachable_seeds(network: Network) -> Vec { + seeds(network).into_iter().filter(|s| s.core.reachable == Reachability::Ok).collect() +} + +/// Return just the Core socket addresses of seeds whose last probe reported +/// the node reachable. +pub fn reachable_addresses(network: Network) -> Vec { + reachable_seeds(network).into_iter().map(|s| s.address).collect() +} + +/// Parse a seed-file body (as produced by `masternode-seeds-fetcher`) into a +/// list of entries. Exposed for tooling — library consumers should usually +/// call [`seeds`] instead. +/// +/// Accepts the current rich format *and* legacy 1- or 2-column formats. +/// Unparsable lines are silently skipped so a single malformed line never +/// prevents the rest of the list from loading. +pub fn parse(raw: &str, default_port: u16) -> Vec { + let mut out = Vec::new(); + for line in raw.lines() { + let line = line.trim(); + if line.is_empty() || line.starts_with('#') { + continue; + } + if let Some(seed) = parse_line(line, default_port) { + out.push(seed); + } + } + out +} + +fn parse_line(line: &str, default_port: u16) -> Option { + let toks: Vec<&str> = line.split_whitespace().collect(); + match toks.len() { + 1 => parse_bare(toks[0], default_port), + 2 => parse_typed(toks[0], toks[1], default_port), + 8 => parse_full(&toks, default_port), + _ => None, + } +} + +fn parse_bare(addr: &str, default_port: u16) -> Option { + let address = parse_address(addr, default_port)?; + Some(MasternodeSeed { + address, + mn_type: MasternodeType::Regular, + platform_http_port: None, + core: CoreStatus::default(), + platform: None, + }) +} + +fn parse_typed(type_tok: &str, addr_tok: &str, default_port: u16) -> Option { + let mn_type = MasternodeType::parse(type_tok)?; + let address = parse_address(addr_tok, default_port)?; + Some(MasternodeSeed { + address, + mn_type, + platform_http_port: None, + core: CoreStatus::default(), + platform: match mn_type { + MasternodeType::Evo => Some(PlatformStatus::default()), + MasternodeType::Regular => None, + }, + }) +} + +fn parse_full(toks: &[&str], default_port: u16) -> Option { + let mn_type = MasternodeType::parse(toks[0])?; + let address = parse_address(toks[1], default_port)?; + let platform_http_port = match toks[2] { + "-" => None, + n => Some(n.parse::().ok()?), + }; + let core = CoreStatus { + reachable: Reachability::parse(toks[3])?, + synced: SyncStatus::parse(toks[4])?, + }; + let platform = match (mn_type, toks[5], toks[6], toks[7]) { + (MasternodeType::Regular, "-", "-", "-") => None, + (MasternodeType::Evo, r, l, s) => Some(PlatformStatus { + reachable: Reachability::parse(r)?, + live: PlatformLiveness::parse(l)?, + ssl: SslStatus::parse(s)?, + }), + _ => return None, + }; + Some(MasternodeSeed { + address, + mn_type, + platform_http_port, + core, + platform, + }) +} + +fn parse_address(tok: &str, default_port: u16) -> Option { + if let Ok(addr) = tok.parse::() { + return Some(addr); + } + if let Ok(ip) = tok.parse::() { + return Some(SocketAddr::new(ip, default_port)); + } + None +} + +// ---------- Tests ---------- + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn testnet_seed_peers_contains_hp_mn_ips() { + let peers = addresses(Network::Testnet); + // The HP-MN range at 68.67.122.1-29 should be present; later runs may + // extend it but never shrink below 29. + let hp_mn = peers.iter().filter(|a| a.ip().to_string().starts_with("68.67.122.")).count(); + assert!(hp_mn >= 29, "expected >=29 HP-MN testnet seeds, got {}", hp_mn); + assert!(peers.iter().all(|a| a.port() == Network::Testnet.default_p2p_port())); + } + + #[test] + fn mainnet_seed_peers_non_empty() { + let peers = addresses(Network::Mainnet); + assert!(!peers.is_empty(), "mainnet seeds must not be empty"); + assert!(peers.iter().all(|a| a.port() == Network::Mainnet.default_p2p_port())); + } + + fn mk_full(addr: &str, mn_type: MasternodeType) -> MasternodeSeed { + MasternodeSeed { + address: addr.parse().unwrap(), + mn_type, + platform_http_port: if mn_type == MasternodeType::Evo { + Some(443) + } else { + None + }, + core: CoreStatus { + reachable: Reachability::Ok, + synced: SyncStatus::Synced, + }, + platform: if mn_type == MasternodeType::Evo { + Some(PlatformStatus { + reachable: Reachability::Ok, + live: PlatformLiveness::Ok, + ssl: SslStatus::Valid, + }) + } else { + None + }, + } + } + + #[test] + fn round_trip_full_evo() { + let seed = mk_full("68.67.122.1:19999", MasternodeType::Evo); + let line = seed.to_line(); + assert_eq!(line, "evo 68.67.122.1:19999 443 ok sync ok ok valid"); + let parsed = parse_line(&line, 19999).unwrap(); + assert_eq!(parsed, seed); + } + + #[test] + fn round_trip_full_regular() { + let seed = mk_full("1.2.3.4:9999", MasternodeType::Regular); + let line = seed.to_line(); + assert_eq!(line, "regular 1.2.3.4:9999 - ok sync - - -"); + let parsed = parse_line(&line, 9999).unwrap(); + assert_eq!(parsed, seed); + } + + #[test] + fn legacy_bare_ip_is_regular_with_unknown_status() { + let p = parse_line("1.2.3.4:9999", 9999).unwrap(); + assert_eq!(p.mn_type, MasternodeType::Regular); + assert_eq!(p.core.reachable, Reachability::Unknown); + assert_eq!(p.core.synced, SyncStatus::Unknown); + assert!(p.platform.is_none()); + } + + #[test] + fn legacy_typed_no_status() { + let p = parse_line("evo 68.67.122.1:19999", 19999).unwrap(); + assert_eq!(p.mn_type, MasternodeType::Evo); + assert_eq!(p.core.reachable, Reachability::Unknown); + let plat = p.platform.unwrap(); + assert_eq!(plat.reachable, Reachability::Unknown); + assert_eq!(plat.ssl, SslStatus::Unknown); + } + + #[test] + fn parse_sync_status_variants() { + assert_eq!(SyncStatus::parse("sync"), Some(SyncStatus::Synced)); + assert_eq!(SyncStatus::parse("-123"), Some(SyncStatus::Behind(123))); + assert_eq!(SyncStatus::parse("+5"), Some(SyncStatus::Ahead(5))); + assert_eq!(SyncStatus::parse("?"), Some(SyncStatus::Unknown)); + assert_eq!(SyncStatus::parse("weird"), None); + } + + #[test] + fn parse_skips_invalid_and_short_lines() { + // 3 columns is not a valid length. + let raw = "evo 1.2.3.4 invalid\nregular 5.6.7.8:9999 - ok sync - - -\n"; + let list = parse(raw, 9999); + assert_eq!(list.len(), 1); + } + + #[test] + fn masternode_type_parse_case_insensitive() { + assert_eq!(MasternodeType::parse("EVO"), Some(MasternodeType::Evo)); + assert_eq!(MasternodeType::parse("Regular"), Some(MasternodeType::Regular)); + assert_eq!(MasternodeType::parse("hpmn"), Some(MasternodeType::Evo)); + assert_eq!(MasternodeType::parse("Nope"), None); + } + + #[test] + fn testnet_seeds_contain_expected_evo_ips() { + let list = seeds(Network::Testnet); + let hpmn_count = list + .iter() + .filter(|s| s.mn_type == MasternodeType::Evo) + .filter(|s| s.address.ip().to_string().starts_with("68.67.122.")) + .count(); + assert!(hpmn_count >= 29, "expected >=29 HP-MN seeds at 68.67.122.x, got {}", hpmn_count); + } + + #[test] + fn mainnet_seeds_non_empty_and_well_formed() { + let list = seeds(Network::Mainnet); + assert!(!list.is_empty(), "mainnet seeds must not be empty"); + for s in &list { + assert_eq!(s.address.port(), Network::Mainnet.default_p2p_port()); + } + } + + #[test] + fn evo_seeds_all_have_platform_status() { + // Post-probe, evo entries carry a platform field regardless of + // whether individual probes succeeded. + for s in evo_seeds(Network::Testnet) { + assert!(s.platform.is_some()); + } + } + + #[test] + fn regular_seeds_never_have_platform_status() { + for s in regular_seeds(Network::Mainnet) { + assert!(s.platform.is_none()); + } + } +} diff --git a/dash-network/src/lib.rs b/dash-network/src/lib.rs index e94e181cc..a49447f42 100644 --- a/dash-network/src/lib.rs +++ b/dash-network/src/lib.rs @@ -118,6 +118,14 @@ impl Network { Network::Regtest => 19899, } } + + pub const fn dns_seeds(self) -> &'static [&'static str] { + match self { + Network::Mainnet => &["dnsseed.dash.org"], + Network::Testnet => &["testnet-seed.dashdot.io"], + Network::Devnet | Network::Regtest => &[""], + } + } } impl fmt::Display for Network { diff --git a/dash-spv/Cargo.toml b/dash-spv/Cargo.toml index 021b5ec1e..b15c60e15 100644 --- a/dash-spv/Cargo.toml +++ b/dash-spv/Cargo.toml @@ -12,6 +12,7 @@ rust-version = "1.89" # Core Dash libraries dashcore = { path = "../dash", features = ["serde", "core-block-hash-use-x11", "message_verification", "bls", "quorum_validation"] } dashcore_hashes = { path = "../hashes" } +dash-network-seeds = { path = "../dash-network-seeds" } key-wallet = { path = "../key-wallet" } key-wallet-manager = { path = "../key-wallet-manager", features = ["parallel-filters"] } diff --git a/dash-spv/src/network/constants.rs b/dash-spv/src/network/constants.rs index 6a27c1e7d..e1278f0f6 100644 --- a/dash-spv/src/network/constants.rs +++ b/dash-spv/src/network/constants.rs @@ -15,15 +15,6 @@ pub const PING_INTERVAL: Duration = Duration::from_secs(120); pub const RECONNECT_DELAY: Duration = Duration::from_secs(5); pub const MAX_RECONNECT_ATTEMPTS: u32 = 3; -// DNS seeds for Dash mainnet -pub const MAINNET_DNS_SEEDS: &[&str] = &[ - "dnsseed.dash.org", - // Note: dnsseed.dashdot.io and dnsseed.masternode.io are currently not resolving -]; - -// DNS seeds for Dash testnet -pub const TESTNET_DNS_SEEDS: &[&str] = &["testnet-seed.dashdot.io"]; - // Peer exchange pub const MAX_ADDR_TO_SEND: usize = 1000; pub const MAX_ADDR_TO_STORE: usize = 2000; diff --git a/dash-spv/src/network/discovery.rs b/dash-spv/src/network/discovery.rs index efa789fc5..4522ab7c4 100644 --- a/dash-spv/src/network/discovery.rs +++ b/dash-spv/src/network/discovery.rs @@ -1,4 +1,15 @@ -//! DNS-based peer discovery for Dash network +//! Peer discovery for Dash network. +//! +//! Peer discovery is seeded from two sources, in priority order: +//! +//! 1. A hardcoded masternode IP list for the network, embedded at compile time +//! from `dash-spv/seeds/.txt`. This file is regenerated weekly by +//! CI from a live Dash Core node (see `masternode-seeds-fetcher`). +//! 2. DNS seed queries as a backup. DNS resolution failures are logged but are +//! not fatal — as long as the embedded list yields at least one peer, the +//! client can bootstrap. +//! +//! Results from both sources are merged and deduplicated. use dashcore::Network; use hickory_resolver::config::{ResolverConfig, ResolverOpts}; @@ -7,9 +18,12 @@ use hickory_resolver::TokioResolver; use std::net::{IpAddr, SocketAddr}; use crate::error::SpvError as Error; -use crate::network::constants::{MAINNET_DNS_SEEDS, TESTNET_DNS_SEEDS}; -/// DNS discovery for finding initial peers +/// DNS discovery for finding initial peers. +/// +/// Despite the name (kept for backwards compatibility), this type also returns +/// hardcoded masternode seeds embedded at compile time; DNS is used as a +/// fallback. pub struct DnsDiscovery { resolver: TokioResolver, } @@ -29,18 +43,19 @@ impl DnsDiscovery { }) } - /// Discover peers for the given network + /// Discover peers for the given network. + /// + /// Returns the union of the embedded hardcoded masternode seeds and any + /// addresses resolved via DNS. DNS resolution failures are logged at warn + /// level but do not cause this function to fail — the embedded list acts + /// as the primary source and DNS is a best-effort backup. pub async fn discover_peers(&self, network: Network) -> Vec { - let (seeds, port) = match network { - Network::Mainnet => (MAINNET_DNS_SEEDS, 9999), - Network::Testnet => (TESTNET_DNS_SEEDS, 19999), - _ => { - tracing::debug!("No DNS seeds for {:?} network", network); - return vec![]; - } - }; + let seeds = network.dns_seeds(); + let port = network.default_p2p_port(); + let mut addresses = dash_network_seeds::addresses(network); - let mut addresses = Vec::new(); + let embedded_count = addresses.len(); + tracing::info!("Loaded {} hardcoded masternode seed(s) for {:?}", embedded_count, network); for seed in seeds { tracing::debug!("Querying DNS seed: {}", seed); @@ -55,16 +70,21 @@ impl DnsDiscovery { } } Err(e) => { - tracing::warn!("Failed to resolve DNS seed {}: {}", seed, e); + // DNS is a best-effort backup; do not propagate the error. + tracing::warn!("Failed to resolve DNS seed {} (backup source): {}", seed, e); } } } - // Deduplicate addresses addresses.sort(); addresses.dedup(); - tracing::info!("Discovered {} unique peer addresses from DNS seeds", addresses.len()); + tracing::info!( + "Discovered {} unique peer addresses for {:?} ({} from embedded seeds + DNS)", + addresses.len(), + network, + embedded_count + ); addresses } @@ -92,33 +112,26 @@ mod tests { println!(" {}", peer); } - // Should find at least some peers - assert!(!peers.is_empty()); - // All peers should use the correct port for peer in &peers { - assert_eq!(peer.port(), 9999); + assert_eq!(peer.port(), Network::Mainnet.default_p2p_port()); } } #[tokio::test] - #[ignore] // Requires network access - async fn test_dns_discovery_testnet() { + async fn test_dns_discovery_testnet_returns_embedded_when_dns_fails() { + // This test does not require network access: even if DNS resolution + // fails, the embedded seed file must yield peers. let discovery = DnsDiscovery::new().await.expect("Failed to create DNS discovery for test"); let peers = discovery.discover_peers(Network::Testnet).await; - // Print discovered peers for debugging - println!("Discovered {} testnet peers:", peers.len()); - for peer in &peers { - println!(" {}", peer); - } - - // Should find at least some peers - assert!(!peers.is_empty()); - - // All peers should use the correct port + assert!( + peers.len() >= 29, + "expected at least the 29 embedded testnet HP-MN seeds, got {}", + peers.len() + ); for peer in &peers { - assert_eq!(peer.port(), 19999); + assert_eq!(peer.port(), Network::Testnet.default_p2p_port()); } } @@ -127,7 +140,7 @@ mod tests { let discovery = DnsDiscovery::new().await.expect("Failed to create DNS discovery for test"); let peers = discovery.discover_peers(Network::Regtest).await; - // Should return empty for regtest (no DNS seeds) + // Should return empty for regtest (no DNS seeds and no embedded list) assert!(peers.is_empty()); } } diff --git a/masternode-seeds-fetcher/Cargo.toml b/masternode-seeds-fetcher/Cargo.toml new file mode 100644 index 000000000..54974dcef --- /dev/null +++ b/masternode-seeds-fetcher/Cargo.toml @@ -0,0 +1,35 @@ +[package] +name = "masternode-seeds-fetcher" +version = { workspace = true } +edition = "2024" +authors = ["Dash Core Team"] +description = "Fetch the current masternode IP list from the Dash P2P network and write per-network seed files used by dash-spv." +license = "MIT" +repository = "https://github.com/dashpay/rust-dashcore" +publish = false + +[[bin]] +name = "masternode-seeds-fetcher" +path = "src/main.rs" + +[dependencies] +dashcore = { path = "../dash", features = ["core-block-hash-use-x11"] } +dash-spv = { path = "../dash-spv" } +dash-network-seeds = { path = "../dash-network-seeds" } + +tokio = { version = "1.0", features = ["full"] } +hickory-resolver = "0.25" + +clap = { version = "4.0", features = ["derive", "env"] } +anyhow = "1.0" +chrono = { version = "0.4.20", default-features = false, features = ["clock"] } +tracing = "0.1" +tracing-subscriber = { version = "0.3.20", features = ["env-filter"] } +rand = "0.8" +futures = "0.3" + +# TLS probing for the Dash Platform HTTP port (Evo nodes). +tokio-rustls = { version = "0.26", default-features = false, features = ["ring", "tls12"] } +rustls = { version = "0.23", default-features = false, features = ["ring", "std", "tls12"] } +rustls-pki-types = "1" +x509-parser = "0.16" diff --git a/masternode-seeds-fetcher/src/main.rs b/masternode-seeds-fetcher/src/main.rs new file mode 100644 index 000000000..ed470d8e8 --- /dev/null +++ b/masternode-seeds-fetcher/src/main.rs @@ -0,0 +1,624 @@ +//! Fetch the current masternode list from the Dash P2P network and write it +//! to a seed file consumed by the `dash-network-seeds` crate. +//! +//! The fetcher does **not** require RPC credentials. It: +//! +//! 1. Resolves candidate peer addresses from the network's DNS seeds and the +//! existing seed file (the very file it will overwrite). +//! 2. Connects to one peer at a time and runs the Dash P2P handshake. +//! 3. Sends `sendheaders` and waits for the peer's next new-block +//! announcement (via a `headers` or `inv` message) to obtain a fresh, +//! valid chain tip hash. Block times of ~2.5 minutes mean this usually +//! returns within a couple of minutes and always within ~6 minutes. +//! 4. Sends `getmnlistd` with `base_block_hash = 0` (full list) and +//! `block_hash = tip` to receive a `mnlistdiff` containing every +//! registered masternode as of that block. +//! 5. Filters to valid masternodes and writes a deterministic, sorted, +//! comment-headed seed file. +//! +//! If a peer fails at any step (connect, handshake, timeout, malformed +//! response) the fetcher tries the next candidate. It refuses to overwrite +//! the output file unless it actually obtained a non-empty mnlistdiff. +//! +//! Typical usage (e.g. from CI): +//! +//! ```bash +//! masternode-seeds-fetcher --network mainnet --out dash-network-seeds/seeds/mainnet.txt +//! ``` + +use std::collections::BTreeSet; +use std::fs; +use std::io::Write; +use std::net::{IpAddr, SocketAddr}; +use std::path::PathBuf; +use std::time::Duration; + +use anyhow::{Context, Result, anyhow}; +use clap::Parser; +use dash_network_seeds::{ + CoreStatus, MasternodeSeed, MasternodeType, PlatformStatus, Reachability, +}; +use dash_spv::network::Peer; +use dashcore::hashes::Hash; +use dashcore::network::Address; +use dashcore::network::constants::ServiceFlags; +use dashcore::network::message::NetworkMessage; +use dashcore::network::message_blockdata::Inventory; +use dashcore::network::message_network::VersionMessage; +use dashcore::network::message_sml::{GetMnListDiff, MnListDiff}; +use dashcore::sml::masternode_list_entry::EntryMasternodeType; +use dashcore::{BlockHash, Network}; +use futures::stream::{FuturesUnordered, StreamExt}; +use hickory_resolver::config::{ResolverConfig, ResolverOpts}; +use hickory_resolver::name_server::TokioConnectionProvider; +use std::sync::Arc; +use tokio::sync::Semaphore; +use tokio::time::Instant; + +mod probe; + +// ---------- CLI ---------- +#[derive(Parser, Debug)] +#[command( + author, + version, + about = "Fetch masternode IPs via the Dash P2P network and write a dash-network-seeds seed file" +)] +struct Args { + /// Target network. + #[arg(long, value_enum)] + network: Network, + + /// Output file path. Defaults to `dash-network-seeds/seeds/.txt` + /// relative to the current directory. + #[arg(long)] + out: Option, + + /// Extra peer addresses (in `ip:port` form) to try in addition to DNS + /// seeds and the existing seed file. May be repeated. + #[arg(long = "peer")] + extra_peers: Vec, + + /// Maximum number of peers to try before giving up. + #[arg(long, default_value_t = 8)] + max_peers: usize, + + /// Also keep masternodes flagged `is_valid = false`. Default is to keep + /// only valid entries so that the resulting list reflects peers that are + /// actually reachable. + #[arg(long, default_value_t = false)] + include_invalid: bool, + + /// Skip the per-masternode reachability probes entirely and write the + /// seed file with all status columns set to unknown. Useful for quick + /// local runs. + #[arg(long, default_value_t = false)] + skip_probes: bool, + + /// Maximum number of probes running concurrently. + #[arg(long, default_value_t = 64)] + probe_concurrency: usize, +} + +// ---------- main ---------- + +#[tokio::main] +async fn main() -> Result<()> { + tracing_subscriber::fmt() + .with_env_filter( + tracing_subscriber::EnvFilter::try_from_default_env() + .unwrap_or_else(|_| tracing_subscriber::EnvFilter::new("info")), + ) + .with_writer(std::io::stderr) + .init(); + + let args = Args::parse(); + let out_path = args + .out + .clone() + .unwrap_or_else(|| PathBuf::from(format!("dash-network-seeds/seeds/{}.txt", args.network))); + + let candidates = + gather_candidate_peers(args.network, &args.extra_peers, &out_path, args.max_peers).await; + if candidates.is_empty() { + return Err(anyhow!( + "no candidate peers to contact (DNS seeds resolved 0, existing seed file empty, \ + and --peer not set)" + )); + } + tracing::info!( + "Trying up to {} of {} candidate peer(s) on {}", + args.max_peers, + candidates.len(), + args.network + ); + + let mut last_error: Option = None; + let mut diff_and_source: Option<(MnListDiff, SocketAddr)> = None; + for peer_addr in candidates.iter().take(args.max_peers) { + tracing::info!("Contacting peer {}", peer_addr); + match fetch_from_peer(*peer_addr, args.network).await { + Ok(diff) => { + diff_and_source = Some((diff, *peer_addr)); + break; + } + Err(e) => { + tracing::warn!("Peer {} failed: {:#}", peer_addr, e); + last_error = Some(e); + } + } + } + + let (diff, peer_addr) = diff_and_source.ok_or_else(|| { + anyhow!( + "exhausted all {} candidate peer(s); last error: {}", + args.max_peers.min(candidates.len()), + last_error.map(|e| format!("{:#}", e)).unwrap_or_else(|| "".to_string()) + ) + })?; + + let tip_height = reference_tip_height(&diff); + tracing::info!("Reference tip height: {:?}", tip_height); + + let collected = collect_seeds(&diff, &args); + if collected.entries.is_empty() { + return Err(anyhow!( + "peer {} returned {} masternodes but none were usable; refusing to overwrite {}", + peer_addr, + collected.total, + out_path.display() + )); + } + + let mut entries = collected.entries; + if !args.skip_probes { + probe_all(&mut entries, args.network, tip_height, args.probe_concurrency).await; + } + + let summary = summarize(&entries); + write_seed_file( + &out_path, + args.network, + peer_addr, + &diff, + tip_height, + &entries, + collected.total, + &summary, + )?; + eprintln!( + "wrote {} seeds ({} regular + {} evo) for {} to {} — core_ok={} plat_ok={} ssl_valid={} (from peer {}, tip {})", + entries.len(), + summary.regular, + summary.evo, + args.network, + out_path.display(), + summary.core_reachable, + summary.platform_reachable, + summary.ssl_valid, + peer_addr, + diff.block_hash + ); + Ok(()) +} + +// ---------- peer discovery ---------- + +async fn gather_candidate_peers( + network: Network, + extra: &[SocketAddr], + existing_seeds: &std::path::Path, + max: usize, +) -> Vec { + let mut out: BTreeSet = BTreeSet::new(); + out.extend(extra.iter().copied()); + + // Existing seed file — the file we are about to overwrite. Gives us a fast + // local starting set even if DNS is unavailable. + if let Ok(raw) = fs::read_to_string(existing_seeds) { + for seed in dash_network_seeds::parse(&raw, network.default_p2p_port()) { + out.insert(seed.address); + } + } + + // DNS seeds. + if let Ok(resolver) = build_resolver() { + for seed in network.dns_seeds() { + match resolver.lookup_ip(*seed).await { + Ok(lookup) => { + for ip in lookup.iter() { + out.insert(SocketAddr::new(ip, network.default_p2p_port())); + } + } + Err(e) => { + tracing::warn!("DNS seed {} failed: {}", seed, e); + } + } + } + } + + let mut list: Vec = out.into_iter().collect(); + // Shuffle so we do not always hit the same peer first across runs. + use rand::seq::SliceRandom; + list.shuffle(&mut rand::thread_rng()); + list.truncate(max.saturating_mul(4).max(max)); + list +} + +fn build_resolver() -> Result { + let resolver = hickory_resolver::Resolver::builder_with_config( + ResolverConfig::default(), + TokioConnectionProvider::default(), + ) + .with_options(ResolverOpts::default()) + .build(); + Ok(resolver) +} + +// ---------- per-peer P2P flow ---------- + +async fn fetch_from_peer(peer_addr: SocketAddr, network: Network) -> Result { + let mut peer = Peer::connect(peer_addr, 15, network) + .await + .with_context(|| format!("connecting to {}", peer_addr))?; + + handshake(&mut peer, peer_addr).await.context("handshake")?; + + let tip = discover_tip(&mut peer).await.context("tip discovery")?; + tracing::info!("Peer {} tip: {}", peer_addr, tip); + + peer.send_message(NetworkMessage::GetMnListD(GetMnListDiff { + base_block_hash: BlockHash::all_zeros(), + block_hash: tip, + })) + .await + .with_context(|| format!("sending getmnlistd to {}", peer_addr))?; + + let diff = wait_for_message(&mut peer, Duration::from_secs(120), |m| match m { + NetworkMessage::MnListDiff(d) => Some(d.clone()), + _ => None, + }) + .await + .with_context(|| format!("waiting for mnlistdiff from {}", peer_addr))?; + + Ok(diff) +} + +async fn handshake(peer: &mut Peer, peer_addr: SocketAddr) -> Result<()> { + let our_addr = SocketAddr::new(IpAddr::V4(std::net::Ipv4Addr::new(0, 0, 0, 0)), 0); + // `VersionMessage::new` picks up `PROTOCOL_VERSION` internally. + let version = VersionMessage::new( + ServiceFlags::NONE, + chrono::Utc::now().timestamp(), + Address::new(&peer_addr, ServiceFlags::NETWORK), + Address::new(&our_addr, ServiceFlags::NONE), + rand::random::(), + format!("/masternode-seeds-fetcher:{}/", env!("CARGO_PKG_VERSION")), + 0, + false, + [0u8; 32], + ); + peer.send_message(NetworkMessage::Version(version)).await?; + + let mut got_version = false; + let mut got_verack = false; + let start = Instant::now(); + loop { + if start.elapsed() > Duration::from_secs(15) { + return Err(anyhow!( + "handshake timeout (version={}, verack={})", + got_version, + got_verack + )); + } + match tokio::time::timeout(Duration::from_millis(300), peer.receive_message()).await { + Ok(Ok(Some(msg))) => match msg.inner() { + NetworkMessage::Version(_v) => { + got_version = true; + peer.send_message(NetworkMessage::SendAddrV2).await.ok(); + peer.send_message(NetworkMessage::Verack).await?; + if got_verack { + return Ok(()); + } + } + NetworkMessage::Verack => { + got_verack = true; + if got_version { + return Ok(()); + } + } + NetworkMessage::Ping(n) => { + peer.send_message(NetworkMessage::Pong(*n)).await.ok(); + } + _ => { /* ignore during handshake */ } + }, + Ok(Ok(None)) => { /* nothing buffered yet */ } + Ok(Err(e)) => return Err(anyhow!("receive failed: {}", e)), + Err(_) => { /* poll interval timeout; keep looping */ } + } + } +} + +/// Discover a recent chain tip by asking the peer to announce via `headers` +/// and then waiting for the next block the peer hears about. +/// +/// This is dramatically faster than walking `getheaders` from genesis: Dash +/// mainnet & testnet target ~2.5 minute block times, so the expected wait is +/// ~75s with an absolute cap of a few minutes. Using a *fresh* block as the +/// `getmnlistd.block_hash` also means each weekly CI run produces a different +/// output file, which is what we want. +async fn discover_tip(peer: &mut Peer) -> Result { + // Request header-style new-block announcements. + peer.send_message(NetworkMessage::SendHeaders).await.ok(); + + const TIP_WAIT: Duration = Duration::from_secs(360); // 6 minutes: comfortably above max inter-block time. + tracing::info!("Waiting up to {:?} for a new-block announcement from peer", TIP_WAIT); + + wait_for_message(peer, TIP_WAIT, |m| match m { + NetworkMessage::Headers(hs) => hs.last().map(|h| h.block_hash()), + NetworkMessage::Inv(items) => items.iter().rev().find_map(|inv| match inv { + Inventory::Block(hash) | Inventory::CompactBlock(hash) => Some(*hash), + _ => None, + }), + _ => None, + }) + .await +} + +async fn wait_for_message( + peer: &mut Peer, + total_timeout: Duration, + mut extract: F, +) -> Result +where + F: FnMut(&NetworkMessage) -> Option, +{ + let start = Instant::now(); + loop { + if start.elapsed() > total_timeout { + return Err(anyhow!("timed out after {:?} waiting for target message", total_timeout)); + } + match tokio::time::timeout(Duration::from_millis(300), peer.receive_message()).await { + Ok(Ok(Some(msg))) => { + match msg.inner() { + NetworkMessage::Ping(n) => { + peer.send_message(NetworkMessage::Pong(*n)).await.ok(); + continue; + } + NetworkMessage::GetHeaders(_) + | NetworkMessage::GetHeaders2(_) + | NetworkMessage::Inv(_) + | NetworkMessage::Addr(_) + | NetworkMessage::AddrV2(_) + | NetworkMessage::SendHeaders + | NetworkMessage::SendHeaders2 + | NetworkMessage::SendCmpct(_) + | NetworkMessage::SendAddrV2 + | NetworkMessage::WtxidRelay + | NetworkMessage::FeeFilter(_) + | NetworkMessage::SendDsq(_) => { /* ignore */ } + _ => {} + } + if let Some(v) = extract(msg.inner()) { + return Ok(v); + } + } + Ok(Ok(None)) => { /* buffer empty, keep looping */ } + Ok(Err(e)) => return Err(anyhow!("receive failed: {}", e)), + Err(_) => { /* poll timeout */ } + } + } +} + +// ---------- output ---------- + +struct CollectedSeeds { + total: usize, + entries: Vec, +} + +struct Summary { + regular: usize, + evo: usize, + core_reachable: usize, + platform_reachable: usize, + ssl_valid: usize, +} + +fn collect_seeds(diff: &MnListDiff, args: &Args) -> CollectedSeeds { + let total = diff.new_masternodes.len(); + // Dedupe by (addr, type). If a given address appears as both regular and + // evo (should never happen on-chain) we keep only the evo variant. + let mut by_addr: BTreeSet<(SocketAddr, MasternodeType, Option)> = BTreeSet::new(); + for mn in &diff.new_masternodes { + if !args.include_invalid && !mn.is_valid { + continue; + } + let addr = mn.service_address; + if addr.port() == 0 { + continue; + } + match addr.ip() { + IpAddr::V4(v4) if v4.is_unspecified() => continue, + IpAddr::V6(v6) if v6.is_unspecified() => continue, + _ => {} + } + let (mn_type, platform_port) = match mn.mn_type { + EntryMasternodeType::Regular => (MasternodeType::Regular, None), + EntryMasternodeType::HighPerformance { + platform_http_port, + .. + } => (MasternodeType::Evo, Some(platform_http_port)), + }; + by_addr.insert((addr, mn_type, platform_port)); + } + let entries: Vec = by_addr + .into_iter() + .map(|(address, mn_type, platform_http_port)| MasternodeSeed { + address, + mn_type, + platform_http_port, + core: CoreStatus::default(), + platform: match mn_type { + MasternodeType::Evo => Some(PlatformStatus::default()), + MasternodeType::Regular => None, + }, + }) + .collect(); + CollectedSeeds { + total, + entries, + } +} + +fn reference_tip_height(diff: &MnListDiff) -> Option { + use dashcore::blockdata::transaction::special_transaction::TransactionPayload; + match diff.coinbase_tx.special_transaction_payload.as_ref()? { + TransactionPayload::CoinbasePayloadType(cb) => Some(cb.height), + _ => None, + } +} + +async fn probe_all( + entries: &mut [MasternodeSeed], + network: Network, + tip_height: Option, + concurrency: usize, +) { + let total = entries.len(); + tracing::info!( + "Probing {} seeds with concurrency={} (tip_height={:?})", + total, + concurrency, + tip_height + ); + let permits = Arc::new(Semaphore::new(concurrency.max(1))); + let start = Instant::now(); + let mut tasks = FuturesUnordered::new(); + for (idx, seed) in entries.iter().enumerate() { + let permits = permits.clone(); + let addr = seed.address; + let mn_type = seed.mn_type; + let platform_port = seed.platform_http_port; + tasks.push(tokio::spawn(async move { + let _permit = permits.acquire_owned().await.ok()?; + let (reach, peer_h) = probe::probe_core(addr, network).await; + let sync = probe::classify_sync(peer_h, tip_height); + let core = probe::core_status(reach, sync); + let platform = match (mn_type, platform_port) { + (MasternodeType::Evo, Some(port)) if port != 0 => { + Some(probe::probe_platform(addr.ip(), port).await) + } + _ => None, + }; + Some((idx, core, platform)) + })); + } + + let mut done = 0usize; + while let Some(res) = tasks.next().await { + done += 1; + if let Ok(Some((idx, core, platform))) = res { + entries[idx].core = core; + if let Some(p) = platform { + entries[idx].platform = Some(p); + } + } + if done.is_multiple_of(200) || done == total { + tracing::info!("Probed {} / {} in {:.1}s", done, total, start.elapsed().as_secs_f64()); + } + } + tracing::info!("Probing complete in {:.1}s", start.elapsed().as_secs_f64()); +} + +fn summarize(entries: &[MasternodeSeed]) -> Summary { + let regular = entries.iter().filter(|s| s.mn_type == MasternodeType::Regular).count(); + let evo = entries.iter().filter(|s| s.mn_type == MasternodeType::Evo).count(); + let core_reachable = entries.iter().filter(|s| s.core.reachable == Reachability::Ok).count(); + let platform_reachable = entries + .iter() + .filter(|s| s.platform.map(|p| p.reachable == Reachability::Ok).unwrap_or(false)) + .count(); + let ssl_valid = entries + .iter() + .filter(|s| { + s.platform.map(|p| p.ssl == dash_network_seeds::SslStatus::Valid).unwrap_or(false) + }) + .count(); + Summary { + regular, + evo, + core_reachable, + platform_reachable, + ssl_valid, + } +} + +#[allow(clippy::too_many_arguments)] +fn write_seed_file( + path: &std::path::Path, + network: Network, + peer: SocketAddr, + diff: &MnListDiff, + tip_height: Option, + entries: &[MasternodeSeed], + total: usize, + summary: &Summary, +) -> Result<()> { + if let Some(parent) = path.parent() { + fs::create_dir_all(parent) + .with_context(|| format!("creating parent dir for {}", path.display()))?; + } + let timestamp = chrono::Utc::now().format("%Y-%m-%dT%H:%M:%SZ"); + let mut file = + fs::File::create(path).with_context(|| format!("opening {} for write", path.display()))?; + writeln!( + file, + "# Auto-generated by masternode-seeds-fetcher on {} for {}", + timestamp, network + )?; + writeln!(file, "# Source: Dash P2P network (mnlistdiff)")?; + writeln!(file, "# Primary peer: {}", peer)?; + writeln!(file, "# Tip block hash: {}", diff.block_hash)?; + if let Some(h) = tip_height { + writeln!(file, "# Tip block height: {}", h)?; + } + writeln!( + file, + "# {} seeds ({} regular + {} evo) of {} total masternodes, valid-only", + entries.len(), + summary.regular, + summary.evo, + total + )?; + writeln!( + file, + "# Probe summary: core_reachable={}/{} platform_reachable={}/{} ssl_valid={}/{}", + summary.core_reachable, + entries.len(), + summary.platform_reachable, + summary.evo, + summary.ssl_valid, + summary.evo, + )?; + writeln!( + file, + "# Columns: " + )?; + writeln!( + file, + "# Values: core_reach/plat_reach=ok|timeout|refused|error|?, core_sync=sync|-N|+N|?, plat_live=ok|none|?|-, plat_ssl=valid|expired|self-signed|untrusted|no-handshake|?|-" + )?; + writeln!( + file, + "# Do not edit manually — refreshed weekly by .github/workflows/update-masternode-seeds.yml" + )?; + // Sort by address so the file is deterministic and diffs stay minimal + // when only membership changes. + let mut sorted: Vec<&MasternodeSeed> = entries.iter().collect(); + sorted.sort_by_key(|s| (s.address, s.mn_type)); + for seed in sorted { + writeln!(file, "{}", seed.to_line())?; + } + Ok(()) +} diff --git a/masternode-seeds-fetcher/src/probe.rs b/masternode-seeds-fetcher/src/probe.rs new file mode 100644 index 000000000..49a1de9cc --- /dev/null +++ b/masternode-seeds-fetcher/src/probe.rs @@ -0,0 +1,332 @@ +//! Per-masternode reachability probes. +//! +//! Given a masternode's advertised Core address (and, for Evo nodes, a +//! platform HTTP port), this module produces a [`CoreStatus`] / +//! [`PlatformStatus`] suitable for embedding in the seed file. All probes are +//! bounded by short timeouts so that even a fully-unresponsive peer costs +//! the fetcher only a few seconds. + +use std::io::ErrorKind; +use std::net::SocketAddr; +use std::sync::Arc; +use std::time::Duration; + +use anyhow::Result; +use dash_network_seeds::{ + CoreStatus, PlatformLiveness, PlatformStatus, Reachability, SslStatus, SyncStatus, +}; +use dashcore::Network as DashNetwork; +use dashcore::network::Address; +use dashcore::network::constants::ServiceFlags; +use dashcore::network::message::NetworkMessage; +use dashcore::network::message_network::VersionMessage; +use rustls::pki_types::{CertificateDer, ServerName, UnixTime}; +use rustls::{ClientConfig, DigitallySignedStruct, SignatureScheme}; +use tokio::io::{AsyncReadExt, AsyncWriteExt}; +use tokio::net::TcpStream; +use x509_parser::prelude::FromDer; +use x509_parser::x509::X509Version; + +use dash_spv::network::Peer; + +/// How long to give a single TCP connect before giving up. +const CONNECT_TIMEOUT: Duration = Duration::from_secs(5); +/// Budget for the whole Core probe (connect + handshake). +const CORE_PROBE_BUDGET: Duration = Duration::from_secs(10); +/// Budget for the whole Platform probe (connect + TLS handshake + baseline HTTP). +const PLATFORM_PROBE_BUDGET: Duration = Duration::from_secs(10); + +/// Number of blocks within which a peer's `start_height` is considered +/// "synced" relative to the reference tip. +const SYNC_TOLERANCE: u32 = 10; + +/// Probe a Core peer: TCP + P2P handshake. Returns reachability and the +/// peer's reported `start_height` (for caller-side sync classification). +pub async fn probe_core( + peer_addr: SocketAddr, + _network: DashNetwork, +) -> (Reachability, Option) { + match tokio::time::timeout(CORE_PROBE_BUDGET, probe_core_inner(peer_addr, _network)).await { + Ok(Ok(h)) => (Reachability::Ok, h), + Ok(Err(e)) => (classify_io(e), None), + Err(_) => (Reachability::Timeout, None), + } +} + +async fn probe_core_inner(peer_addr: SocketAddr, network: DashNetwork) -> Result> { + let mut peer = Peer::connect(peer_addr, CONNECT_TIMEOUT.as_secs(), network).await?; + + let version = VersionMessage::new( + ServiceFlags::NONE, + chrono::Utc::now().timestamp(), + Address::new(&peer_addr, ServiceFlags::NETWORK), + Address::new( + &SocketAddr::new(std::net::IpAddr::V4(std::net::Ipv4Addr::new(0, 0, 0, 0)), 0), + ServiceFlags::NONE, + ), + rand::random::(), + format!("/masternode-seeds-fetcher:{}/probe", env!("CARGO_PKG_VERSION")), + 0, + false, + [0u8; 32], + ); + peer.send_message(NetworkMessage::Version(version)).await?; + + let start = tokio::time::Instant::now(); + let mut got_version = false; + let mut got_verack = false; + let mut start_height: Option = None; + + while start.elapsed() < CORE_PROBE_BUDGET { + match tokio::time::timeout(Duration::from_millis(300), peer.receive_message()).await { + Ok(Ok(Some(msg))) => match msg.inner() { + NetworkMessage::Version(v) => { + got_version = true; + start_height = Some(v.start_height.max(0) as u32); + peer.send_message(NetworkMessage::SendAddrV2).await.ok(); + peer.send_message(NetworkMessage::Verack).await?; + if got_verack { + return Ok(start_height); + } + } + NetworkMessage::Verack => { + got_verack = true; + if got_version { + return Ok(start_height); + } + } + NetworkMessage::Ping(n) => { + peer.send_message(NetworkMessage::Pong(*n)).await.ok(); + } + _ => { /* ignore */ } + }, + Ok(Ok(None)) | Err(_) => { /* poll tick */ } + Ok(Err(e)) => return Err(anyhow::anyhow!("{}", e)), + } + } + Err(anyhow::anyhow!("handshake incomplete within budget")) +} + +/// Classify a `SyncStatus` given a peer's reported `start_height` and a +/// reference tip height captured from the primary fetch. +pub fn classify_sync(peer_height: Option, reference_tip: Option) -> SyncStatus { + let (Some(peer), Some(reference)) = (peer_height, reference_tip) else { + return SyncStatus::Unknown; + }; + if peer >= reference { + let ahead = peer - reference; + if ahead <= SYNC_TOLERANCE { + SyncStatus::Synced + } else { + SyncStatus::Ahead(ahead) + } + } else { + let behind = reference - peer; + if behind <= SYNC_TOLERANCE { + SyncStatus::Synced + } else { + SyncStatus::Behind(behind) + } + } +} + +/// Probe a Platform HTTP port: TCP connect, TLS handshake (chain check + +/// cert introspection), and a minimal HTTP `GET /` to gauge liveness. +pub async fn probe_platform(ip: std::net::IpAddr, http_port: u16) -> PlatformStatus { + let addr = SocketAddr::new(ip, http_port); + match tokio::time::timeout(PLATFORM_PROBE_BUDGET, probe_platform_inner(addr)).await { + Ok(result) => result, + Err(_) => PlatformStatus { + reachable: Reachability::Timeout, + live: PlatformLiveness::None, + ssl: SslStatus::NoHandshake, + }, + } +} + +async fn probe_platform_inner(addr: SocketAddr) -> PlatformStatus { + let tcp = match tokio::time::timeout(CONNECT_TIMEOUT, TcpStream::connect(addr)).await { + Ok(Ok(s)) => s, + Ok(Err(e)) => { + return PlatformStatus { + reachable: classify_io(anyhow::Error::from(e)), + live: PlatformLiveness::None, + ssl: SslStatus::NoHandshake, + }; + } + Err(_) => { + return PlatformStatus { + reachable: Reachability::Timeout, + live: PlatformLiveness::None, + ssl: SslStatus::NoHandshake, + }; + } + }; + + // TLS handshake. We use a custom verifier that accepts *any* certificate + // chain, then inspect the end-entity cert ourselves — this gives us + // "valid" / "expired" / "self-signed" / "untrusted" classifications + // without having to pin to a hostname (which is pointless when connecting + // by IP). + let config = ClientConfig::builder() + .dangerous() + .with_custom_certificate_verifier(Arc::new(AcceptAllVerifier)) + .with_no_client_auth(); + let connector = tokio_rustls::TlsConnector::from(Arc::new(config)); + + // ServerName::try_from requires a DNS name; we don't have one. Use a + // dummy "no-hostname" marker — the custom verifier ignores it. + let dummy_name: ServerName<'static> = ServerName::try_from("example.invalid").unwrap(); + + let mut tls = match connector.connect(dummy_name, tcp).await { + Ok(s) => s, + Err(_) => { + return PlatformStatus { + reachable: Reachability::Ok, + live: PlatformLiveness::None, + ssl: SslStatus::NoHandshake, + }; + } + }; + + let ssl = { + let (_, conn) = tls.get_ref(); + classify_cert(conn.peer_certificates()) + }; + + // Minimal HTTP probe. We send `GET / HTTP/1.1` and check for *any* HTTP + // status line. Platform nodes running gRPC-over-HTTP/2 will usually + // reject this with a 4xx or 5xx — which still counts as "live". + let live = match http_liveness(&mut tls).await { + true => PlatformLiveness::Ok, + false => PlatformLiveness::None, + }; + + PlatformStatus { + reachable: Reachability::Ok, + live, + ssl, + } +} + +async fn http_liveness(stream: &mut tokio_rustls::client::TlsStream) -> bool { + let req = b"GET / HTTP/1.1\r\nHost: dash-platform\r\nUser-Agent: masternode-seeds-fetcher\r\nAccept: */*\r\nConnection: close\r\n\r\n"; + if stream.write_all(req).await.is_err() { + return false; + } + if stream.flush().await.is_err() { + return false; + } + let mut buf = [0u8; 16]; + match tokio::time::timeout(Duration::from_secs(3), stream.read(&mut buf)).await { + Ok(Ok(n)) if n >= 5 => buf.starts_with(b"HTTP/"), + _ => false, + } +} + +fn classify_cert(chain: Option<&[CertificateDer<'_>]>) -> SslStatus { + let Some(chain) = chain else { + return SslStatus::NoHandshake; + }; + let Some(leaf_der) = chain.first() else { + return SslStatus::NoHandshake; + }; + let Ok((_, leaf)) = x509_parser::certificate::X509Certificate::from_der(leaf_der.as_ref()) + else { + return SslStatus::Untrusted; + }; + if leaf.tbs_certificate.version != X509Version::V3 { + // V1 / V2 certs in the wild are almost always dodgy. + return SslStatus::Untrusted; + } + let not_after = leaf.tbs_certificate.validity.not_after; + let now = chrono::Utc::now().timestamp(); + if not_after.timestamp() < now { + return SslStatus::Expired; + } + // Self-signed: Issuer == Subject and only one cert in the chain. + let self_signed_hint = + leaf.tbs_certificate.issuer == leaf.tbs_certificate.subject && chain.len() == 1; + if self_signed_hint { + return SslStatus::SelfSigned; + } + // We don't do a full PKI walk (that's what rustls's default verifier is + // for, but it'd reject based on hostname mismatch). Lacking full chain + // verification, the best we can say is "looks valid enough". + SslStatus::Valid +} + +fn classify_io(err: anyhow::Error) -> Reachability { + // Walk the source chain for an io::Error kind. + let mut src: Option<&dyn std::error::Error> = Some(err.as_ref()); + while let Some(current) = src { + if let Some(io) = current.downcast_ref::() { + return match io.kind() { + ErrorKind::TimedOut => Reachability::Timeout, + ErrorKind::ConnectionRefused => Reachability::Refused, + _ => Reachability::Error, + }; + } + src = current.source(); + } + Reachability::Error +} + +/// Convenience: turn a pair of probes into a fully-populated [`CoreStatus`]. +pub fn core_status(reachable: Reachability, synced: SyncStatus) -> CoreStatus { + CoreStatus { + reachable, + synced, + } +} + +// ---------- rustls custom verifier ---------- + +#[derive(Debug)] +struct AcceptAllVerifier; + +impl rustls::client::danger::ServerCertVerifier for AcceptAllVerifier { + fn verify_server_cert( + &self, + _end_entity: &CertificateDer<'_>, + _intermediates: &[CertificateDer<'_>], + _server_name: &ServerName<'_>, + _ocsp_response: &[u8], + _now: UnixTime, + ) -> Result { + Ok(rustls::client::danger::ServerCertVerified::assertion()) + } + + fn verify_tls12_signature( + &self, + _message: &[u8], + _cert: &CertificateDer<'_>, + _dss: &DigitallySignedStruct, + ) -> Result { + Ok(rustls::client::danger::HandshakeSignatureValid::assertion()) + } + + fn verify_tls13_signature( + &self, + _message: &[u8], + _cert: &CertificateDer<'_>, + _dss: &DigitallySignedStruct, + ) -> Result { + Ok(rustls::client::danger::HandshakeSignatureValid::assertion()) + } + + fn supported_verify_schemes(&self) -> Vec { + vec![ + SignatureScheme::RSA_PKCS1_SHA256, + SignatureScheme::RSA_PKCS1_SHA384, + SignatureScheme::RSA_PKCS1_SHA512, + SignatureScheme::ECDSA_NISTP256_SHA256, + SignatureScheme::ECDSA_NISTP384_SHA384, + SignatureScheme::ECDSA_NISTP521_SHA512, + SignatureScheme::RSA_PSS_SHA256, + SignatureScheme::RSA_PSS_SHA384, + SignatureScheme::RSA_PSS_SHA512, + SignatureScheme::ED25519, + ] + } +}