github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/consensus/clique/snapshot_test.go (about) 1 2 //此源码被清华学神尹成大魔王专业翻译分析并修改 3 //尹成QQ77025077 4 //尹成微信18510341407 5 //尹成所在QQ群721929980 6 //尹成邮箱 yinc13@mails.tsinghua.edu.cn 7 //尹成毕业于清华大学,微软区块链领域全球最有价值专家 8 //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620 9 //版权所有2017 Go Ethereum作者 10 //此文件是Go以太坊库的一部分。 11 // 12 //Go-Ethereum库是免费软件:您可以重新分发它和/或修改 13 //根据GNU发布的较低通用公共许可证的条款 14 //自由软件基金会,或者许可证的第3版,或者 15 //(由您选择)任何更高版本。 16 // 17 //Go以太坊图书馆的发行目的是希望它会有用, 18 //但没有任何保证;甚至没有 19 //适销性或特定用途的适用性。见 20 //GNU较低的通用公共许可证,了解更多详细信息。 21 // 22 //你应该收到一份GNU较低级别的公共许可证副本 23 //以及Go以太坊图书馆。如果没有,请参见<http://www.gnu.org/licenses/>。 24 25 package clique 26 27 import ( 28 "bytes" 29 "crypto/ecdsa" 30 "math/big" 31 "testing" 32 33 "github.com/ethereum/go-ethereum/common" 34 "github.com/ethereum/go-ethereum/core" 35 "github.com/ethereum/go-ethereum/core/rawdb" 36 "github.com/ethereum/go-ethereum/core/types" 37 "github.com/ethereum/go-ethereum/crypto" 38 "github.com/ethereum/go-ethereum/ethdb" 39 "github.com/ethereum/go-ethereum/params" 40 ) 41 42 type testerVote struct { 43 signer string 44 voted string 45 auth bool 46 } 47 48 //TestAccountPool是一个用于维护当前活动的测试人员帐户的池, 49 //从下面测试中使用的文本名称映射到实际的以太坊私有 50 //能够签署事务的密钥。 51 type testerAccountPool struct { 52 accounts map[string]*ecdsa.PrivateKey 53 } 54 55 func newTesterAccountPool() *testerAccountPool { 56 return &testerAccountPool{ 57 accounts: make(map[string]*ecdsa.PrivateKey), 58 } 59 } 60 61 func (ap *testerAccountPool) sign(header *types.Header, signer string) { 62 //确保我们有签名者的持久密钥 63 if ap.accounts[signer] == nil { 64 ap.accounts[signer], _ = crypto.GenerateKey() 65 } 66 //在头上签名并将签名嵌入额外的数据中 67 sig, _ := crypto.Sign(sigHash(header).Bytes(), ap.accounts[signer]) 68 copy(header.Extra[len(header.Extra)-65:], sig) 69 } 70 71 func (ap *testerAccountPool) address(account string) common.Address { 72 //确保我们有帐户的持久密钥 73 if ap.accounts[account] == nil { 74 ap.accounts[account], _ = crypto.GenerateKey() 75 } 76 //解析并返回以太坊地址 77 return crypto.PubkeyToAddress(ap.accounts[account].PublicKey) 78 } 79 80 //TestChainReader实现consension.chainReader以访问Genesis 81 //块。所有其他方法和请求都会恐慌。 82 type testerChainReader struct { 83 db ethdb.Database 84 } 85 86 func (r *testerChainReader) Config() *params.ChainConfig { return params.AllCliqueProtocolChanges } 87 func (r *testerChainReader) CurrentHeader() *types.Header { panic("not supported") } 88 func (r *testerChainReader) GetHeader(common.Hash, uint64) *types.Header { panic("not supported") } 89 func (r *testerChainReader) GetBlock(common.Hash, uint64) *types.Block { panic("not supported") } 90 func (r *testerChainReader) GetHeaderByHash(common.Hash) *types.Header { panic("not supported") } 91 func (r *testerChainReader) GetHeaderByNumber(number uint64) *types.Header { 92 if number == 0 { 93 return rawdb.ReadHeader(r.db, rawdb.ReadCanonicalHash(r.db, 0), 0) 94 } 95 return nil 96 } 97 98 //测试在各种简单和复杂的情况下是否正确评估投票。 99 func TestVoting(t *testing.T) { 100 // 101 tests := []struct { 102 epoch uint64 103 signers []string 104 votes []testerVote 105 results []string 106 }{ 107 { 108 //单签名人,无投票权 109 signers: []string{"A"}, 110 votes: []testerVote{{signer: "A"}}, 111 results: []string{"A"}, 112 }, { 113 //单个签名人,投票添加两个其他人(只接受第一个,第二个需要2票) 114 signers: []string{"A"}, 115 votes: []testerVote{ 116 {signer: "A", voted: "B", auth: true}, 117 {signer: "B"}, 118 {signer: "A", voted: "C", auth: true}, 119 }, 120 results: []string{"A", "B"}, 121 }, { 122 //两个签名者,投票加三个(只接受前两个,第三个已经需要3票) 123 signers: []string{"A", "B"}, 124 votes: []testerVote{ 125 {signer: "A", voted: "C", auth: true}, 126 {signer: "B", voted: "C", auth: true}, 127 {signer: "A", voted: "D", auth: true}, 128 {signer: "B", voted: "D", auth: true}, 129 {signer: "C"}, 130 {signer: "A", voted: "E", auth: true}, 131 {signer: "B", voted: "E", auth: true}, 132 }, 133 results: []string{"A", "B", "C", "D"}, 134 }, { 135 //单个签名者,放弃自己(很奇怪,但明确允许这样做的话就少了一个死角) 136 signers: []string{"A"}, 137 votes: []testerVote{ 138 {signer: "A", voted: "A", auth: false}, 139 }, 140 results: []string{}, 141 }, { 142 // 143 signers: []string{"A", "B"}, 144 votes: []testerVote{ 145 {signer: "A", voted: "B", auth: false}, 146 }, 147 results: []string{"A", "B"}, 148 }, { 149 //两个签名者,实际上需要双方同意放弃其中一个(满足) 150 signers: []string{"A", "B"}, 151 votes: []testerVote{ 152 {signer: "A", voted: "B", auth: false}, 153 {signer: "B", voted: "B", auth: false}, 154 }, 155 results: []string{"A"}, 156 }, { 157 //三个签名者,其中两个决定放弃第三个 158 signers: []string{"A", "B", "C"}, 159 votes: []testerVote{ 160 {signer: "A", voted: "C", auth: false}, 161 {signer: "B", voted: "C", auth: false}, 162 }, 163 results: []string{"A", "B"}, 164 }, { 165 //四个签名者,两个的共识不足以让任何人放弃 166 signers: []string{"A", "B", "C", "D"}, 167 votes: []testerVote{ 168 {signer: "A", voted: "C", auth: false}, 169 {signer: "B", voted: "C", auth: false}, 170 }, 171 results: []string{"A", "B", "C", "D"}, 172 }, { 173 //四个签名者,三个人的共识已经足够让某人离开 174 signers: []string{"A", "B", "C", "D"}, 175 votes: []testerVote{ 176 {signer: "A", voted: "D", auth: false}, 177 {signer: "B", voted: "D", auth: false}, 178 {signer: "C", voted: "D", auth: false}, 179 }, 180 results: []string{"A", "B", "C"}, 181 }, { 182 //每个签名者对每个目标的授权计数一次 183 signers: []string{"A", "B"}, 184 votes: []testerVote{ 185 {signer: "A", voted: "C", auth: true}, 186 {signer: "B"}, 187 {signer: "A", voted: "C", auth: true}, 188 {signer: "B"}, 189 {signer: "A", voted: "C", auth: true}, 190 }, 191 results: []string{"A", "B"}, 192 }, { 193 //允许同时授权多个帐户 194 signers: []string{"A", "B"}, 195 votes: []testerVote{ 196 {signer: "A", voted: "C", auth: true}, 197 {signer: "B"}, 198 {signer: "A", voted: "D", auth: true}, 199 {signer: "B"}, 200 {signer: "A"}, 201 {signer: "B", voted: "D", auth: true}, 202 {signer: "A"}, 203 {signer: "B", voted: "C", auth: true}, 204 }, 205 results: []string{"A", "B", "C", "D"}, 206 }, { 207 //每个目标的每个签名者对取消授权计数一次 208 signers: []string{"A", "B"}, 209 votes: []testerVote{ 210 {signer: "A", voted: "B", auth: false}, 211 {signer: "B"}, 212 {signer: "A", voted: "B", auth: false}, 213 {signer: "B"}, 214 {signer: "A", voted: "B", auth: false}, 215 }, 216 results: []string{"A", "B"}, 217 }, { 218 //允许同时解除多个帐户的授权 219 signers: []string{"A", "B", "C", "D"}, 220 votes: []testerVote{ 221 {signer: "A", voted: "C", auth: false}, 222 {signer: "B"}, 223 {signer: "C"}, 224 {signer: "A", voted: "D", auth: false}, 225 {signer: "B"}, 226 {signer: "C"}, 227 {signer: "A"}, 228 {signer: "B", voted: "D", auth: false}, 229 {signer: "C", voted: "D", auth: false}, 230 {signer: "A"}, 231 {signer: "B", voted: "C", auth: false}, 232 }, 233 results: []string{"A", "B"}, 234 }, { 235 //取消授权签名者的投票将立即被丢弃(取消授权投票) 236 signers: []string{"A", "B", "C"}, 237 votes: []testerVote{ 238 {signer: "C", voted: "B", auth: false}, 239 {signer: "A", voted: "C", auth: false}, 240 {signer: "B", voted: "C", auth: false}, 241 {signer: "A", voted: "B", auth: false}, 242 }, 243 results: []string{"A", "B"}, 244 }, { 245 //来自未授权签名者的投票将立即丢弃(授权投票) 246 signers: []string{"A", "B", "C"}, 247 votes: []testerVote{ 248 {signer: "C", voted: "B", auth: false}, 249 {signer: "A", voted: "C", auth: false}, 250 {signer: "B", voted: "C", auth: false}, 251 {signer: "A", voted: "B", auth: false}, 252 }, 253 results: []string{"A", "B"}, 254 }, { 255 //不允许级联更改,只有被投票的帐户才可以更改 256 signers: []string{"A", "B", "C", "D"}, 257 votes: []testerVote{ 258 {signer: "A", voted: "C", auth: false}, 259 {signer: "B"}, 260 {signer: "C"}, 261 {signer: "A", voted: "D", auth: false}, 262 {signer: "B", voted: "C", auth: false}, 263 {signer: "C"}, 264 {signer: "A"}, 265 {signer: "B", voted: "D", auth: false}, 266 {signer: "C", voted: "D", auth: false}, 267 }, 268 results: []string{"A", "B", "C"}, 269 }, { 270 //达成共识的变化超出范围(通过deauth)触摸执行 271 signers: []string{"A", "B", "C", "D"}, 272 votes: []testerVote{ 273 {signer: "A", voted: "C", auth: false}, 274 {signer: "B"}, 275 {signer: "C"}, 276 {signer: "A", voted: "D", auth: false}, 277 {signer: "B", voted: "C", auth: false}, 278 {signer: "C"}, 279 {signer: "A"}, 280 {signer: "B", voted: "D", auth: false}, 281 {signer: "C", voted: "D", auth: false}, 282 {signer: "A"}, 283 {signer: "C", voted: "C", auth: true}, 284 }, 285 results: []string{"A", "B"}, 286 }, { 287 //达成共识的变化(通过deauth)可能会在第一次接触时失去共识。 288 signers: []string{"A", "B", "C", "D"}, 289 votes: []testerVote{ 290 {signer: "A", voted: "C", auth: false}, 291 {signer: "B"}, 292 {signer: "C"}, 293 {signer: "A", voted: "D", auth: false}, 294 {signer: "B", voted: "C", auth: false}, 295 {signer: "C"}, 296 {signer: "A"}, 297 {signer: "B", voted: "D", auth: false}, 298 {signer: "C", voted: "D", auth: false}, 299 {signer: "A"}, 300 {signer: "B", voted: "C", auth: true}, 301 }, 302 results: []string{"A", "B", "C"}, 303 }, { 304 //确保挂起的投票不会在授权状态更改后继续有效。这个 305 //只有快速添加、删除签名者,然后 306 //阅读(或相反),而其中一个最初的选民投了。如果A 307 //过去的投票被保存在系统中的某个位置,这将干扰 308 //最终签名者结果。 309 signers: []string{"A", "B", "C", "D", "E"}, 310 votes: []testerVote{ 311 {signer: "A", voted: "F", auth: true}, //授权F,需要3票 312 {signer: "B", voted: "F", auth: true}, 313 {signer: "C", voted: "F", auth: true}, 314 {signer: "D", voted: "F", auth: false}, //取消F的授权,需要4票(保持A以前的投票“不变”)。 315 {signer: "E", voted: "F", auth: false}, 316 {signer: "B", voted: "F", auth: false}, 317 {signer: "C", voted: "F", auth: false}, 318 {signer: "D", voted: "F", auth: true}, //几乎授权F,需要2/3票 319 {signer: "E", voted: "F", auth: true}, 320 {signer: "B", voted: "A", auth: false}, //取消授权A,需要3票 321 {signer: "C", voted: "A", auth: false}, 322 {signer: "D", voted: "A", auth: false}, 323 {signer: "B", voted: "F", auth: true}, //完成授权F,需要3/3票 324 }, 325 results: []string{"B", "C", "D", "E", "F"}, 326 }, { 327 //epoch转换重置所有投票以允许链检查点 328 epoch: 3, 329 signers: []string{"A", "B"}, 330 votes: []testerVote{ 331 {signer: "A", voted: "C", auth: true}, 332 {signer: "B"}, 333 {signer: "A"}, //检查点块(不要在这里投票,它是在快照之外验证的) 334 {signer: "B", voted: "C", auth: true}, 335 }, 336 results: []string{"A", "B"}, 337 }, 338 } 339 //运行场景并测试它们 340 for i, tt := range tests { 341 //创建帐户池并生成初始签名者集 342 accounts := newTesterAccountPool() 343 344 signers := make([]common.Address, len(tt.signers)) 345 for j, signer := range tt.signers { 346 signers[j] = accounts.address(signer) 347 } 348 for j := 0; j < len(signers); j++ { 349 for k := j + 1; k < len(signers); k++ { 350 if bytes.Compare(signers[j][:], signers[k][:]) > 0 { 351 signers[j], signers[k] = signers[k], signers[j] 352 } 353 } 354 } 355 //使用初始签名者集创建Genesis块 356 genesis := &core.Genesis{ 357 ExtraData: make([]byte, extraVanity+common.AddressLength*len(signers)+extraSeal), 358 } 359 for j, signer := range signers { 360 copy(genesis.ExtraData[extraVanity+j*common.AddressLength:], signer[:]) 361 } 362 //创建一个原始的区块链,注入Genesis 363 db := ethdb.NewMemDatabase() 364 genesis.Commit(db) 365 366 // 367 headers := make([]*types.Header, len(tt.votes)) 368 for j, vote := range tt.votes { 369 headers[j] = &types.Header{ 370 Number: big.NewInt(int64(j) + 1), 371 Time: big.NewInt(int64(j) * 15), 372 Coinbase: accounts.address(vote.voted), 373 Extra: make([]byte, extraVanity+extraSeal), 374 } 375 if j > 0 { 376 headers[j].ParentHash = headers[j-1].Hash() 377 } 378 if vote.auth { 379 copy(headers[j].Nonce[:], nonceAuthVote) 380 } 381 accounts.sign(headers[j], vote.signer) 382 } 383 //把所有的头条都传给小集团,确保理货成功。 384 head := headers[len(headers)-1] 385 386 snap, err := New(¶ms.CliqueConfig{Epoch: tt.epoch}, db).snapshot(&testerChainReader{db: db}, head.Number.Uint64(), head.Hash(), headers) 387 if err != nil { 388 t.Errorf("test %d: failed to create voting snapshot: %v", i, err) 389 continue 390 } 391 //验证签名者的最终列表与预期列表 392 signers = make([]common.Address, len(tt.results)) 393 for j, signer := range tt.results { 394 signers[j] = accounts.address(signer) 395 } 396 for j := 0; j < len(signers); j++ { 397 for k := j + 1; k < len(signers); k++ { 398 if bytes.Compare(signers[j][:], signers[k][:]) > 0 { 399 signers[j], signers[k] = signers[k], signers[j] 400 } 401 } 402 } 403 result := snap.signers() 404 if len(result) != len(signers) { 405 t.Errorf("test %d: signers mismatch: have %x, want %x", i, result, signers) 406 continue 407 } 408 for j := 0; j < len(result); j++ { 409 if !bytes.Equal(result[j][:], signers[j][:]) { 410 t.Errorf("test %d, signer %d: signer mismatch: have %x, want %x", i, j, result[j], signers[j]) 411 } 412 } 413 } 414 }