Skip to content

v0.10.0-beta

Latest

Choose a tag to compare

@marcello33 marcello33 released this 14 Jul 07:00
8dceb1d

Release candidate on top of v0.9.0, introducing the Ithaca hardfork.
Full diff: v0.9.0...v0.10.0-beta-candidate

Highlights

This is a hardfork release. The headline work is the new Ithaca hardfork (autonomous recovery from a producer stall under a pending milestone), gated at a per-network Heimdall block height; until the height is reached, runtime behavior is unchanged. The rest is a mempool DoS guard, a transaction-fee nil-guard, operator-facing per-module logging, and dependency/CI housekeeping.

Ithaca activation heights

  • Amoy at block 40,776,000 (2026-07-20 ~14:00 UTC)
  • Mainnet at block 50,185,000 (2026-07-29 ~14:00 UTC)

Heimdall block heights (not Bor). All validators must upgrade before their network's height.

Ithaca hardfork — span rotation on bor pending-head stall

Post-Rio, a pending milestone (1/3 <= PM < 2/3) unconditionally suppressed span rotation. If the block producer stalled while a milestone sat in that band, the chain wedged with no autonomous recovery (the ~15-min stress-test halt). Ithaca adds a hardfork-gated rule: even under a pending milestoneen the >1/3-agreed bor head stops advancing for a stall threshold, starting the new span atN+1 (no reorg of pending blocks). The >1/3 agreement is the adversarial guard against a fabricated head.

Key pieces:

  • helper — Ithaca fork gate (per-network activation heights) + configurable bor-stall thresher.
  • x/milestone — carries the validator's actual latest bor head in the milestone vote extension (latest_block_number / latest_block_hash, emitted post-fork only); tallies a >1/3 agreed head selected by greatest summed voting power (GetMajorityActualHead), so a byzantine minority reporting a fabricated the honest tip. Deterministic canonical-parent selection in GetMajorityMilestoneProposition.
  • x/bor — honors an explicit excluded-producer set in both active and fallback selection; applies exclusions before the empty check so an exclusion that empties the active set re-triggers the fallback instead of wedging.
  • app — gated PreBlocker dispatch that rotates from the agreed actual head +1, bounds the agreed head to the span that owns the stall region, debounces both rotation clocks, and guards span-exhaustion / overflow (MaxUint64) boundaries.

Extensive adversarial hardening and regression coverage across the milestone tally, VE valid and boundary cases. The new vote-extension fields and pending-headtracking keys are only written/emitted post-fork, so there's no migration of existing state.

VeBLOP producer fallback when candidate set empties (#618)

SelectNextSpanProducer could hand an empty candidate slice to SelectProducer when the elected producer set collapsed to the current producer and it was filtered out of the active set; in the future-span path that error propagated out of PreBlocker. Adds a deterministic, Ithaca-gated fallback that draws ave/supporting set, then the validator set (sorted, excluding current and excluded producers), so future-span creation always has a candidate. Scoped to the future-span path only (checkAndAddFutureSpan) via an explicit opt-in flag; non-fatal rotation paths keep their skip-and-retry behavior.

CheckTx mempool DoS guard — maxMsgsPerTx (#621)

Caps a single tx at 16 messages in CheckTx. An oversized multi-message tx would otherwise trigger the per-message VeBLOP validation loop and full ante processing on every gossip hop. Enforced in CheckTx only — block validity and consensus are unaffected.

Transaction fee nil-guard (cosmos-sdk fork v0.2.12-polygon, #620)

The tx wrapper's fee accessors (GetGas, GetFee, FeePayer, FeeGranter) now return zero/nil when a decoded tx carries no AuthInfo.Fee instead of dereferencing it. A fee-less tx can be decoded during mempool admission and gossiped between nodes; without the guard the first fee-reading ante decorator dereferences the nil fee and panics on the processing node. The guard makes such a tx fail validation cleanly. Node-local hardening — no consensus change, no fee-behavior change for well-formed txs. Ships via the cosmos-sdk fork bump v0.2.11-polygon to v0.2.12-polygon.

Operator-facing: granular per-module logging (#619)

log_level now accepts a per-module form in addition to a single global level:

  • Single level applied to every module, e.g. "info" or "debug".
  • Comma-separated module:level pairs with an optional *:level default, e.g. "*:info,mempool:debug" — scope debug to one subsystem without the volume of a global debug level..

Levels: trace, debug, info, warn, error, fatal, panic, disabled. The module key is the module field of a log line (CometBFT: consensus, p2p, mempool, blocksync, statesync, …; Heimdall: server, x/bor, x/checkpoint, x/milestone, bridge/processor, …). Documented in the packaged mainnet/amoy config.toml.

Dependencies & CI

  • go.mod — cosmos-sdk fork v0.2.11-polygon → v0.2.12-polygon (the fee nil-guard above) (#620).
  • chore — remove SonarQube/SonarCloud integration and sonar-project.properties (#622).
  • CI — pin kurtosis-pos to v1.3.4 for e2e (#613).

Rollout notes

  • Consensus-affecting hardfork. Ithaca activates at the per-network Heimdall heights above, wired in helper/config.go (Amoy 40,776,000 ≈ 2026-07-20 14:00 UTC; mainnet 50,185,000 ≈ 2026-07-29 14:00 UTC). All validators must upgrade before their network's height; the fork is inert until then. Heightst cadence and may be nudged before the tag if cadence drifts (mainnet is furthest out).
  • No store migration / ConsensusVersion bump in this release (Ithaca adds only post-fork vote-extension fields and tracking keys, no migration of existing state).
  • maxMsgsPerTx, the fee nil-guard, and per-module logging take effect immediately on upgrade (require no coordination).

Merged PRs

  • #611 — app, bor, milestone, helper: rotate span when bor pending head stalls
  • #618 — bor: fall back to eligible producers when veblop candidate set is empty
  • #621 — app: add maxMsgsPerTx
  • #619 — cmd, helper, x/bor: granular per-module logs
  • #620 — go.mod: bump cosmos dep
  • #622 — chore: remove SonarQube/SonarCloud integration
  • #613 — fix: pin kurtosis-pos to v1.3.4