Skip to content

HF16 / release 4.2.0 ​

Activation and rollout ​

HF16 is scheduled for 2026-10-31 00:00:00 UTC (1793404800), version 4.2.0. Activation also requires the production hardfork voting threshold; merely installing the binary does not activate the fork early. Update validators before the activation date. Use a verified production image, not a BUILD_TESTNET image (its chain identity and quorum differ).

After the master image is built, check its revision/version, startup, synchronization and block production before distributing that exact image/digest. Keep the configured validator key and data-directory backup. Do not delete the data directory as an update procedure.

Verify readiness ​

Activation needs CHAIN_HARDFORK_REQUIRED_VALIDATORS = 17 schedule slots voting 4.2.0 at 2026-10-31T00:00:00. Only validators with a signing key are scheduled, so the schedule can hold fewer than 21 slots; with fewer than 17 the fork cannot activate, however many validators have upgraded. An upgraded validator with a null key returns to the schedule at the next shuffle after a validator_update that sets its key. The chain recounts every 21 blocks. If the quorum forms after 2026-10-31 00:00 UTC, the fork activates in the recount block itself, with no announced moment.

Run the same recount the chain does:

bash
python3 scripts/hardfork_readiness.py --url https://api.viz.world

It prints the slot count, the slots per vote, scheduled validators voting otherwise, and validators that vote 4.2.0 but are unscheduled because their key is null (only those with votes > 0, see below). Exit code 0 means the quorum is reached, 1 not yet, 2 the recount disagrees with the chain or the API answer is unusable.

To check by hand:

json
{ "method": "database_api.get_next_scheduled_hardfork", "params": [] }
{ "method": "validator_api.get_active_validators", "params": [] }
  • get_next_scheduled_hardfork returns hf_version 4.2.0 and live_time 2026-10-31T00:00:00 once the vote has locked in. Until then it mirrors the current version.
  • get_active_validators returns the scheduled slots, which is the set the tally counts. Drop committee if emergency consensus is active, look each name up with validator_api.get_validator_by_account and count hardfork_version_vote 4.2.0 with hardfork_time_vote 2026-10-31T00:00:00. Fewer than 17 names means the fork cannot activate yet.
  • get_validators_by_vote is not the tally's set: it includes unscheduled validators with a null key and stops at the first validator with zero votes, so it misses zero-vote validators that hold support slots.

Slots, QC, TC and finality ​

  • The runtime slot changes from 3 seconds to 1 second at HF16. Use the node's current get_config value and block timestamps; the compile-time legacy CHAIN_BLOCK_INTERVAL is not the post-fork slot.
  • A QC collects signatures from scheduled validators. The implementation uses max(floor(2N/3)+1, floor(0.75N)): 15 of 21, not the old 14-confirmation post-validation description.
  • A producer handover carries a parent QC. Timeout certificates (TCs) allow progress after skipped rounds. LIB uses the 2-chain rule: certified parent and child on the local main branch, adjacent heights and consecutive rounds. The signed child header must carry that parent's QC. A child using the late-QC grandparent fallback does not finalize its parent merely because the local vote pool later collects QCs for both. One isolated QC is insufficient.
  • Votes are limited to one block per validator per round; the highest voted round is persisted before broadcasting. Repeating the same vote is allowed. Conflicting votes can be proved by header evidence and produce virtual operation validator_equivocation (ID 106).
  • Header extension tags are append-only: 3 QC, 4 TC, 5 equivocation proof. Transaction extensions and existing operation IDs are unchanged.
  • Block-denominated governance values whose wall-time meaning must survive the slot change are scaled at activation. Do not mechanically replace every 3-second timer: independent retry/shutdown timers remain separate.

Recovery and emergency mode ​

Normal recovery after transient connectivity loss does not require a restart or an emergency key. Acceptance on 21 validators covered six temporarily unreachable validators, 20% loss with 150±50 ms delay, a full outage lasting 241 seconds, and a 10/11 partition. After healing, all 21 nodes finalized the same checked block. These are tested scenarios, not a guarantee of bounded recovery under every attack.

Deferred-chain catch-up now retains the LIB ancestors needed when fork_db is ahead of the applied state. Emergency consensus is separate: its configured timeout remains 1200 seconds (20 minutes). The short-outage tests do not reduce that threshold to five minutes. See Emergency consensus.

DAO and markets ​

At request creation, the DAO maximum is floor(current_supply.amount / 100) in raw units: 1% of current total VIZ supply, rounded down to 0.001 VIZ. It is recomputed for each request, not based on initial supply or the committee fund balance. Before HF16, replay retains the old 500,000 VIZ ceiling. Existing request amounts are not rewritten. See Committee operations.

For no-contest declared under HF16, the nominal penalty is frozen at announcement. Settlement applies the insurance cap; legacy declarations retain the old calculation. A frozen zero is distinct from a fee never frozen. See No-contest fee freeze.

Operator UI and MCP ​

The optional node_admin plugin provides a built-in browser UI at /ui/ and an HTTP MCP endpoint on its separate admin listener. It exposes health, diagnostics, plugins, logs, audit, P2P, snapshots, validator operations and config plans. Bearer tokens restrict actions by scope; configuration/plugin changes use reviewable plan / apply. Listen on loopback by default and use a tunnel for remote operation. Do not expose the admin listener as the public chain API. See Node administration.

Client libraries ​

JS 0.18.5 supports the new block-header formats and is published to npm. PHP keeps the existing transaction format and passes header JSON through. Python 1.4.0 source/dependencies passed CI on Python 3.10–3.14; PyPI publication is a separate step. Clients must not enforce the obsolete fixed DAO ceiling.

Emission and bounded vote history ​

HF16 deliberately retains 1.000 VIZ minted per produced block (owner decision Q3105=C). At uninterrupted production, 1-second slots therefore increase gross annual issuance from about 10.5 million to 31.5 million VIZ. This is a monetary-policy change, not an unscaled constant to divide by three. Missed slots do not mint a block reward.

Vote/equivocation history retains its one-hour wall-time window: 3600 / block_interval() rounds (3600 after HF16). This is distinct from the emergency timeout and from any recovery SLA. Key-blanking block thresholds scale by three at HF16, preserving the previous roughly 10-minute normal and 5-minute emergency durations. The minimum distribution epoch duration is also preserved: new property votes must meet the HF16-scaled lower bound, while pre-fork replay retains the old bound.

Re-voting block parameters ​

Stored and voted properties remain native block counts, per the selected HF16 migration policy. The one-time migration scales existing votes and the median by three; it cannot identify a later vote copied from an old script. Validators must update hard-coded inflation_recalc_period, distribution_epoch_length, pm_batch_epoch_blocks and pm_reveal_window_blocks by three to preserve time. Alternatively, use live get_config.CHAIN_DEFAULT_CHAIN_PROPERTIES when intentionally voting defaults, or preserve the current on-chain properties when editing unrelated fields. Do not re-vote stale struct defaults.

get_config reports consistent live blocks/hour/day/year, undo capacity, missed-block thresholds and default properties. The reserve-ratio adjustment retains its 60-second cadence. CHAIN_EMERGENCY_EXIT_NORMAL_BLOCKS is an unused legacy constant; actual emergency exit depends on the active-validator schedule quorum, not a 21-block timer.

P2P sync thresholds (fall-behind, fork resolution, wedge watchdog) are scaled by the live slot length, so they keep their wall-clock meaning. Operator options denominated in blocks are not rescaled: dlt-block-log-max-blocks, snapshot-every-n-blocks, history-count-blocks, block-archive-range cover one third of the previous time after HF16. The default rolling block log of 100000 blocks serves peer sync for about 28 hours instead of 3.5 days; set 300000 to keep the old window.