VAL 19 — Relay Local-Network Impairment Validation¶
Status: Implemented Scripts:
scripts/labs/run_relay_impairment_val19_lab.sh— single-shot lab runnerscripts/labs/relay_impairment_proxy.go— TCP impairment proxy binaryscripts/labs/edge_relay_impairment_setup.go— VAL19 lab setup binary
Evidence dir: operator-chosen directory (default evidence/val19-relay-impairment-YYYY-MM-DD/)
Ports: edged → 19030 · proxy listen → 19031 · peer server → 19032 · proxy control → 19033
Purpose¶
Validates Edge Relay store-and-forward correctness, delivery-after-reconnection, and performance characterisation under four network impairment conditions:
Outage — peer unreachable; messages must accumulate in the deadletter queue and be delivered after the peer is restored (workplan: “store-and-forward correctness”)
Bandwidth constraint — 1 Mbps and 10 Mbps transport limits; relay must deliver all segments; throughput is measured and captured as evidence
Connection delay — 200 ms and 500 ms pre-dial delay per connection; relay must deliver correctly when connection establishment is delayed
Connection instability — mid-transfer disconnect (proxy closes after 500 bytes); relay must handle the partial transfer gracefully, retain the segment in the deadletter queue, and deliver on the subsequent clean retry
Branch-Specific Rule Application¶
Question |
Answer |
|---|---|
Is this covered by an existing LAB? |
Partially. |
Which LAB/evidence bundle is extended? |
New standalone script — extending |
New evidence files |
30+ files in the evidence directory — see Evidence Files table. |
Tutorial/runbook docs updated |
|
Reason new runner required |
(a) Requires two new Go binaries built at runtime. (b) 3–4 min runtime due to outage cycles + bandwidth tests. (c) The proxy routes edged to a different peer address than the deadletter lab, requiring a separate |
Test Architecture¶
edged (relay executor)
│ mTLS connection to peer-val19
│
▼
relay_impairment_proxy (127.0.0.1:19031)
│ control API at 127.0.0.1:19033
│ PUT /mode GET /stats POST /reset
│
▼ (transparent TCP forward; mTLS end-to-end)
edge_deadletter_lab_peer (127.0.0.1:19032)
│ peer-val19.crt — mTLS identity
│
▼
peer-received.json (segment delivery log)
Key invariant: The proxy is a raw-TCP passthrough; mTLS authentication occurs end-to-end between edged and the peer server. The proxy never decrypts or inspects TLS content — it only delays, rate-limits, or closes connections at the TCP layer.
Network Impairment Plan¶
Impairment proxy modes¶
Mode |
|
Effect |
|---|---|---|
|
|
Full passthrough, no impairment |
|
|
Immediately closes every new incoming connection |
|
|
Token-bucket rate limit on the primary (edged→peer) direction, interpreted as bits per second |
|
|
Sleeps N ms before dialling the target (adds per-connection pre-dial delay) |
|
|
Closes connection after forwarding N bytes in the primary direction |
Scenario-to-mode mapping¶
User scenario |
Mode used |
Value |
|---|---|---|
30s–5m intermittent outages |
|
immediate close (outage period controlled by test script) |
200–500 ms connection delay |
|
200 ms (VAL19-08), 500 ms (VAL19-09) |
1 Mbps bandwidth |
|
|
10 Mbps bandwidth |
|
|
1–5% packet loss |
|
|
Note on “packet loss” simulation: TCP provides reliable delivery, so
true per-packet loss cannot be injected via a TCP proxy. The cutoff mode
simulates the observable effect — a connection reset mid-transfer — which
triggers the same relay retry path as packet-loss-induced TCP RST. True
packet-level loss (e.g., via tc netem) requires CAP_NET_ADMIN / root and
is out of scope for this lab; the cutoff mechanism provides equivalent relay
behaviour coverage without OS privileges.
Harness and Tooling Setup¶
Pre-built binaries (built by lab script)¶
Binary |
Source |
Role |
|---|---|---|
|
|
Edge daemon with relay executor |
|
|
CLI: relay deadletter list/retry; relay status |
|
|
TCP impairment proxy with HTTP control API |
Setup binary (run via go run)¶
Binary |
Source |
Role |
|---|---|---|
|
|
Generates CA + certs, edge.toml (proxy address for |
|
|
Reused from deadletter lab; records received segments to |
|
|
Reused; dumps final ledger state per segment |
Pre-seeded segments¶
Segment ID |
Size |
Purpose |
|---|---|---|
|
64 B |
VAL19-01 clean baseline |
|
64 B |
VAL19-02/03 outage accumulate + recovery |
|
64 B |
VAL19-05 repeated outage cycle 1 |
|
64 B |
VAL19-05 repeated outage cycle 2 |
|
64 B |
VAL19-05 repeated outage cycle 3 |
|
128 KB |
VAL19-06 bandwidth 1 Mbps |
|
128 KB |
VAL19-07 bandwidth 10 Mbps |
|
64 B |
VAL19-08 latency 200 ms |
|
64 B |
VAL19-09 latency 500 ms |
|
4 KB |
VAL19-10 cutoff + clean retry |
All segments are seeded in the relay BoltDB ledger with one prior failed attempt
(error_detail: "seed: peer unreachable") so they are visible in
relay deadletter list at lab start.
Metrics and Logs to Collect¶
Per-scenario evidence files¶
Check |
Key evidence file(s) |
|---|---|
VAL19-01 |
|
VAL19-02 |
|
VAL19-03 |
|
VAL19-04 |
|
VAL19-05 |
|
VAL19-06 |
|
VAL19-07 |
|
VAL19-08 |
|
VAL19-09 |
|
VAL19-10 |
|
Proxy stats JSON schema (proxy-stats-final.json, val19-0X-proxy-stats.json)¶
{
"bytes_fwd": N,
"conn_accepted": N,
"conn_dropped": N,
"active_conn": N,
"last_conn_bytes": N,
"last_conn_ms": N
}
last_conn_bytes and last_conn_ms give per-connection throughput:
throughput_bps = last_conn_bytes * 1000 / last_conn_ms.
Persistent lab logs¶
File |
Content |
|---|---|
|
Edge daemon relay executor log; includes |
|
Peer server log; includes per-segment receive events |
|
Proxy startup and error log |
VAL19 10-Check Matrix¶
Check |
Name |
Mode |
Pass Criterion |
|---|---|---|---|
VAL19-01 |
clean_baseline_delivery |
|
|
VAL19-02 |
outage_deadletter_accumulate |
|
|
VAL19-03 |
outage_recovery_delivery |
|
|
VAL19-04 |
data_integrity |
(from 01) |
Peer-recorded size for |
VAL19-05 |
repeated_outage_resilience |
|
All of |
VAL19-06 |
bandwidth_1mbps_delivery |
|
|
VAL19-07 |
bandwidth_10mbps_delivery |
|
|
VAL19-08 |
latency_200ms_delivery |
|
|
VAL19-09 |
latency_500ms_delivery |
|
|
VAL19-10 |
cutoff_retry_converges |
|
cutoff retry exits non-zero, |
Pass/Fail Criteria¶
Outcome |
Condition |
|---|---|
PASS |
All 10 checks pass |
PARTIAL |
Checks 1, 2, 3, 5 pass (store-and-forward + outage resilience) |
FAIL |
Check 1 fails (relay baseline broken) OR check 3 fails (outage recovery broken) OR check 4 fails (data integrity) |
Mandatory checks: VAL19-01 (clean delivery), VAL19-03 (outage recovery), VAL19-04 (data integrity). A relay that delivers segments cleanly but loses them after an outage cycle, or corrupts payload sizes, fails the public store-and-forward claim regardless of bandwidth or latency check outcomes.
Performance Degradation Characterisation¶
The lab captures the following performance metrics as evidence (informational, not hard pass/fail gates):
Metric |
Source |
Interpretation |
|---|---|---|
|
|
Actual relay throughput under 1 Mbps proxy limit |
|
|
Actual throughput under 10 Mbps proxy limit |
|
|
Wall time of retry + delivery under 200 ms pre-dial delay |
|
|
Wall time of retry + delivery under 500 ms pre-dial delay |
Expected characterisation results (with 128 KB segments):
1 Mbps: ~131 ms transfer + scheduler overhead ≈ 1.1–1.5 s total elapsed
10 Mbps: ~13 ms transfer + scheduler overhead ≈ 1.0–1.1 s total elapsed
200 ms delay: 200 ms pre-dial delay + ~10 ms transfer + scheduler ≈ 1.2 s total
500 ms delay: 500 ms pre-dial delay + ~10 ms + scheduler ≈ 1.5 s total
Evidence Files¶
File |
Description |
|---|---|
|
Edge daemon config with |
|
VAL19 segment catalogue (IDs, sizes, purposes) |
|
All 10 segments visible before tests start |
|
Initial edgectl status (edged ready) |
|
Relay status at lab start |
|
All segments received by the peer server (grows across test) |
|
Edge daemon full log |
|
Peer server log |
|
Proxy log |
|
Retry output for clean baseline |
|
Retry output under outage |
|
Deadletter list after failed outage retry |
|
Retry output after proxy restored |
|
|
|
|
|
Deadletter list after 3 outage cycles |
|
Retry under 1 Mbps bandwidth |
|
Proxy stats after 1 Mbps test |
|
|
|
Retry under 10 Mbps bandwidth |
|
Proxy stats after 10 Mbps test |
|
|
|
Retry under 200 ms latency |
|
|
|
Retry under 500 ms latency |
|
|
|
Retry output with proxy in cutoff mode |
|
Deadletter list after cutoff (seg-10 present) |
|
|
|
Final retry output after clean restore |
|
Final proxy stats (cumulative) |
|
Remaining deadletter entries after all tests |
|
Final relay status |
|
BoltDB ledger dump per segment (10 files) |
|
Human-readable 10-check PASS/FAIL report |
|
Machine-readable JSON report with throughput metrics |
Known Failure Modes¶
Failure |
Likely Cause |
Mitigation |
|---|---|---|
VAL19-01 FAIL: baseline not delivered |
edged not ready before first retry; scheduler not running |
Check |
VAL19-02 FAIL: seg-02 not in deadletter after outage retry |
Relay scheduled the retry AFTER proxy mode was restored to clean |
Increase |
VAL19-03 FAIL: recovery delivery not received |
Retry command returned non-zero; peer server crashed |
Check |
VAL19-04 FAIL: wrong size |
|
Check raw |
VAL19-05 FAIL: not all 3 delivered |
Outage cycles ran too fast; segment didn’t return to deadletter state before clean retry |
Increase |
VAL19-06/07 FAIL: not delivered |
edged scheduler timed out waiting for the rate-limited transfer; |
Increase |
VAL19-08/09 FAIL: not delivered |
|
Check |
VAL19-10 FAIL: seg-10 not delivered after clean |
Cutoff partially delivered mTLS handshake leaving peer in bad state |
Kill and restart peer server; re-run |
Proxy control API unreachable |
Proxy not started or crashed |
Check |
Port conflict |
Ports 19030-19033 in use |
Kill any leftover processes; |
Final Report Template¶
# VAL 19 — Relay Local-Network Impairment Validation
Generated: <timestamp>
Evidence dir: <path>
## Network Impairment Summary
Proxy listen: 127.0.0.1:19031 → 127.0.0.1:19032
Proxy control: 127.0.0.1:19033
edged listen: 127.0.0.1:19030
## Throughput Characterisation (informational)
1 Mbps constraint: 1,004,320 bps (131 ms, 131,072 B)
10 Mbps constraint: 9,962,481 bps (13 ms, 131,072 B)
Latency 200 ms: delivery_elapsed=1247 ms
Latency 500 ms: delivery_elapsed=1531 ms
## Check Results
VAL19-01 clean_baseline_delivery: PASS
VAL19-02 outage_deadletter_accumulate: PASS
VAL19-03 outage_recovery_delivery: PASS
VAL19-04 data_integrity: PASS (size=64 expected=64)
VAL19-05 repeated_outage_resilience: PASS (3/3 delivered)
VAL19-06 bandwidth_1mbps_delivery: PASS
VAL19-07 bandwidth_10mbps_delivery: PASS
VAL19-08 latency_200ms_delivery: PASS
VAL19-09 latency_500ms_delivery: PASS
VAL19-10 cutoff_retry_converges: PASS
## Summary
pass=10 fail=0 total=10
Relay Store-and-Forward Assessment:
PASS requires VAL19-01 (clean delivery) + VAL19-03 (outage recovery) + VAL19-04 (data integrity)
VAL19-05 (repeated outage resilience) is the key Gate D evidence for the “store-and-forward correctness” workplan claim
Throughput characterisation values (
throughput_1mbps_bps,last_conn_ms) are recorded as baseline performance evidence; no hard thresholds imposed (relay delivers correctly regardless of transport speed)