1. 两台物理机器
192.168.1.244 root密码t5
192.168.1.246 root密码t5
2. tendermint搭建 在tendermint/docs/examples这个目录,有四个节点的配置和文档,可以参考使用
2.1 编译出tendermint可执行文件,然后分别scp到245和246
2.2 在245执行 ./tendermint init,在root/.tendermint下会生成两个目录,分别是config和data目录。
2.2.1 config/config.toml tendermint的配置信息 这里有3个关键端口46656,46657,46658,各参数有对应解释。
2.2.2 config/genesis.json 创世validator信息。注意,所有节点的chain-id必须是一样的。
2.3 同理在246上执行
2.4 将245和246的genesis.json的validators进行配置,将两台机器都配置起来。也就是说,将245和246的validators信息相互添加。比如,244的genesis.json内容如下:
---------------------
{"genesis_time":"0001-01-01T00:00:00Z","chain_id":"test-chain-zusn4r","validators":[{"pub_key":{"type":"ed25519","data":"26AB8CCB5836A85EBFCB3BC5EAEA2A9E91C0ADBA58FBDA43F18BA2801AAB3074"},"power":10,"name":""},{"pub_key":{"type":"ed25519","data":"E058A49F4AA4AD852738F77316728644360F368CDA91AFAAF310DBAFFC7AC8FB"},"power":10,"name":""}],"app_hash":""}
---------------------
2.5 在两台机器上都依次运行如下命令
./two-nodes-server & //这是一个tendermint abci server,实现了deliver_tx, check_tx, commit三个函数,但都是空的。(注意,这个two-nodes-server是用户自己写的,tendermint上没有,请参考tendermint的规范自行实现)
/root/tendermint node --p2p.persistent_peers=192.168.1.245:46656,192.168.1.246:46656
2.6 genesis.jon的文件内容如下
------------------------------------
{
"genesis_time":"0001-01-01T00:00:00Z",
"chain_id":"test-chain-zusn4r", #注意,两个节点的chain_id必须相同
"validators":[
{
"pub_key":{
"type":"ed25519",
"data":"E058A49F4AA4AD852738F77316728644360F368CDA91AFAAF310DBAFFC7AC8FB"
},
"power":10,
"name":""
}
],
"app_hash":""
}
------------------------------------
name不需要设置
app_hash不需要设置
2.7 如果只启动一个node,会出现如下log错误
I[03-16|09:31:29.744] Ignoring inbound connection: error while adding peer module=p2p address=192.168.199.245:24420 err="Connect to self"
E[03-16|09:31:29.744] Failed to add peer module=p2p address=192.168.199.245:46656 err="Connect to self"
E[03-16|09:31:29.744] Error dialing peer module=p2p err="Connect to self"
I[03-16|09:31:31.161] Dialing peer module=p2p address=192.168.199.246:46656
E[03-16|09:31:31.162] Failed to dial peer module=p2p address=192.168.199.246:46656 err="Error creating peer: dial tcp 192.168.199.246:46656: getsockopt: connection refused"
E[03-16|09:31:31.162] Error dialing peer module=p2p err="Error creating peer: dial tcp 192.168.199.246:46656: getsockopt: connection refused"
I[03-16|09:31:38.487] Ensure peers module=p2p numOutPeers=0 numDialing=0 numToDial=10
I[03-16|09:31:38.487] No addresses to dial nor connected peers. Falling back to seeds module=p2p
不知道什么意思。
如果两个node都启动了,两边都会反复发送各种信息,导致数据增加。
两个节点会进行各种数据一致性操作,形如
I[03-16|09:29:30.442] enterCommit(37/0). Current: 37/0/RoundStepPrecommit module=consensus
I[03-16|09:29:30.460] Finalizing commit of block with 0 txs module=consensus height=37 hash=7309D981D10A34DC32524A43E5263F3670BD20E4 root=
I[03-16|09:29:30.461] Block{
Header{
ChainID: test-chain-zusn4r
Height: 37
Time: 2018-03-16 17:29:29.799 +0800 CST
NumTxs: 0
TotalTxs: 0
LastBlockID: 29E35DB1BFEDAE943E22A0BFC80DCC9FA0870156:1:E7262AFCF107
LastCommit: 71C5837C2EAA278B75C9B52FA1486E27DFFF1D8D
Data:
Validators: 869EA33897CCB904E6BDEF9127DD0F2B7F85942E
App:
Conensus: 0B8CEF95EC57AC2D96038FD0AE3901C14FAE8E73
Results:
Evidence:
}#7309D981D10A34DC32524A43E5263F3670BD20E4
Data{
}#
Data{
}#
Commit{
BlockID: 29E35DB1BFEDAE943E22A0BFC80DCC9FA0870156:1:E7262AFCF107
Precommits: Vote{0:6B09230E6A6D 36/00/2(Precommit) 29E35DB1BFED {/C2CCC1696A99.../} @ 2018-03-16T09:29:28.192Z}
Vote{1:6E9331178A68 36/00/2(Precommit) 29E35DB1BFED {/AE54DB25FD29.../} @ 2018-03-16T09:29:28.395Z}
}#71C5837C2EAA278B75C9B52FA1486E27DFFF1D8D
}#7309D981D10A34DC32524A43E5263F3670BD20E4 module=consensus
I[03-16|09:29:30.544] Executed block module=state height=37 validTxs=0 invalidTxs=0
I[03-16|09:29:30.576] Committed state module=state height=37 txs=0 appHash=
I[03-16|09:29:30.576] Recheck txs module=mempool numtxs=0 height=37
3.双节点配置成功。当两个节点同时运行时,会不停地添加新区块。分析其运行逻辑。
3.1 连接自身的错误
I[03-17|07:23:59.274] Dialed peer with unknown ID - unable to authenticate module=p2p peer=192.168.199.246:46656 addr=192.168.199.246:46656
E[03-17|07:23:59.274] Failed to add peer module=p2p address=192.168.199.246:46656 err="Connect to self"
E[03-17|07:23:59.274] Error dialing peer module=p2p err="Connect to self"
I[03-17|07:23:59.274] Ignoring inbound connection: error while adding peer module=p2p address=192.168.199.246:28486 err="Connect to self"
3.2 一个节点运行若干次完整的提交
I[03-17|07:24:00.309] Connected to peer module=p2p peer="Peer{MConn{192.168.199.245:46656} 37c4c21306aeec4df34750add95317cb8292ba36 out}"
//height=183的提交
I[03-17|07:24:01.143] Time to switch to consensus reactor! module=blockchain height=183
/*
本语句在tendermint/blockchain/reactor.go:260执行,这个语句的意思是,如果本地的区块已经是最新的,那么就中断poolRoutine,然后转入到consensos共识引擎。
*/
I[03-17|07:24:01.143] Stopping BlockPool module=blockchain impl=BlockPool
//进入共识引擎执行,tendermint/consensus/reactor.go:86
I[03-17|07:24:01.143] SwitchToConsensus module=consensus
//然后,执行conR.conS.updateToState(state),产生一个新的NewRoundStepMessage.
//updateToState在tendermint/consensus/state.go:427
I[03-17|07:24:01.145] Ignoring updateToState() module=consensus newHeight=183 oldHeight=183
I[03-17|07:24:01.145] Starting ConsensusState module=consensus impl=ConsensusState
I[03-17|07:24:01.145] Starting baseWAL module=consensus wal=/root/.tendermint/data/cs.wal/wal impl=baseWAL
I[03-17|07:24:01.145] Starting TimeoutTicker module=consensus impl=TimeoutTicker
I[03-17|07:24:01.204] Catchup by replaying consensus messages module=consensus height=183
I[03-17|07:24:01.204] Replay: New Step module=consensus height=183 round=0 step=RoundStepNewHeight
I[03-17|07:24:01.204] Replay: Done module=consensus
I[03-17|07:24:01.205] Timed out module=consensus dur=-4.1239649s height=183 round=0 step=RoundStepNewHeight
//待确认:可见,这里的原理是,定时触发,也就是说,只要系统运行起来了,就是连续不断地主动对transaction进行打包区块,然后存入数据库,没有数据就上传空块。
//在config.toml,有timeout的各配置,也有是否创建空块的配置。
//to-do:修改timeout配置,减慢新块生成; 不允许创建空块,看执行效果。
//这个逻辑都在 enterNewRound 这个函数里。
I[03-17|07:24:01.231] enterNewRound(183/0). Current: 183/0/RoundStepNewHeight module=consensus
//发起了新一轮之后,等待transaction过来,如果到了,就进入propose阶段。关键代码如下
/*
cs.eventBus.PublishEventNewRound(cs.RoundStateEvent())
// Wait for txs to be available in the mempool
// before we enterPropose in round 0. If the last block changed the app hash,
// we may need an empty "proof" block, and enterPropose immediately.
waitForTxs := cs.config.WaitForTxs() && round == 0 && !cs.needProofBlock(height)
if waitForTxs {
if cs.config.CreateEmptyBlocksInterval > 0 {
cs.scheduleTimeout(cs.config.EmptyBlocksInterval(), height, round, cstypes.RoundStepNewRound)
}
go cs.proposalHeartbeat(height, round)
} else {
cs.enterPropose(height, round)
}
*/
I[03-17|07:24:01.231] enterPropose(183/0). Current: 183/0/RoundStepNewRound module=consensus
I[03-17|07:24:01.231] enterPropose: Not our turn to propose module=consensus proposer=6B09230E6A6DF383F6BD87E8476604E6FB3D9BF9 privValidator="PrivValidator{6E9331178A680C23F74161DC8150B71AA55911D4 LH:182, LR:0, LS:3}"
I[03-17|07:24:01.548] Added to prevote module=consensus vote="Vote{0:6B09230E6A6D 183/00/1(Prevote) C63EA5FFB734 {/0986998AD845.../} @ 2018-03-17T07:21:56.596Z}" prevotes="VoteSet{H:183 R:0 T:1 +2/3: BA{2:X_} map[]}"
I[03-17|07:24:01.564] Received complete proposal block module=consensus height=183 hash=C63EA5FFB7346ACFAE5C930BECC536482EB7B9F5
I[03-17|07:24:01.565] enterPrevote(183/0). Current: 183/0/RoundStepPropose module=consensus
I[03-17|07:24:01.566] enterPrevote: ProposalBlock is valid module=consensus height=183 round=0
I[03-17|07:24:01.589] Signed and pushed vote module=consensus height=183 round=0 vote="Vote{1:6E9331178A68 183/00/1(Prevote) C63EA5FFB734 {/BBBD2EE8D8FD.../} @ 2018-03-17T07:24:01.566Z}" err=null
I[03-17|07:24:01.623] Added to prevote module=consensus vote="Vote{1:6E9331178A68 183/00/1(Prevote) C63EA5FFB734 {/BBBD2EE8D8FD.../} @ 2018-03-17T07:24:01.566Z}" prevotes="VoteSet{H:183 R:0 T:1 +2/3:C63EA5FFB7346ACFAE5C930BECC536482EB7B9F5:1:B687C704F4C7 BA{2:XX} map[]}"
I[03-17|07:24:01.623] enterPrecommit(183/0). Current: 183/0/RoundStepPrevote module=consensus
I[03-17|07:24:01.623] enterPrecommit: +2/3 prevoted proposal block. Locking module=consensus hash=C63EA5FFB7346ACFAE5C930BECC536482EB7B9F5
I[03-17|07:24:01.640] Signed and pushed vote module=consensus height=183 round=0 vote="Vote{1:6E9331178A68 183/00/2(Precommit) C63EA5FFB734 {/2923B4309FA8.../} @ 2018-03-17T07:24:01.625Z}" err=null
I[03-17|07:24:01.674] Added to precommit module=consensus vote="Vote{1:6E9331178A68 183/00/2(Precommit) C63EA5FFB734 {/2923B4309FA8.../} @ 2018-03-17T07:24:01.625Z}" precommits="VoteSet{H:183 R:0 T:2 +2/3: BA{2:_X} map[]}"
I[03-17|07:24:02.365] Added to precommit module=consensus vote="Vote{0:6B09230E6A6D 183/00/2(Precommit) C63EA5FFB734 {/0C489D106468.../} @ 2018-03-17T07:24:01.788Z}" precommits="VoteSet{H:183 R:0 T:2 +2/3:C63EA5FFB7346ACFAE5C930BECC536482EB7B9F5:1:B687C704F4C7 BA{2:XX} map[37c4c21306aeec4df34750add95317cb8292ba36:C63EA5FFB7346ACFAE5C930BECC536482EB7B9F5:1:B687C704F4C7]}"
I[03-17|07:24:02.365] enterCommit(183/0). Current: 183/0/RoundStepPrecommit module=consensus
I[03-17|07:24:02.383] Finalizing commit of block with 0 txs module=consensus height=183 hash=C63EA5FFB7346ACFAE5C930BECC536482EB7B9F5 root=
I[03-17|07:24:02.384] Block{
Header{
ChainID: test-chain-zusn4r
Height: 183
Time: 2018-03-17 15:21:56.46 +0800 CST
NumTxs: 0
TotalTxs: 0
LastBlockID: 7236DB885E7926BFD636EA41F2F7B8C1B1ABDC89:1:6D13078EE514
LastCommit: 2A8FE9A778D4BB154273C531B79B93613981E2D0
Data:
Validators: 869EA33897CCB904E6BDEF9127DD0F2B7F85942E
App:
Conensus: 0B8CEF95EC57AC2D96038FD0AE3901C14FAE8E73
Results:
Evidence:
}#C63EA5FFB7346ACFAE5C930BECC536482EB7B9F5
Data{
}#
Data{
}#
Commit{
BlockID: 7236DB885E7926BFD636EA41F2F7B8C1B1ABDC89:1:6D13078EE514
Precommits: Vote{0:6B09230E6A6D 182/00/2(Precommit) 7236DB885E79 {/F4819FCC3235.../} @ 2018-03-17T07:21:54.678Z}
Vote{1:6E9331178A68 182/00/2(Precommit) 7236DB885E79 {/35BF5493AD1A.../} @ 2018-03-17T07:21:54.868Z}
}#2A8FE9A778D4BB154273C531B79B93613981E2D0
}#C63EA5FFB7346ACFAE5C930BECC536482EB7B9F5 module=consensus
I[03-17|07:24:02.434] Executed block module=state height=183 validTxs=0 invalidTxs=0
I[03-17|07:24:02.457] Committed state module=state height=183 txs=0 appHash=
I[03-17|07:24:02.457] Recheck txs module=mempool numtxs=0 height=183
I[03-17|07:24:03.366] Timed out module=consensus dur=817.386392ms height=184 round=0 step=RoundStepNewHeight
I[03-17|07:24:03.390] enterNewRound(184/0). Current: 184/0/RoundStepNewHeight module=consensus
I[03-17|07:24:03.390] enterPropose(184/0). Current: 184/0/RoundStepNewRound module=consensus
I[03-17|07:24:03.390] enterPropose: Our turn to propose module=consensus proposer=6E9331178A680C23F74161DC8150B71AA55911D4 privValidator="PrivValidator{6E9331178A680C23F74161DC8150B71AA55911D4 LH:183, LR:0, LS:3}"
I[03-17|07:24:03.415] Signed proposal module=consensus height=184 round=0 proposal="Proposal{184/0 1:074B0C7D3F2F (-1,:0:000000000000) {/BB9FB54A39E1.../} @ 2018-03-17T07:24:03.391Z}"
I[03-17|07:24:03.466] Received complete proposal block module=consensus height=184 hash=AF8E0F68D4C66E76B88B9EFDA793BBF1DF591A10
I[03-17|07:24:03.466] enterPrevote(184/0). Current: 184/0/RoundStepPropose module=consensus
I[03-17|07:24:03.467] enterPrevote: ProposalBlock is valid module=consensus height=184 round=0
I[03-17|07:24:03.482] Signed and pushed vote module=consensus height=184 round=0 vote="Vote{1:6E9331178A68 184/00/1(Prevote) AF8E0F68D4C6 {/09BE46698FA6.../} @ 2018-03-17T07:24:03.467Z}" err=null
I[03-17|07:24:03.549] Added to prevote module=consensus vote="Vote{1:6E9331178A68 184/00/1(Prevote) AF8E0F68D4C6 {/09BE46698FA6.../} @ 2018-03-17T07:24:03.467Z}" prevotes="VoteSet{H:184 R:0 T:1 +2/3: BA{2:_X} map[]}"
I[03-17|07:24:03.941] Added to prevote module=consensus vote="Vote{0:6B09230E6A6D 184/00/1(Prevote) AF8E0F68D4C6 {/56B63ACBE0F0.../} @ 2018-03-17T07:24:03.713Z}" prevotes="VoteSet{H:184 R:0 T:1 +2/3:AF8E0F68D4C66E76B88B9EFDA793BBF1DF591A10:1:074B0C7D3F2F BA{2:XX} map[]}"
I[03-17|07:24:03.941] enterPrecommit(184/0). Current: 184/0/RoundStepPrevote module=consensus
I[03-17|07:24:03.942] enterPrecommit: +2/3 prevoted proposal block. Locking module=consensus hash=AF8E0F68D4C66E76B88B9EFDA793BBF1DF591A10
I[03-17|07:24:03.957] Signed and pushed vote module=consensus height=184 round=0 vote="Vote{1:6E9331178A68 184/00/2(Precommit) AF8E0F68D4C6 {/A43D527016E1.../} @ 2018-03-17T07:24:03.943Z}" err=null
I[03-17|07:24:03.991] Added to precommit module=consensus vote="Vote{1:6E9331178A68 184/00/2(Precommit) AF8E0F68D4C6 {/A43D527016E1.../} @ 2018-03-17T07:24:03.943Z}" precommits="VoteSet{H:184 R:0 T:2 +2/3: BA{2:_X} map[]}"
I[03-17|07:24:04.050] Added to precommit module=consensus vote="Vote{0:6B09230E6A6D 184/00/2(Precommit) AF8E0F68D4C6 {/A471C4BC8148.../} @ 2018-03-17T07:24:03.814Z}" precommits="VoteSet{H:184 R:0 T:2 +2/3:AF8E0F68D4C66E76B88B9EFDA793BBF1DF591A10:1:074B0C7D3F2F BA{2:XX} map[]}"
I[03-17|07:24:04.050] enterCommit(184/0). Current: 184/0/RoundStepPrecommit module=consensus
I[03-17|07:24:04.068] Finalizing commit of block with 0 txs module=consensus height=184 hash=AF8E0F68D4C66E76B88B9EFDA793BBF1DF591A10 root=
I[03-17|07:24:04.068] Block{
Header{
ChainID: test-chain-zusn4r
Height: 184
Time: 2018-03-17 15:24:03.39 +0800 CST
NumTxs: 0
TotalTxs: 0
LastBlockID: C63EA5FFB7346ACFAE5C930BECC536482EB7B9F5:1:B687C704F4C7
LastCommit: 3B2FBDDFA6759D78886A69A607A425798F1EE56F
Data:
Validators: 869EA33897CCB904E6BDEF9127DD0F2B7F85942E
App:
Conensus: 0B8CEF95EC57AC2D96038FD0AE3901C14FAE8E73
Results:
Evidence:
}#AF8E0F68D4C66E76B88B9EFDA793BBF1DF591A10
Data{
}#
Data{
}#
Commit{
BlockID: C63EA5FFB7346ACFAE5C930BECC536482EB7B9F5:1:B687C704F4C7
Precommits: Vote{0:6B09230E6A6D 183/00/2(Precommit) C63EA5FFB734 {/0C489D106468.../} @ 2018-03-17T07:24:01.788Z}
Vote{1:6E9331178A68 183/00/2(Precommit) C63EA5FFB734 {/2923B4309FA8.../} @ 2018-03-17T07:24:01.625Z}
}#3B2FBDDFA6759D78886A69A607A425798F1EE56F
}#AF8E0F68D4C66E76B88B9EFDA793BBF1DF591A10 module=consensus
I[03-17|07:24:04.118] Executed block module=state height=184 validTxs=0 invalidTxs=0
I[03-17|07:24:04.150] Committed state module=state height=184 txs=0 appHash=
I[03-17|07:24:04.150] Recheck txs module=mempool numtxs=0 height=184
I[03-17|07:24:05.051] Timed out module=consensus dur=784.086656ms height=185 round=0 step=RoundStepNewHeight
I[03-17|07:24:05.066] enterNewRound(185/0). Current: 185/0/RoundStepNewHeight module=consensus