Directory / cardanodocs.com / 2017-01-04-updater.md
You are browsing a mirror of a file hosted on GitHub. View original
layout: default title: 卡尔达诺结算层更新器 permalink: /technical/updater/cn/ group: cn-technical visible: true language: cn
卡尔达诺结算层更新器概览
更新系统的实现可以从 Pos.Update 系列模块中找到。实现的方法与 CSL 的其他子系统相同,比如 Txp, Ssc 和委派。更新系统有一个全局状态,存储在数据库中。全局状态可以从区块链中明确导出。本地状态,有时候也被称为『内存池』,被存储在内存中。内存池用于数据传输,将传输的数据保存到区块中。在二进制文档中描述的二进制协议在应用级文档中描述了网络协议(使用标准的 Inv/Req/Data pattern 模式构建)。
目前,通过软件更新,执行研究部分所述的硬分叉来增加硬分叉的功能已经准备好了;软分叉(或者说软件更新)已经完全实现。
软分叉可更新字段
一个 UpdateProposal 包含用于修改由卡尔达诺结算层使用的一些参数(例如 slot 持续时间)的字段。具体来说,upBlockVersion
用于提议协议有了一些修改;如果 upBlockVersion
比上一次使用的区块还新,upBlockVersionData
的修改就会被采用。
upBlockVersionData
具有 BlockVersionData 的类型。
这些字段如下所述:
bvdScriptVersion
- 用于验证脚本转账的脚本语言版本,如果协议中upBlockVersion
增加了,它必须也给增加upBlockVersion
1(不能保持不变)。bvdSlotDuration
- slot 持续时间(以毫秒为单位)。bvdMaxBlockSize
- 区块大小限制(以字节为单位)。与上一个限制相比而言,协议不能将区块的大小限制增加两倍以上。bvdMaxHeaderSize
- 区块大小限制(以字节为单位)。bvdMaxTxSize
- 转账大小限制(以字节为单位,当前为4096字节),限制 TxAux 的大小。
这些检查在 verifyNextBVData 中进行。
此外,有一些现在未被使用,但将来会被使用的字段。以下是它们的简要说明:
bvdMpcThd
MPC 的资格临界值。bvdHeavyDelThd
重量级委派的临界值。bvdUpdateVoteThd
投赞成票和反对更新所需的股份份额。bvdUpdateProposalThd
所有股份的一个份额,要让区块拥有UpdateProposal
,权益所有人的投票份额必须大于这一份额。bvdUpdateImplicit
静默更新之后的 slot 数(除非它有更多的否定票数)。bvdUpdateSoftforkThd
所有股份的一个份额,如果某些区块权益所有人的总持股比例比该数值大,则采用该区块版本。
内存池结构
内存池
由投票和提案组成。除此以外,内存池
还包含 tip,slot 以及 MemPool
对应的 PollModifier
(当前 GState
,即应用的 MemPool
对应 GState
)。无论是来自网络/内存池提案状态改变,还是来自区块链加载的提案状态改变,PollModifier
都表示全局状态的改变,会被应用到内存池。
更新内存池
随着节点反序列化更新系统消息的数据,内存池会被更新,实现在这里。
MemPool
在三种情况下会被更新:
当收到新的提案/表决时。在这种情况下,调用一个处理函数,然后调用
verifyAndApplyUSPayload
并更新当前PollModifier
和MemPool
。当一个新 slot 开始时。在这种情况下,一些内存池的数据可能会失效。事实上,只有 epoch 发生变化时才会发生这种情况。这种情况可能会发生是因为稳定的股份分配发生了变化,有些投票可能没有足够的股份。这是
processNewSlot
方法实现的。当
GState
更新时。它被称为usNormalize
。有些数据可能由于区块应用程序或回滚而变得无效。例如,我们在内存中有个提案,将这个提案应用于区块,然后它变无效了(因为它已经在区块中)。我们应该放弃这个提案。或者我们从某个区块对提案进行投票,然后回滚这个区块,然后投票变得无效。它通过将所有本地数据应用于空状态来实现的,忽略所有不再有效的数据。
提案和投票累计
要为提案投票,节点应该发送它们的投票。提案和投票存储在内存池(即使没有足够的选票加入区块,这种方式也可以自动收集投票),或者从区块链收集,以确定哪个方案通过。
与数据库的交互
为了验证更新系统数据,我们必须从全局状态(数据库)获取这些数据。有一个文档详实的类型类 MonadPollRead
提供这样的接口。这种类型不但用于数据库交互,还用于在处理从网络接收到的数据时将内存池写入账户。非常重要的一点是,它的实现依赖于 Pos.Update.DB
模块中的函数。
核心类型
核心类型在二进制协议文档中提到。这些类型直接反映了研究章节的概念,有关更多信息,请参阅核心类型模块。
更新提案批准
更新机制实现的一个很重要的部分是创始块的部分。这个逻辑在 processGenesisBlock
中。下面将解释与该过程有关的术语。
阈值
假设有一个区块版本 X
。以及在 slots S
中创建的版本为 X
的区块(其中 S
是一组 slots)。如果所有 slot 的领导者的总相对资产 S
≥ softforkResolutionThreshold
(在代码中被称为阈值),则 X
被采纳。请参阅研究概述获取更详细说明。
提案状态
更新的提案状态可处于下面的状态之一。
未定
这意味着更新提案被包含在其中一个区块中,但是它没有 50%
的赞成/反对票(这里的 50%
的意义是赞成/反对提案选民总数相对于系统所有权益相关者的总股权),默认赞同规则还没有触发。
批准
这意味着这个提案有超过 50%
的投票或很久之前加入了区块(根据默认批准规则),赞同的票数比反对的票数更多(与股权比较)。
拒绝
如果反对该提案的投票超过 50%
,或很久之前加入了区块(根据默认批准规则),反对的票数比赞同的票数更多(再次与股权比较)。
确认
如果至少 k
个区块提案通过,那么这个批准的提案被称为确认。这时候我们可以确定该提案不会被拒绝。因为深度超过 k
的回滚是不可能的。
废弃
如果至少 k
个区块提案未通过,那么这个拒绝的提案被废弃。这时候我们可以确定该提案不会被通过。因为深度超过 k
的回滚是不可能的。
下载新版本
在 Pos.Update.Download
模块中,实现了以下算法。已下载的更新通过一个叫做 cardano-launcher
的工具操作。
下载更新的版本
要下载更新的版本,我们从 ConfirmedProposalState
提取更新的哈希值。如果更新哈希值成功提取了,则调用『下载更新哈希值』算法以下载保存更新的版本,这取决于我们是否在给定的平台使用安装程序。
通过哈希值下载更新
为了通过哈希值下载更新,我们会使用 HTTP 中的 httpLBS
,遍历已知的更新服务器,用给定的哈希值下载更新。很简单:最后,我们要么完成了更新的下载,要么遍历完服务器清单,上报错误信息。已知更新服务器的 URI 使用 cardano-node
可执行文件的 --update-server
参数定义。