1. 前言
通过修改创世文件中的公钥和地址,和修改配置文件中的持续节点信息是静态更新网络节点,通过向网络中广播提交一笔交易(代码中规定交易的格式,用来区分是具体的交易还是更新节点)是动态更新(删除、添加、修改)网络节点。先通过静态的方式搭建一个多节点网络,然后动态的添加验证节点。
准备至少5台虚拟机,若没有虚拟机,可以通过修改配置文件的端口号来创建多个节点。根据PBFT算法的 3f+1≤n (f 是可容忍出错节点数,n 是总节点数,可以用来验证移除节点是否成功),可知至少需要4个验证节点才可以符合一致性要求,此时最多可以容忍一个节点出错。
2. 静态搭建网络
参考至说明文档搭建网络,1. 节点集群,2. Tendermint 网络。
搭建四个验证节点的网络:
-
在4个机器的终端中初始化
tendermint init -
将四个机器的公钥和地址放到一个创世文件中(genesis.json),保证 chain_id 唯一,如下图所示
-
修改配置文件(config.toml),这三处修改,其他的根据需要改
create_empty_blocks = false (不产生空块)
#create_empty_blocks_interval = “0s”
addr_book_strict = false (允许私有网络)
version = “v1” (可选,v1重构了v0版本以提高可测试性)将这个配置文件复制到另外三个机器上
-
每个机器上都创建四个配置文件目录
tendermint testnet --o /home/tender/node/ (指定目录路径,可选) -
依次启动四个 abci 应用程序
abci-cli kvstore --persist /home/tender/chain/abcidata (一定要指定数据存放目录,否则后续无法动态更新节点) -
依次启动四个节点
tendermint node --p2p.persistent_peers=“e821237e1642f786e0e0b7af5d374c833a487408@192.168.0.222:26656,7fbb589634d211427fc06612cc572a9cfb15884b@192.168.0.223:26656,3ac9d87708e6e92d63ac62bf72aa3c8ed2bc6cad@192.168.0.224:26656”e821237e1642f786e0e0b7af5d374c833a487408:节点ID,通过 tendermint show_node_id 获取,192.168.0.222:本地ip。启动时不要包含本机器的IP。当启动到第三个节点时,就会开始出块,若设置了禁止创建空块,就只会出现两个块。
-
在任意一台机器上广播一笔交易,其他节点能同步数据,则说明网络搭建成功。
curl localhost:26657/broadcast_tx_commit?tx=“test=1024b”
3. 动态更新验证节点
定位到代码:tendermint/abci/example/kvstore/persistent_kvstore.go => execValidatorTx(),
由这个函数可以明确知道交易的格式以及动态更新验证节点的规则,可以根据需求修改此函数。
-
首先在第五台机器上启动单abci应用程序和单节点
– tendermint init
– abci-cli kvstore --persist /home/tender/chain/abcidata
– tendermint testnet --o /home/tender/node/
– tendermint node -
查看该节点状态,若正常响应,则成功启动
curl localhost:26657/status -
添加验证节点——在之前搭建好的网络中广播提交一笔添加验证节点的交易
curl localhost:26657/broadcast_tx_commit?tx=“val:yHhS4dfxSxH1KscpARtsOnG6Gb6fSCxvlfnswaV320g=!11”
使用 curl localhost:26657/validators,可查看验证节点集合。此时另外四个节点都可以同步第五个节点的数据块,但是第五个节点还不能同步另外四个节点的数据块。 -
新加的验证节点同步网路中的数据块
– 将网络中任意一个节点的创世文件复制到新验证节点的数据目录下,保证五个节点的创世文件一致
– 将 abci 和 tendermint 进程强制关闭,然后删除 abcidata 目录
– tendermint unsafe_reset_all (新验证节点还没有数据,所以此命令是安全的)
– tendermint init
– tendermint testnet --o /home/tender/node/
– tendermint node --p2p.persistent_peers="c9a22e087554e19fe2930c867c2c410c7a7893dd@192.168.0.221:26656,e821237e1642f786e0e0b7af5d374c833a487408@192.168.0.222:26656,7fbb589634d211427fc06612cc572a9cfb15884b@192.168.0.223:26656,5afb11495ec427332fce3addc87dccbb459e9b5a@192.168.0.224:26656 (持久化除本节点外的另外四个节点的数据)建议在确保命令执行顺序没有错误之后,将命令制作成 .sh 执行文件 -
修改验证节点的权限
curl localhost:26657/broadcast_tx_commit?tx=\"val\:WN8v9LPPWCHle2XJR/3MhwfIyy0cCaZPCLCxR5n0/c8\=\!10\"
特殊字符必须加上转义符号。WN8v9LPPWCHle2XJR/3MhwfIyy0cCaZPCLCxR5n0/c8=:要修改权限的节点的公钥;10:修改后的权限。
注意:使用 curl localhost:26657/validators 查看的验证者集合并不是实时的,判断是否更新成功的依据是,五个节点都几乎同时展示下图
-
移除验证节点
将上面的“10”改为“0”,即可实现移除。当权限为0时,就会从集群中移除。验证是否移除成功:将移除的验证节点的 Tendermint 进程强制关掉,然后再将网络中任意一个节点的 tendermint 进程强制关掉,再发送一笔交易,若能达成共识,说明成功移除。
由于第五步对新加的验证节点与网络中的节点的数据块做了同步处理,这里移除后,数据还是会同步的。那么问题来了,怎么关闭掉移除验证节点的数据块同步呢?
注意:动态添加、修改、移除节点都是根据源码逻辑来的,并未对源码做修改