extends SceneTree
## Test: C++ DHT lookup against a JS-announced peer.
## Reads bootstrap from /tmp/layer_bootstrap.txt.
## Writes PASS/FAIL to /tmp/test_dht_lookup_result.txt.
const TIMEOUT := 20.0
const POLL_HZ := 0.05
var _peer: Object
var _found_pks: Array = []
func _init() -> void:
_start.call_deferred()
func _start() -> void:
var f := FileAccess.open("/tmp/layer_bootstrap.txt", FileAccess.READ)
if f == null:
_result("FAIL: no bootstrap")
quit()
return
var bootstrap := PackedStringArray(f.get_as_text().strip_edges().split(","))
f.close()
print("[lookup] bootstrap: %s" % str(bootstrap))
_peer = ClassDB.instantiate(&"HyperswarmMultiplayerPeer")
var kp: Dictionary = _peer.generate_dht_keypair()
var pk: PackedByteArray = kp["public_key"]
var sk: PackedByteArray = kp["secret_key"]
print("[lookup] my pk: %s" % pk.hex_encode().left(16))
_peer.dht_peer_found.connect(func(found_pk: PackedByteArray) -> void:
var hex := found_pk.hex_encode()
print("[lookup] dht_peer_found: %s" % hex.left(16))
_found_pks.append(hex)
)
var err = _peer.join_dht(pk, sk, bootstrap)
if err != OK:
_result("FAIL: join_dht=%d" % err)
quit()
return
# Wait for DHT active
var elapsed := 0.0
while elapsed < 10.0:
_peer.poll()
var status: Dictionary = _peer.get_dht_status()
if status.get("active", false):
break
await create_timer(POLL_HZ).timeout
elapsed += POLL_HZ
var dht_status: Dictionary = _peer.get_dht_status()
print("[lookup] DHT active=%s table_size=%s" % [
str(dht_status.get("active", false)),
str(dht_status.get("table_size", -1))])
if not dht_status.get("active", false):
_result("FAIL: DHT not active after 10s")
_peer.close()
quit()
return
# Lookup topic
var topic := "test-p2p-layer2".sha256_buffer()
err = _peer.lookup_topic(topic)
if err != OK:
_result("FAIL: lookup_topic=%d" % err)
_peer.close()
quit()
return
print("[lookup] lookup_topic called, polling...")
# Poll and wait for peers
elapsed = 0.0
while elapsed < TIMEOUT:
_peer.poll()
if _found_pks.size() > 0:
break
if int(elapsed * 10) % 20 == 0:
print("[lookup] elapsed=%.1f found=%d" % [elapsed, _found_pks.size()])
await create_timer(POLL_HZ).timeout
elapsed += POLL_HZ
if _found_pks.size() > 0:
# Check if we found the JS server's pk
var js_pk_file := FileAccess.open("/tmp/test_dht_js_pk.txt", FileAccess.READ)
if js_pk_file != null:
var js_pk := js_pk_file.get_as_text().strip_edges()
js_pk_file.close()
var matched := false
for fpk in _found_pks:
if fpk == js_pk:
matched = true
break
if matched:
print("[lookup] Found JS server pk — PASS")
_result("PASS")
else:
print("[lookup] Found peers but not JS server")
print("[lookup] expected: %s" % js_pk.left(16))
print("[lookup] got: %s" % str(_found_pks))
_result("FAIL: wrong pk")
else:
print("[lookup] Found %d peers (no JS pk file to verify)" % _found_pks.size())
_result("PASS")
else:
print("[lookup] No peers found after %.1fs" % elapsed)
_result("FAIL: no peers found")
_peer.close()
quit()
func _result(msg: String) -> void:
print("[lookup] RESULT: %s" % msg)
var wf := FileAccess.open("/tmp/test_dht_lookup_result.txt", FileAccess.WRITE)
if msg.begins_with("PASS"):
wf.store_string("PASS")
else:
wf.store_string("FAIL")
wf.close()