Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
S
share
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
JIRA
JIRA
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
张振华
share
Commits
54d54509
Commit
54d54509
authored
May 05, 2019
by
张振华
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
update
parent
6b89a8c2
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
77 additions
and
18 deletions
+77
-18
DPOS共识算法介绍.md
dpos共识/DPOS共识算法介绍.md
+77
-18
No files found.
dpos共识/DPOS共识算法介绍.md
View file @
54d54509
本文介绍常见的POS及DPOS共识算法
本文介绍常见的POS及DPOS共识算法,包括本次新实现的chain33的DPOS共识插件。
本文循序渐渐,通过对常见的Pos、DPos算法的介绍,使读者了解Pos、Dpos共识机制,并逐步演进到Eos的Dpos共识、Tendmint的Pos共识,最后介绍了Chain33的Dpos共识算法实现。
# 一、POS共识机制
# 一、POS共识机制
...
@@ -172,11 +173,11 @@ Tendermint蜉荳贋コ煤逧惻蛻カ悟菴灘ーア譏ッ悟惠隨ャ7豁・悟叉菴ソproposer蜃コ
...
@@ -172,11 +173,11 @@ Tendermint蜉荳贋コ煤逧惻蛻カ悟菴灘ーア譏ッ悟惠隨ャ7豁・悟叉菴ソproposer蜃コ


一个Cycle周期中,所有委托节点按时间槽(Period)顺序轮一遍。
一个Cycle周期中,所有委托节点按时间槽(Period)顺序轮一遍。
一个Cycle由多个Period构成,每个Period对应一个委托节点负责出块的时间段(时间槽)。
一个Cycle由多个Period构成,每个Period对应一个委托节点负责持续出块的时间段(时间槽
)。
一个Period分为多个出块周期,每个出块周期由负责出块的节点生成一个区块,并广播。
一个Period分为多个出块周期,每个出块周期由负责出块的节点生成一个区块,并通过P2P广播到其他节点。
Period切换时,要对已生成区块确认,并进行节点重新选举,推举出2/3多数公认的下一个Period负责出块的节点。
Period切换时,要对已生成区块确认,并进行节点重新选举,推举出2/3多数公认的下一个Period继续负责下一个Period的出块的节点。
选举投票及切换通知确认,都保存下来,作
为证据。
选举投票及切换通知确认,可以保存下来,
作为证据,因为每张投票都有具体节点的签名。
对于各节点时间不同步,投票共识未达成等异常情况,会部分节点、甚至全部节点
停止生成区块,直到修正错误。
对于各节点时间不同步,投票共识未达成等异常情况,可能会有部分节点、甚至全
部节点停止生成区块的情况,直到错误被修正;通常情况下,各受托节点或者多数受托节点保持系统时间和时间服务器同步,可保证2/3多数的共识可以达成,系统可以正常工作。
...
@@ -185,7 +186,7 @@ Period蛻困譌カ瑚ヲ∝ッケ蟾イ逕滓蛹コ蝮礼。ョ隶、悟ケカ霑幄。瑚鰍轤ケ驥肴眠騾我クセ梧
...
@@ -185,7 +186,7 @@ Period蛻困譌カ瑚ヲ∝ッケ蟾イ逕滓蛹コ蝮礼。ョ隶、悟ケカ霑幄。瑚鰍轤ケ驥肴眠騾我クセ梧


### (1). Init状态处理逻辑:
### (1). Init状态处理逻辑:
1.
3s周期检查链接状态,超过2/3节点链接正常,则发起Vote,包含本节点认为接下来的时间应该哪一个节点出块、时间范围、起始高度等信
息。
1.
3s周期检查链接状态,超过2/3节点链接正常,则发起Vote,包含本节点认为接下来的时间段应该哪一个节点出块、时间范围、出块起始高
度等信息。
2.
如果收到超时消息,则重新检查链接状态。
2.
如果收到超时消息,则重新检查链接状态。
3.
如果收到投票消息,则保存,到Voting状态统计选票。
3.
如果收到投票消息,则保存,到Voting状态统计选票。
4.
如果收到其他消息,则做丢弃处理。
4.
如果收到其他消息,则做丢弃处理。
...
@@ -194,36 +195,94 @@ Period蛻困譌カ瑚ヲ∝ッケ蟾イ逕滓蛹コ蝮礼。ョ隶、悟ケカ霑幄。瑚鰍轤ケ驥肴眠騾我クセ梧
...
@@ -194,36 +195,94 @@ Period蛻困譌カ瑚ヲ∝ッケ蟾イ逕滓蛹コ蝮礼。ョ隶、悟ケカ霑幄。瑚鰍轤ケ驥肴眠騾我クセ梧
### (2). Voting状态处理逻辑:
### (2). Voting状态处理逻辑:
1.
3s周期检查投票状态,未超过2/3,则切换状态到Init状态。
1.
3s周期检查投票状态,未超过2/3,则切换状态到Init状态。
2.
如果收到超时消息,则认为是超时未达成共识,切换到Init状态,重新开始新一轮投票。
2.
如果收到超时消息,则认为是超时未达成共识,切换到Init状态,重新开始新一轮投票。
3.
如果收到投票消息,则判断是否超过2/3,如果
超过,则达成共识,切换状态到Voted状态,对于出块节点设定出块定时器;对于非出块节点设定周期超时定时器;。
3.
如果收到投票消息,则判断是否有节点票数超过2
/3,如果超过,则达成共识,切换状态到Voted状态,对于出块节点设定出块定时器;对于非出块节点设定周期超时定时器,并同步出块节点生成的区块。
### (3). Voted状态处理逻辑:
### (3). Voted状态处理逻辑:
1.
对于出块节点:
1.
对于出块节点:
1s定时器超时,如果还处在周期内,
一个出块循环中尚未出块则出块,已经出块则空转;如果周期结束,则notify周边节点本周期结
束,包括结束height,time等信息。
1s定时器超时,如果还处在Peri
od周期内,一个出块循环中尚未出块则出块,已经出块则空转等待下一个出块周期的到来;如果Period周期结束,则notify周边节点本周期结束,包括结束he
ight,time等信息。
状态切换到Init状态,开始新一个节点的选举。
状态切换到Init状态,开始新一个节点的选举。
2.
对于非出块节点:
2.
对于非出块节点:
周期定时器超时,则切换状态到WaitNotify状态,等待出块节点发来的notify消息,确定不可逆区块。
周期定时器超时,则切换状态到WaitNotify状态,等待出块节点发来的notify消息,如果高度不同步,需要进行区块同步。
3.
如果收到投票消息,则返回本周期的本地票,以帮助新启动节点的状态切换。如果收到notify通知,则缓存等待切换到WaitNotify状态进行处理。
3.
如果收到出块节点发来的notify消息,直接切换状态到WaitNotify状态,检查区块高度,如果高度不同步,需要进行区块同步。
4.
如果收到投票消息,则返回本周期的本地票,以帮助新启动节点完成投票及状态切换。
### (4). WaitNotify状态处理逻辑:
### (4). WaitNotify状态处理逻辑:
1.
2s周期检查是否收到Notify。
1.
2s周期检查是否收到Notify。
如果超时未收到,则进入Init状态,参与投票。
如果超时未收到,则进入Init状态,参与投票。
如果超时前收到,则记录相关结果,标记不可逆高度,并进入Init状态,参与新一轮投票。
如果超时前收到,则记录相关结果,如果区块高度未同步则进行区块同步,并进入Init状态,参与新一轮投票。
## 3 DPos共识相关配置
当前实现,对于受托节点采用了配置制定的方式,各受托节点的公钥配置在genesis.json文件中,各个受托节点使用相同的genesis.json文件;各受托节点自身的私钥、地址信息保存在各自的priv_validator.json文件中。
这种配置方式借鉴了tendermint的配置方式,后续可以进一步修改为投票选举受托节点的方式,则通过智能合约来对受托节点进行管理。
1.
genesis.json:
```
json
{
"genesis_time"
:
"0001-01-01T00:00:00Z"
,
"chain_id"
:
"test-chain-Ep9EcD"
,
"validators"
:[
{
"pub_key"
:{
"type"
:
"ed25519"
,
"data"
:
"220ACBE680DF2473A0CB48987A00FCC1812F106A7390BE6B8E2D31122C992A19"
},
"name"
:
""
}
],
"app_hash"
:
""
}
```
2.
priv_validator.json
```
json
{
"address"
:
"02A13174B92727C4902DB099E51A3339F48BD45E"
,
"pub_key"
:{
"type"
:
"ed25519"
,
"data"
:
"220ACBE680DF2473A0CB48987A00FCC1812F106A7390BE6B8E2D31122C992A19"
},
"priv_key"
:{
"type"
:
"ed25519"
,
"data"
:
"B3DC4C0725884EBB7264B92F1D8D37584A64ADE1799D997EC64B4FE3973E08DE220ACBE680DF2473A0CB48987A00FCC1812F106A7390BE6B8E2D31122C992A19"
}
}
```
## 3 代码配合时序
### 3.1 Chain33 DPOS 代码时序:
## 4 代码配合时序
### 4.1 Chain33 DPOS 代码时序:


Client会启动EventLoop和StartConsensus两个go routine。
StartConsensus中做如下处理:
1.
做区块同步。
2.
判断本节点是否为受托节点:
如果不是,则不参与出块共识,只是被动同步区块。
如果是,则创建共识模块,启动Node模块,进行共识通信和共识状态机运行。
3.
Node模块做如下处理:
启动listenRoutine,进行共识通信的监听,接受外部连接,并通过收发go routine进行通信。
主动连接其他受托节点。
启动BroadcastRoutine,支持消息广播到其他参与共识的受托节点。
启动共识模块go routine。
4.
共识模块做如下处理:
启动receiveRoutine,对接收到的共识消息进行处理,主要通过消息驱动dposState状态机的运行,在不同的状态中,做不同的事情。
timeoutTicker,作为定时器模块,会启动timeoutRoutine,在状态机中会设定不同的超时定时器到timeoutTicker模块,timeoutRoutine会把超时事件通过channel通知到receiveRoutine模块,最终驱动状态机的处理和状态变化。
dosState作为状态机核心逻辑,受各种消息(投票、投票响应、切换通知等)、事件(各种超时)的驱动,进行状态的维护和跃迁,保证各节点处理的一致。
附录
:
参考附录
:
###
3
.2 Solo共识代码时序:
###
4
.2 Solo共识代码时序:


###
3
.3 Tendermint共识代码时序:
###
4
.3 Tendermint共识代码时序:


...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment