引言:
bsc_relayer
跨链同步主要涉及两个系统合约,分别为
TendermintLightClient.sol
: 同步区块头的操作时会调用到CrossChain.sol
: 同步跨链数据包的操作会调用到
上篇blog我们搞定了同步区块头
的问题,本篇继续解决同步跨链数据包
的问题。
目的:
-
本地搭建起BSC和BC两条链
-
启动bsc_relayer,能成功与两条链建立连接
-
在BC上创建新的验证者
-
bsc_relayer要能同步数据成功,在BSC对应合约
BSCValidatorSet
里,能查询到新增的验证者
BC权益质押管理:
参考币安智能链白皮书,可知BSC的权益质押模块是在BC上实现的,再通过跨链的方式,将质押等信息同步回BSC上
理想情况下,这样的权益质押和奖励发放逻辑应该包含在区块链中,并在产生新区块时自动执行。与币安链一样采用Tendermint共识库的Cosmos Hub就是这样工作的。
自设计之日起,BC就一直在准备启用PoS。另一方面,BSC想要尽可能地与以太坊保持兼容,在其上直接实现PoSA是一个巨大的挑战和压力。特别是考虑到以太坊本身可能在短时间(或更长时间)内迁移到PoS共识协议时,尤其如此。为了保持以太坊的兼容性和复用BC的基础架构,我们在BC上完成了BSC的
权益质押逻辑
:
质押代币是 BNB,这是因为它是两个区块链上的原生代币。
在BC上记录BSC的权益质押和委托行为。
BSC 验证人集由它的权益质押和委托逻辑来决定,在BC上构建一个BSC的权益质押模块,并通过跨链通信在每天UTC 00:00:00 由BC传送到BSC。
BC上的奖励分配发生在每天UTC 00:00时刻。
本篇我们主要解决的是,与权益质押管理相关的跨链数据包的同步问题。
同步跨链数据包调用图:
如图所示,bsc-relayer会构造tx,调用系统合约CrossChain
,通过默克尔树校验后,再调用其他合约(如BSCValidatorSet.sol
)完成具体跨链数据包的处理与同步。
现在先来看看系统合约/跨链合约
CrossChain.sol
的源码及其实现
系统合约CrossChain:
简介:
负责执行bsc-relayer
发送过来的“同步跨链数据包”的交易,进行跨链包预处理,通过emit
事件发送跨链包到BC
.
主要处理逻辑是:
-
调用预编译合约
iavlMerkleProofValidate
对跨链数据包进行校验 -
根据不同的
channelId
,内部调用对应的系统合约,进行具体的数据包处理
简言之,主要做的工作是跨链数据包的校验
和路由
工作。
初始化函数:
1 | // 初始化函数 |
在初始化函数里,主要做的工作是从System.sol
读取配置变量,在registeredContractChannelMap
映射中,建立channelId=>系统合约地址
的映射。
有以下映射:
ContractName | ContractNameCN | Role | ChannelID |
---|---|---|---|
TokenManager Contract | 跨链代币管理(绑定/解绑)合约 | 用于BC 和BSC 两边代币的绑定/解绑 |
1 |
TokenHub Contract | 跨链代币转移合约 | 用于BC 与BSC 的跨链代币转移 |
2,3 |
BSCValidatorSet Contract | 智能链验证者集合合约 | 用于 BC 更新 bsc-validator 验证者节点地址列表(查询or更新) | 8 |
GovHub Contract | 治理管理合约 | 处理来自BC 上的链上治理数据包 |
9 |
Liveness Slash Contract | 惩罚合约 | 用于惩罚违规操作的 bsc-validator | 11 |
处理跨链数据包函数:
1 | // 处理跨链数据包 |
一开始有多个modifier检验:
-
onlyRelayer
: 仅允许中继器调用 -
sequenceInOrder
: 检验sequence序列号是否按顺序 -
blockSynced
: 在轻客户端合约中,该区块是否已经同步 -
channelSupported
: 该通道是否已经注册,相当于channelId白名单机制
能够成功同步区块头数据是同步跨链数据包的前提。
其中关键的代码段是:
1 | if (packageType == SYN_PACKAGE) { |
并不是在跨链合约CrossChain
中进行具体的数据包同步逻辑,CrossChain
主要起到跨链数据包校验、路由
的作用,根据不同的channelId
,CrossChain
会去调用对应的系统合约,由它们各自进行具体的跨链数据包处理。
完整验证步骤:
-
初始化并运行起BC链
-
获取新的初始化共识状态数据,生成新的
genesis.json
,初始化并运行起BSC链 -
BC链上,新增验证者
1 | [root@localhost ~]# bnbcli staking bsc-create-validator --chain-id 715 --from bnb186t4z2pdu02khlfn5skqxpd36fwsa393mgu4hq --amount 2100000000000:BNB --moniker jerry_v1 --commission-rate 80000000 --commission-max-rate 95000000 --commission-max-change-rate 3000000 --side-chain-id bsc --side-cons-addr 0x86fDBAE16949433E5338846f75764067219fb221 --side-fee-addr 0x86fDBAE16949433E5338846f75764067219fb221 |
-
在BC上,查询top验证者
1 | [root@localhost ~]# bnbcli staking side-top-validators --trust-node --side-chain-id="bsc" |
-
启动bsc-relayer,拉取BC数据,同步到BSC上
-
查看区块浏览器的结果:
调用CrossChain
系统合约的交易均成功 -
查询系统合约
BSCValidatorSet
里的数据
能查到新的验证者数据。