Block 4.812.003 war laut zwei Dritteln der Validatoren gültig. Laut dem restlichen Drittel nicht. Beide Seiten hatten recht, gemessen an dem Code, den sie liefen. Genau das ist das Problem mit Grenzwerten: Sie sind nie falsch für sich genommen, nur falsch im Vergleich zur Implementierung, die neben ihnen läuft.
Die Prüfung, um die es ging, war banal: Ein Block darf höchstens MAX_OPS Operationen enthalten. In der Referenzimplementierung stand if (ops.length > MAX_OPS) reject(). In einem zweiten, unabhängig entwickelten Client, der etwa vierzig Prozent des Netzwerks stellte, stand if (ops.length >= MAX_OPS) reject(). Ein einziges Zeichen Unterschied. Für 4.811.999 Blöcke lang war das egal, weil kein Block je genau MAX_OPS Operationen enthielt. Block 4.812.003 enthielt exakt MAX_OPS.
Warum das niemand vorher bemerkte
Beide Implementierungen hatten Tests. Beide Testsuiten prüften den Fall "ein Operation zu viel" und den Fall "deutlich zu wenige". Keine prüfte den exakten Grenzwert selbst, weil er als Sonderfall galt, der praktisch nie auftritt, bis er es tut. Das ist die Pointe von Off-by-One-Fehlern: Sie verstecken sich nicht in der Logik, sie verstecken sich in der Grenze zwischen zwei Fällen, die beide für sich genommen korrekt aussehen.
Die Chain teilte sich für etwa neunzig Minuten. Beide Zweige produzierten weiter Blöcke, beide waren nach ihrer eigenen Logik konsistent. Erst als die Diskrepanz in einem Monitoring-Dashboard als roter Balken auftauchte, jemand den Diff zwischen den beiden Client-Implementierungen zog, und darin genau eine Zeile fand, war klar, was passiert war.
Ein Grenzwert, der nur einmal in Millionen Blöcken erreicht wird, ist kein Randfall. Er ist ein Termin, der noch nicht stattgefunden hat.
Postmortem-Report, intern, August 2026Die Reparatur war der einfache Teil
Ein Zeichen ändern, den Fix koordiniert ausrollen, den Zweig mit der kleineren Wirtschaftsgewichtung verwerfen. Das dauerte Stunden. Was länger dauerte: eine Regel für zukünftige Grenzwerte einzuführen, nach der jeder MAX_*-Vergleich im Code mit einem expliziten Testfall am exakten Grenzwert dokumentiert sein muss, nicht nur knapp darüber und knapp darunter. Zwei unabhängige Implementierungen einer Spezifikation sind eine Stärke für Dezentralität und eine Schwäche für Grenzwerte. Beides gleichzeitig wahr zu halten, ist die eigentliche Arbeit.