共识
NeuroChain 运行 Malachite(Informal Systems)——以 Rust 库形式提供并嵌入节点的 Tendermint BFT。只要持有超过 2/3 质押的验证者对一个区块完成 precommit,该区块即最终确定:没有需要等待消解的分叉,也不需要数确认数。
| 属性 | 值 |
|---|---|
| 算法 | Tendermint BFT:propose → prevote → precommit |
| 投票权 | 验证者的质押,以 uNRO 计 |
| 提交阈值 | 超过总投票权的 2/3 |
| 容错能力 | 3f + 1 个验证者中最多 f 个故障 |
| 投票与提案签名 | ML-DSA-65(后量子) |
| 最终性 | 提交即最终 |
一个高度,逐步分解
- Propose。
(height, round)对应的提议者从 mempool 构建区块:交易列表、其 Merkle 根tx_root,以及prev_state_root——它在上一个区块之后得到的状态根。 - 校验。 其他每个验证者都根据
tx_root检查交易,并将prev_state_root与自己在上一高度的状态根比较。不一致意味着某一方的状态已经分叉;该验证者拒绝 prevote,并记录STATE DIVERGENCE。 - Prevote、precommit。 验证者为该区块投票;若区块无效或未按时到达,则投 nil。
- 提交。 当收到超过 2/3 投票权的 precommit 时,区块即被确定。每个验证者执行其中的交易、拆分手续费、在奖励高度发放质押奖励,并计算新的状态根——全部是确定性的,因此每个诚实节点最终得到相同的状态根。
- 未按时达到法定人数时,该高度进入下一轮,更换提议者并延长超时。
轮次超时使用 Malachite 的默认值。区块之间的节奏按节点设置:
| 变量 | 默认值 | 含义 |
|---|---|---|
NEUROCHAIN_BLOCK_MS | 200 | 提议包含交易的区块前的最短等待时间 |
NEUROCHAIN_EMPTY_BLOCK_MS | 2000 | 提议空区块前的最短等待时间,让空闲的链保持安静 |
谁来提议
提议者仅按质押确定性地选出,因此每个节点算出的结果相同:
- 取活跃验证者及其质押;将所有质押除以它们的最大公约数,使得只有比例起作用。
- 对
SHA3-256("neuro-proposer|" ‖ height ‖ round)求哈希,得到一个在总权重上均匀分布的数。 - 按顺序遍历验证者;该数落在谁的权重区间内,谁就是提议者。
质押翻倍的验证者,提议频率也翻倍。轮次变更会选出一个新数,因此宕机的验证者会被跳过。如果所有验证者都已没有质押,选择会退回到轮询,以保证链继续前进。
验证者集合
当以下条件全部满足时,验证者参与共识:
- 其地址以
.node结尾,且其 ML-DSA-65 共识公钥已上链。 - 其质押至少为
min_stake(默认 10 000 NRO)。 - 它未被 slash,也未被 jail。
- 在分片网络中,它属于本分片。
该集合从链上状态重新推导,因此质押变化、slash 和新注册都通过每个验证者已执行的交易生效。
要实现真正的拜占庭容错,协议至少需要 7 个验证者(f = 2)。验证者数量不足的节点会在启动时记录警告;GET /health 报告 validator_count、bft_quorum(当前集合的 2f + 1 数量)和 bft_ready。可用 NEUROCHAIN_MIN_VALIDATORS 为测试网络覆盖该最小值。
AI 可以和不可以作用的地方
Tendermint 的安全性证明建立在投票权即质押这一点上。AI 绝不能改变它。
| 是否允许? | 状态 | |
|---|---|---|
| 改变投票权或 2/3 阈值 | 绝不 | 已强制执行:投票由 Malachite 按质押计数 |
| 移除验证者(jail、slash → 投票权 0) | 是——只能移除,绝不增加权重 | 已上线,由双签证据触发 |
| 按信任度偏置提议者选择 | 原则上允许 | 未启用:提议者选择仅基于质押 |
ConsensusAI 根据每个验证者近期的参与情况计算信任评分。目前该评分只报告,不使用:你可以在 GET /api/v1/validators 以及每个区块的预言机决策日志中看到它。它之所以被移出提议者选择,是因为每个节点都按自己的视角统计参与情况;一次中断之后,这些视角逐渐偏离,节点对谁可以提议产生分歧,且再也没有重新收敛。要让信任度重新参与提议者选择,所用的参与数据本身必须在共识中达成一致(上一个区块的提交信息随下一个区块一起携带)。
Slashing 与 jail
在同一高度和轮次签署两个不同的投票是可证明的不当行为。当此类证据被提交并在共识中验证后:
| 效果 | 默认值 | 治理参数 |
|---|---|---|
| 质押被 slash | min_stake 的 5%(以验证者的质押为上限) | slash_fraction_double_sign_bps = 500 |
| 举报者奖励 | 被 slash 金额的 1% | slash_reward_fraction_bps = 100 |
| 剩余部分 | 销毁 | — |
| Jail(投票权 0) | 10 000 个区块 | jail_blocks(环境变量 NEUROCHAIN_JAIL_BLOCKS) |
每份证据只执行一次。jail 期结束后,只要其质押仍至少为 min_stake,验证者会自动回到集合中。slash 记录列在 GET /api/v1/slashing/history。
重启与追赶
- 重启。 Malachite 维护一份预写日志(write-ahead log)。重启的验证者会重放它,并可能确定一个它已经提交过的高度;节点会识别出该区块已执行并继续运行,而不是停机。
- 追赶。 离线过的节点会向对等节点请求它错过的已确定区块——每个都附带提交证书和完整的交易列表——并按顺序执行,与亲自参与时完全一致。对等节点为此保留最近 10 000 个已确定区块(
NEUROCHAIN_SYNC_HISTORY_BLOCKS)。落后超过这一范围的节点会明显地保持落后,而不会复制它未执行过的区块记录;旧的区块记录同步现在只对节点已持有的区块比较状态根。 - 新节点。 新节点可以从已签名的状态快照启动,而不必从 genesis 开始重放——见运行节点。
分片 实验性
网络可以拆分为多个分片,每个分片运行自己的 Malachite 实例,拥有自己的验证者和区块高度:
- 账户或验证者属于分片
FNV-1a(address) mod n_shards。 - 节点服务于
NEUROCHAIN_SHARD_ID指定的分片;分片数为NEUROCHAIN_SHARDS。未设置NEUROCHAIN_SHARD_ID时,节点运行单个分片,没有跨分片转账。 - 发往另一个分片的转账是两阶段提交:源分片锁定金额;目标分片在检查扣款的 Merkle 证明后提交它;若 10 个区块(
RELAY_TIMEOUT_BLOCKS)内未完成,源分片向发送方退款。
测试方式。 节点中的单元测试覆盖分片分配、按分片过滤的 mempool 和投票、锁定 → 提交路径以及超时退款(test_cross_shard_2pc_commit、test_cross_shard_2pc_timeout_refund,用 cargo test -p neurochain-node 运行)。迄今为止的多验证者网络运行都只使用单个分片;尚未进行多分片、每分片多验证者的运行。运维方面见 IBC v2 与分片。
自行验证
curl -s "$NODE_RPC/health" # 高度、轮次、对等节点、validator_count、bft_quorum、bft_ready
curl -s "$NODE_RPC/api/v1/validators" # 质押、信任评分、已提议区块、已投票数
curl -s "$NODE_RPC/api/v1/blocks?limit=1" # 最新区块:提议者、tx_root、state_root