feat(thorchain): HaltMonovaultKeygen mimir — halt XMR keygen independent of churn

Problem (live mainnet 2026-06-28)

The Monero monovault FROST keygen (XMRMonovaultKeygen) is scheduled on every churn and fails at full-active-set (95-party) scale → mass node jailing (~79/95) + frozen migration.

The only existing lever is HaltChurning, which is coarse: it gates ALL keygen scheduling (scheduleKeygen), so halting the XMR keygen also halts normal Asgard churn. There's no way to stop just the XMR monovault keygen.

Fix — a dedicated, node-votable halt decoupled from churn

Add an operational mimir HaltMonovaultKeygen (constants/mimir_strings.go). The Halt prefix makes IsOperationalMimir classify it node-votable (operational quorum, ~3 nodes — not the 2/3 economic supermajority). Default 0 (off). When set (> 0 && <= blockHeight) it skips only the XMR monovault keygen:

  • Churn trigger (manager_validator_current.go, the shouldMaintainXMRMonovault → TriggerXMRKeygen block): skip the trigger when the mimir is set, mirroring the existing HaltChurning pattern.
  • scheduleKeygen (manager_network_current.go): a defensive keygenType == XMRMonovaultKeygen guard so every scheduling path is covered (churn trigger and the genesis bootstrap calls). Not gated on genesisBlockHeight — at real genesis the mimir is 0, but covering the genesis code path keeps the guard total.

Normal Asgard churn is unaffected (the gate only matches XMRMonovaultKeygen).

Operation: set HaltMonovaultKeygen to a height ≤ current to stop the XMR keygen storm; set to 0 to resume. ~3-node operational quorum, no release cut required.

Test

TestHaltMonovaultKeygenMimir mirrors TestProcessGenesisSetup (which sets HaltChurning and the XMR keygen IS still scheduled, proving HaltChurning doesn't gate it) — here the dedicated mimir is set instead: the XMR monovault keygen is skipped (keygenBlock.Keygens HasLen 0) while the regular non-XMR Asgard vault still forms. Demonstrates the decoupling + "Asgard churn unaffected".

⚠️ Follow-up (separate, bigger — NOT solved here)

The root cause is that the XMR monovault committee = the full active set (95-party FROST), so the keygen can't complete at scale. This mimir is a reliable off-switch for the incident, not the cure. A durable fix shrinks the committee/threshold to a smaller subset (so the FROST keygen actually finishes) — flagged as a follow-up.

Notes

DRAFT — do not merge. Incident response off-switch + test; the committee-size fix is the real remediation and is tracked separately.

Merge request reports

Loading