前言

对 Tendermint 有了一个的了解之后,我们需要对 Tendermint 进行开发和操作,该如何运行这个项目。
Tendermint 使用的是 cobra 这个命令行框架,需要对 cobra 有一定的了解。

初始化项目

配置IDEA

我使用 goland开发调试,先将项目 clone 到本地,配置好go mod。

goland配置gomod

安装内置命令: tendermint

git clone 之后,找开项目,Tendermint 是go项目,内置的一些功能需要先进行编译。

make install

这一步的操作是为了将内置命令: tendermint,安装到当前系统中。

验证命令正确安装,执行一下:tendermint

tendermint命令安装验证

这个图中展示了 tendermint 支持的各种命令,对节点运行来说,需要关注的是

  1. init
  2. start

初始化 validator 节点

tendermint 可以初始化三种节点类型

  1. FullNode
  2. seed
  3. validator

初始化节点类型

这三种类型是常见的三种节点类型,FullNode 用于区块广播、查询等;seed 是种子节点,用来做节点发现;validator 是验证人节点,也就是产块节点(选举出Propose产块)。节点类型初始化以后,可以通过配置文件进行修改节点类型。

tendermint init [validator|full|seed]

我们初始化为 validator 节点

初始化为validator节点

生成了一套配置文件:

  1. validator 的key文件
  2. priv_validator的状态文件
  3. node_key 节点私钥
  4. genesis 配置文件,实际就是链相关的初始化配置

validator keyFile=/Users/liukai/.tendermint/config/priv_validator_key.json
module=main stateFile=/Users/liukai/.tendermint/data/priv_validator_state.json
node key module=main path=/Users/liukai/.tendermint/config/node_key.json
genesis file module=main path=/Users/liukai/.tendermint/config/genesis.json
mode=validator module=main

到这里,初始化工作就差不多完成了,可以直接启动,默认情况下,tendermint 服务会去连接一个 ABCI 的应用,如果没有 tendermint 启动后一直偿试去连接一个应用,这里我使用官方提供的内置KV存储应用,在启动时指定连接该应用。

完整命令

tendermint node --proxy-app=kvstore

连接应用启动

看一下这个日志,能从日志中看出什么来,下面的日志是共识模块打印出来的日志。

  1. Timed out dur: 执行周期,表示本次处理之间经过了多久时间
  2. received proposal: 这里validator只有它自己一个,所有其实这个 proposal 就是当前节点自己
  3. finalizing commit of block: 共识了commit阶段打印的日志,来自state.go的finalizeCommit这个方法,往上回溯是共识流程中的commit阶段中最后打印的日志,从这里分析出共识的代码。

到这里,证明这个项目的代码是能正常初始化并启动的,我们开发的话,使用IDE来启动项目,方便一些。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2022-01-15T18:09:12+08:00 INFO started node module=main node=Node
2022-01-15T18:09:13+08:00 INFO Timed out dur=955.244 height=1 module=consensus round=0 step=1
2022-01-15T18:09:13+08:00 INFO received proposal module=consensus proposal={"Type":32,"block_id":{"hash":"602C388864F8CBF5F799ED7AAEE8A71F206F200719187CF6B918101F748F8438","parts":{"hash":"3DC5C676DC9DAFC0EFB9EA5705D1FEAB57F4B89663FD57D8CA01885931C83C73","total":1}},"height":1,"pol_round":-1,"round":0,"signature":"UKRIZf+EKc73YFoDvvvet8pswiR/JWP7WT0ms+hmpqo/NgXX1Z+iLWtTRiryjNNoeTZOFESnyauzKa6z4HGiCQ==","timestamp":"2022-01-15T10:09:13.046562Z"}
2022-01-15T18:09:13+08:00 INFO received complete proposal block hash=602C388864F8CBF5F799ED7AAEE8A71F206F200719187CF6B918101F748F8438 height=1 module=consensus
2022-01-15T18:09:13+08:00 INFO finalizing commit of block hash=602C388864F8CBF5F799ED7AAEE8A71F206F200719187CF6B918101F748F8438 height=1 module=consensus num_txs=0 root=
2022-01-15T18:09:13+08:00 INFO executed block height=1 module=state num_invalid_txs=0 num_valid_txs=0
2022-01-15T18:09:13+08:00 INFO committed state app_hash=0000000000000000 height=1 module=state num_txs=0
2022-01-15T18:09:14+08:00 INFO Timed out dur=903.604 height=2 module=consensus round=0 step=1
2022-01-15T18:09:14+08:00 INFO received proposal module=consensus proposal={"Type":32,"block_id":{"hash":"5677777BE540DADC8D5C29238FCE04D60B8F37F694C3E2455E7C84211192BCD6","parts":{"hash":"F14D63CF02B3E24873FB882DD14BB24451AC7C3B727C7E2B701187C4C1E0FB7D","total":1}},"height":2,"pol_round":-1,"round":0,"signature":"4dxc7YP4kj3kYxcAA+gVd45gzPm7OR+jjnEO/yysqjtPpNZShz/xNwQ1lGr/ez/VbQ6VYpyiWpfEkZ0yZzQvAw==","timestamp":"2022-01-15T10:09:14.182702Z"}
2022-01-15T18:09:14+08:00 INFO received complete proposal block hash=5677777BE540DADC8D5C29238FCE04D60B8F37F694C3E2455E7C84211192BCD6 height=2 module=consensus
2022-01-15T18:09:14+08:00 INFO finalizing commit of block hash=5677777BE540DADC8D5C29238FCE04D60B8F37F694C3E2455E7C84211192BCD6 height=2 module=consensus num_txs=0 root=0000000000000000
2022-01-15T18:09:14+08:00 INFO executed block height=2 module=state num_invalid_txs=0 num_valid_txs=0
2022-01-15T18:09:14+08:00 INFO committed state app_hash=0000000000000000 height=2 module=state num_txs=0
2022-01-15T18:09:15+08:00 INFO Timed out dur=916.435 height=3 module=consensus round=0 step=1
2022-01-15T18:09:15+08:00 INFO received proposal module=consensus proposal={"Type":32,"block_id":{"hash":"D0D03A1D4F18E4437BE7DC0A5A5CAEEC4AC60844812925FF49E5D100A1734EA7","parts":{"hash":"162DFDBEAD99485E176D568C492B166BCB171050FEB687B6126F555920B49E47","total":1}},"height":3,"pol_round":-1,"round":0,"signature":"SISLt3TOCH1kMyMvdwzxUgM1Pt+iXcB/7erNo1Hoz/etJ/bES4+yHT/NLpUMxR4/6yuItCl5tLCnn7lAkiOrDA==","timestamp":"2022-01-15T10:09:15.317317Z"}
2022-01-15T18:09:15+08:00 INFO received complete proposal block hash=D0D03A1D4F18E4437BE7DC0A5A5CAEEC4AC60844812925FF49E5D100A1734EA7 height=3 module=consensus
2022-01-15T18:09:15+08:00 INFO finalizing commit of block hash=D0D03A1D4F18E4437BE7DC0A5A5CAEEC4AC60844812925FF49E5D100A1734EA7 height=3 module=consensus num_txs=0 root=0000000000000000
2022-01-15T18:09:15+08:00 INFO executed block height=3 module=state num_invalid_txs=0 num_valid_txs=0
2022-01-15T18:09:15+08:00 INFO committed state app_hash=0000000000000000 height=3 module=state num_txs=0
2022-01-15T18:09:16+08:00 INFO Timed out dur=913.594 height=4 module=consensus round=0 step=1
2022-01-15T18:09:16+08:00 INFO received proposal module=consensus proposal={"Type":32,"block_id":{"hash":"CBD114A414D57D92273EDCAEE541088B745606B989891B8B486A62846F451146","parts":{"hash":"752DE3634222AC0150B8A2187D2559149B85599693A52F0BB3539B3C4E3D1573","total":1}},"height":4,"pol_round":-1,"round":0,"signature":"kIzWuc2D/0NmQG2n6dIZmD0RFIwSF9Yra9+bPgkpZCS2oM5B1v6yT9HKj71r0lExaVbvNQ66TRKmaSftBUCKBg==","timestamp":"2022-01-15T10:09:16.429801Z"}
2022-01-15T18:09:16+08:00 INFO received complete proposal block hash=CBD114A414D57D92273EDCAEE541088B745606B989891B8B486A62846F451146 height=4 module=consensus
2022-01-15T18:09:16+08:00 INFO finalizing commit of block hash=CBD114A414D57D92273EDCAEE541088B745606B989891B8B486A62846F451146 height=4 module=consensus num_txs=0 root=0000000000000000
2022-01-15T18:09:16+08:00 INFO executed block height=4 module=state num_invalid_txs=0 num_valid_txs=0
2022-01-15T18:09:16+08:00 INFO committed state app_hash=0000000000000000 height=4 module=state num_txs=0

goland中配置

添加启动参数: node --proxy-app=kvstore

goland启动参数配置

tendermint的启动依赖于cobra这个命仅行框架,通过源码可以看到,启动命令start的别名就是 node、run,所以使用 start 和 node 是等价就是,node只是start的一个别名。

start启动源码

通过debug启动

到这里,通过debug就可以正常进行开发调试了。

debug启动

vim-go 启动项目

有时候,习惯于在vim-go进行开发,我很多时间是用vim-go在开发,这里介绍一个使用vim-go进行启动和调试。

vim-go启动

tendermint 的启动服务命令在:cmd/tendermint 目录下。
在命令模式下输入:

:GoRun main.go node --proxy-app=kvstore

vim-go启动
启动输出
启动输出.png

vim-go debug启动

:GoDebug main.go node --proxy-app=kvstore

vim-godebug启动tendermint

查看节点状态

curl -s localhost:26657/status

查看节点状态

OK,基本上 tendermint 项目的启动方式都介绍完毕,使用基于tendermint 开发的小伙伴应该能解决一些小问题。