10. 搭建XPoA共识的超级链网络
XPoA是为许可链设计的共识算法,XPoA共识算法的原理可以参考超级链的设计文档 XPoA技术文档 。许可链指的是所有参与链系统的节点,都需经过许可,未经过许可的节点不可接入系统。下面介绍下如何搭建一个XPoA共识的超级链网络。
10.1. 搭建XPoA共识网络
10.1.1. p2p网络配置
以搭建3节点网络为例,拷贝xuperchain编译产出的output到node1~node3。每个节点需修改配置文件 conf/xchain.yaml 中p2p一节,使用p2pv1,p2pv1是为许可链设计的p2p网络插件。
p2p:
module: p2pv1
# port是节点p2p网络监听的默认端口,如果在一台机器上部署注意端口配置不要冲突,
# node1配置的是47101,node2、node3可以分别设置为47102、47103
port: 47101
# 不使用证书
isUseCert: false
# 配置网络中所有节点的neturl, 格式ip:port, 也加上本节点的neturl
staticNodes:
xuper:
- "127.0.0.1:47101"
- "127.0.0.1:47102"
- "127.0.0.1:47103"
注意,如果节点分布在不同的机器之上,需要把网络地址中的本地ip改为机器的实际ip。
10.1.2. 更新各节点的keys
由于节点目录下的keys都是默认的,node1保持不变,更新node2、node3的keys。更新前需手动删掉data/keys目录。更新keys命令如下:
./xchain-cli account newkeys
10.1.3. 配置创世块
XuperChain系统支持可插拔共识,通过修改创世块的参数,可以创建一个以XPoA为共识的链。创世块配置位于 data/config/xuper.json ,修改genesis_consensus一节。各个配置参数详解配置说明如下所示:
{
"version" : "1",
"predistribution":[
{
"address" : "dpzuVdosQrF2kmzumhVeFQZa1aYcdgFpN",
"quota" : "100000000000000000000"
}
],
"maxblocksize" : "128",
"award" : "1000000",
"decimals" : "8",
"award_decay": {
"height_gap": 31536000,
"ratio": 1
},
"gas_price": {
"cpu_rate": 1000,
"mem_rate": 1000000,
"disk_rate": 1,
"xfee_rate": 1
},
"new_account_resource_amount": 1000,
"genesis_consensus":{
"name": "xpoa",
"config": {
// 声明共识的起始时间戳,建议设置为一个刚过去不久的时间戳,更新前10位
"timestamp": "1590636296000000000",
// 每个矿工连续出块的出块间隔
"period":"3000",
// 每一轮内每个矿工轮值任期内连续出块的个数
"block_num":"10",
// xpoa共识依赖的合约名称,无需修改
"contract_name":"xpoa_validates",
// xpoa共识查询候选人的合约方法,无需修改
"method_name":"get_validates",
// 指定第一轮初始矿工,所指定的初始矿工需要在网络中存在,不然系统轮到该节点出块时会没有节点出块
"init_proposer": [
{
"address" : "dpzuVdosQrF2kmzumhVeFQZa1aYcdgFpN"
, "neturl" : "10.26.29.40:47101"
},
{
"address" : "VSML7NenZnGZgCEwtbQDKDSrPHhT5wsu6"
, "neturl" : "10.26.29.40:47102"
},
{
"address" : "bg3KLC3YCmvLWBCNAVHGHLfk3qeWEdoD3"
, "neturl" : "10.26.29.40:47103"
}
],
// 使用chained-bft
"bft_config": {}
}
}
}
将修改好的1份xuper.json拷贝到另外2个节点的data/config目录下。
注意,拷贝配置内容到xuper.json时需去掉注释。
10.1.4. 创建链并启动xchain
检查data/blockchain 目录下内容为空之后,创建链并启动所有节点。命令如下:
# 创建xuper链
./xchain-cli createChain
# 启动服务节点
nohup ./xchain &
# check服务运行状况,修改-H后参数,可以查询每个节点状态
for((i=1;i<=3;i++));do
./xchain-cli status -H 127.0.0.1:3710$i |grep -i height
done
通过变更-H 参数,查看每个节点的状态,若所有节点高度都是一致变化的,则证明环境状态正常。
10.2. 验证集合合约部署和调用
XPoA共识算法中,候选人的变更依赖”验证集合”合约,所以需要部署”验证集合”合约。通过调用合约中的add_validate方法新增候选人、del_validate方法删除候选人、update_validate方法更新候选人neturl、get_validates方法查询候选人列表。通过设置合约方法的ACL,可以限制哪些用户具有变更候选人的权限,设置方法参考 设置合约方法的ACL。
10.2.1. 创建合约账号
合约账号用来做合约的管理,创建合约账号,并给合约账号转账。
# 创建合约账号
[work@]$ node1 -> ./xchain-cli account new --account 1111111111111111 --fee 1000 -H 127.0.0.1:37101
# 执行结果
# contract response:
# {
# "pm": {
# "rule": 1,
# "acceptValue": 1.0
# },
# "aksWeight": {
# "dpzuVdosQrF2kmzumhVeFQZa1aYcdgFpN": 1.0
# }
# }
# The gas you cousume is: 1000
# The fee you pay is: 1000
# Tx id: eb9924c85a16d72f5daf6e6feabb130ef9c8a3ce8f507db08dcb726111aef74f
# account name: XC1111111111111111@xuper
# 给合约账号转账
[work@]$ node1 -> ./xchain-cli transfer --to XC1111111111111111@xuper --amount 100000000 -H 127.0.0.1:37101
# 执行结果
# ec6fa53446a8c6ab0d8d45f2bba80c7e5122341ce9b0c85779f80ce1a55f37b6
10.2.2. 编译合约
“验证集合”合约源码位于core/contractsdk/cpp/example/xpoa_validates,执行如下命令编译合约,编译结果为xpoa_validates.wasm。
# prj是xuperchain源码所在目录,设定环境变量
export PATH=$prj/xuperchain/output:$PATH
export XDEV_ROOT=$prj/xuperchain/core/contractsdk/cpp
# 编译合约
cd $prj/xuperchain/core/contractsdk/cpp/example/xpoa_validates
xdev build
10.2.3. 部署合约
部署合约,并设置node1、node2为初始候选人。
[work@]$ node1 -> ./xchain-cli wasm deploy --account XC1111111111111111@xuper --cname xpoa_validates --arg '{"addresss":"dpzuVdosQrF2kmzumhVeFQZa1aYcdgFpN;VSML7NenZnGZgCEwtbQDKDSrPHhT5wsu6","neturls":"127.0.0.1:47101;127.0.0.1:47102"}' ./xpoa_validates.wasm --fee 222065 -H 127.0.0.1:37101
# 执行结果
# contract response: initialize succeed
# The gas you cousume is: 221920
# The fee you pay is: 222065
# Tx id: 4f9f11afcf080199b93d5f308b6dc0e07ce5b9099c36cbf9b4edb2ee398bcfa3
参数说明:
- wasm deploy:部署wasm合约
- –account XC1111111111111111@xuper:此为部署wasm合约的账号
- –cname xpoa_validates :合约名称,需与xuper.json中配置的contract_name参数一致
- –arg :此为传入合约的参数,这里设置初始矿工,所指定的初始矿工需要在网络中存在,多个矿工用分号间隔,且address与netrul要 一一对应。
- ./xpoa_validates.wasm :是编译合约产出的文件
10.2.4. 增加候选人
以添加node3为候选人为例,添加后等待1分钟,调查看候选人命令,查看是否添加成功。
[work@]$ node1 -> ./xchain-cli wasm invoke xpoa_validates --method add_validate --args '{"address":"bg3KLC3YCmvLWBCNAVHGHLfk3qeWEdoD3","neturl":"127.0.0.1:47103"}' --fee 300 -H 127.0.0.1:37101
# 执行结果
# contract response: {"address":"bg3KLC3YCmvLWBCNAVHGHLfk3qeWEdoD3","neturl":"127.0.0.1:47103"}
# The gas you cousume is: 252
# The fee you pay is: 300
# Tx id: 5a3993d0e001aa0b140b204c013c6ea0b9741f8e1dfe81db71887579d63ce785
参数说明:
- wasm invoke:调用合约
- –method add_validate:调用add_validate方法
- –args:传入的参数,填写待添加候选人的address和neturl
10.2.5. 查看候选人
查询结果中,候选人按字典序排列。
[work@]$ node1 -> ./xchain-cli wasm invoke xpoa_validates --method get_validates -H 127.0.0.1:37101
# 执行结果
# contract response: {"proposers":[{"address":"VSML7NenZnGZgCEwtbQDKDSrPHhT5wsu6","neturl":"127.0.0.1:47102"},{"address":"bg3KLC3YCmvLWBCNAVHGHLfk3qeWEdoD3","neturl":"127.0.0.1:47103"},{"address":"dpzuVdosQrF2kmzumhVeFQZa1aYcdgFpN","neturl":"127.0.0.1:47101"}]}
# The gas you cousume is: 439
# You need add fee
- wasm invoke:调用合约
- –method get_validates:调用get_validates方法
10.2.6. 更新候选人
候选人的netrul发生变化后,需要更新。以更新node3的neturl为例,比如更新为localhost:47103。修改后等待1分钟,调查看候选人命令,查看是否修改成功。
[work@]$ node1 -> ./xchain-cli wasm invoke xpoa_validates --method update_validate -a '{"address":"bg3KLC3YCmvLWBCNAVHGHLfk3qeWEdoD3","neturl":"localhost:47103"}' --fee 300 -H 127.0.0.1:37101
# 执行结果
# contract response: {"address":"bg3KLC3YCmvLWBCNAVHGHLfk3qeWEdoD3","neturl":"localhost:47103"}
# The gas you cousume is: 263
# The fee you pay is: 300
# Tx id: 6e6289c513169cd32c44fa05bb06c0eba0f37f05acd5eb6ae4573ae266363b76
参数说明:
- wasm invoke:调用合约
- –method update_validate:调用update_validate方法
- –args:传入的参数,填写待更新候选人的address和neturl
10.2.7. 删除候选人
将node3从候选人集合删除。删除后等待1分钟,调查看候选人命令,查看是否删除成功。
[work@]$ node1 -> ./xchain-cli wasm invoke xpoa_validates --method del_validate -a '{"address":"bg3KLC3YCmvLWBCNAVHGHLfk3qeWEdoD3"}' --fee 300 -H 127.0.0.1:37101
# 执行结果
# contract response: ok
# The gas you cousume is: 128
# The fee you pay is: 300
# Tx id: a033b1c4b548c3515a29b5d643fdad20cc778c71a75a95869ddaae067177d7c4
- wasm invoke:调用合约
- –method del_validate:调用del_validate方法
- –args:传入的参数,填写待删除候选人的address和neturl
10.2.8. 查看当前正在出块的候选人
通过日志,可查看当前正在出块的候选人。示例如下,其中proposer是正在出块候选人。并且,多个候选人按字典序轮值出块。
[work@]$ node1 -> tailf logs/xchain.log|grep "bft NewView"
t=2020-06-28T17:04:24+0800 lvl=info msg="bft NewView" module=xchain viewNum=550 dpm.currentView=550 proposer=bg3KLC3YCmvLWBCNAVHGHLfk3qeWEdoD3 preProposer=VSML7NenZnGZgCEwtbQDKDSrPHhT5wsu6 err=nil
t=2020-06-28T17:04:27+0800 lvl=info msg="bft NewView" module=xchain viewNum=551 dpm.currentView=551 proposer=bg3KLC3YCmvLWBCNAVHGHLfk3qeWEdoD3 preProposer=VSML7NenZnGZgCEwtbQDKDSrPHhT5wsu6 err=nil
10.3. 常见问题
- 端口冲突:注意如果在一台机器上部署多个节点,各个节点的RPC监听端口以及p2p监听端口都需要设置地不相同,避免冲突;
- 节点公私钥冲突:注意网络中不同节点./data/keys下的文件内容都应该不一样,这个文件夹是节点在网络中的唯一标识,每个节点需要独自生成,否则网络启动异常;
- 遇到The gas you cousume is: XXXX, You need add fee 通过加–fee XXXX 参数附加资源;
- Chained-Bft算法要求3个矿工的集群,不可以有矿工故障,所以如果使用更新候选人接口将节点neturl更新错误,将无法出块,需删除data/blockchain 目录下内容后,从10.1.4节开始重新部署环境。