OSDN Git Service

Merge pull request #41 from Bytom/dev
[bytom/vapor.git] / docs / vapor-docs / 0.1 / core / consensus.md
1 # dpos共识
2
3 ​     在共识协议上,vapor采用了委托权益证明(DPOS)的机制。DPoS 是基于 POW 及 POS 的基础上,出现的一种新型的保障数字货币网络安全的共识算法。它既能解决 POW 在挖矿过程中产生的大量能源过耗的问题,也能避免 POS 权益分配下可能产生的“信任天平”偏颇的问题。
4
5 ## DPoS 共识机制
6
7 ​     其原理是让每一个持币者进行投票,选出一定数量的持币者代表,或理解为一定数量的代表节点,并由这些代表节点来完成交易验证和区块生产的工作。持币者可以随时通过投票更换这些代表,以维系链上系统的“长久纯洁性”,保证该协议有充分的去中心化程度。
8
9 ​     在目前区块链的实现中DPoS共识只用于账户模型, UTXO模型与DPos的结合也会有许多额外的优势,UTXO 模型是存放记录的一种方式,用于交易存储、组织及验证;DPoS 是一种共识算法,用于保证在分布式网络中参与者也可以对交易数据取得一致认识。
10
11 ## 时间戳
12
13 ​     UTXO 和 DPoS 结合的一大难点在于时间戳,DPoS 共识基于时间,会严格检查区块时间。全节点系统时间必须设置为和标准时间一样,否则共识一致性会出现问题。而 UTXO 本身也记录了时间戳的功能,但时间戳并不基于标准时间。在 LBTC 里将时间戳统一成标准时间协议,以保证区块的正常运行。当存在作恶节点或者时间不同步的区块时,出块被作为异常块处理,出块节点被作为异常节点处理
14
15 ## 数据快照
16
17 ​     在 UTXO 模型中,并不支持查询地址余额的功能,是通过全局遍历 UTXO 数据,实时计算地址余额。实时计算的工作量相当巨大,现实中不具备可行性。为了 DPoS 算法的需要,vapor中新增地址余额计算、节点注册、节点投票新功能。考虑到共识算法的高性能要求、注册节点数目的有限性,把地址余额、节点注册及投票信息保存在内存中,并把数据回写到db。通过数据库和地址余额、投票信息来链接 UTXO 记账信息和 DPoS 共识机制:
18
19 - 注册、投票的信息由vapor底层协议负责传输。
20 - 把注册、投票信息保存在内存以及db中。
21 - DPoS 共识模块查看注册、投票信息,完成共识。
22
23
24
25 ## 业务流程
26
27 1、vapor侧链启动,由创始块中超级出块人出块
28
29 2、用户从主链转移资产到侧链,并注册为候选出块人
30
31 3、用户投票给候选出块人,赛选出块人
32
33 ## dpos逻辑
34
35 1、交易格式
36
37 ​     dpos_type: 1代表注册为候选出块人,2代表投票,3代表取消投票
38
39 ​        type: dpos表示跟共识有关系的交易
40
41 ​     amount: 表示注册交易的交易费,目前是1btm
42
43 ~~~json
44         注册交易
45         ```
46         {
47         "base_transaction":null,
48         "actions":[
49             {
50                 "address":"vsm1qndq3w79kwtk9acnuswxlwxjqweglwhg8yrzp2c",
51                 "amount":100000000,
52                 "asset_id":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
53                 "name":"test-node1",
54                 "dpos_type":1,
55                 "type":"dpos"
56             }
57         ],
58         "ttl":0,
59         "time_range":43432
60         }
61        ```
62         投票交易
63            ```
64         {
65             "base_transaction":null,
66             "actions":[
67                 {
68                     "address":"vsm1qkm743xmgnvh84pmjchq2s4tnfpgu9ae2f9slep",
69                     "amount":100000000,
70                     "asset_id":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
71                     "forgers":[
72                         "vsm1qndq3w79kwtk9acnuswxlwxjqweglwhg8yrzp2c",
73                         "vsm1q93jcjhwe62n5mdtym6m7utle95erd6s3jsn4tn",
74                         "vsm1qtu926tcsky876hflm93getsv27w7pccv4jg2fs",
75                         "vsm1qyd4rcrdnwexgg2gwk33frrrqymzyrycggjslu2",
76                         "vsm1qacp9zg2h4950lr5yhlychn6686fhullkuyzd5s",
77                         "vsm1qlf8s9tv90x9ys25fl2kczy44jjnnaa8e542nea"
78                     ],
79                     "dpos_type":2,
80                     "type":"dpos"
81                 }
82             ],
83             "ttl":0,
84             "time_range":43432
85         }
86                 ```
87         取消投票
88         ```
89         {
90             "base_transaction":null,
91             "actions":[
92                 {
93                     "address":"vsm1qkm743xmgnvh84pmjchq2s4tnfpgu9ae2f9slep",
94                     "amount":100000000,
95                     "asset_id":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
96                     "forgers":[
97                         "vsm1qndq3w79kwtk9acnuswxlwxjqweglwhg8yrzp2c",
98                         "vsm1q93jcjhwe62n5mdtym6m7utle95erd6s3jsn4tn",
99                         "vsm1qtu926tcsky876hflm93getsv27w7pccv4jg2fs"
100                     ],
101                     "dpos_type":3,
102                     "type":"dpos"
103                 }
104             ],
105             "ttl":0,
106             "time_range":43432
107         }
108         ```
109 ~~~
110
111 2、逻辑说明
112
113 ​     (1)、检查交易费在用户地址是否够用,序列化的注册\投票\取消投票、注册类型(用op表示)序列化后放入tx的referenceData
114
115 ​     (2)、判断当前节点是否出块人,否不出块,是获取到出块人列表,并在coinbase交易的referenceData存出块人列表信息
116
117 ​             注:出块人列表只有本轮第一个块获取到,其他的块根据这个块做验证。
118
119 ​     (3)、在内核chain做saveBlock之前做dpos验证
120
121 - 验证块的时间-当前时间的>出块时间间隔
122 - 通过上一个块与当前出的块的时间获取出块轮数以及当前轮的出块索引,判断当前出块的顺序是否正确
123
124 ​     (4)、验证不可逆的区块时候有效(针对同步)
125
126 ​     (5)、验证block中的候选人列表时候正确,并且生成不可逆区块
127
128 - 如果当前block与上一个不是同一个出块的轮,验证出块人列表,并确认不可逆的区块
129 - 如果在同一个出块轮,验证出块顺序以及出块人列表。
130 - 验证当前的出块人是否正确
131
132 ​     (6)、验证交易完成后,先计算用户的余额,在处理与dpos相关的交易(注册、投票、取消投票)
133
134 ### 计算余额
135
136 统计交易的输入输出计算每个地址的余额
137
138 ### 注册逻辑
139
140 1、判断注册交易的交易费是否大于RegisrerForgerFee
141
142 2、判断注册的名字是否已经注册,存在则注册失败
143
144 3、判断注册的地址是否已经注册,存在则注册失败
145
146 4、否则,添加到name、address的注册列表
147
148 ### 投票逻辑
149
150 1、判断投票人的投票的出块人是否大于MaxNumberOfVotes
151
152 2、判断被投票人地址是否已经注册
153
154 3、判断被投票人是否被投票人投过
155
156 4、判断通过写入到投票人、被投票人的投票列表
157
158 ### 取消投票逻辑
159
160 1、判断被投票人是否已经投票,投过就从被投票人列表中删除
161
162 2、从投票人列表删除被投票人信息
163
164
165
166 ### dpos相关数据结构
167
168 1、交易结构ReferenceData的数据
169
170 | 字段 | 类型   | 描述                   |
171 | :--- | ------ | ---------------------- |
172 | Type | vm.Op  | dpos相关的数据类型     |
173 | Data | []byte | dpos相关的数据的序列化 |
174
175 Type字段的值如下:   
176
177 ​    OP_DELEGATE Op = 0xd0
178
179 ​    OP_REGISTE  Op = 0xd1
180
181 ​    OP_VOTE     Op = 0xd2
182
183 ​    OP_REVOKE   Op = 0xd3
184
185 2、coinbase交易中的出块人列表
186
187 // DELEGATE_IDS PUBKEY SIG(block.time)
188
189 | 字段            | 类型               | 描述                     |
190 | --------------- | ------------------ | ------------------------ |
191 | Delegate        | DelegateInfo       | 出块人信息列表           |
192 | Xpub            | chainkd.XPub       | 当前出块人的公钥         |
193 | SigTime         | chainjson.HexBytes | 当前出块人的对时间的签名 |
194
195
196
197 | 字段            | 类型               | 描述       |
198 | --------------- | ------------------ | ---------- |
199 | Delegates       | []Delegate         | 出块人类表 |
200
201
202
203 | 字段            | 类型               | 描述       |
204 | --------------- | ------------------ | ---------- |
205 | DelegateAddress | string             | 出块人地址 |
206 | Votes           | uint64             | 出块人票数 |
207
208
209
210 3、注册出块人的信息
211
212 | 字段 | 类型   | 描述                 |
213 | ---- | ------ | -------------------- |
214 | Name | string | 注册候选出块人的名称 |
215
216 4、投票的信息
217
218 | 字段    | 类型     | 描述               |
219 | ------- | -------- | ------------------ |
220 | Forgers | []string | 投票给候选人的列表 |
221
222 5、取消投票的信息
223
224 | 字段    | 类型     | 描述                 |
225 | ------- | -------- | -------------------- |
226 | Forgers | []string | 取消投票候选人的列表 |
227