github iotexproject/iotex-core v2.4.0

5 hours ago

Summary

v2.4.0 is a mandatory release. It activates at block 48985561, ETA Sun, 07 Jun 2026 23:52:19 +UTC, which brings the Pectra EVM upgrade (IIP-60) and the candidate exit queue mechanism to IoTeX.

Changes

Feat: Pectra EVM Upgrade

Implements four EIPs from the Ethereum Pectra upgrade. All features are activated at yapHeight.

EIP-7702: Set EOA Account Code

Introduces transaction type 0x04, allowing an EOA to temporarily delegate its code execution to a smart contract by signing authorization tuples. Each authorization costs 12,500 gas; creating a new delegated account costs 25,000 gas. Delegated accounts are identified by the prefix 0xef0100 || address. An abuse-prevention blacklist is applied on top of the standard Ethereum behavior.

EIP-7623: Increase Calldata Cost

Raises the cost floor for data-heavy transactions to reduce the maximum possible block size. IoTeX sets TX_COST_FLOOR_PER_TOKEN = 250 instead of Ethereum's value of 40, reflecting IoTeX's existing calldata baseline of 100 gas/byte versus Ethereum's 16 gas/byte, so that the relative cost increase is proportional.

EIP-2935: Historical Block Hashes from State

Stores the most recent 8,191 block hashes in a system contract at 0x0000F90827F1C53a10cb7A02335B175320002935, extending hash accessibility beyond the standard 256-block EVM window. Useful for rollups and cross-chain applications that need to reference older block hashes.

EIP-2537: BLS12-381 Precompiles

Adds seven precompile operations at addresses 0x0b0x11 for BLS12-381 curve operations, enabling efficient on-chain BLS signature verification with 120+ bits of security. Primarily benefits bridges and cross-chain protocols.


Feat: Candidate Exit Queue

Replaces the previous immediate-deactivation model with a queue-based mechanism that enforces a notice period before a candidate can fully exit. The change is designed to give the network visibility into upcoming validator exits and prevent sudden stake withdrawals.

Three-stage lifecycle:

  1. Request — The candidate owner calls CandidateDeactivate(OpRequest). The self-stake bucket is locked (cannot be unstaked) and DeactivatedAt is set to a sentinel value indicating the exit has been requested.

  2. Schedule — At each epoch boundary, the protocol automatically scans for pending requests. At most one candidate is admitted per ExitAdmissionInterval epochs (default: 24 epochs). When admitted, the protocol generates a system ScheduleCandidateDeactivation action and sets DeactivatedAt to a specific future block height (currentHeight + ExitAdmissionInterval × blocksPerEpoch).

  3. Confirm — Once currentHeight >= DeactivatedAt, the candidate owner calls CandidateDeactivate(OpConfirm). The self-stake is cleared (set to 0), the self-stake bucket index is removed from the candidate record, and the candidate is fully deactivated. The former self-stake bucket reverts to a regular vote bucket.

Key constraints:

  • The self-stake bucket cannot be unstaked between request and confirmation.
  • Only one candidate per ExitAdmissionInterval epochs is admitted into the queue, preventing a rush of simultaneous exits.
  • The request cannot be cancelled once submitted.
  • ScheduleCandidateDeactivation is a zero-gas system action, not callable by users.

Fix

  • Fixed CandidateDeactivateOpConfirm swallowing errors due to := shadowing
  • Fixed GetStorageRoot polluting contract cache
  • Fixed contract staking index checking
  • Fixed candidate BLS public key update by operator
  • Fixed CandsMap not saved during full sync
  • Fixed WebSocket double-close

Upgrade Priority

v2.4.0 is a mandatory release for all node types.

Node type Action
Delegate Mandatory
Fullnode Mandatory
API node Mandatory

Commits

v2.3.8...v2.4.0

Don't miss a new iotex-core release

NewReleases is sending notifications on new releases.