Cumulus
Cumulus用来连接Substrate生态区块链到Polkadot。
Polkadot提供中继链(relay chain),连接一系列的平行链(parachains),在基于Substrate的区块链里,使用定制的运行时来实现安装cumulus共识。
cumulus-consensus
cumulus-consensus
是一个共识引擎,给Substrate项目使用的,其遵循波卡中继链的共识。中继链内部运行一个波卡的节点,指挥客户端和同步算法,哪个链应该遵循,哪些区块应该被确认一致性,哪条链应该被当作最佳链。
cumulus-runtime
基于Substrate runtimes的,设计好的包装器,将Substrate 的runtimes转变为平行链验证者代码,并且提供证明生成的routines。
准备
可以参与三种角色:
- 中继链节点:Gossip传播中继链区块和交易,同步中继链,追踪各个平行链最新的区块头。
- 平行链收集者:在几个提供平行链中某一个链上的出块认证者。
- 平行链开发者:用自己已经编写好的runtime来使用Cumulus。
先安装Substrate:
curl https://getsubstrate.io -sSf | bash -s -- --fast
准备一个中继链节点
拉下代码,使用bkchr-cumulus-branch
分支:
git clone -b bkchr-cumulus-branch https://github.com/paritytech/polkadot.git
cd polkadot
编译中继链节点:
cargo build --release
运行开发者链:
./target/release/polkadot --dev
准备一个收集者节点
重点是注册parachains,并确认它们的区块是由中继链跟踪的,而不是实际使用parachains。尽管如此,我们还是提供了三个具有独特功能的parachains。选择要为其收集的平行链,并构建相应的收集器。
Parachain Zero - A Token Chain
第一个平行链是扮演一个基本的加密货币的角色,其使用的是Substrate的资产管理模块。
Parachain One - A Proof of Existence Chain
第二个平行链包括一个runtime模块,其提供一个去中心化的时间戳,编写一个Substrate模块的教程。
Parachain Two - A Collator Template
第三个平行链包括模版模块,在Substrate的模版里,将其作为其中一个平行链,也是作为编写自定义平行链的起点。
编译 Collator
在选择哪个collator去编译,拉下Cumulus仓库代码,使用joshy-workshop
分支:
git clone -b joshy-workshop https://github.com/paritytech/cumulus.git
编译平行链,有三个平行链可以选择,对应上面描述的三个平行链,对于每个平行链,如果想收集,就编译成二进制文件:
cargo build --release -p parachain-zero-collator
cargo build --release -p parachain-one-collator
cargo build --release -p parachain-two-collator
然后执行一个开发链,确保收集者跑起来:
./target/release/parachain-zero-collator --dev
准备开发一个平行链
在这个教程中,将一个普通的基于Substrate的链作为一个基于cumulus的收集者角色,如果需要写自己独特运行时的,可以参考Substrate开发教程。
发布中继链
Polkadot的架构
[图片上传失败...(image-db862c-1576755397174)]
在波卡生态中,波卡主链就是扮演一个中继链的角色,其他基于Substate开发的链通过插槽接入中继链来扮演平行链的角色。
开启一个中继链
在我们能够连接上任何基于cumulus的平行链的时候,我们需要发布一个中继链。
节点监控台
下载链的配置文件
为确保你的节点能够加入到正在运行的Polkadot的测试网络,需要下载链的配置文件
开启你的节点
./target/release/polkadot \
--chain=WorkshopRelayChainRaw.json \
--bootnodes --bootnodes /dns4/relaychain.bootnodes.net/tcp/30333/p2p/QmayQzZgh1t41b3ta5GSm6tKvV7gpWnBYfHrPAYh756vSH \
--name MyNode
前端开发UI
- UI for Alice's node
- UI for Bob's node
- UI for local node
发布平行链
连接上Parachain Zero
我们开始部署第一个平行链,parachain zero,加密货币功能的平行链,作为一个单独的收集者角色。
生成创世状态
注册一个平行链,中继链需要去知道这个平行链的创世状态,收集者节点能够导出创世状态为一个文件,下面的命令能够创建一个文件,这个文件能够包含平行链的全部创世状态,采用hex-encoded。
./target/release/parachain-zero-collator export-genesis-state genesis-state-zero
开启收集者节点
使用下面的命令能够开启收集者节点,注意,我们能够使用同样的中继链chain spec来发布中继链节点。
./target/release/parachain-zero-collator \
--base-path collator-zero \
--chain WorkshopRelayChainRaw.json \
--bootnodes --bootnodes /dns4/relaychain.bootnodes.net/tcp/30333/p2p/QmayQzZgh1t41b3ta5GSm6tKvV7gpWnBYfHrPAYh756vSH
注册交易
当Polkadot式存活的,平行链插槽能够被拍卖,当然在这个教程中,我们会跳过这个拍卖过程,直接使用sudo来执行平行链注册进中继链的交易过程。这个交易能够在下面操作中执行,Apps > Sudo > Registrar > registerPara
使用下面的参数:
id: 0 ParaInfo: Always code: from wbuild directory initial_head_data: from previous step
当平行链跟中继链注册后,能够看到一些事情开始发生了,能够观察到平行链是存活的。
区块生产
收集者会开始生产平行链的区块,当平行链开始注册成功的时候,这个收集者节点会开始产生如下的日志信息:
Starting consensus session on top of parent 0x0ab7cf219c9579ec3db799bb588364f97e7b0674f393e4795fff89e372c627dc
2019-12-05 07:24:21 Prepared block for proposing at 1 [hash: 0x637dec2916ca32653d1a19f7b4ba39e0406f2e0b44758ba49de88fbf28758cc7; parent_hash: 0x0ab7…27dc; extrinsics: [0x9bc9…a263]]
更新区块头
中继链会追踪平行链最新的区块头,当一个中继链区块最终一致性被确认的时候,任何被中继链引用的平行链区块和父区块都被确认了一致性。这也是波卡之所以能够实现共享的共识安全。我们能够查询,新的平行链区块是否被中继链所引用,通过中继链的链上状态能够查询: Apps -> Chain state -> parachains > heads
。你能够看到在一些区块周期中,这个值会改变。
连接上 Parachains One and Two
我们现在开启平行链One 和 Two,每一个平行链对应的收集者能够自愿去开启第一个收集者。还是用之前的步骤进行部署。
提交注册
只有sudo key的持有者才能完成注册交易,有两个选项需要被处理到:
- 这个教程leader共享链sudo key,所以参与者能够注册。
- 参与者能够共享创世状态,所以leader能够注册。
硬编码IDs
你可能关心,平行链在哪个插槽上注册了。现在cumulus的状态是将平行链ID进行了硬编码到收集者。现在的收集者在 src/main.rs
中有如下的一行进行直接硬编码:
pub const PARA_ID: ParaId = ParaId::new(0);
到目前,指定的插槽是匹配的,这一块在将来会被改变。
添加更多收集者
按照之前展示的,一个平行链在只有一个收集者的情况下也是可以运行的。但是其配置就不够去中心化了,攻击者只需要拿下一个收集者节点就能够瘫痪一个平行链。
Cumulus还在快速开发中,给平行链配置多个收集者当然是其中的目标,这些探索都是实验性质的。
开启收集者
这个命令是开启另外一个parachain-zero收集者:
./target/release/parachain-zero-collator \
--chain=WorkshopRelayChainRaw.json \
--bootnodes \
--base-path collator2
开发平行链
收集者模版
现在收集者模块是使用一个简单的runtime来作为收集者工作模块,这个runtime包括一个模版模块,开发者能够根据需求加入自己的逻辑。
使用模板
复制collator template
目录到一个新的项目位置:
cp -r cumulus/collator-template my-parachain
在 Cargo.toml
中改变项目名字。
在使用Cumulus时,你将不需要像 grandpa
或者 babe
这样的跟共识相关的模块。
自带运行时
有些基于Substrate开发的项目已经有像标准的区块链项目那样运行了,这些运行时需要使用Cumulus调整来工作。
概述:
- 拉下收集者模版代码。
- 改变运行时依赖,在自己runtime的代码 Cargo.toml 里。
- parachain-runtime = { package = "parachain-two-runtime", path = "runtime" }
- parachain-runtime = { package = "my-runtime", git = “”}
- 复制创世配置到收集者模版中(或者将其放在自己模块中)。
- 在
src/main.rs
中改变硬编码。
最大的难题是需要版本匹配,为了使现在的cumulus能够跟你的runtime工作,你不得不在编译的时候针对Substrate的 bkchr-cumulus-branch
分支来编译。
MacOS给Linux或者安卓编译Rust可执行二进制文件
添加平台应用程序:
rustup target add x86_64-unknown-linux-musl # First time only
在MacOS使用musl可以通过安装musl-cross-make
实现:
brew install FiloSottile/musl-cross/musl-cross
创建musl-gcc:
ln -s /usr/local/bin/x86_64-linux-musl-gcc /usr/local/bin/musl-gcc
设置linker,创建一个文件.cargo/config
,增加下面两行:
[target.x86_64-unknown-linux-musl]
linker = "x86_64-linux-musl-gcc"
下面命令进行交叉编译:
CROSS_COMPILE=x86_64-linux-musl- cargo build --release --target x86_64-unknown-linux-musl
安卓系统的如下:
rustup target add arm-linux-androideabi
cargo build --release --target=arm-linux-androideabi