Skip to content

MESS — Modified Exponential Subjective Scoring

MESS (ECBP-1100) is an artificial finality mechanism for Ethereum Classic. It penalizes deep reorganizations by applying an exponential scoring penalty to alternative chains that diverge far from the canonical head.

Network activation

MESS shipped as a temporary safety measure, not a permanent consensus rule, so it is not part of the fork ID — core-geth classifies ECBP-1100 as a cross-compatible transition rather than a hard fork, so it never enters the forkid block list. In go-ethereum-classic it is configured only for Classic mainnet (params/config_etc.go):

Network MESS activated MESS deactivated
Classic (mainnet) 11,380,000 (09 Oct 2020) 19,250,000 (31 Jan 2024, with the Spiral hard fork)
Mordor (testnet) not configured not configured

ECIP-1110 ties MESS deactivation to the Spiral activation block (19,250,000), which Ethereum Classic announced for 31 Jan 2024.

Mordor divergence (intentional): getc's MordorChainConfig leaves ECBP1100Transition / ECBP1100DeactivateTransition unset, so IsECBP1100 is always false on Mordor — a deliberate divergence from core-geth. This does not affect syncing or block validity: MESS is a fork-choice / reorg policy (it only vetoes deep reorgs against a competing chain via reorgFilter), never a block-validity rule, and it is only active once a node is already synced — not during catch-up. Mordor replays to the same canonical chain with or without it. The only thing getc forgoes is MESS's deep-reorg protection during the elapsed 2,380,000 → 10,400,000 window.

Note: MESS activated at 11,380,000 — distinct from Etchash (ECIP-1099) at 11,700,000. Etchash is a consensus fork (it changes the PoW DAG) and counts toward the fork ID, which is why it appears in the fork list and MESS does not.

Metric Value
Dedicated files 3
Extension points 6
Upstream files touched 5

Architecture

Fork-choice flow

block arrives → blockchain.go writeKnownBlock / writeBlockAndSetHead
  → forker.ReorgNeeded(current, extern)       [core/forkchoice_pow.go]
    → TD comparison
    → reorgFilter(current, extern)
      → IsMESSEnabled() && IsECBP1100(num)
      → findCommonAncestor()
          → if unresolved (no ancestor / missing header) → REJECT + log (fail-closed)
      → ecbp1100(): antigravity polynomial check
          → REJECT (errReorgFinality) + log, or ALLOW

Note the fail-closed stance: if the common ancestor cannot be resolved, MESS rejects the reorg rather than allowing it — a reorg it cannot verify is exactly the case MESS exists to guard. (core-geth propagates the same error in its equivalent ForkChoice.ReorgNeeded.)

Activation lifecycle

chainSyncer loop  [eth/sync_pow.go]            — on sync done / when already synced
  → checkMESSActivation()                      [eth/sync_mess.go]
      enable:  !enabled && shouldEnableMESS() && peers ≥ 5  → EnableMESS(true,  "synced")
      disable: enabled && peers < 5                         → EnableMESS(false, "low peers")
      shouldEnableMESS() = !messForceDisable && (messForceEnable || IsECBP1100(head))

messSafetyLoop  [eth/sync_mess.go]             — separate ticker, 30 × blocktime ≈ 6.5 min (ECIP-1100)
  → if enabled && head stale → EnableMESS(false, "stale head")

Dedicated Files

These files are entirely new and exist only for MESS. Files that MESS merely hooks into — like the revived core/forkchoice_pow.go — are shown under Fork Choice below, not here.

File Description Changed
core/blockchain_mess.go · diff MESS algorithm — ecbp1100 polynomial, findCommonAncestor, NewForkChoiceWithMESS +270 -0
core/blockchain_mess_test.go · diff MESS unit tests +700 -0
eth/sync_mess.go · diff MESS activation control — messSafetyLoop, checkMESSActivation, shouldEnableMESS +107 -0

Fork Choice — revived, with the MESS hook

core/forkchoice_pow.go is not a MESS-only file: it transplants back the pre-purge total-difficulty fork choice that upstream removed with TD. MESS only adds a hook here — the reorgFilter / reorgAllowed callback that lets the MESS algorithm veto a reorg. The symbols below are that revived fork choice (full picture in the Total Difficulty subsystem); the MESS algorithm itself lives in core/blockchain_mess.go.

Symbol Original Current Status Diff
ChainReader forkchoice forkchoice_pow view
ForkChoice 📋 forkchoice forkchoice_pow +10 -0 view
NewForkChoice forkchoice forkchoice_pow view
ForkChoice.ReorgNeeded 📋 forkchoice forkchoice_pow +13 -10 view
ForkChoice.reorgAllowed forkchoice_pow 🆕 view

Extension Points

Modifications to upstream files that wire in MESS behavior.

Struct Fields

# File Name Lines Description Wires To
1 params/config.go ChainConfig ETC fields 497-507 ECIP fork blocks (1017/1041/1099/Spiral), era rounds, DieHard bomb pause, MESS (ECBP-1100) activation/deactivation params/config_etc.go
2 eth/handler.go handler.messForceEnable/Disable 126-127 MESS emergency override flags propagated from ethconfig eth/sync_mess.go
3 eth/ethconfig/config.go Config.MESSForceEnable/Disable 214-215 Emergency MESS overrides — force enable or force disable regardless of chain config eth/ethconfig/config.go

Conditional Blocks

# File Name Lines Description Wires To
4 eth/handler.go isPow in Start (PoW syncer) 467-477 Starts chainSyncer, block fetcher, and MESS safety loop for PoW chains eth/handler_pow.go, eth/sync_pow.go
5 core/blockchain.go IsPow in NewBlockChain 428-429 Initializes ForkChoice with MESS for PoW chains core/forkchoice_pow.go

Config Plumbing

# File Name Lines Description Wires To
6 eth/backend.go MESS flags passthrough 343-344 Passes MESSForceEnable/Disable from ethconfig to handler config eth/handler.go