feat: v0.8 Iteration C — narrow mesh, N1-N4 uniques index, anchor convection
Topology rework. The mesh's job is width; depth now comes from knowledge.
Slots:
- Local/Wide collapse into ONE mesh pool: 20 desktop / 15 mobile
- Temp referral slots +4..+10 ABOVE the cap (10 desktop / 4 mobile), carry no
knowledge exchange, graduate into a freed mesh slot or expire (5 min TTL),
never evict an established mesh peer
- Fixes the Wide-never-fills bug: outbound paths hardcoded Local while the
growth gate counted Local only, so growth stopped at 71 and 20 slots were
inbound-only. Also closes register_connection paths that enforced no cap.
Knowledge — two-pool uniques announce (replaces N1/N2/N3 share lists):
- Pool 1 (forwardable): our N0-N2 uniques, deduped. Receiver stores shifted one
bounce deeper as N1-N3, reporter-tagged.
- Pool 2 (terminal): our N3, deduped against pool 1. Receiver stores as N4,
USED for search/resolution but NEVER re-announced. No N5 anywhere.
- Uniques merge mesh peers + social directs + CDN file authors + holder peers,
so receivers cannot tell how we know an ID
- Anchor entries carry addresses; every other entry is a bare ID. The pools
double as the anchor directory.
- Dedup at both store and announce; per-bounce caps; 2 MB payload ceiling
- Device-tiered depth: mobile holds 3 bounces and drops the terminal pool
Anchor convection (register loop retired — 0xC0 AnchorRegister deleted):
- Rolling in-memory caller window (no registration DB): a caller gets the 2
most recent viable prior callers, its address goes to the next 2, then
rotates out; still-connected callers preferred; RelayIntroduce coordinated
when both ends are live
- Request classes: entry (<2 connections) always served; top-up refused
cheaply under load, and the refusal feeds the adaptive weights
- Stochastic per-disconnect action {nothing | anchor intro | mesh intro} with
weights from local anchor density + refusal feedback. No thresholds, no
jitter timer. Recovery (mesh < 2) stays immediate and non-stochastic.
- Anchors mined from the uniques pools incl. retained pools of disconnected
peers; known_anchors demoted to a bootstrap cache
Security fixes from review: remote address poisoning (hearsay anchors could be
dialled — known_anchors/is_anchor now written only from completed handshakes),
N4 leaking back into announcements via the anchor mirror (infinite propagation),
missing payload size caps, unbounded candidate scoring, and a bulk SQLite write
held under the ConnectionManager mutex.
deploy.sh: version regex now captures pre-release suffixes (0.8.0-alpha would
have truncated to 0.8.0 and broken every artifact path), announce channel
derives from the suffix, and the anchor runs --publish-registry at genesis.
228 core tests; a3 integration 9/9; new c_topology_test.sh 33/33 (both
independently re-run). EDM corpse, session-relay gating, Iteration A/B intact.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LGiPD2cF75mnvneSCjdDC5
This commit is contained in:
parent
36e3871c4b
commit
e756fabb11
14 changed files with 5503 additions and 2367 deletions
|
|
@ -27,6 +27,12 @@ check() { # check <desc> <cmd...>
|
|||
else FAIL=$((FAIL+1)); echo "FAIL: $desc"; fi
|
||||
}
|
||||
strip_ansi() { sed 's/\x1b\[[0-9;]*m//g' "$1" | grep -v "WARN.*netlink\|WARN.*buffer_tool"; }
|
||||
# Same noise filter for the tail-window checks below. The netlink/mDNS watcher
|
||||
# logs in unpredictable bursts, and a burst landing between a REPL command and
|
||||
# its assertion pushes the answer out of a raw `tail -N` window — a false
|
||||
# failure with nothing wrong in the node.
|
||||
quiet_tail() { grep -av "netlink\|buffer_tool\|iroh_quinn\|swarm_discovery" "$1" | tail -"$2"; }
|
||||
export -f quiet_tail
|
||||
sq() { sqlite3 "/tmp/itsgoin-test$1/itsgoin.db" "$2"; }
|
||||
|
||||
cleanup() {
|
||||
|
|
@ -91,7 +97,7 @@ sleep 3
|
|||
echo "search rust" >&15
|
||||
sleep 8
|
||||
check "node3 re-search finds nothing after signed delete" \
|
||||
bash -c 'tail -20 /tmp/itsgoin-cli3.log | grep -q "no registry matches"'
|
||||
bash -c 'quiet_tail /tmp/itsgoin-cli3.log 20 | grep -q "no registry matches"'
|
||||
|
||||
echo "== step 3: greeting roundtrip =="
|
||||
# node2's bio post id (latest Profile post) from its DB.
|
||||
|
|
@ -128,7 +134,8 @@ sleep 4
|
|||
echo "search rust" >&15
|
||||
sleep 8
|
||||
check "node3 sees exactly one (newest) entry for node2's persona" \
|
||||
bash -c 'tail -6 /tmp/itsgoin-cli3.log | grep -c "rust" | grep -q "^1$" && tail -6 /tmp/itsgoin-cli3.log | grep -q AliceV2'
|
||||
bash -c 'quiet_tail /tmp/itsgoin-cli3.log 6 | grep -c "rust" | grep -q "^1$" &&
|
||||
quiet_tail /tmp/itsgoin-cli3.log 6 | grep -q AliceV2'
|
||||
|
||||
echo
|
||||
echo "== results: $PASS passed, $FAIL failed =="
|
||||
|
|
|
|||
278
scripts/c_topology_test.sh
Executable file
278
scripts/c_topology_test.sh
Executable file
|
|
@ -0,0 +1,278 @@
|
|||
#!/usr/bin/env bash
|
||||
# v0.8 Iteration C integration test — TOPOLOGY.
|
||||
#
|
||||
# Run from the repo root after `cargo build -p itsgoin-cli`, AFTER
|
||||
# scripts/a3_integration_test.sh (C does not replace A). Drives interactive
|
||||
# REPLs over FIFOs, asserts by grepping logs and by sqlite3 against node DBs.
|
||||
#
|
||||
# SCENARIO 1 Two-pool uniques exchange over a chain: pool 1 shifts one bounce
|
||||
# deeper per hop, pool 2 lands at N4, and N4 is USED but NEVER
|
||||
# re-announced (no N5 anywhere). Plus the §layers privacy
|
||||
# invariant: only anchor entries carry an address.
|
||||
# SCENARIO 2 Anchor convection: the rolling window hands each caller the 2
|
||||
# most recent prior callers, produces a REAL connection, rotates
|
||||
# entries out after 2 hand-outs, coordinates a RelayIntroduce when
|
||||
# both ends are live, and refuses a top-up CHEAPLY.
|
||||
# SCENARIO 3 Temp referral slots: allocated ABOVE the mesh cap, carrying no
|
||||
# knowledge, never evicting an established mesh peer, graduating
|
||||
# into a freed mesh slot.
|
||||
# STANDING 0xC0 AnchorRegister is gone; no automatic session relay anywhere.
|
||||
#
|
||||
# Exit code 0 = all checks passed. Logs: /tmp/itsgoin-ctop{1..7}.log
|
||||
set -u
|
||||
cd "$(dirname "$0")/.."
|
||||
BIN=target/debug/itsgoin
|
||||
[ -x "$BIN" ] || { echo "build first: cargo build -p itsgoin-cli"; exit 2; }
|
||||
|
||||
PASS=0; FAIL=0
|
||||
check() { # check <desc> <cmd...>
|
||||
local desc="$1"; shift
|
||||
if "$@" >/dev/null 2>&1; then PASS=$((PASS+1)); echo "PASS: $desc";
|
||||
else FAIL=$((FAIL+1)); echo "FAIL: $desc"; fi
|
||||
}
|
||||
strip_ansi() { sed 's/\x1b\[[0-9;]*m//g' "$1" | grep -v "WARN.*netlink\|WARN.*buffer_tool"; }
|
||||
sq() { sqlite3 "/tmp/itsgoin-ctop$1/itsgoin.db" "$2"; }
|
||||
|
||||
# Is `id` (hex) present in node N's uniques index at `bounce`?
|
||||
at_bounce() { # at_bounce <node> <id_hex> <bounce>
|
||||
[ "$(sq "$1" "SELECT count(*) FROM reachable WHERE lower(hex(reachable_id))='$2' AND bounce=$3")" != "0" ]
|
||||
}
|
||||
anywhere() { # anywhere <node> <id_hex>
|
||||
[ "$(sq "$1" "SELECT count(*) FROM reachable WHERE lower(hex(reachable_id))='$2'")" != "0" ]
|
||||
}
|
||||
# `check` runs its command via `bash -c`, which does not inherit shell functions.
|
||||
export -f strip_ansi sq at_bounce anywhere
|
||||
|
||||
NODES="1 2 3 4 5 6 7"
|
||||
FDS=""
|
||||
cleanup() {
|
||||
for fd in 21 22 23 24 25 26 27; do eval "exec $fd>&-" 2>/dev/null || true; done
|
||||
kill $(pgrep -f 'itsgoin.*itsgoin-ctop') 2>/dev/null
|
||||
rm -f /tmp/itsgoin-ctopcmd*
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
# Test gates:
|
||||
# - loopback referrals: the convection address filter is publicly-routable-only
|
||||
# (bugs-fixed #8), which would make every 127.0.0.1 referral unusable.
|
||||
# - mesh cap 2: reaches the temp-referral boundary with 4 nodes, not 21.
|
||||
# - no growth loop: on loopback the growth loop collapses any chain into a
|
||||
# full mesh in seconds, and a full mesh has no N2 at all (every peer is a
|
||||
# direct). Topology here is script-controlled on purpose.
|
||||
export ITSGOIN_TEST_ALLOW_LOOPBACK_REFERRALS=1
|
||||
export ITSGOIN_TEST_ALLOW_REGISTRY_GENESIS=1
|
||||
export ITSGOIN_TEST_NO_GROWTH=1
|
||||
export RUST_LOG="${RUST_LOG:-itsgoin_core=debug,info,iroh=warn,swarm_discovery=warn}"
|
||||
|
||||
echo "== setup =="
|
||||
kill $(pgrep -f 'itsgoin.*itsgoin-ctop') 2>/dev/null; sleep 1
|
||||
for i in $NODES; do
|
||||
rm -rf /tmp/itsgoin-ctop$i /tmp/itsgoin-ctopcmd$i /tmp/itsgoin-ctop$i.log
|
||||
mkdir -p /tmp/itsgoin-ctop$i
|
||||
mkfifo /tmp/itsgoin-ctopcmd$i
|
||||
done
|
||||
|
||||
start_node() { # start_node <n> <port> [extra env assignments...]
|
||||
local i="$1" port="$2"; shift 2
|
||||
( exec env "$@" "$BIN" /tmp/itsgoin-ctop$i --bind 127.0.0.1:$port \
|
||||
< /tmp/itsgoin-ctopcmd$i > /tmp/itsgoin-ctop$i.log 2>&1 ) &
|
||||
}
|
||||
|
||||
# Nodes 1-6: chain + convection. Node 7 joins late (fresh index).
|
||||
for i in 1 2 3 4 5 6 7; do start_node $i $((18430 + i)) ITSGOIN_TEST_NO_GROWTH=1; done
|
||||
exec 21>/tmp/itsgoin-ctopcmd1 22>/tmp/itsgoin-ctopcmd2 23>/tmp/itsgoin-ctopcmd3 \
|
||||
24>/tmp/itsgoin-ctopcmd4 25>/tmp/itsgoin-ctopcmd5 26>/tmp/itsgoin-ctopcmd6 \
|
||||
27>/tmp/itsgoin-ctopcmd7
|
||||
sleep 7
|
||||
|
||||
for i in $NODES; do
|
||||
eval "n${i}=\$(strip_ansi /tmp/itsgoin-ctop$i.log | grep -m1 'Node ID:' | awk '{print \$3}')"
|
||||
done
|
||||
echo "n1=$n1 n2=$n2 n3=$n3 n4=$n4 n5=$n5"
|
||||
[ -n "$n5" ] || { echo "FAIL: nodes did not start"; exit 1; }
|
||||
|
||||
##############################################################################
|
||||
echo
|
||||
echo "== scenario 1: two-pool uniques exchange, N4 terminal =="
|
||||
##############################################################################
|
||||
# Chain 1 - 2 - 3 - 4 - 5. Built inward so each hop's initial exchange already
|
||||
# carries the deeper knowledge where possible.
|
||||
echo "connect $n1@127.0.0.1:18431" >&22; sleep 3
|
||||
echo "connect $n2@127.0.0.1:18432" >&23; sleep 3
|
||||
echo "connect $n3@127.0.0.1:18433" >&24; sleep 3
|
||||
echo "connect $n4@127.0.0.1:18434" >&25; sleep 4
|
||||
|
||||
# Drive propagation explicitly: each uniques-pull round moves knowledge one
|
||||
# bounce along the chain. This IS the v0.8 pull — an index exchange, no posts.
|
||||
for round in 1 2 3 4 5; do
|
||||
for fd in 21 22 23 24 25; do echo "uniques-pull" >&$fd; done
|
||||
sleep 3
|
||||
done
|
||||
|
||||
check "uniques pull is an index exchange (peers exchanged, no post transfer)" \
|
||||
bash -c 'grep -q "uniques-pull: exchanged with [1-9]" /tmp/itsgoin-ctop3.log'
|
||||
|
||||
# Pool 1 shifts one bounce deeper per hop, tagged to the reporter.
|
||||
check "node1 holds node3 at N2 (pool 1 shifted one bounce)" at_bounce 1 "$n3" 2
|
||||
check "node1 holds node4 at N3" at_bounce 1 "$n4" 3
|
||||
check "node1 holds node5 at N4 (terminal pool)" at_bounce 1 "$n5" 4
|
||||
check "node5 holds node1 at N4 from the other end of the chain" at_bounce 5 "$n1" 4
|
||||
|
||||
# N4 is USED — address resolution and search read it.
|
||||
check "node1 can look up its N4 entry (used, not merely stored)" \
|
||||
bash -c 'grep -q "N4 via" <(echo "uniques '"$n5"'" >&21; sleep 3; tail -40 /tmp/itsgoin-ctop1.log)'
|
||||
|
||||
# §layers privacy invariant: ONLY anchor entries carry an address.
|
||||
check "no non-anchor index row carries an address (on any node)" \
|
||||
bash -c 'for i in 1 2 3 4 5; do
|
||||
c=$(sqlite3 /tmp/itsgoin-ctop$i/itsgoin.db \
|
||||
"SELECT count(*) FROM reachable WHERE is_anchor=0 AND addresses NOT IN ('"''"',\"[]\")");
|
||||
[ "$c" = "0" ] || exit 1; done'
|
||||
|
||||
# Per-reporter dedup: one row per (reporter, id) — an ID can never sit at two
|
||||
# depths from the same reporter.
|
||||
check "one index row per (reporter, id) — no duplicate depths" \
|
||||
bash -c 'for i in 1 2 3 4 5; do
|
||||
d=$(sqlite3 /tmp/itsgoin-ctop$i/itsgoin.db \
|
||||
"SELECT count(*) FROM (SELECT reporter_node_id, reachable_id FROM reachable
|
||||
GROUP BY reporter_node_id, reachable_id HAVING count(*) > 1)");
|
||||
[ "$d" = "0" ] || exit 1; done'
|
||||
|
||||
# Nothing is stored past bounce 4. There is no N5 table and no N5 row.
|
||||
check "stored horizon never exceeds 4 bounces" \
|
||||
bash -c 'for i in 1 2 3 4 5; do
|
||||
m=$(sqlite3 /tmp/itsgoin-ctop$i/itsgoin.db "SELECT ifnull(max(bounce),0) FROM reachable");
|
||||
[ "$m" -le 4 ] || exit 1; done'
|
||||
|
||||
# THE KEY ASSERTION: a fresh node joining node1 must NOT learn node5. node1
|
||||
# knows node5 only at N4, and the terminal pool is never re-announced.
|
||||
echo "connect $n1@127.0.0.1:18431" >&27; sleep 4
|
||||
for round in 1 2 3; do echo "uniques-pull" >&27; echo "uniques-pull" >&21; sleep 3; done
|
||||
check "N4 is never re-announced: node7 never learns node5" \
|
||||
bash -c '! /usr/bin/env bash -c "[ \"\$(sqlite3 /tmp/itsgoin-ctop7/itsgoin.db \
|
||||
\"SELECT count(*) FROM reachable WHERE lower(hex(reachable_id))=\\\"'"$n5"'\\\"\")\" != \"0\" ]"'
|
||||
check "node7 DID learn node2 (the exchange itself works)" anywhere 7 "$n2"
|
||||
|
||||
##############################################################################
|
||||
echo
|
||||
echo "== scenario 2: anchor convection =="
|
||||
##############################################################################
|
||||
# Node 6 plays the anchor: directly dialable, and it is the one every caller
|
||||
# asks. Callers are node1 and node5 — the two ENDS of the chain, so they have
|
||||
# no path to each other and a referral that lands is unambiguous.
|
||||
echo "connect $n6@127.0.0.1:18436" >&21; sleep 3
|
||||
echo "convect $n6" >&21; sleep 5 # node1 admitted; window was empty
|
||||
echo "connect $n6@127.0.0.1:18436" >&25; sleep 3
|
||||
echo "convect $n6" >&25; sleep 10 # node5 is referred to node1
|
||||
|
||||
check "anchor serves referrals out of the rolling window" \
|
||||
bash -c 'grep -q "Convection: serving referrals" /tmp/itsgoin-ctop6.log'
|
||||
check "the anchor admitted callers to the window without any registration msg" \
|
||||
bash -c 'grep -q "Convection: admitted caller to rolling window" /tmp/itsgoin-ctop6.log'
|
||||
check "the anchor referred the PRIOR caller to the next one" \
|
||||
bash -c 'grep "Convection: referring peer" /tmp/itsgoin-ctop6.log | grep -q "'"$n1"'"'
|
||||
check "a convection referral produced a real peer connection" \
|
||||
bash -c 'grep -q "Convection: connected to referred peer\|Convection: connected via introduction" \
|
||||
/tmp/itsgoin-ctop5.log'
|
||||
check "node5 is now actually mesh-connected to node1 (chain ends joined)" \
|
||||
bash -c 'echo "connections" >&25; sleep 3; strip_ansi /tmp/itsgoin-ctop5.log | tail -20 | grep -q "'"${n1:0:12}"'"'
|
||||
|
||||
# Both ends live on the anchor => coordinate an introduction, not a cold address.
|
||||
check "anchor coordinates RelayIntroduce when both ends are live" \
|
||||
bash -c 'grep -q "Convection: coordinated introduction" /tmp/itsgoin-ctop6.log'
|
||||
|
||||
# Rotation: an entry is handed to exactly 2 callers, then leaves the window.
|
||||
echo "convect $n6" >&24; sleep 6
|
||||
echo "convect $n6" >&23; sleep 6
|
||||
echo "convect $n6" >&27; sleep 6
|
||||
check "each window entry is handed out at most twice, then rotates out" \
|
||||
bash -c 'n=$(grep "Convection: referring peer" /tmp/itsgoin-ctop6.log | grep -c "referred=\"\?'"$n1"'"); \
|
||||
[ "$n" -le 2 ]'
|
||||
check "later callers are served the more RECENT callers" \
|
||||
bash -c 'grep "Convection: referring peer" /tmp/itsgoin-ctop6.log | tail -3 | grep -q "'"$n5"'\|'"$n4"'"'
|
||||
|
||||
# CHEAP REFUSAL: node3 is an interior chain node (2 mesh peers) so its request
|
||||
# is TOP-UP class. It asks node5, whose own convection window is empty — there
|
||||
# is nothing fresh to circulate, so the refusal must be one message, not a
|
||||
# burned timeout.
|
||||
echo "connect $n5@127.0.0.1:18435" >&23; sleep 4
|
||||
echo "convect $n5" >&23; sleep 6
|
||||
check "top-up against an empty window is refused" \
|
||||
bash -c 'grep -q "convection: refused" /tmp/itsgoin-ctop3.log'
|
||||
check "the refusal is CHEAP (single message, well under a timeout)" \
|
||||
bash -c 'ms=$(grep -o "convection: refused in [0-9]*ms" /tmp/itsgoin-ctop3.log | tail -1 |
|
||||
grep -o "[0-9]*" | head -1); [ -n "$ms" ] && [ "$ms" -lt 3000 ]'
|
||||
check "entry class is served even where top-up was refused" \
|
||||
bash -c 'grep "Convection: serving referrals" /tmp/itsgoin-ctop6.log | grep -q entry'
|
||||
check "the refusing anchor lands in the caller's penalty box (refusal feedback)" \
|
||||
bash -c 'echo "convection" >&23; sleep 3; strip_ansi /tmp/itsgoin-ctop3.log | tail -20 |
|
||||
grep -oE "anchor_bias [0-9.]+" | tail -1 | awk "{ exit !(\$2 < 1.0) }"'
|
||||
|
||||
##############################################################################
|
||||
echo
|
||||
echo "== scenario 3: temp referral slots (mesh cap 2) =="
|
||||
##############################################################################
|
||||
# Restart nodes 1-4 with a mesh cap of 2 so the temp-referral band is reachable.
|
||||
for fd in 21 22 23 24 25 26 27; do echo "quit" >&$fd 2>/dev/null; done
|
||||
sleep 3
|
||||
kill $(pgrep -f 'itsgoin.*itsgoin-ctop') 2>/dev/null; sleep 2
|
||||
for fd in 21 22 23 24 25 26 27; do eval "exec $fd>&-" 2>/dev/null || true; done
|
||||
|
||||
for i in 1 2 3 4; do
|
||||
rm -rf /tmp/itsgoin-ctop$i /tmp/itsgoin-ctopcmd$i /tmp/itsgoin-ctop$i.log
|
||||
mkdir -p /tmp/itsgoin-ctop$i; mkfifo /tmp/itsgoin-ctopcmd$i
|
||||
start_node $i $((18440 + i)) ITSGOIN_TEST_MESH_SLOTS=2 \
|
||||
ITSGOIN_TEST_ALLOW_LOOPBACK_REFERRALS=1 ITSGOIN_TEST_NO_GROWTH=1
|
||||
done
|
||||
exec 21>/tmp/itsgoin-ctopcmd1 22>/tmp/itsgoin-ctopcmd2 23>/tmp/itsgoin-ctopcmd3 \
|
||||
24>/tmp/itsgoin-ctopcmd4
|
||||
sleep 7
|
||||
for i in 1 2 3 4; do
|
||||
eval "m${i}=\$(strip_ansi /tmp/itsgoin-ctop$i.log | grep -m1 'Node ID:' | awk '{print \$3}')"
|
||||
done
|
||||
|
||||
# Fill node1's 2 mesh slots, then send a third peer at it.
|
||||
echo "connect $m1@127.0.0.1:18441" >&22; sleep 4
|
||||
echo "connect $m1@127.0.0.1:18441" >&23; sleep 4
|
||||
echo "slots" >&21; sleep 3
|
||||
check "mesh pool fills to the cap" \
|
||||
bash -c 'strip_ansi /tmp/itsgoin-ctop1.log | grep -q "mesh 2/2"'
|
||||
|
||||
echo "connect $m1@127.0.0.1:18441" >&24; sleep 5
|
||||
echo "slots" >&21; sleep 3
|
||||
check "the 4th peer lands in a temp referral slot ABOVE the cap" \
|
||||
bash -c 'strip_ansi /tmp/itsgoin-ctop1.log | tail -30 | grep -q "mesh 2/2 temp-referral 1/"'
|
||||
check "an established mesh peer was never evicted to make room" \
|
||||
bash -c 'strip_ansi /tmp/itsgoin-ctop1.log | tail -30 | grep -q "mesh 2/2"'
|
||||
check "the temp slot carries NO knowledge (never a reporter in our index)" \
|
||||
bash -c '[ "$(sqlite3 /tmp/itsgoin-ctop1/itsgoin.db \
|
||||
"SELECT count(*) FROM reachable WHERE lower(hex(reporter_node_id))=\"'"$m4"'\"")" = "0" ]'
|
||||
check "and a temp peer is never written to mesh_peers" \
|
||||
bash -c '[ "$(sqlite3 /tmp/itsgoin-ctop1/itsgoin.db \
|
||||
"SELECT count(*) FROM mesh_peers WHERE lower(hex(node_id))=\"'"$m4"'\"")" = "0" ]'
|
||||
|
||||
# Free a mesh slot: the temp peer graduates into it. The wait covers the mesh
|
||||
# keepalive interval (30s) — an abruptly-gone QUIC peer is noticed when the
|
||||
# next keepalive write fails, not instantly.
|
||||
echo "quit" >&22; sleep 45
|
||||
echo "slots" >&21; sleep 5
|
||||
check "the temp referral slot GRADUATES into the freed mesh slot" \
|
||||
bash -c 'strip_ansi /tmp/itsgoin-ctop1.log | tail -20 | grep -q "temp-referral 0/"'
|
||||
check "the graduated peer now exchanges knowledge (written to mesh_peers)" \
|
||||
bash -c '[ "$(sqlite3 /tmp/itsgoin-ctop1/itsgoin.db \
|
||||
"SELECT count(*) FROM mesh_peers WHERE lower(hex(node_id))=\"'"$m4"'\"")" != "0" ]'
|
||||
|
||||
##############################################################################
|
||||
echo
|
||||
echo "== standing assertions =="
|
||||
##############################################################################
|
||||
check "0xC0 AnchorRegister is gone from the tree" \
|
||||
bash -c '! grep -rn "AnchorRegister" crates/ --include=*.rs'
|
||||
check "no automatic session relay anywhere in the convection path" \
|
||||
bash -c '! grep -riE "session relay" /tmp/itsgoin-ctop*.log'
|
||||
check "no registration cycle writes known_anchors (bootstrap cache only)" \
|
||||
bash -c '! grep -rn "start_anchor_register_cycle" crates/ --include=*.rs'
|
||||
|
||||
echo
|
||||
echo "== results: $PASS passed, $FAIL failed =="
|
||||
[ "$FAIL" -eq 0 ]
|
||||
Loading…
Add table
Add a link
Reference in a new issue