LOADING...
LOADING...
LOADING...
当前位置: 玩币族首页 > 区块链资产 > 硬核分享|CrustNetwork如何玩转Substrate的“黑魔法”?

硬核分享|CrustNetwork如何玩转Substrate的“黑魔法”?

2020-06-23 Crust分布式云 来源:区块链网络

Crust 实现了去中心化存储的激励层协议,适配包括 IPFS 在内的多种存储层协议,并对应用层提供支持。同时 Crust 的架构也有能力对去中心化计算层提供支持,构建分布式云生态。

6月 18 日,Crust Show 第 3 期活动中,我们邀请了?Parity?工程师 kai chao老师,与?Crust Network CTO 子琨一起,就 Crust 核心技术相关进行了硬核的技术探讨。

本期分享,从 Crust 协议组的设计与技术实现、对于无缝升级的设计与思考以及 Crust 如何利用 Runtime Interface 扩展链上密码库、对于链上定时器(Scheduler)的运用、Crust 链上身份绑定的设计与实现等 5 个方面,子琨和大家进行了详细的讲解。

由于分享内容过长,分为上下两篇。上一篇内容为《Crust 核心协议栈的设计与实现》,本篇主要介绍?Crust?如何运用?Substrate。

以下为 Crust Show 003(下篇)分享整理。

01.

Substrate 是一个开源、模块化、可扩展的区块链开发框架,能简单介绍一下为什么会选择 Substrate 进行开发吗?

子琨:首先,Substrate 是特别好的开发工具,得力于 Rust 语言的 Generic 和 Substrate 良好的设计模式,让 Substrate 形成了别具一格的搭积木的开发模式,这使得开发者能够很轻易的开箱即用。这也是我刚接触 Substrate 的第一感受。

随着对 Substrate 的深入了解,其很多“黑魔法”让人眼前一亮,包括大家熟知的 Forkless Upgrade、Offchain Worker、链上治理,或是 Crust 运用到的 Runtime interface 和链上定时器等等,都让不同种类和不同功能的协议开发变得纯粹简单。

Crust 是协议栈相对比较复杂的去中心化存储公链,其链上链下复杂的交互机制,SGX 特殊的验证机制,精巧的经济模型设计等等都让实现 Crust 协议难度增加。

在这之前,Crust 尝试过 1 个多月的以太坊 +Tendermint 的开发。但从去年年底开始使用 Substrate 以来,Substrate 的种种“黑魔法”大大加速了 Crust 协议的实现,Crust 已经完成了 70% 的协议开发,今天也会跟大家分享 Crust 是如何使用这些“黑魔法”的。

02.

Substrate 提供的一些组件包括底层的数据库、点对点网络、共识算法、交易池,以及模块化的 Runtime,也就是状态转换函数。

Crust 在 Substrate 的基础上复用了哪些组件,又有哪些新的功能特性呢?

在当前的 Crust 代码库中有 5 大模块,分别是 Staking,Payment,TEE,Market 和 Balance。其 Staking 和 Balance 模块是复用的 Substrate 原生的组件,Crust 对原生 Staking 提供的 NPoS 以及 Phragmen Election 算法进行了修改以适配 GPoS 协议,我们对原生 Balance 模块也进行了修改去配合延缓释放的功能。

新的功能包括了实现 MPoW 协议的 TEE 模块,实现去中心化存储/检索市场的 Market 模块以及负责订单支付的 Payment 模块。其中在 Market 模块的 Provider Slashing 机制也参考了 Staking 模块的 Slashing,对 Slashing Span 的机制也做了部分移植。

最后,Crust 也参考了 Substrate 的很多设计模式,比如为了解决循环引用引入的 Trait 和 Frame_support, 公共类型定义 Primitives,以及 Mock/Tests。这些都大大提升了 Crust 的代码质量。

03.

你刚刚提到了无分叉升级,据我所知 Substrate 的一个核心优势就是它,Crust 是怎么使用的,以及使用过程遇到了哪些问题呢?

由于 Crust 协议组包含链上和链下两个部分,所以无分叉升级其实也分为链上和链下两个部分。

首先是链上升级,由于 Crust 是 Base 在 Substrate 之上搭建的公链,所以链上部分的升级 Crust 直接使用了 Substrate 的 Forkless Upgrade。

在 Substrate中, Runtime 的代码会以 Wasm 的形式存储在链上,这部分是主要的链上逻辑,Runtime 的修改可以通过无分叉升级方式进行,非 Runtime 的代码修改还是需要升级 Native 程序。

对此,Crust 有两个方面的考虑,如何进行升级以及升级的限制。

首先是如何进行升级。目前 Crust 采用的方法是在 Sudo 或者议会模块会发起一个链上定时器,约定好在指定块进行一次链上升级,这也是官方推荐的升级方法。

其原理是通过 Scheduler,将 setCode 这个操作分摊到定时 Duration 的每个块进行,所以不用担心 Code 过大而超过一个块的打包容量或者超出了 MaxWeight 的值而导致 Extrinsic 不被接受。

而对于链上升级的限制,官方的 Rule 是只要不涉及到 Native 改动以及保证逻辑和存储相匹配的条件下就都能进行链上升级。但对于一些细节没有给出特别的说明,Crust 其实对涉及到的业务和可能出现的情况做了比较详细的实验。

这些实验包括了:

1. Offchain Worker 的升级

2. 链上密码库的升级

3. 链上存储的更改

4. DB 的升级

5. Substrate Client 模块的升级

6. 链上参数的调整

等等都做了测试,并做出了详细的升级说明,之后也会给出 Upgrade Red Line的报告,可以关注 Crust Github Wiki。

但总的来讲,Crust 可以得力于 Substrate 提供的链上升级机制做到 99% 以上的升级。也会在 Maxwell 测试网中将 1% 的情况完全确定下来,让 Hard Fork 的概率做到最低。

其次是链下的升级,也就是 SGX 程序的升级。这个升级的意义是在于修补一些量化程序和加解密程序的漏洞或者提升其效率,Crust 设计了一套 AB Upgrade 的机制,去解决两个 Enclave 无法互相信任的问题。

上图的意思是,在 Block Number=500 的时候,此时链上被认为合法的是 Enclave A,那么 Account A 绑定的 Enclave A 所提交的 Id A 以及其工作量报告,会被链认为是合法的输入。

当 Sudo/Democracy 通过 Set TEE Code 操作更改链上存储状态,将 Enclave B 认证为合法代码后,将会规定所有的 Enclave A 在 1000 块后失效。

但在 500 到 1500 块中间,会出现 A、B 同时有效的中间状态,其是为了让(新)B 同步(老) A 的存储状态。

直到 Block Number 变为 1500,Enclave A 提交上来的内容将被链认为是无效的,简单来讲就是,Enclave A 和 Enclave B 会在升级的过程中同时存在并且进行量化存储资源,链上也会允许 A、B 两个 Enclave Code 上报的工作量。

简单来讲就是,Enclave A 和 Enclave B 会在升级的过程中同时存在并且进行量化存储资源,链上也会允许 A、B 两个 Enclave Code 上报的工作量。

但在约定期间内,节点需要完成从 A 到 B 的升级,超出约定期间,链上将不再接受A上报的所有信息。

这套机制有点类似于 ETH 的难度炸弹升级,利用 AB Upgrade 可以很好的规避掉去解决 A、B 互信这个无解的问题,同时可以做到用户无感知的升级。

04.

下一个问题,你在开始的时候提到了 Runtime Interface,这其实是 Substrate 里的一个比较复杂的技术点,请跟我们详细介绍下吧

首先对于 Runtime Interface 的介绍比较少,原因是因为 Substrate 本身并没有期待大家直接使用这个 Crate,而是用构建在此基础上的 Offchain Worker。

换句话说,Runtime Interface 是为 Offchain Worker 打造的基础组件。

其原理是在 Native 和 Wasm 环境中桥接一些固定的接口,通过 Wasm executo r定义的外部函数,接受从 Wasm 传入的参数,并且在 Native 中执行任何程序,并将结果返回给 Wasm 环境。

听起来其实和 Offchain Worker 特别像,但使用上面会比 Offchain Worker 轻量,因为你不需要像 Offchain Worker 一样制定一套生命周期,仅仅只需要把它当作一个函数调用就可以了。

但和 Offchain Worker一样,Runtime Interface 的使用也需要注意不要对链产生副作用,因为完全裸露没有超时机制,Runtime Interface 更容易让你对链产生副作用。

所以按照 Crust 的经验来看,尽量不要引入很复杂的计算或者 IO 开销,比如网络等待等等。

Crust 对 Runtime Interface 的运用仅仅在于扩展密码库,这也是 MPoW 协议不能缺失的部分。包含了 CA X509 签名算法,ECDSA P256 椭圆曲线算法和 EVP Sha256 算法。Runtime Interface 的引入的确大大减轻了 Crust 实现链上验证的工作量。

05.

在 Runtime 升级时,通常可以使用链上定时器(Scheduler)来指定升级的区块,那么 Crust 也是这么使用的吗?

链上定时器(Scheduler)是 Substrate 中比较有特色的模块,可以允许你 Arrange 一个 Task 或者函数在某个 Block Number 去执行,并且支持周期性重复执行的操作。

Substrate 提供的 Scheduler 模块完美匹配了 Crust 的一个业务场景,就是存储订单金额的线性释放,也就是用户支付给存储节点的金额,会在文件有效期内线性的释放给存储节点。

举个例子,用户 Alice 存取一张照片给节点 A,存储时常为 3 个月,一共付给 A 300 CRUs,Market 模块会将 300 个 CRUs 拆分为 3*30*24*60*0.0023 个 CRU,每 10 个块也就是 1 分钟,会支付给 A 0.0023 个 CRU,在 3 个月内支付完毕。

所以 Crust 在 Market 模块引入了 Scheduler ,但是由于 Substrate 网络对全网Scheduler 的数量有所限制(大概可容纳 30-40 个左右),所以我们无法对单个订单分配一个 Scheduler。

基于这个考虑,Crust 设计了一个链下结算系统,也就是利用 Substrate 特有的 Offchain Worker,让 Scheduler 去周期性执行一个链下结算的系统,从链下提交一个 Quote 到链上,然后执行一个 Batch 的清算转账工作。

这样的话,我们可以平均分配 10 个 Scheduler 在 1 个 era (300 个块)的周期内实现大约 30W 笔订单释放。目前这个方案还没有完全实现,所以没有 Benchmark 和准确的测试数据,只是做了一个比较粗略的估算。

但总的来讲,Scheduler 为 Crust 的延缓释放提供了一个简便的思路,如果没有链上定时器的话,我们可能要基于 on_initialize 或者 on_finalize 做很多事情,并且还需要自己去测算具体的 Cost。

06.

终于到我的最后一个问题了,Crust 的链上身份具体是如何设计和实现的呢?

Crust 的身份绑定有三层逻辑:

1. 取得 Intel 认证和 TEE Enclave Code(环境可靠:为了保证可信运行环境),环境可靠是为了保证没有恶意的人修改 Enclave Code 并保证 Enclave 运行的环境是可信的。

2. 绑定 TEE Enclave Code 和生成的公钥(输出可靠:为了保证运行环境和TEE身份的匹配)。

由于 Enclave 之外的所有行为,用户都可以控制和修改,所以必须在 Enclave 内部生成用户的公私钥(私钥只在 Enclave 内部才能获取),并且对所有 Enclave 的输出进行私钥加密。

这使得用户无法修改从 Enclave 中输出的所有内容,保证了输出的可靠性。

3. 绑定生成的公钥和链上身份(链上身份可靠:为了保证 TEE 身份和链上身份的匹配),避免女巫攻击,多个链上身份绑定一个 TEE。

这样会导致 TEE 身份的盗用,所以这一步会在 TEE 内部生成链上身份的绑定信息,并且在链上进行唯一性确认。

通过这三层绑定,能够保证 Enclave 到 Chain 的全链路可信,为 MPoW 提供了可信基础。

—-

编译者/作者:Crust分布式云

玩币族申明:玩币族作为开放的资讯翻译/分享平台,所提供的所有资讯仅代表作者个人观点,与玩币族平台立场无关,且不构成任何投资理财建议。文章版权归原作者所有。

LOADING...
LOADING...