mirror of
https://github.com/BigBodyCobain/Shadowbroker.git
synced 2026-07-11 22:46:38 +02:00
Harden mesh bootstrap defaults
This commit is contained in:
@@ -1489,9 +1489,21 @@ def _refresh_node_peer_store(*, now: float | None = None) -> dict[str, Any]:
|
||||
push_records = [record for record in push_records if _is_private_infonet_transport(record.transport)]
|
||||
swarm_sync_peer_count = len([record for record in sync_records if str(record.source or "") == "swarm"])
|
||||
swarm_push_peer_count = len([record for record in push_records if str(record.source or "") == "swarm"])
|
||||
swarm_pull_ok = bool(swarm_pull.get("ok")) and not bool(swarm_pull.get("skipped"))
|
||||
if swarm_pull_ok or manifest is not None or swarm_sync_peer_count > 0:
|
||||
bootstrap_state = "ready"
|
||||
bootstrap_detail = "Bootstrap peer discovery is ready."
|
||||
elif bootstrap_seed_peers:
|
||||
bootstrap_state = "connecting"
|
||||
bootstrap_detail = "Bootstrap seeds are configured; local node stays active and retries in the background."
|
||||
else:
|
||||
bootstrap_state = "solo"
|
||||
bootstrap_detail = "No bootstrap seeds configured; local node is running in solo mode."
|
||||
snapshot = {
|
||||
"node_mode": mode,
|
||||
"private_transport_required": private_transport_required,
|
||||
"bootstrap_state": bootstrap_state,
|
||||
"bootstrap_detail": bootstrap_detail,
|
||||
"skipped_clearnet_peer_count": skipped_clearnet_peers,
|
||||
"pruned_clearnet_peer_count": pruned_clearnet_peers,
|
||||
"manifest_loaded": manifest is not None,
|
||||
|
||||
@@ -148,12 +148,15 @@ def _is_private_infonet_transport(transport: str) -> bool:
|
||||
|
||||
def _configured_bootstrap_seed_peer_urls() -> list[str]:
|
||||
from services.config import get_settings
|
||||
from services.mesh.mesh_fleet_defaults import configured_bootstrap_seed_peers_with_fleet_default
|
||||
from services.mesh.mesh_router import parse_configured_relay_peers
|
||||
|
||||
settings = get_settings()
|
||||
primary = str(getattr(settings, "MESH_BOOTSTRAP_SEED_PEERS", "") or "").strip()
|
||||
legacy = str(getattr(settings, "MESH_DEFAULT_SYNC_PEERS", "") or "").strip()
|
||||
return parse_configured_relay_peers(primary or legacy)
|
||||
return configured_bootstrap_seed_peers_with_fleet_default(
|
||||
parse_configured_relay_peers(primary or legacy)
|
||||
)
|
||||
|
||||
|
||||
def _refresh_node_peer_store(*, now: float | None = None) -> dict[str, Any]:
|
||||
|
||||
@@ -39,7 +39,10 @@ class Settings(BaseSettings):
|
||||
MESH_PUBLIC_PEER_URL: str = ""
|
||||
# Bootstrap seeds are discovery hints, not authoritative network roots.
|
||||
# Nodes promote healthy discovered peers from the store/manifest over time.
|
||||
MESH_BOOTSTRAP_SEED_PEERS: str = "http://gqpbunqbgtkcqilvclm3xrkt3zowjyl3s62kkktvojgvxzizamvbrqid.onion:8000"
|
||||
MESH_BOOTSTRAP_SEED_PEERS: str = ""
|
||||
# Optional comma-separated override for the public fleet's bundled onion seeds.
|
||||
# This lets seed rotation/addition ship as env/config without weakening private sync.
|
||||
MESH_FLEET_SEED_PEERS: str = ""
|
||||
# Legacy name kept for older compose/.env files.
|
||||
MESH_DEFAULT_SYNC_PEERS: str = ""
|
||||
# Infonet/Wormhole must fail closed to private transports by default.
|
||||
|
||||
@@ -10,6 +10,9 @@ FLEET_NETWORK_ID = "sb-testnet-0"
|
||||
FLEET_SEED_ONION_URL = (
|
||||
"http://gqpbunqbgtkcqilvclm3xrkt3zowjyl3s62kkktvojgvxzizamvbrqid.onion:8000"
|
||||
)
|
||||
FLEET_SEED_ONION_URLS = (
|
||||
FLEET_SEED_ONION_URL,
|
||||
)
|
||||
FLEET_BOOTSTRAP_SIGNER_PUBLIC_KEY_B64 = (
|
||||
"ul1d0kj/ODPIp0OhHzX8eLAVXzJ3CVvzW1vn2IC6q3I="
|
||||
)
|
||||
@@ -56,9 +59,35 @@ def effective_peer_push_secret() -> str:
|
||||
return ""
|
||||
|
||||
|
||||
def _dedupe_peer_urls(peers: list[str]) -> list[str]:
|
||||
from services.mesh.mesh_router import parse_configured_relay_peers
|
||||
|
||||
seen: set[str] = set()
|
||||
normalized: list[str] = []
|
||||
for peer in parse_configured_relay_peers(",".join(str(item or "") for item in peers)):
|
||||
if peer in seen:
|
||||
continue
|
||||
seen.add(peer)
|
||||
normalized.append(peer)
|
||||
return normalized
|
||||
|
||||
|
||||
def effective_fleet_seed_peers() -> list[str]:
|
||||
try:
|
||||
from services.config import get_settings
|
||||
|
||||
configured = str(getattr(get_settings(), "MESH_FLEET_SEED_PEERS", "") or "").strip()
|
||||
if configured:
|
||||
return _dedupe_peer_urls([configured])
|
||||
except Exception:
|
||||
pass
|
||||
return _dedupe_peer_urls(list(FLEET_SEED_ONION_URLS))
|
||||
|
||||
|
||||
def configured_bootstrap_seed_peers_with_fleet_default(peers: list[str]) -> list[str]:
|
||||
if peers:
|
||||
return peers
|
||||
normalized_peers = _dedupe_peer_urls(peers)
|
||||
if normalized_peers:
|
||||
return normalized_peers
|
||||
if infonet_fleet_join_enabled():
|
||||
return [FLEET_SEED_ONION_URL]
|
||||
return effective_fleet_seed_peers()
|
||||
return []
|
||||
|
||||
@@ -301,8 +301,9 @@ def refresh_swarm_manifest_from_seeds(*, now: float | None = None, force: bool =
|
||||
if not _signer_public_key_b64():
|
||||
return {"ok": False, "detail": "MESH_BOOTSTRAP_SIGNER_PUBLIC_KEY is not configured"}
|
||||
|
||||
last_error = "manifest fetch failed"
|
||||
for seed_url in _configured_seed_peer_urls():
|
||||
seed_urls = _configured_seed_peer_urls()
|
||||
last_error = "bootstrap seeds unreachable; local node will retry"
|
||||
for seed_url in seed_urls:
|
||||
manifest = fetch_remote_bootstrap_manifest(seed_url, now=timestamp)
|
||||
if manifest is None:
|
||||
continue
|
||||
@@ -311,12 +312,18 @@ def refresh_swarm_manifest_from_seeds(*, now: float | None = None, force: bool =
|
||||
return {
|
||||
"ok": True,
|
||||
"seed_peer_url": seed_url,
|
||||
"tried_seed_count": len(seed_urls),
|
||||
"peer_count": len(manifest.peers),
|
||||
"merged_peer_count": merged,
|
||||
}
|
||||
except Exception as exc:
|
||||
last_error = str(exc or type(exc).__name__)
|
||||
return {"ok": False, "detail": last_error}
|
||||
return {
|
||||
"ok": False,
|
||||
"detail": last_error,
|
||||
"tried_seed_count": len(seed_urls),
|
||||
"retrying": bool(seed_urls),
|
||||
}
|
||||
|
||||
|
||||
def announce_local_peer_to_seeds(*, now: float | None = None, force: bool = False) -> dict[str, Any]:
|
||||
|
||||
@@ -103,11 +103,12 @@ def _invite_lookup_request_timeout(peer_url: str) -> tuple[int, int]:
|
||||
def _bootstrap_seed_peer_urls() -> set[str]:
|
||||
try:
|
||||
from services.config import get_settings
|
||||
from services.mesh.mesh_fleet_defaults import configured_bootstrap_seed_peers_with_fleet_default
|
||||
from services.mesh.mesh_router import parse_configured_relay_peers
|
||||
|
||||
seeds: set[str] = set()
|
||||
raw = str(getattr(get_settings(), "MESH_BOOTSTRAP_SEED_PEERS", "") or "")
|
||||
for peer in parse_configured_relay_peers(raw):
|
||||
for peer in configured_bootstrap_seed_peers_with_fleet_default(parse_configured_relay_peers(raw)):
|
||||
normalized = str(peer or "").strip().rstrip("/")
|
||||
if normalized:
|
||||
seeds.add(normalized)
|
||||
@@ -318,6 +319,8 @@ def _configured_public_lookup_peer_urls() -> list[str]:
|
||||
from services.mesh.mesh_router import active_sync_peer_urls, parse_configured_relay_peers
|
||||
|
||||
settings = get_settings()
|
||||
from services.mesh.mesh_fleet_defaults import configured_bootstrap_seed_peers_with_fleet_default
|
||||
|
||||
candidates: list[str] = []
|
||||
# Operator-configured peers first, then recently active fleet nodes.
|
||||
# Invite handles are minted on a specific node; cold bootstrap seeds
|
||||
@@ -330,7 +333,11 @@ def _configured_public_lookup_peer_urls() -> list[str]:
|
||||
for raw in (
|
||||
getattr(settings, "MESH_BOOTSTRAP_SEED_PEERS", ""),
|
||||
):
|
||||
candidates.extend(parse_configured_relay_peers(str(raw or "")))
|
||||
candidates.extend(
|
||||
configured_bootstrap_seed_peers_with_fleet_default(
|
||||
parse_configured_relay_peers(str(raw or ""))
|
||||
)
|
||||
)
|
||||
except Exception:
|
||||
return []
|
||||
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
from services.mesh.mesh_fleet_defaults import (
|
||||
FLEET_SEED_ONION_URL,
|
||||
FLEET_PEER_PUSH_SECRET,
|
||||
configured_bootstrap_seed_peers_with_fleet_default,
|
||||
effective_bootstrap_signer_public_key_b64,
|
||||
effective_fleet_seed_peers,
|
||||
effective_peer_push_secret,
|
||||
infonet_fleet_join_enabled,
|
||||
)
|
||||
@@ -9,8 +12,8 @@ from services.mesh.mesh_fleet_defaults import (
|
||||
def test_fleet_defaults_apply_when_join_enabled(monkeypatch):
|
||||
from services.config import get_settings
|
||||
|
||||
monkeypatch.delenv("MESH_BOOTSTRAP_SIGNER_PUBLIC_KEY", raising=False)
|
||||
monkeypatch.delenv("MESH_PEER_PUSH_SECRET", raising=False)
|
||||
monkeypatch.setenv("MESH_BOOTSTRAP_SIGNER_PUBLIC_KEY", "")
|
||||
monkeypatch.setenv("MESH_PEER_PUSH_SECRET", "")
|
||||
monkeypatch.setenv("MESH_INFONET_FLEET_JOIN", "true")
|
||||
get_settings.cache_clear()
|
||||
try:
|
||||
@@ -21,6 +24,52 @@ def test_fleet_defaults_apply_when_join_enabled(monkeypatch):
|
||||
get_settings.cache_clear()
|
||||
|
||||
|
||||
def test_empty_bootstrap_peers_use_fleet_seed_defaults(monkeypatch):
|
||||
from services.config import get_settings
|
||||
|
||||
monkeypatch.delenv("MESH_FLEET_SEED_PEERS", raising=False)
|
||||
monkeypatch.setenv("MESH_INFONET_FLEET_JOIN", "true")
|
||||
get_settings.cache_clear()
|
||||
try:
|
||||
assert configured_bootstrap_seed_peers_with_fleet_default([]) == [FLEET_SEED_ONION_URL]
|
||||
finally:
|
||||
get_settings.cache_clear()
|
||||
|
||||
|
||||
def test_configured_bootstrap_peers_override_fleet_defaults(monkeypatch):
|
||||
from services.config import get_settings
|
||||
|
||||
monkeypatch.setenv("MESH_INFONET_FLEET_JOIN", "true")
|
||||
get_settings.cache_clear()
|
||||
try:
|
||||
assert configured_bootstrap_seed_peers_with_fleet_default(
|
||||
["http://alphaexample.onion:8000", "http://alphaexample.onion:8000"]
|
||||
) == ["http://alphaexample.onion:8000"]
|
||||
finally:
|
||||
get_settings.cache_clear()
|
||||
|
||||
|
||||
def test_fleet_seed_override_can_ship_multiple_seeds(monkeypatch):
|
||||
from services.config import get_settings
|
||||
|
||||
monkeypatch.setenv(
|
||||
"MESH_FLEET_SEED_PEERS",
|
||||
"http://alphaexample.onion:8000,http://betaexample.onion:8000,http://alphaexample.onion:8000",
|
||||
)
|
||||
get_settings.cache_clear()
|
||||
try:
|
||||
assert effective_fleet_seed_peers() == [
|
||||
"http://alphaexample.onion:8000",
|
||||
"http://betaexample.onion:8000",
|
||||
]
|
||||
assert configured_bootstrap_seed_peers_with_fleet_default([]) == [
|
||||
"http://alphaexample.onion:8000",
|
||||
"http://betaexample.onion:8000",
|
||||
]
|
||||
finally:
|
||||
get_settings.cache_clear()
|
||||
|
||||
|
||||
def test_fleet_defaults_disabled(monkeypatch):
|
||||
from services.config import get_settings
|
||||
|
||||
|
||||
@@ -479,4 +479,4 @@ def test_meshnode_scripts_enable_private_hashchain_runtime():
|
||||
assert "MESH_INFONET_ALLOW_CLEARNET_SYNC=false" in script
|
||||
assert "MESH_ARTI_ENABLED=true" in script
|
||||
assert "MESH_DM_HASHCHAIN_SPOOL_LIMIT=2" in script
|
||||
assert "gqpbunqbgtkcqilvclm3xrkt3zowjyl3s62kkktvojgvxzizamvbrqid.onion:8000" in script
|
||||
assert "sb-testnet fleet defaults" in script
|
||||
|
||||
@@ -16,6 +16,7 @@ from services.mesh.mesh_swarm_runtime import (
|
||||
merge_manifest_into_peer_store,
|
||||
peer_registry_enabled,
|
||||
publish_registry_manifest,
|
||||
refresh_swarm_manifest_from_seeds,
|
||||
record_peer_announcement,
|
||||
)
|
||||
|
||||
@@ -180,6 +181,30 @@ def test_parse_bootstrap_manifest_dict_rejects_expired():
|
||||
)
|
||||
|
||||
|
||||
def test_refresh_swarm_manifest_reports_retrying_when_all_seeds_unreachable(monkeypatch):
|
||||
from services.config import get_settings
|
||||
|
||||
monkeypatch.setenv("MESH_BOOTSTRAP_SIGNER_PUBLIC_KEY", "ul1d0kj/ODPIp0OhHzX8eLAVXzJ3CVvzW1vn2IC6q3I=")
|
||||
monkeypatch.setenv(
|
||||
"MESH_BOOTSTRAP_SEED_PEERS",
|
||||
"http://seed-a.onion:8000,http://seed-b.onion:8000",
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
"services.mesh.mesh_swarm_runtime.fetch_remote_bootstrap_manifest",
|
||||
lambda *_args, **_kwargs: None,
|
||||
)
|
||||
get_settings.cache_clear()
|
||||
try:
|
||||
result = refresh_swarm_manifest_from_seeds(force=True, now=1_750_000_000)
|
||||
finally:
|
||||
get_settings.cache_clear()
|
||||
|
||||
assert result["ok"] is False
|
||||
assert result["retrying"] is True
|
||||
assert result["tried_seed_count"] == 2
|
||||
assert result["detail"] == "bootstrap seeds unreachable; local node will retry"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_bootstrap_manifest_endpoint_serves_live_registry(tmp_path, monkeypatch):
|
||||
import main
|
||||
|
||||
Reference in New Issue
Block a user