java-topology/tests/bench/WalkeruinElytraStressBenchmark.java
russell@unturf.com 0a580b313d undefect. CWE-407 — 63 sites patched across 27 ecosystems
Authors: russell@unturf.com · brackishbert@gmail.com · foxhop.net · TimeHexOn.com

Patches, unit tests, benchmarks, whitepaper, and outreach briefs.
Public domain — no copyright claimed. Use freely.
2026-03-26 17:11:57 -04:00

317 lines
17 KiB
Java
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package bench;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import java.util.*;
/**
* WalkeruinElytraStressBenchmark — final benchmark.
*
* Scenario: 30 players launched from spawn (Y=200) with elytra + 64 fireworks each.
* Directions: evenly spread 360° (12° apart). Firework boost every 3 s.
* All players above terrain; consistent speed/magnitude.
*
* NOTE: This benchmark has two distinct sections:
*
* §A World load — measures DependencySorter.isCyclic algorithm in isolation.
* Numbers are ALGORITHM MICRO-BENCHMARK, not real server wall-clock.
* Real server /reload: vanilla 19,255 ms → patched 3,087 ms (6.2×).
* Algorithm isolation shows higher speedup because real server time
* includes I/O, JSON parsing, and other /reload work.
*
* §B Elytra flight — PHYSICS SIMULATION ONLY.
* Models player spread, chunk boundary crossings, firework timing.
* Distance/chunk numbers reflect the simulation model, not verified
* Minecraft server behavior.
*
* Defect exercised:
* minecraft-0001: DependencySorter.isCyclic O(2^D) → O(V+E) (world load)
*
* Three tiers:
* unpatched D=16 / 200 NS — vanilla isCyclic (O(2^D))
* mitigated D=16 / 200 NS — visited-set fix (O(V+E))
* enriched D=48 / 1000 NS — new territory, vanilla StackOverflows at D>20
*
* Server config note: PLAYERS=30 requires max-players=30 in server.properties
* (default Minecraft server cap is 20).
*/
public class WalkeruinElytraStressBenchmark {
// ── Simulation constants ──────────────────────────────────────────────────
static final int PLAYERS = 30;
static final int SIM_TICKS = 1200; // 60 s at 20 TPS
static final long TICK_BUDGET_NS = 50_000_000L; // 50 ms
static final double RENDER_DIST = 128.0; // blocks
static final double CHUNK_SZ = 16.0;
static final double START_Y = 200.0; // above terrain (simulation)
static final double DRAG = 0.99; // per-tick horizontal drag
static final double BASE_SPEED = 0.55; // blocks/tick (glide launch)
static final double MAX_SPEED = 2.2; // blocks/tick at full boost (~44 m/s)
static final double BOOST_IMPULSE = 1.5; // velocity delta per firework
static final int BOOST_INTERVAL = 60; // ticks between fireworks (3 s)
static final int WARMUP_ROUNDS = 5; // JIT warmup rounds before measuring
// Tag graph
static final int UNPATCHED_DEPTH = 16;
static final int UNPATCHED_NS = 200;
static final int ENRICHED_DEPTH = 48;
static final int ENRICHED_NS = 1000;
static final int VANILLA_DEPTH_LIMIT = 20; // beyond this, vanilla StackOverflows
// Real server numbers for reference (bench-server.sh, server-26.1, JDK 25)
static final long REAL_VANILLA_RELOAD_MS = 19_255;
static final long REAL_PATCHED_RELOAD_MS = 3_087;
// ── Player (physics simulation) ───────────────────────────────────────────
static final class Player {
final int id;
final double dirX, dirZ;
double x, y, z, vx, vy, vz;
int fw, fwCool, boostLeft;
long chunks;
double dist;
int lastCx, lastCz;
Player(int id) {
this.id = id;
double a = Math.toRadians(id * (360.0 / PLAYERS));
dirX = Math.sin(a);
dirZ = Math.cos(a);
reset();
}
void reset() {
x = 0; y = START_Y; z = 0;
vx = dirX * BASE_SPEED; vy = 0; vz = dirZ * BASE_SPEED;
fw = 64;
// stagger launches so not all 30 rockets fire same tick
fwCool = id % BOOST_INTERVAL;
boostLeft = 0;
chunks = 0; dist = 0;
lastCx = Integer.MIN_VALUE; lastCz = Integer.MIN_VALUE;
}
void tick() {
// Firework boost
if (fwCool > 0) {
fwCool--;
} else if (fw > 0) {
fw--;
fwCool = BOOST_INTERVAL;
boostLeft = 20;
vx += dirX * BOOST_IMPULSE;
vz += dirZ * BOOST_IMPULSE;
double spd = Math.hypot(vx, vz);
if (spd > MAX_SPEED) { vx = vx / spd * MAX_SPEED; vz = vz / spd * MAX_SPEED; }
}
if (boostLeft > 0) boostLeft--;
// Simplified elytra physics (simulation model — not verified Minecraft physics)
vx *= DRAG; vz *= DRAG;
if (y < START_Y) vy += 0.08; else vy *= 0.7;
double px = x, pz = z;
x += vx; y = Math.max(START_Y, y + vy); z += vz;
dist += Math.hypot(x - px, z - pz);
// Chunk boundary crossing
int cx = (int) Math.floor(x / CHUNK_SZ);
int cz = (int) Math.floor(z / CHUNK_SZ);
if (cx != lastCx || cz != lastCz) { chunks++; lastCx = cx; lastCz = cz; }
}
}
// ── DependencySorter algorithm simulation ─────────────────────────────────
// Models the diamond DAG that triggers O(2^D) isCyclic behavior.
// Each namespace gets its own multimap (conservative — real Minecraft uses
// one shared multimap, making cross-namespace contamination worse).
static Map<String, List<String>> buildDiamondTags(int depth, String pfx) {
Map<String, List<String>> m = new LinkedHashMap<>();
m.put(pfx + "_base", List.of());
String pL = pfx + "_base", pR = pfx + "_base";
for (int d = 1; d <= depth; d++) {
String l = pfx + "_L" + d, r = pfx + "_R" + d;
m.put(l, List.of(pL, pR));
m.put(r, List.of(pL, pR));
pL = l; pR = r;
}
m.put(pfx + "_root", List.of(pL, pR));
return m;
}
static boolean isCyclicVanilla(Multimap<String,String> m, String from, String to) {
Collection<String> d = m.get(to);
if (d.contains(from)) return true;
return d.stream().anyMatch(dep -> isCyclicVanilla(m, from, dep));
}
static boolean isCyclicPatched(Multimap<String,String> m, String from, String to, Set<String> seen) {
if (!seen.add(to)) return false;
Collection<String> d = m.get(to);
if (d.contains(from)) return true;
return d.stream().anyMatch(dep -> isCyclicPatched(m, from, dep, seen));
}
static long resolveWorldLoad(int depth, int ns, boolean patched) {
long t0 = System.nanoTime();
for (int i = 0; i < ns; i++) {
Map<String, List<String>> tags = buildDiamondTags(depth, "ns" + i);
HashMultimap<String,String> mm = HashMultimap.create();
for (Map.Entry<String, List<String>> e : tags.entrySet()) {
for (String dep : e.getValue()) {
if (patched) {
if (!isCyclicPatched(mm, e.getKey(), dep, new HashSet<>())) mm.put(e.getKey(), dep);
} else {
if (!isCyclicVanilla(mm, e.getKey(), dep)) mm.put(e.getKey(), dep);
}
}
}
}
return System.nanoTime() - t0;
}
// ── Tier runner ───────────────────────────────────────────────────────────
static record TierResult(long worldLoadMs, double maxDist, long totalChunks) {}
static TierResult runTier(String name, int depth, int ns, boolean patched) {
System.out.println();
System.out.println("══════════════════════════════════════════════════════════════════");
System.out.printf(" %s%n", name);
System.out.printf(" datapack: D=%-2d NS=%-4d isCyclic: %s%n",
depth, ns, patched ? "visited-set O(V+E)" : "vanilla O(2^D)");
System.out.println("══════════════════════════════════════════════════════════════════");
// §A — World load (algorithm micro-benchmark)
System.out.printf(" §A World load — algorithm micro-benchmark (%d NS × D=%d)... ", ns, depth);
System.out.flush();
if (!patched && depth > VANILLA_DEPTH_LIMIT) {
System.out.printf("ABORT%n");
System.out.printf(" Vanilla D=%d: ~%.2e isCyclic node visits.%n",
depth, (double) ns * 4 * Math.pow(2, depth));
System.out.println(" StackOverflow — server never reaches play state at this depth.");
return null;
}
// JIT warmup — enough rounds to fully compile the hot paths at this depth
int warmupDepth = Math.min(depth, 10);
for (int i = 0; i < WARMUP_ROUNDS; i++) resolveWorldLoad(warmupDepth, 10, patched);
long worldNs = resolveWorldLoad(depth, ns, patched);
long worldMs = worldNs / 1_000_000;
System.out.printf("%,d ms [algorithm isolation]%n", worldMs);
// §B — Elytra flight (physics simulation)
Player[] players = new Player[PLAYERS];
for (int i = 0; i < PLAYERS; i++) players[i] = new Player(i);
// warmup physics
for (Player p : players) p.reset();
for (int t = 0; t < 200; t++) for (Player p : players) p.tick();
// measure
for (Player p : players) p.reset();
long flightStart = System.nanoTime();
for (int t = 0; t < SIM_TICKS; t++) for (Player p : players) p.tick();
long flightNs = System.nanoTime() - flightStart;
long totalChunks = 0;
double totalDist = 0, maxDist = 0;
for (Player p : players) {
totalChunks += p.chunks;
totalDist += p.dist;
if (p.dist > maxDist) maxDist = p.dist;
}
System.out.printf(" §B Elytra flight — physics simulation [not verified Minecraft physics]:%n");
System.out.printf(" sim time: %,d µs%n", flightNs / 1000);
System.out.printf(" max distance: %,.0f m from spawn (simulation)%n", maxDist);
System.out.printf(" avg distance: %,.0f m per player (simulation)%n", totalDist / PLAYERS);
System.out.printf(" chunk crossings: %,d total (%,.0f per player, %,.1f/s)%n",
totalChunks, totalChunks / (double) PLAYERS, totalChunks / 60.0);
// §C — Tier summary
long tagNodes = (long) ns * (depth * 2 + 1); // in-memory nodes, not files
System.out.printf(" §C Tier summary:%n");
System.out.printf(" world load: %,d ms [algorithm isolation]%n", worldMs);
System.out.printf(" datapack scale: D=%d × %d NS = %,d tag nodes (in-memory)%n",
depth, ns, tagNodes);
System.out.printf(" players airborne: %d / %d%n", PLAYERS, PLAYERS);
System.out.printf(" max range: %,.0f m from spawn (simulation)%n", maxDist);
return new TierResult(worldMs, maxDist, totalChunks);
}
// ── Main ─────────────────────────────────────────────────────────────────
public static void main(String[] args) {
System.out.println();
System.out.println("╔══════════════════════════════════════════════════════════════════╗");
System.out.println("║ walkeruin ElytraStressBenchmark · Final Benchmark ║");
System.out.println("║ 30 players · elytra + 64 fireworks · all directions · Y=200 ║");
System.out.println("╠══════════════════════════════════════════════════════════════════╣");
System.out.println("║ §A = algorithm micro-benchmark · §B = physics simulation ║");
System.out.println("║ Real server /reload: vanilla 19,255 ms → patched 3,087 ms (6.2×)║");
System.out.println("╚══════════════════════════════════════════════════════════════════╝");
System.out.printf(" Players: %d (%.1f° apart, evenly spread 360°, requires max-players=30)%n",
PLAYERS, 360.0 / PLAYERS);
System.out.printf(" Altitude: Y=%.0f (simulation — above terrain model)%n", START_Y);
System.out.printf(" Duration: %d ticks = %d s at 20 TPS%n", SIM_TICKS, SIM_TICKS / 20);
System.out.printf(" Max speed: %.0f m/s (elytra + firework boost, simulation)%n", MAX_SPEED * 20);
System.out.printf(" Defect: minecraft-0001 — DependencySorter.isCyclic O(2^D) → O(V+E)%n");
TierResult unpatched = runTier(
"UNPATCHED (control — vanilla isCyclic O(2^D))",
UNPATCHED_DEPTH, UNPATCHED_NS, false);
TierResult mitigated = runTier(
"MITIGATED (fix applied — visited-set O(V+E))",
UNPATCHED_DEPTH, UNPATCHED_NS, true);
TierResult enriched = runTier(
"ENRICHED (D=48 / 1000 NS — new territory, vanilla StackOverflows at D>20)",
ENRICHED_DEPTH, ENRICHED_NS, true);
// ── Final comparison table ────────────────────────────────────────────
System.out.println();
System.out.println("══════════════════════════════════════════════════════════════════");
System.out.println(" FINAL COMPARISON — 30-player elytra stress, three tiers");
System.out.println(" §A = algorithm isolation · not real server wall-clock");
System.out.println("══════════════════════════════════════════════════════════════════");
System.out.printf(" %-16s %-20s %-14s %s%n",
"Tier", "World load [§A]", "Max range [§B]", "Tag nodes");
System.out.println(" " + "".repeat(72));
if (unpatched != null)
System.out.printf(" %-16s %,7d ms %,7.0f m D=%d/%dNS%n",
"unpatched", unpatched.worldLoadMs(), unpatched.maxDist(),
UNPATCHED_DEPTH, UNPATCHED_NS);
else
System.out.printf(" %-16s %-20s%n", "unpatched", "CRASH (StackOverflow)");
if (mitigated != null)
System.out.printf(" %-16s %,7d ms %,7.0f m D=%d/%dNS%n",
"mitigated", mitigated.worldLoadMs(), mitigated.maxDist(),
UNPATCHED_DEPTH, UNPATCHED_NS);
if (enriched != null)
System.out.printf(" %-16s %,7d ms %,7.0f m D=%d/%dNS%n",
"enriched", enriched.worldLoadMs(), enriched.maxDist(),
ENRICHED_DEPTH, ENRICHED_NS);
else
System.out.printf(" %-16s %-20s %-14s D=%d/%dNS%n",
"enriched (vanilla)", "CRASH", "N/A", ENRICHED_DEPTH, ENRICHED_NS);
System.out.println();
if (unpatched != null && mitigated != null) {
System.out.printf(" Algorithm isolation speedup (D=%d): %.1f×%n",
UNPATCHED_DEPTH, (double) unpatched.worldLoadMs() / mitigated.worldLoadMs());
System.out.printf(" Real server /reload speedup (6.2×): 19,255 ms → 3,087 ms%n");
System.out.printf(" (algorithm numbers exceed real server — isolates isCyclic only)%n");
}
System.out.printf(" Enriched (D=48/1000NS): %,d tag nodes in-memory%n",
(long) ENRICHED_NS * (ENRICHED_DEPTH * 2 + 1));
System.out.printf(" Vanilla at D=%d: StackOverflow — server never starts%n",
ENRICHED_DEPTH);
System.out.println("══════════════════════════════════════════════════════════════════");
}
}