From 14a6516749d13a0f8f266edef4ec309261371d63 Mon Sep 17 00:00:00 2001 From: Vladimir Babin Date: Tue, 27 Oct 2026 20:30:48 +0800 Subject: [PATCH] docs: HF16 readiness in zh-CN, quorum by schedule slots in PM freeze doc; chain: correct next_shuffle_block_num comments Comment-only in chain code: next_shuffle_block_num is write-only, the schedule (and the emergency hybrid override) is rebuilt when head % 21 == 0. --- .../pm-no-contest-fee-freeze.md | 3 ++- @l10n/zh-CN/docs/consensus/hf16.md | 23 +++++++++++++++++++ .../pm-no-contest-fee-freeze.md | 5 ++-- libraries/chain/database.cpp | 10 ++++---- .../graphene/chain/validator_objects.hpp | 2 ++ 5 files changed, 34 insertions(+), 9 deletions(-) diff --git a/@l10n/ru/docs/prediction-markets/pm-no-contest-fee-freeze.md b/@l10n/ru/docs/prediction-markets/pm-no-contest-fee-freeze.md index 46b76eb33e..0dda66e517 100644 --- a/@l10n/ru/docs/prediction-markets/pm-no-contest-fee-freeze.md +++ b/@l10n/ru/docs/prediction-markets/pm-no-contest-fee-freeze.md @@ -79,7 +79,8 @@ no-contest-списание). Он накапливается вперёд от смог бы никогда. Полное обоснование — `pm-audit-fix-upgrade.md` §2. * **Активация: 2026-10-31 00:00:00 UTC** (`CHAIN_HARDFORK_16_TIME` = 1793404800 в обеих конфигурациях, задано владельцем 20.10.2026). Объявление валидаторам должно называть именно этот - момент, и до него 17 из 21 валидатора должны стоять на бинаре 4.2.0. Держать значение в **будущем**: с прошедшим + момент, и до него 17 слотов расписания должны голосовать за 4.2.0 (в расписание попадают только + валидаторы с ключом подписи; проверка — `scripts/hardfork_readiness.py`, см. [HF16](../consensus/hf16.md)). Держать значение в **будущем**: с прошедшим таймстемпом форк активируется в том блоке, где случился кворум, и объявляемого момента нет. Менять его вместе с текстом объявления и никогда — после публикации. * **Версия, а не ревизия.** `CHAIN_VERSION` переезжает на `4.2.0` в **обеих** конфигурациях, diff --git a/@l10n/zh-CN/docs/consensus/hf16.md b/@l10n/zh-CN/docs/consensus/hf16.md index 59d3462456..228dba3854 100644 --- a/@l10n/zh-CN/docs/consensus/hf16.md +++ b/@l10n/zh-CN/docs/consensus/hf16.md @@ -6,6 +6,29 @@ HF16 计划在 **2026 年 10 月 31 日 00:00:00 UTC**(`1793404800`)激活 master 镜像构建后,分发前应核对具体镜像的版本、提交、启动、同步和出块。保留验证者密钥配置及数据备份。升级不要求删除数据目录。 +### 检查就绪状态 + +激活需要 `CHAIN_HARDFORK_REQUIRED_VALIDATORS` = 17 个**调度槽位**投票支持 4.2.0(时间 2026-10-31T00:00:00)。只有设置了签名密钥的验证者才会进入调度,因此槽位可能少于 21 个;少于 17 个时,无论多少验证者已经升级,分叉都无法激活。已升级但使用空密钥的验证者,发送设置签名密钥的 `validator_update` 后,会在下一次洗牌时回到调度中。链每 21 个区块重新计票一次。如果在 2026-10-31 00:00 UTC 之后才达到门槛,分叉会在该次计票的区块中直接激活,没有预先公布的时刻。 + +按链的方式重新计票: + +```bash +python3 scripts/hardfork_readiness.py --url https://api.viz.world +``` + +脚本输出槽位数量、每种投票占用的槽位数、投票不同的调度验证者,以及投票支持 4.2.0 但因空密钥不在调度中的验证者(仅限票数 > 0 的验证者,见下文)。退出码 0 表示已达到门槛,1 表示尚未达到,2 表示计票结果与链不一致或 API 响应不可用。 + +手动检查: + +```json +{ "method": "database_api.get_next_scheduled_hardfork", "params": [] } +{ "method": "validator_api.get_active_validators", "params": [] } +``` + +- 投票锁定后,`get_next_scheduled_hardfork` 返回 `hf_version` 4.2.0 和 `live_time` 2026-10-31T00:00:00;在此之前它与当前版本相同。 +- `get_active_validators` 返回调度槽位,正是计票统计的集合。紧急共识激活时去掉 `committee`,用 `validator_api.get_validator_by_account` 逐个查询,统计 `hardfork_version_vote` 为 4.2.0 且 `hardfork_time_vote` 为 2026-10-31T00:00:00 的验证者。名单少于 17 个时,分叉暂时无法激活。 +- `get_validators_by_vote` 不是计票统计的集合:它包含使用空密钥、不在调度中的验证者,并且在第一个零票验证者处停止,因此会遗漏占用支持槽位的零票验证者。 + ## 时隙、QC、TC 与最终性 - HF16 激活时,运行时时隙从 **3 秒改为 1 秒**。读取节点当前 `get_config` 和区块时间;旧编译常量 `CHAIN_BLOCK_INTERVAL` 不能代表分叉后的时隙。 diff --git a/docs/prediction-markets/pm-no-contest-fee-freeze.md b/docs/prediction-markets/pm-no-contest-fee-freeze.md index d7607185cb..a0ef044c76 100644 --- a/docs/prediction-markets/pm-no-contest-fee-freeze.md +++ b/docs/prediction-markets/pm-no-contest-fee-freeze.md @@ -79,8 +79,9 @@ gated — they derive from the same state the settlement will read: same reason: the shelter testnet is a **production-config** deployment, so a testnet-only fork could never activate there. See `pm-audit-fix-upgrade.md` §2 for the full argument. * **Activation: 2026-10-31 00:00:00 UTC** (`CHAIN_HARDFORK_16_TIME` = 1793404800 in both configs, set - by the owner on 2026-10-20). The validator announcement must name this moment, and 17 of 21 - validators must run the 4.2.0 binary before it. Keep the value in the **future**: + by the owner on 2026-10-20). The validator announcement must name this moment, and 17 schedule + slots must vote 4.2.0 before it (only validators with a signing key are scheduled; check with + `scripts/hardfork_readiness.py`, see [HF16](../consensus/hf16.md#verify-readiness)). Keep the value in the **future**: a past timestamp activates the fork in whatever block quorum is reached, with no announceable moment. Change it together with the announcement text, never after it is published. * **Version, not revision.** `CHAIN_VERSION` moves to `4.2.0` in **both** `config.hpp` and diff --git a/libraries/chain/database.cpp b/libraries/chain/database.cpp index 6ff6c5c103..43eec93794 100644 --- a/libraries/chain/database.cpp +++ b/libraries/chain/database.cpp @@ -6720,12 +6720,10 @@ namespace graphene { namespace chain { remove(current); } - // Override validator schedule: all slots -> emergency validator - // Also update next_shuffle_block_num so the hybrid override - // runs on the next schedule update. Without this, if - // next_shuffle_block_num is still N blocks away, the node - // would run an all-committee schedule until then, rejecting - // blocks from real validators during that window. + // Override validator schedule: all slots -> emergency validator. + // The hybrid schedule replaces it at the next update_validator_schedule, + // which runs when head % (CHAIN_MAX_VALIDATORS * REPEAT) == 0. + // next_shuffle_block_num is informational only: nothing reads it. const validator_schedule_object &wso = get_validator_schedule_object(); modify(wso, [&](validator_schedule_object &_wso) { for (int i = 0; i < _wso.num_scheduled_validators; i++) { diff --git a/libraries/chain/include/graphene/chain/validator_objects.hpp b/libraries/chain/include/graphene/chain/validator_objects.hpp index 67632fe230..878968dfcf 100644 --- a/libraries/chain/include/graphene/chain/validator_objects.hpp +++ b/libraries/chain/include/graphene/chain/validator_objects.hpp @@ -127,6 +127,8 @@ namespace graphene { namespace chain { id_type id; fc::uint128_t current_virtual_time; + // Write-only: head + num_scheduled_validators at the last rebuild. The schedule + // is rebuilt when head % (CHAIN_MAX_VALIDATORS * REPEAT) == 0, not at this block. uint32_t next_shuffle_block_num = 1; fc::array current_shuffled_validators; uint8_t num_scheduled_validators = 1;