You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
enm v0.5.230 — stdio:'ignore' on chain spawn + F28 CR Council Inactive
Two follow-ups to v0.5.229.
## 1. stdio:'ignore' on detached chain spawn (NativeProcessService:567)
Pre-230 ENM spawned children with `stdio:['pipe','pipe','pipe']`. The
stdin pipe was used (ela reads its keystore password from stdin per
node.sh:878 + the BPoS arbiter mode password feed in
ElaMainChainAdapter), but stdout/stderr pipes were never read on the
ENM side — they were just held open for the child's lifetime, with
ENM's runtime as the other end.
Consequence: every ENM restart (deploy SIGTERM, crash, OOM) closed
the stdout/stderr pipe FDs. The child's next write to stdout/stderr
delivered SIGPIPE → default handler is terminate → ALL 8 child
chains died on every ENM restart, even with detached:true. autoStart
then respawned them ~60s later via the oracle/arbiter pairing logic
shipped in v0.5.228. Operator-visible as "chains briefly down on
every ENM deploy."
Fix: `stdio:['pipe','ignore','ignore']`. stdin stays a pipe for the
password feed; stdout/stderr resolve to /dev/null inside the child.
The child can write to stdout/stderr forever without anyone closing
on them; ENM exiting becomes invisible to the child's stdio.
Combined with detached:true + child.unref(), children are now truly
long-lived across ENM lifecycle events. Chain binaries already write
their own logs via --logdir / --log flags, so dropping the unused
pipes loses nothing in observability terms.
## 2. F28 — CR Council MemberState degraded (parallel to F12)
F12 fires when a BPoS producer-registry record shows state='Inactive'
(producer skipped rotation slots for too many consecutive rounds).
F28 is its CR Council sibling: fires when this node's CR Committee
record (in `listcurrentcrs.crmembersinfo[]`) shows MemberState !=
'Elected'. Same risk class (missed rounds → lost rewards → eventual
seat loss); same NEVER_AUTOMATIC tier (ENM can't recover — Activate
requires the operator's owner key).
Cited file:line for the MemberState enum:
Elastos.ELA/cr/state/keyframe.go:24-42
State decision table:
Elected → quiet (steady state)
Inactive → WARN if impeachmentVotes=0, CRITICAL if >0
Impeached → CRITICAL (seat lost for term)
Returned → CRITICAL (voluntary withdrawal)
Terminated → CRITICAL (term ended)
Illegal → CRITICAL (caught misbehaving — deposit forfeited)
Wiring:
- snap.cr populated by HealthChecker._fetchCrState (thin wrapper over
CrMembershipService.detectCrMembership; reuses 30s cache)
- Hard-gated to mainchain (snap.chainId === 'mainchain')
- Hard-gated to actual CR members (cr.isCrMember === true)
- Defensive null-guard pattern same as F12's null-guard on
snap.bpos.producer
- Filtered into HealthChecker's rule-runner alongside F12 + F25
Operator-facing copy is state-specific so the right recovery hint
surfaces in the audit log. Activate/Recover from Inactive points at
Essentials (where the operator's owner key lives).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: enm-server/package.json
+1-1Lines changed: 1 addition & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,6 @@
1
1
{
2
2
"name": "@elacity/enm-server",
3
-
"version": "0.5.229",
3
+
"version": "0.5.230",
4
4
"description": "Elastos Node Manager — standalone sidecar server for PC2 that runs and self-heals an Elastos mainchain node for BPoS supernode AND CR Council operators.",
description: 'On an EVM sidechain (ESC/EID/PG) that is stuck for >20 min with peers but a PBFT recovery-stall log signature ("wait for recoved states" / "can not find active peer"), surface a critical alert. This is a quorum / peer problem, not a data fork — an auto-resync cannot fix it, so F26 yields to this alert and the operator restores peers/bootnodes instead.'},
1245
+
// v0.5.230 — Class A (mainchain) — alert-only. CR Council MemberState drift.
1246
+
F28: {tier: 'NEVER_AUTOMATIC',title: 'CR Council member state degraded',
1247
+
description: 'Parallel to F12 for BPoS producers. Fires when this node\'s CR Committee MemberState is anything other than \'Elected\' — typically Inactive (skipped slots for too many consecutive rounds), Impeached, Returned, Terminated, or Illegal. Recovery for Inactive is the Activate flow in Elastos Essentials; other states are terminal-for-the-term and need the operator to investigate via Essentials. ENM cannot recover this for the operator (no owner key).'},
1138
1248
});
1139
1249
1140
1250
// beta.3.22 — every rule is enabled by default. The operator-facing
0 commit comments