3.2 KiB
title |
---|
承诺 |
承诺度量旨在为客户提供一个衡量特定区块上的网络确认和利益水平的标准。 然后,客户可以使用这些信息来推导出自己的承诺度量。
计算远程调用
客户端可以通过get_block_commitment(s: Signature) -> BlockCommitment
,使用远程调用向验证节点请求签名s
的承诺指标。 BlockCommitment
结构包含一个u64[u64,MAX_CONFIRMATIONS]
的数组。 这个数组表示验证节点投票的最后一个区块M
时,包含签名s
的特定区块N
的承诺度量。
BlockCommitment
数组中索引i
处的条目s
意味着验证节点观察到s
在某一区块M
中观察到的集群中的总质押达到i
个确认的区块N
。 这个数组中会有MAX_CONFIRMATIONS
元素,代表从1到MAX_CONFIRMATIONS
的所有可能的确认数。
承诺度量的计算
建立这个BlockCommitment
结构利用了为建立共识而进行的计算。 consensus.rs
中的collect_vote_lockouts
函数建立了一个HashMap,其中每个条目的形式是(b, s)
,其中s
是银行b
的质押数量。
对可投票候选银行b
的计算如下。
let output: HashMap<b, Stake> = HashMap::new();
for vote_account in b.vote_accounts {
for v in vote_account.vote_stack {
for a in ancestors(v) {
f(*output.get_mut(a), vote_account, v);
}
}
}
其中f
是一些累积函数,它用一些可从投票v
和vote_account
派生的数据(stake、lockout等) 来修改插槽a
的stake
条目。 这里注意,这里的ancestors
只包括当前状态缓存中存在的插槽。 比状态缓存中存在的更早的银行的签名无论如何也查询不到,所以这里的承诺计算中不包括这些银行。
现在,我们自然可以通过以下方法来增强上述计算,为每一个银行b
也建立一个BlockCommitment
数组。
- 增加一个
ForkCommitmentCache
来收集BlockCommitment
结构 - 用
f
代替f'
,使上述计算也为每一个银行b
建立这个BlockCommitment
。
由于1) 是不是很重要,所以我们将继续讨论2) 的细节。
在继续之前,值得注意的是,对于某个验证节点的投票账户a
,该验证节点在插槽s
上的本地确认数为v.num_confirmations
,其中v
是投票堆栈a.vails
中最小的一票,这样v.slot >= s
(即不需要查看任何大于v的投票>,因为确认数会更低)。
现在更具体的说,我们把上面的计算增强为。
let output: HashMap<b, Stake> = HashMap::new();
let fork_commitment_cache = ForkCommitmentCache::default();
for vote_account in b.vote_accounts {
// vote stack is sorted from oldest vote to newest vote
for (v1, v2) in vote_account.vote_stack.windows(2) {
for a in ancestors(v1).difference(ancestors(v2)) {
f'(*output.get_mut(a), *fork_commitment_cache.get_mut(a), vote_account, v);
}
}
}
其中f'
被定义为:
fn f`(
stake: &mut Stake,
some_ancestor: &mut BlockCommitment,
vote_account: VoteAccount,
v: Vote, total_stake: u64
){
f(stake, vote_account, v);
*some_ancestor.commitment[v.num_confirmations] += vote_account.stake;
}