Model 2 — Centurion Phase 1 Topology Optimizer (ASCII Diagrams)¶
Visual companion to final_report.md, topology_summary.csv, scenario_matrix.csv, tradeoff_table.csv, and centurion_topology_results.json.
Recommended profile: recommended_safe · 48 validators · risk-adjusted net 86.52 CTN/yr · 52/52 protected scenarios survived · solver scipy-highs.
1. Recommended Topology — Physical Layout¶
Six failure domains, 8 validators each. Five run a full combined node (EL+CL+VC); HOME runs validator-client only and leans on remote beacons.
CENTURION PHASE 1 — 48 VALIDATORS
( 6 failure domains × 8 validators )
┌──────────────────── AWS PROVIDER ─────────────────────┐ ┌──── GCP PROVIDER ────┐
│ │ │ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ ┌────────┐ ┌────────┐│
│ │ AWS_A │ │ AWS_B │ │ AWS_C │ │ │ │ GCP_A │ │ GCP_B ││
│ │ combined │ │ combined │ │ combined │ │ │ │combined│ │combined││
│ │ EL+CL │ │ EL+CL │ │ EL+CL │ │ │ │ EL+CL │ │ EL+CL ││
│ │ +VC │ │ +VC │ │ +VC │ │ │ │ +VC │ │ +VC ││
│ │ ⛁ x8 │ │ ⛁ x8 │ │ ⛁ x8 │ │ │ │ ⛁ x8 │ │ ⛁ x8 ││
│ └──────────┘ └──────────┘ └──────────┘ │ │ └────────┘ └────────┘│
│ │ │ │
└───────────────────────────────────────────────────────┘ └──────────────────────┘
┌─────────────────────────────┐
│ HOME │
│ validator_client_only │
│ (no local beacon) │
│ ⛁ x8 │
└─────────────────────────────┘
Legend: ⛁ = validator combined = Execution + Consensus + Validator client
HOME = VC-only, depends entirely on remote AWS/GCP beacon endpoints
┌── Beacon endpoints (full nodes) ──┐ ┌── Validator clients (signers) ──┐
│ AWS_A AWS_B AWS_C GCP_A GCP_B │ │ AWS_A AWS_B AWS_C GCP_A GCP_B HOME│
│ ( 5 endpoints, HOME has none ) │ │ ( all 6 sites sign ) │
└───────────────────────────────────┘ └───────────────────────────────────┘ 2. Beacon Dependency Graph — All-to-All Failover¶
Every VC subscribes to every healthy beacon endpoint (5 full nodes). No VC is single-provider-bound, so AWS VCs fail over to GCP and vice-versa. HOME has no local beacon and is purely a consumer.
BEACON ENDPOINTS (full nodes)
AWS_A AWS_B AWS_C GCP_A GCP_B
o o o o o
/|\ /|\ /|\ /|\ /|\
╱ │ ╲ ╱ │ ╲ ╱ │ ╲ ╱ │ ╲ ╱ │ ╲
┌───┘ │ └─────┐│┌─────┘ │ └─... (fully-meshed: every VC → every endpoint)
│ │ │││ │
┌───┴──┐ ┌─┴────┐ ┌─┴┴┴──┐ ┌──┴───┐ ┌──────┐ ┌──────┐
│AWS_A │ │AWS_B │ │AWS_C │ │GCP_A │ │GCP_B │ │ HOME │ ◄── VALIDATOR CLIENTS
│ VC │ │ VC │ │ VC │ │ VC │ │ VC │ │ VC │
└──────┘ └──────┘ └──────┘ └──────┘ └──────┘ └──────┘
Adjacency matrix (VC row → beacon column, ● = subscribed):
│ AWS_A AWS_B AWS_C GCP_A GCP_B │ (HOME has no endpoint)
─────────┼────────────────────────────────────┤
VC AWS_A │ ● ● ● ● ● │
VC AWS_B │ ● ● ● ● ● │
VC AWS_C │ ● ● ● ● ● │
VC GCP_A │ ● ● ● ● ● │
VC GCP_B │ ● ● ● ● ● │
VC HOME │ ● ● ● ● ● │
─────────┴────────────────────────────────────┘
Each VC keeps a working beacon as long as ANY of the 5 is healthy. 3. Failure-Domain Stake Map¶
48 validators spread evenly across 6 independent domains → no domain holds more than 1/6 of stake. This even spread is what makes the double-failure math work out.
Domain Provider Role Validators Share of 48
─────────────────────────────────────────────────────────────────────
AWS_A AWS combined_node ████████ 8 16.7%
AWS_B AWS combined_node ████████ 8 16.7%
AWS_C AWS combined_node ████████ 8 16.7%
GCP_A GCP combined_node ████████ 8 16.7%
GCP_B GCP combined_node ████████ 8 16.7%
HOME Home vc_only ████████ 8 16.7%
─────────────────────────────────────────────────────────────────────
TOTAL 48 100%
Provider concentration: AWS ███████████████ 24 (50%)
GCP ██████████ 16 (33%)
HOME █████ 8 (17%) 4. Finality Threshold Ladder¶
The binding design constraint. Two thresholds: hard 2/3 finality and the preferred 72% operational target. Active-validator count must stay above the relevant line in every protected scenario.
active
validators
48 ┤██████████████████████████ baseline / beacon-only faults (margin +16 vs 2/3)
│
40 ┤██████████████████████ any SINGLE host/VC/full down (margin +8)
│ - - - - - - - - - - - - - 35 ◄ preferred operational target (72% of 48)
│
32 ┤████████████████ worst protected DOUBLE failure (margin 0)
│ ═══════════════════════════ 32 ◄ HARD 2/3 finality floor (⌈2·48/3⌉)
│ ↑ exactly on the line — zero slack
24 ┤████████████ AWS-provider-wide (NOT protected) ✗ below floor
│
0 ┤ shared client bug / bad-config-all ✗ liveness lost
└──────────────────────────────────────────────────────────────────────
Why exactly 48 and not 49+:
48 → any protected pair removes 16 → 32 active ≥ 32 floor ✔ feasible
49 → some protected pair removes 17 → 32 active < 33 floor ✗ INFEASIBLE
⇒ Safety caps the count at 48 BEFORE the 64-validator capital limit binds. 5. Scenario Survival Map (52 / 52 protected)¶
FAMILY COUNT ACTIVE THRESHOLD RESULT
────────────────────────────────────────────────────────────────────
baseline 1 48 35 ✔ PASS (margin +13)
single_failure 14 40 35 ✔ PASS (margin +5)
beacon_dependency 12 48 35 ✔ PASS (margin +13)
critical_double 22 32 / 40 32 ✔ PASS (margin 0..+8)
correlated (protected) 3 32..48 32 / 35 ✔ PASS
────────────────────────────────────────────────────────────────────
PROTECTED TOTAL 52 ✔ 52/52 SURVIVE
Coverage tree:
PROTECTED ─┬─ no failure ........................... 48 active ✔
├─ every single host down (6) ............ 40 active ✔
│ AWS_A/B/C · GCP_A/B · HOME
├─ HOME power / internet down ............ 40 active ✔
├─ single beacon endpoint down (6) ....... 48 active ✔
├─ single VC group down (6) .............. 40 active ✔
├─ single full node down (6) ............. 48 active ✔
├─ AWS host + HOME ....................... 32 active ✔ (on floor)
├─ AWS host + GCP node ................... 32 active ✔ (on floor)
├─ two AWS regions down (ab/ac/bc) ....... 32 active ✔ (on floor)
├─ GCP_A + GCP_B unavailable ............. 32 active ✔ (on floor)
├─ AWS host + remote beacon partition .... 40 active ✔
└─ GCP provider-wide failure ............. 32 active ✔ (on floor) 6. Residual / Correlated Risks (evaluated, NOT claimed protected)¶
SCENARIO ACTIVE / 48 THRESHOLD STATUS
──────────────────────────────────────────────────────────────────────────
aws_provider_wide_failure 24 32 ✗ -8
bad_config_deployed_to_all_aws_core_nodes 24 32 ✗ -8
shared_cl_client_bug 0 32 ✗ -32
shared_el_client_bug 0 32 ✗ -32
bad_config_deployed_to_all_nodes 0 32 ✗ -32
──────────────────────────────────────────────────────────────────────────
liveness ─────────────────────────────────────────────────► failure
48 │██████████████████████████ protected envelope
32 │════════════════════ floor ════════════════════════════════
24 │████████████ ◄ AWS-wide / AWS bad-config (finality LOST, recoverable)
0 │ ◄ shared client bug / all-node bad config (total liveness loss)
⚠ Assumptions that must hold or the recommendation is void:
• distinct validator keys per site (no duplicate-key signing)
• all-to-all beacon failover actually configured
• no single config/client monoculture pushed to every node 7. Risk-Adjusted Economics — Waterfall (CTN / year)¶
Gross expected rewards ┤████████████████████████████████████ +184.32
− infrastructure cost (28.80) ┤ ▼ -28.80 ($7,200/yr · $600/mo)
− capital opportunity (46.08) ┤ ▼ -46.08 (principal 1,536 CTN)
− expected downtime (17.56) ┤ ▼ -17.56
− slashing risk ( 1.44) ┤ ▼ -1.44
− operational risk ( 0.96) ┤ ▼ -0.96
− provider concentr. ( 1.12) ┤ ▼ -1.12
− failure-domain conc(0.64) ┤ ▼ -0.64
− operational cmplx. ( 2.40) ┤ ▼ -2.40
+ beacon diversity (+1.20) ┤ ▲ +1.20
─────────────────────────────────────────────────────────────────────────
RISK-ADJUSTED NET VALUE ┤██████████████████ = +86.52 CTN / yr
(objective 86.20) 8. Profile Comparison¶
PROFILE VAL AWS GCP HOME ROLES NET PROTECTED
# sum sum # CTN/yr
──────────────────────────────────────────────────────────────────────────────────
minimal_viable 12 12 0 0 3×AWS only 12.57 1-host only
cheaper_riskier 45 45 0 0 3×AWS only 98.36 fails 10 ✗
higher_resilience 36 12 16 8 AWS↓ GCP+HOME↑ 54.53 AWS-wide ✔
► recommended_safe 48 24 16 8 5×combined+HOME 86.52 52/52 ✔ ◄
maximum_reward_curr_safety 48 24 16 8 = recommended 86.52 52/52 ✔
──────────────────────────────────────────────────────────────────────────────────
Net value vs validator count (CTN/yr):
145 ┤ ● 3-AWS-only @63 (tradeoff, fails 10 protected)
100 ┤ ● cheaper_riskier 98.36 (45, fails 10)
86 ┤ ★ recommended_safe / max_reward 86.52 ◄ best FEASIBLE
55 ┤ ○ higher_resilience 54.53 (survives AWS-wide, lower yield)
13 ┤ ○ minimal_viable 12.57
└────────────────────────────────────────────────────────────
12 36 45 48 63 validators
★ = recommended & feasible ● = higher net but UNSAFE ○ = safe but lower net
Key insight: maximum_reward == recommended_safe. Safety constraints cap the
validator count at 48 before the 64-validator capital ceiling is ever reached,
so there is no "extra reward" topology to trade safety for. 9. Decision Logic — How the Optimizer Chose¶
┌──────────────────────────────┐
│ Fixed-role MILP per profile │
│ (Gurobi → SciPy/HiGHS fb) │
└───────────────┬──────────────┘
│
┌────────────────▼─────────────────┐
│ maximise risk-adjusted net value │
│ s.t. capital ≤ 64-val principal │
│ AND survive ALL protected │
│ scenarios at finality │
└────────────────┬──────────────────┘
│
┌───────────────────────┼─────────────────────────┐
▼ ▼ ▼
AWS-only (cheap) GCP VC-only add-on 3×AWS+2×GCP combined+HOME
higher raw net keeps AWS beacon dep. all-to-all beacon failover
✗ fails double-fail ✗ fails AWS-beacon ✔ 52/52 protected
& beacon scenarios degradation ✔ even 8×6 spread
│ │ │
└───────────────┬───────┴───────────┬─────────────┘
▼ ▼
REJECTED (unsafe) ★ SELECTED: recommended_safe
48 validators, 86.52 CTN/yr 10. Full Explanation — Everything, From First Principles¶
This section explains, in plain language, what Model 2 is, what every number means, and why the optimizer landed where it did. Read top to bottom; no prior context needed.
10.1 What problem is being solved?¶
Centurion is launching a Phase 1 validator deployment on a proof-of-stake network whose native token is CTN. Running validators earns staking rewards, but it also exposes you to two opposing forces:
- Reward pressure — the more validators you run, the more CTN you earn per year.
- Safety pressure — if too many of your validators go offline at once, the network cannot reach finality on your stake. Beyond a point, concentration also risks slashing (being penalised for double-signing or mass downtime).
Model 2 is a topology optimizer: given a fixed menu of infrastructure sites, a capital budget, a reward model, and a catalogue of failure scenarios, it decides how many validators to place at each site and what role each site plays, so as to maximise risk-adjusted net CTN per year while surviving every scenario you declare "must not break finality."
10.2 The building blocks (the vocabulary)¶
| Term | Meaning in this model |
|---|---|
| Site / failure domain | A physical/cloud location that can fail independently: AWS_A, AWS_B, AWS_C (three AWS regions), GCP_A, GCP_B (two GCP regions), HOME (operator's home setup). 6 domains total. |
| EL (Execution Layer) | The execution client (processes transactions / EVM state). |
| CL (Consensus Layer) / beacon node | The consensus client. It is the beacon endpoint a validator client talks to. |
| VC (Validator Client) | The process that actually holds keys and signs attestations/blocks. It needs a healthy beacon (CL) endpoint to know what to sign. |
| combined_node | A site running EL + CL + VC together. It is both a beacon endpoint and a signer. |
| validator_client_only | A site running only a VC (no local beacon). It must borrow a remote beacon endpoint from another site to function. HOME is this. |
| off | The site is not used in that profile. |
| Validator | One staking unit (32-unit stake equivalent). The model places a count of these per site. |
| Active validator | A validator that, in a given scenario, is both alive and can reach a healthy beacon endpoint, so it can keep signing. |
10.3 The two finality thresholds (the heart of the model)¶
A validator only contributes if it is active. The network reaches finality on your stake only when at least 2/3 of your validators are active. Two lines matter:
-
Hard 2/3 finality floor —
ceil(2 × total / 3). For 48 validators this isceil(96/3) = 32. If active validators drop below 32, finality is lost. This is a hard physical/cryptoeconomic limit, not a preference. -
Preferred operational target = 72% —
ceil(0.72 × total) = ceil(34.56) = 35. This is a comfort margin Centurion chose: in everyday single-failure conditions they want to stay at/above 35 active (not just barely above 32), so there is slack before anything becomes urgent.
So every scenario is scored against either 35 (operational) or 32 (hard finality), depending on how severe it is. Single failures are held to the stricter 35; the worst double-failures are only required to clear the hard 32 floor. That is the threshold column you see in scenario_matrix.csv and Diagrams 4–5.
10.4 Why 48 validators — the exact arithmetic¶
This is the single most important result, so here it is step by step:
- Stake is spread evenly: 8 validators on each of the 6 domains (8 × 6 = 48).
- A single domain failure removes 8 →
48 − 8 = 40active.40 ≥ 35✔ (and ≥ 32). - A double domain failure (the worst protected case) removes 16 →
48 − 16 = 32active. The hard floor for 48 is exactly 32, so32 ≥ 32✔ — right on the line. - Now try 49: an even spread is impossible, so some pair of domains would hold 17 between them. Losing that pair leaves
49 − 17 = 32active, but the hard floor for 49 isceil(98/3) = 33.32 < 33✗ — finality would break under a protected double failure.
Conclusion: 48 is the largest validator count that still survives every protected double-failure. The optimizer is not stopped by money — the capital budget would fund up to 64 validators. It is stopped by safety. That is why, in Diagram 8, maximum_reward_current_safety is identical to recommended_safe: there is no higher-reward topology that is also safe. (See Diagram 4.)
10.5 The beacon dependency design (why all-to-all)¶
A VC is useless if it can sign but cannot reach a beacon to learn what to sign. A naive setup makes each VC talk only to its local beacon — but then if a site's beacon degrades while its VC stays up, those validators silently go idle. Worse, if all VCs point only at AWS beacons, a single AWS-beacon problem idles everyone.
Model 2 deliberately wires every VC to every one of the 5 beacon endpoints (AWS_A/B/C + GCP_A/B). This is the all-to-all mesh in Diagram 2. Consequences:
- A VC keeps working as long as any one of the 5 beacons is healthy.
- AWS VCs can fail over to GCP beacons and vice-versa → no single-provider beacon dependency. This is what earns the +1.20 CTN beacon diversity bonus.
- HOME has no beacon of its own; it consumes the same 5 remote endpoints. HOME is a signer, never a beacon provider.
This is also why GCP nodes are combined_node (full beacon) and not VC-only: a GCP-VC-only add-on would add signers but keep everyone dependent on AWS beacons, so it fails the AWS-beacon-degradation scenarios. The tradeoff table proves this — the "2 GCP VC-only" candidate fails 16 protected scenarios; "2 GCP combined" fails far fewer, and only the full + HOME version reaches 0 failures.
10.6 The scenario catalogue (what "protected" means)¶
The model evaluates ~60 scenarios grouped into families (Diagram 5):
- baseline — nothing fails. 48 active.
- single_failure — any one host / VC / power / internet down. 40 active.
- beacon_dependency — one beacon or full node unavailable, but VCs fail over. 48 active.
- critical_double — two simultaneous failures (e.g. two AWS regions, or AWS+GCP, or AWS+HOME). The dangerous ones land exactly on 32 active.
- correlated — provider-wide or systemic faults (AWS-wide, GCP-wide, shared client bug, bad config to all nodes).
A scenario is "protected" if Centurion has declared it a must-survive case. The recommended topology survives all 52 protected scenarios (52/52). Note that the report headline says 52 while scenario_matrix.csv lists ~60 rows: the extra rows are correlated scenarios that are evaluated but NOT claimed as protected — they are shown for honesty, not counted as guarantees.
10.7 The residual risks (what is honestly NOT covered)¶
These appear in Diagram 6 and section "Evaluated but not fully survived" of the report. They are deliberately excluded from the protection guarantee because no validator placement can fix them — they are correlation failures, not capacity failures:
aws_provider_wide_failure→ 24/48 active (−8 below floor). Half the stake is on AWS; if all of AWS dies at once, finality is lost. Surviving this would require moving most stake off AWS (that is exactly what thehigher_resilienceprofile does, at the cost of lower yield).shared_cl_client_bug/shared_el_client_bug→ 0/48. If every full node runs the same consensus or execution client and that client has a consensus bug, all beacons fail together. Fix = client diversity, not topology.bad_config_deployed_to_all_*→ 24 or 0 active. A bad config/deploy pushed to every node bricks them simultaneously. Fix = staged rollouts / deploy discipline.
The model is explicit that these are real and unsolved by placement, and it states the assumptions that must hold or the whole recommendation is void: distinct validator keys per site (no duplicate-key slashing), and the all-to-all beacon failover actually being configured in production.
10.8 The economics — how 184.32 becomes 86.52¶
Diagram 7 is a waterfall. Start from gross rewards and subtract every cost and risk penalty (all figures CTN/year, from the economics block of the JSON):
+184.32 gross_expected_annual_rewards (48 validators × per-validator yield)
− 28.80 annual_infrastructure_cost ($7,200/yr = $600/mo of cloud + home)
− 46.08 annual_capital_opportunity_cost (cost of locking 1,536 CTN principal)
− 17.56 expected_downtime_penalty (probabilistic reward loss from outages)
− 1.44 slashing_risk_penalty (expected loss from slashing exposure)
− 0.96 operational_risk_penalty (human/ops error expectation)
− 1.12 provider_concentration_penalty (50% on AWS is penalised)
− 0.64 failure_domain_concentration_penalty
− 2.40 operational_complexity_penalty (running 6 sites costs ops overhead)
+ 1.20 beacon_diversity_bonus (reward for cross-provider failover)
─────────
= 86.52 risk_adjusted_annual_net_value (the number the optimizer maximises) A few clarifications:
- Principal = 1,536 CTN is the staked capital (48 validators × 32 CTN). The capital opportunity cost (46.08) is what that capital could have earned elsewhere — it is the largest single deduction, which is why over-staking is not "free."
- Objective value (86.20) is very slightly below the reported net (86.52). The objective is the optimizer's internal scoring expression; the reported net is the fully itemised post-hoc economics. The ~0.32 gap is just rounding/representation between the two and is immaterial to the decision.
- The gross > net by more than half is normal: roughly 27% of gross is eaten by infra+ops and another 25% is the capital opportunity cost.
10.9 The five profiles (the menu of strategies)¶
topology_summary.csv holds five complete solutions. They are strategies, not iterations — each answers "what if we optimised for a different priority?":
| Profile | Stance | Layout | Net CTN/yr | Verdict |
|---|---|---|---|---|
| minimal_viable | absolute cheapest that survives 1 AWS loss at theoretical 2/3 | 3×AWS combined, 4 each (12 total) | 12.57 | safe but tiny; no margin, no non-AWS beacon |
| cheaper_riskier | maximise raw net on AWS only | 3×AWS combined, 15 each (45) | 98.36 | higher net but UNSAFE — fails 10 protected scenarios |
| recommended_safe | best net that survives ALL protected scenarios | 3×AWS + 2×GCP combined + HOME VC (48) | 86.52 | ★ the recommendation |
| maximum_reward_current_safety | max reward under safety constraints | identical to recommended | 86.52 | proves you cannot do better safely |
| higher_resilience | also survive AWS-provider-wide failure | 4 each AWS, 8 each GCP_A/B/HOME (36) | 54.53 | survives AWS-wide at the cost of ~37% less yield |
The crucial comparison: cheaper_riskier shows a higher number (98.36) than the recommendation (86.52). That number is a trap — it ignores that the layout fails 10 must-survive scenarios. The optimizer rejects it because feasibility (surviving protected scenarios) is a hard constraint, not a term to be traded against reward. higher_resilience is the opposite trade: it buys protection against an entire-AWS outage by shifting stake to GCP/HOME, but the smaller, less reward-efficient placement drops net value to 54.53. Centurion picks the middle: survive everything reasonable, accept the named correlated risks, and keep yield high.
10.10 How the optimizer actually computes this¶
Diagram 9 shows the pipeline. Mechanically:
- For each profile, it builds a fixed-role MILP (Mixed-Integer Linear Program): role per site is fixed, validator counts per site are the integer decision variables.
- Objective: maximise risk-adjusted net value (the waterfall of §10.8).
- Constraints: capital ≤ the 64-validator principal ceiling AND for every protected scenario, active validators ≥ that scenario's threshold.
- It solves with Gurobi if available, else falls back to SciPy/HiGHS. In this run Gurobi was not installed, so
solver_backend = scipy-highsand the notes record "gurobipy not available; used SciPy/HiGHS fallback." The math is identical; only the solver engine differs. - The notes also record "57 infeasible/skipped assignments" — those are role combinations the solver tried and discarded because they could not satisfy the protected-scenario constraints.
10.11 The one-paragraph takeaway¶
Run 48 validators, 8 on each of AWS_A/B/C, GCP_A/B, and HOME. Make the five cloud sites full combined nodes and HOME validator-client-only, and wire every validator client to all five beacon endpoints so any site can fail over to any other and across providers. This is the highest-yield layout (86.52 CTN/yr) that still survives every single failure, every beacon outage, and every protected double failure (52/52). You cannot safely run more than 48 — at 49 a protected double failure drops you below the finality floor — so maximum-reward and recommended-safe coincide. You are knowingly not protected against a total-AWS outage, a shared client bug, or a bad deploy pushed everywhere; mitigate those with client diversity and staged rollouts, not with more validators.
Generated from centurion_topology_results.json (recommended_safe profile) and the model_2 report/CSV artifacts. Values match the committed baseline.