summaryrefslogtreecommitdiffstats
path: root/poc
diff options
context:
space:
mode:
authorChristophe Besson <cbesson@gmail.com>2026-09-19 14:24:13 +0200
committerChristophe Besson <cbesson@gmail.com>2026-09-19 14:24:13 +0200
commit86188385cbdae1ee90c1dca7a7b9db2edef1ecd4 (patch)
treecc01153f05e84ad6cd34556caecd3f4bc335d0bd /poc
parentd2495a2c4b89fbbfc18cefec83ae96cabdd745e2 (diff)
downloadmeshbay-86188385cbdae1ee90c1dca7a7b9db2edef1ecd4.tar.gz
style: ruff's own fixes, mechanically applied
`ruff check .` had gone unrun long enough to report 568 errors, which is the same as having no linter: the next real finding would have been invisible in the noise. This is the 521 it fixes by itself, in 173 files, and nothing else — the 98 it cannot fix are the next commit. What actually changed: import sorting (225), imports nobody used (87, none of them a re-export — no `__init__.py` is touched, which was the one way this could have broken an import elsewhere), `datetime.timezone.utc` to `datetime.UTC` (69) and `asyncio.TimeoutError` to `TimeoutError` (18), both plain aliases on the 3.12 this project requires, `Optional[X]` to `X | None` (24), and f-strings with nothing to interpolate (19). Checked rather than assumed: every module in the three packages still imports, and the suite is 2893 passed — the same count, test for test, as the merge before it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Diffstat (limited to 'poc')
-rw-r--r--poc/spike1_crypto.py15
-rw-r--r--poc/spike2_hub.py11
-rw-r--r--poc/spike3_node.py17
-rw-r--r--poc/spike4_nat.py26
-rw-r--r--poc/spike5_client.py16
-rw-r--r--poc/spike5_node.py16
-rw-r--r--poc/spike6_gek.py20
7 files changed, 79 insertions, 42 deletions
diff --git a/poc/spike1_crypto.py b/poc/spike1_crypto.py
index 335758c..1e8491c 100644
--- a/poc/spike1_crypto.py
+++ b/poc/spike1_crypto.py
@@ -4,17 +4,20 @@ MeshBay — Spike 1: Crypto Primitives
Validates the full cryptographic stack needed for MeshBay.
"""
-import os, time, base64, sys
+import base64
+import os
+import sys
+import time
+import blake3
+import jwt
+from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
from cryptography.hazmat.primitives.asymmetric.x25519 import X25519PrivateKey
+from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.primitives.ciphers.aead import ChaCha20Poly1305
-from cryptography.hazmat.primitives.kdf.hkdf import HKDF
from cryptography.hazmat.primitives.kdf.argon2 import Argon2id
-from cryptography.hazmat.primitives import hashes, serialization
-from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
-import blake3
-import jwt
+from cryptography.hazmat.primitives.kdf.hkdf import HKDF
PASS = "✓"
FAIL = "✗"
diff --git a/poc/spike2_hub.py b/poc/spike2_hub.py
index f8c1b08..a0ebd6f 100644
--- a/poc/spike2_hub.py
+++ b/poc/spike2_hub.py
@@ -4,10 +4,15 @@ Minimal FastAPI hub: user registration, JWT issuance, node announcement.
In-memory storage only — not persistent across restarts.
"""
-from fastapi import FastAPI, HTTPException, Depends, Header
-from pydantic import BaseModel
+import base64
+import os
+import time
+import uuid
+
+import jwt
from cryptography.hazmat.primitives.kdf.argon2 import Argon2id
-import jwt, uuid, os, time, base64
+from fastapi import Depends, FastAPI, Header, HTTPException
+from pydantic import BaseModel
app = FastAPI(title="MeshBay Hub POC", version="0.1.0")
diff --git a/poc/spike3_node.py b/poc/spike3_node.py
index c0ddde0..0b6d694 100644
--- a/poc/spike3_node.py
+++ b/poc/spike3_node.py
@@ -12,12 +12,17 @@ Sequence:
8. Simulate token refresh
"""
-import asyncio, httpx, base64, json, os, time
+import asyncio
+import base64
+import json
+import time
from pathlib import Path
+
+import httpx
+import jwt
+from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
from cryptography.hazmat.primitives.asymmetric.x25519 import X25519PrivateKey
-from cryptography.hazmat.primitives import serialization
-import jwt
HUB_URL = "http://meshbay.org"
STATE_FILE = Path("node_state.json") # persists keys and tokens between runs
@@ -52,7 +57,7 @@ def _load_or_generate_keys(state: dict) -> tuple:
sk_x = X25519PrivateKey.generate()
state["sk_ed25519_b64"] = _sk_to_b64(sk_ed)
state["sk_x25519_b64"] = _sk_to_b64(sk_x)
- print(f" Generated new keypair")
+ print(" Generated new keypair")
return sk_ed, sk_x
# ── Main ──────────────────────────────────────────────────────────────────────
@@ -101,7 +106,7 @@ async def main():
state["user_id"] = r.json()["user_id"]
print(f" {PASS} Registered — user_id={state['user_id'][:8]}...")
elif r.status_code == 409:
- print(f" Already registered (409) — continuing with existing account")
+ print(" Already registered (409) — continuing with existing account")
else:
raise RuntimeError(f"Register failed: {r.status_code} {r.text}")
@@ -149,7 +154,7 @@ async def main():
node_id = r.json()["node_id"]
state["node_id"] = node_id
print(f" {PASS} Node announced — node_id={node_id[:8]}...")
- print(f" endpoint_hint : None (STUN/UPnP discovery in Spike 4)")
+ print(" endpoint_hint : None (STUN/UPnP discovery in Spike 4)")
# ── Step 7: Retrieve node record ──────────────────────────────────────
print("\n[ 7 ] Retrieve node record from hub")
diff --git a/poc/spike4_nat.py b/poc/spike4_nat.py
index 44bcdca..e34a4c4 100644
--- a/poc/spike4_nat.py
+++ b/poc/spike4_nat.py
@@ -12,9 +12,15 @@ Tests:
E. Update hub endpoint_hint
"""
-import asyncio, socket, struct, os, json, httpx, time, subprocess
+import asyncio
+import json
+import os
+import socket
+import struct
from pathlib import Path
+import httpx
+
PASS = "✓"; FAIL = "✗"; SKIP = "–"
LOCAL_PORT = 19000
@@ -148,7 +154,7 @@ async def udp_hole_punch_test(local_port: int) -> tuple[bool, str|None, str|None
try:
await asyncio.wait_for(recv_event.wait(), timeout=8)
- except asyncio.TimeoutError:
+ except TimeoutError:
pass
finally:
transport.close()
@@ -192,7 +198,7 @@ async def main():
print(f" {FAIL} {nat_type}")
print(f" Cloudflare STUN : {stun_ip1}:{stun_port1}")
print(f" Google STUN : {stun_ip2}:{stun_port2}")
- print(f" → Hole punching unreliable; TURN relay required")
+ print(" → Hole punching unreliable; TURN relay required")
elif stun_ip1:
nat_type = "Unknown (only one STUN server responded)"
print(f" {SKIP} {nat_type}")
@@ -202,7 +208,7 @@ async def main():
print(f" {FAIL} {nat_type}")
# ── Phase C: Bidirectional UDP hole punching ───────────────────────────────
- print(f"\n[ C ] Bidirectional UDP hole punch (node → meshbay.org → echo back)")
+ print("\n[ C ] Bidirectional UDP hole punch (node → meshbay.org → echo back)")
print(f" Starting UDP echo server on meshbay.org:{MESHBAY_ECHO_PORT} ...")
udp_ok = False
seen_ext_addr = None
@@ -234,7 +240,7 @@ async def main():
print(f" {FAIL} Error: {e}")
# ── Phase D: UPnP ─────────────────────────────────────────────────────────
- print(f"\n[ D ] UPnP port mapping")
+ print("\n[ D ] UPnP port mapping")
upnp_ip, upnp_port = try_upnp(LOCAL_PORT)
if upnp_ip:
print(f" {PASS} Mapped {upnp_ip}:{upnp_port}")
@@ -243,7 +249,7 @@ async def main():
print(f" {FAIL} UPnP not available on this router")
# ── Phase E: Update hub ────────────────────────────────────────────────────
- print(f"\n[ E ] Update endpoint_hint on hub")
+ print("\n[ E ] Update endpoint_hint on hub")
if endpoint_hint and state.get("username"):
async with httpx.AsyncClient(timeout=10) as client:
r = await client.post(f"{HUB_URL}/v1/users/login", json={
@@ -270,10 +276,10 @@ async def main():
print(f" UPnP : {PASS + ' works' if upnp_ip else FAIL + ' disabled'}")
print(f" endpoint_hint : {endpoint_hint or 'none'}")
if udp_ok:
- print(f"\n P2P UDP is functional. QUIC transport will work.")
- print(f" Spike 4 COMPLETE.")
+ print("\n P2P UDP is functional. QUIC transport will work.")
+ print(" Spike 4 COMPLETE.")
else:
- print(f"\n P2P blocked — TURN relay needed for this configuration.")
- print(f" Spike 4 COMPLETE (with finding: relay required).")
+ print("\n P2P blocked — TURN relay needed for this configuration.")
+ print(" Spike 4 COMPLETE (with finding: relay required).")
asyncio.run(main())
diff --git a/poc/spike5_client.py b/poc/spike5_client.py
index 11b3ac0..6ac2fba 100644
--- a/poc/spike5_client.py
+++ b/poc/spike5_client.py
@@ -12,12 +12,18 @@ Acts as the "file requester":
- Reports timing and results
"""
-import asyncio, json, base64, struct, time, sys
+import asyncio
+import base64
+import json
+import struct
+import sys
+import time
+
+import blake3
+from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PublicKey
from cryptography.hazmat.primitives.ciphers.aead import ChaCha20Poly1305
from cryptography.hazmat.primitives.kdf.hkdf import HKDF
-from cryptography.hazmat.primitives import hashes
-import blake3
PORT = 19003
CHUNK_INDEX = 0
@@ -115,7 +121,7 @@ async def handle_node(reader, writer):
total_ms = recv_ms + verify_ms
print(f"\n {'='*50}")
- print(f" Timings:")
+ print(" Timings:")
print(f" Network receive : {recv_ms:.0f} ms")
print(f" Verify+decrypt : {verify_ms:.1f} ms")
print(f" Total : {total_ms:.0f} ms")
@@ -133,7 +139,7 @@ async def main():
async with server:
try:
await asyncio.wait_for(server.serve_forever(), timeout=30)
- except asyncio.TimeoutError:
+ except TimeoutError:
print(f" {FAIL} Timeout — node did not connect within 30s")
sys.exit(1)
diff --git a/poc/spike5_node.py b/poc/spike5_node.py
index 6104e00..b560dc1 100644
--- a/poc/spike5_node.py
+++ b/poc/spike5_node.py
@@ -14,13 +14,19 @@ Note: node initiates the TCP connection (reversed for POC — in production,
the QUIC client connects to the node using the hole-punching from Spike 4).
"""
-import asyncio, json, base64, struct, os, time
+import asyncio
+import base64
+import json
+import os
+import struct
+import time
from pathlib import Path
+
+import blake3
+from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
from cryptography.hazmat.primitives.ciphers.aead import ChaCha20Poly1305
from cryptography.hazmat.primitives.kdf.hkdf import HKDF
-from cryptography.hazmat.primitives import hashes, serialization
-import blake3
MESHBAY_HOST = "meshbay.org"
MESHBAY_PORT = 19003
@@ -125,7 +131,7 @@ async def main():
print(f" {PASS} Test file: {TEST_FILE} ({file_size/1024/1024:.1f} MB)")
# Pre-compute file hash (used in HKDF info string — identifies the file)
- print(f" Computing file hash...")
+ print(" Computing file hash...")
t0 = time.perf_counter()
file_hash = blake3.blake3(TEST_FILE.read_bytes()).digest()
print(f" {PASS} File hash: {file_hash.hex()[:16]}... ({(time.perf_counter()-t0)*1000:.0f}ms)")
@@ -166,7 +172,7 @@ async def main():
print(f" {PASS} Sent {payload_kb:.1f} KB in {send_ms:.0f}ms ({throughput:.1f} MB/s)")
print(f"\n {'='*50}")
- print(f" Timings (node side):")
+ print(" Timings (node side):")
print(f" Encrypt + sign : {enc_ms:.1f} ms")
print(f" TCP send : {send_ms:.0f} ms")
print(f" Total : {total_ms:.0f} ms")
diff --git a/poc/spike6_gek.py b/poc/spike6_gek.py
index 89ab06c..3595d6d 100644
--- a/poc/spike6_gek.py
+++ b/poc/spike6_gek.py
@@ -16,14 +16,20 @@ Validates the full GEK lifecycle:
The hub stores opaque encrypted blobs — it never sees the GEK in cleartext.
"""
-import asyncio, httpx, base64, os, json, time
+import asyncio
+import base64
+import json
+import os
+import time
from pathlib import Path
+
+import blake3
+import httpx
+from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
from cryptography.hazmat.primitives.asymmetric.x25519 import X25519PrivateKey, X25519PublicKey
from cryptography.hazmat.primitives.ciphers.aead import ChaCha20Poly1305
from cryptography.hazmat.primitives.kdf.hkdf import HKDF
-from cryptography.hazmat.primitives import hashes, serialization
-import blake3
HUB_URL = "http://meshbay.org"
STATE_FILE = Path("node_state.json")
@@ -218,7 +224,7 @@ async def main():
wrap_ms = (time.perf_counter()-t0)*1000
print(f" {PASS} Wrapped in {wrap_ms:.2f}ms")
print(f" pk_eph : {bundle_bob['pk_eph_b64'][:24]}...")
- print(f" (different from Alice's bundle — ephemeral key is unique)")
+ print(" (different from Alice's bundle — ephemeral key is unique)")
r = await c.post(
f"{HUB_URL}/v1/groups/{group_id}/members/bob_member/gek",
@@ -301,10 +307,10 @@ async def main():
print(f" {PASS} Wrong private key correctly rejected (AEAD auth failed)")
print("\n" + "="*55)
- print(f"Spike 6 COMPLETE — GEK distribution validated.")
+ print("Spike 6 COMPLETE — GEK distribution validated.")
print(f" wrap_gek : {wrap_ms:.2f} ms")
print(f" unwrap_gek : {unwrap_ms:.2f} ms")
- print(f" Hub role : stores opaque bundle, never sees GEK in clear")
- print(f" Security : wrong key rejected by AEAD authentication tag")
+ print(" Hub role : stores opaque bundle, never sees GEK in clear")
+ print(" Security : wrong key rejected by AEAD authentication tag")
asyncio.run(main())