github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/consensus/clique/snapshot_test.go (about)

     1  
     2  //<developer>
     3  //    <name>linapex 曹一峰</name>
     4  //    <email>linapex@163.com</email>
     5  //    <wx>superexc</wx>
     6  //    <qqgroup>128148617</qqgroup>
     7  //    <url>https://jsq.ink</url>
     8  //    <role>pku engineer</role>
     9  //    <date>2019-03-16 19:16:34</date>
    10  //</624450074604212224>
    11  
    12  
    13  package clique
    14  
    15  import (
    16  	"bytes"
    17  	"crypto/ecdsa"
    18  	"sort"
    19  	"testing"
    20  
    21  	"github.com/ethereum/go-ethereum/common"
    22  	"github.com/ethereum/go-ethereum/core"
    23  	"github.com/ethereum/go-ethereum/core/types"
    24  	"github.com/ethereum/go-ethereum/core/vm"
    25  	"github.com/ethereum/go-ethereum/crypto"
    26  	"github.com/ethereum/go-ethereum/ethdb"
    27  	"github.com/ethereum/go-ethereum/params"
    28  )
    29  
    30  //TestAccountPool是一个用于维护当前活动的测试人员帐户的池,
    31  //从下面测试中使用的文本名称映射到实际的以太坊私有
    32  //能够签署事务的密钥。
    33  type testerAccountPool struct {
    34  	accounts map[string]*ecdsa.PrivateKey
    35  }
    36  
    37  func newTesterAccountPool() *testerAccountPool {
    38  	return &testerAccountPool{
    39  		accounts: make(map[string]*ecdsa.PrivateKey),
    40  	}
    41  }
    42  
    43  //
    44  //
    45  func (ap *testerAccountPool) checkpoint(header *types.Header, signers []string) {
    46  	auths := make([]common.Address, len(signers))
    47  	for i, signer := range signers {
    48  		auths[i] = ap.address(signer)
    49  	}
    50  	sort.Sort(signersAscending(auths))
    51  	for i, auth := range auths {
    52  		copy(header.Extra[extraVanity+i*common.AddressLength:], auth.Bytes())
    53  	}
    54  }
    55  
    56  //地址通过标签检索测试人员帐户的以太坊地址,创建
    57  //如果以前的帐户还不存在,则为新帐户。
    58  func (ap *testerAccountPool) address(account string) common.Address {
    59  //返回非地址的零帐户
    60  	if account == "" {
    61  		return common.Address{}
    62  	}
    63  //确保我们有帐户的持久密钥
    64  	if ap.accounts[account] == nil {
    65  		ap.accounts[account], _ = crypto.GenerateKey()
    66  	}
    67  //解析并返回以太坊地址
    68  	return crypto.PubkeyToAddress(ap.accounts[account].PublicKey)
    69  }
    70  
    71  //符号为给定的块计算一组数字签名并将其嵌入
    72  //回到标题。
    73  func (ap *testerAccountPool) sign(header *types.Header, signer string) {
    74  //确保我们有签名者的持久密钥
    75  	if ap.accounts[signer] == nil {
    76  		ap.accounts[signer], _ = crypto.GenerateKey()
    77  	}
    78  //在头上签名并将签名嵌入额外的数据中
    79  	sig, _ := crypto.Sign(sigHash(header).Bytes(), ap.accounts[signer])
    80  	copy(header.Extra[len(header.Extra)-extraSeal:], sig)
    81  }
    82  
    83  //testervote表示一个由parcitular帐户签名的单个块,其中
    84  //该账户可能会或可能不会投集团票。
    85  type testerVote struct {
    86  	signer     string
    87  	voted      string
    88  	auth       bool
    89  	checkpoint []string
    90  	newbatch   bool
    91  }
    92  
    93  //测试团体签名者投票是否正确地评估各种简单和
    94  //复杂的场景,以及一些特殊的角落案例会正确失败。
    95  func TestClique(t *testing.T) {
    96  //定义要测试的各种投票方案
    97  	tests := []struct {
    98  		epoch   uint64
    99  		signers []string
   100  		votes   []testerVote
   101  		results []string
   102  		failure error
   103  	}{
   104  		{
   105  //单签名人,无投票权
   106  			signers: []string{"A"},
   107  			votes:   []testerVote{{signer: "A"}},
   108  			results: []string{"A"},
   109  		}, {
   110  //单个签名人,投票添加两个其他人(只接受第一个,第二个需要2票)
   111  			signers: []string{"A"},
   112  			votes: []testerVote{
   113  				{signer: "A", voted: "B", auth: true},
   114  				{signer: "B"},
   115  				{signer: "A", voted: "C", auth: true},
   116  			},
   117  			results: []string{"A", "B"},
   118  		}, {
   119  //两个签名者,投票加三个(只接受前两个,第三个已经需要3票)
   120  			signers: []string{"A", "B"},
   121  			votes: []testerVote{
   122  				{signer: "A", voted: "C", auth: true},
   123  				{signer: "B", voted: "C", auth: true},
   124  				{signer: "A", voted: "D", auth: true},
   125  				{signer: "B", voted: "D", auth: true},
   126  				{signer: "C"},
   127  				{signer: "A", voted: "E", auth: true},
   128  				{signer: "B", voted: "E", auth: true},
   129  			},
   130  			results: []string{"A", "B", "C", "D"},
   131  		}, {
   132  //单个签名者,放弃自己(很奇怪,但明确允许这样做的话就少了一个死角)
   133  			signers: []string{"A"},
   134  			votes: []testerVote{
   135  				{signer: "A", voted: "A", auth: false},
   136  			},
   137  			results: []string{},
   138  		}, {
   139  //两个签名者,实际上需要双方同意放弃其中一个(未履行)
   140  			signers: []string{"A", "B"},
   141  			votes: []testerVote{
   142  				{signer: "A", voted: "B", auth: false},
   143  			},
   144  			results: []string{"A", "B"},
   145  		}, {
   146  //两个签名者,实际上需要双方同意放弃其中一个(满足)
   147  			signers: []string{"A", "B"},
   148  			votes: []testerVote{
   149  				{signer: "A", voted: "B", auth: false},
   150  				{signer: "B", voted: "B", auth: false},
   151  			},
   152  			results: []string{"A"},
   153  		}, {
   154  //三个签名者,其中两个决定放弃第三个
   155  			signers: []string{"A", "B", "C"},
   156  			votes: []testerVote{
   157  				{signer: "A", voted: "C", auth: false},
   158  				{signer: "B", voted: "C", auth: false},
   159  			},
   160  			results: []string{"A", "B"},
   161  		}, {
   162  //四个签名者,两个的共识不足以让任何人放弃
   163  			signers: []string{"A", "B", "C", "D"},
   164  			votes: []testerVote{
   165  				{signer: "A", voted: "C", auth: false},
   166  				{signer: "B", voted: "C", auth: false},
   167  			},
   168  			results: []string{"A", "B", "C", "D"},
   169  		}, {
   170  //四个签名者,三个人的共识已经足够让某人离开
   171  			signers: []string{"A", "B", "C", "D"},
   172  			votes: []testerVote{
   173  				{signer: "A", voted: "D", auth: false},
   174  				{signer: "B", voted: "D", auth: false},
   175  				{signer: "C", voted: "D", auth: false},
   176  			},
   177  			results: []string{"A", "B", "C"},
   178  		}, {
   179  //每个签名者对每个目标的授权计数一次
   180  			signers: []string{"A", "B"},
   181  			votes: []testerVote{
   182  				{signer: "A", voted: "C", auth: true},
   183  				{signer: "B"},
   184  				{signer: "A", voted: "C", auth: true},
   185  				{signer: "B"},
   186  				{signer: "A", voted: "C", auth: true},
   187  			},
   188  			results: []string{"A", "B"},
   189  		}, {
   190  //允许同时授权多个帐户
   191  			signers: []string{"A", "B"},
   192  			votes: []testerVote{
   193  				{signer: "A", voted: "C", auth: true},
   194  				{signer: "B"},
   195  				{signer: "A", voted: "D", auth: true},
   196  				{signer: "B"},
   197  				{signer: "A"},
   198  				{signer: "B", voted: "D", auth: true},
   199  				{signer: "A"},
   200  				{signer: "B", voted: "C", auth: true},
   201  			},
   202  			results: []string{"A", "B", "C", "D"},
   203  		}, {
   204  //每个目标的每个签名者对取消授权计数一次
   205  			signers: []string{"A", "B"},
   206  			votes: []testerVote{
   207  				{signer: "A", voted: "B", auth: false},
   208  				{signer: "B"},
   209  				{signer: "A", voted: "B", auth: false},
   210  				{signer: "B"},
   211  				{signer: "A", voted: "B", auth: false},
   212  			},
   213  			results: []string{"A", "B"},
   214  		}, {
   215  //允许同时解除多个帐户的授权
   216  			signers: []string{"A", "B", "C", "D"},
   217  			votes: []testerVote{
   218  				{signer: "A", voted: "C", auth: false},
   219  				{signer: "B"},
   220  				{signer: "C"},
   221  				{signer: "A", voted: "D", auth: false},
   222  				{signer: "B"},
   223  				{signer: "C"},
   224  				{signer: "A"},
   225  				{signer: "B", voted: "D", auth: false},
   226  				{signer: "C", voted: "D", auth: false},
   227  				{signer: "A"},
   228  				{signer: "B", voted: "C", auth: false},
   229  			},
   230  			results: []string{"A", "B"},
   231  		}, {
   232  //取消授权签名者的投票将立即被丢弃(取消授权投票)
   233  			signers: []string{"A", "B", "C"},
   234  			votes: []testerVote{
   235  				{signer: "C", voted: "B", auth: false},
   236  				{signer: "A", voted: "C", auth: false},
   237  				{signer: "B", voted: "C", auth: false},
   238  				{signer: "A", voted: "B", auth: false},
   239  			},
   240  			results: []string{"A", "B"},
   241  		}, {
   242  //来自未授权签名者的投票将立即丢弃(授权投票)
   243  			signers: []string{"A", "B", "C"},
   244  			votes: []testerVote{
   245  				{signer: "C", voted: "B", auth: false},
   246  				{signer: "A", voted: "C", auth: false},
   247  				{signer: "B", voted: "C", auth: false},
   248  				{signer: "A", voted: "B", auth: false},
   249  			},
   250  			results: []string{"A", "B"},
   251  		}, {
   252  //不允许级联更改,只有被投票的帐户才可以更改
   253  			signers: []string{"A", "B", "C", "D"},
   254  			votes: []testerVote{
   255  				{signer: "A", voted: "C", auth: false},
   256  				{signer: "B"},
   257  				{signer: "C"},
   258  				{signer: "A", voted: "D", auth: false},
   259  				{signer: "B", voted: "C", auth: false},
   260  				{signer: "C"},
   261  				{signer: "A"},
   262  				{signer: "B", voted: "D", auth: false},
   263  				{signer: "C", voted: "D", auth: false},
   264  			},
   265  			results: []string{"A", "B", "C"},
   266  		}, {
   267  //达成共识的变化超出范围(通过deauth)触摸执行
   268  			signers: []string{"A", "B", "C", "D"},
   269  			votes: []testerVote{
   270  				{signer: "A", voted: "C", auth: false},
   271  				{signer: "B"},
   272  				{signer: "C"},
   273  				{signer: "A", voted: "D", auth: false},
   274  				{signer: "B", voted: "C", auth: false},
   275  				{signer: "C"},
   276  				{signer: "A"},
   277  				{signer: "B", voted: "D", auth: false},
   278  				{signer: "C", voted: "D", auth: false},
   279  				{signer: "A"},
   280  				{signer: "C", voted: "C", auth: true},
   281  			},
   282  			results: []string{"A", "B"},
   283  		}, {
   284  //达成共识的变化(通过deauth)可能会在第一次接触时失去共识。
   285  			signers: []string{"A", "B", "C", "D"},
   286  			votes: []testerVote{
   287  				{signer: "A", voted: "C", auth: false},
   288  				{signer: "B"},
   289  				{signer: "C"},
   290  				{signer: "A", voted: "D", auth: false},
   291  				{signer: "B", voted: "C", auth: false},
   292  				{signer: "C"},
   293  				{signer: "A"},
   294  				{signer: "B", voted: "D", auth: false},
   295  				{signer: "C", voted: "D", auth: false},
   296  				{signer: "A"},
   297  				{signer: "B", voted: "C", auth: true},
   298  			},
   299  			results: []string{"A", "B", "C"},
   300  		}, {
   301  //确保挂起的投票不会在授权状态更改后继续有效。这个
   302  //只有快速添加、删除签名者,然后
   303  //阅读(或相反),而其中一个最初的选民投了。如果A
   304  //过去的投票被保存在系统中的某个位置,这将干扰
   305  //最终签名者结果。
   306  			signers: []string{"A", "B", "C", "D", "E"},
   307  			votes: []testerVote{
   308  {signer: "A", voted: "F", auth: true}, //授权F,需要3票
   309  				{signer: "B", voted: "F", auth: true},
   310  				{signer: "C", voted: "F", auth: true},
   311  {signer: "D", voted: "F", auth: false}, //取消F的授权,需要4票(保持A以前的投票“不变”)。
   312  				{signer: "E", voted: "F", auth: false},
   313  				{signer: "B", voted: "F", auth: false},
   314  				{signer: "C", voted: "F", auth: false},
   315  {signer: "D", voted: "F", auth: true}, //几乎授权F,需要2/3票
   316  				{signer: "E", voted: "F", auth: true},
   317  {signer: "B", voted: "A", auth: false}, //取消授权A,需要3票
   318  				{signer: "C", voted: "A", auth: false},
   319  				{signer: "D", voted: "A", auth: false},
   320  {signer: "B", voted: "F", auth: true}, //完成授权F,需要3/3票
   321  			},
   322  			results: []string{"B", "C", "D", "E", "F"},
   323  		}, {
   324  //epoch转换重置所有投票以允许链检查点
   325  			epoch:   3,
   326  			signers: []string{"A", "B"},
   327  			votes: []testerVote{
   328  				{signer: "A", voted: "C", auth: true},
   329  				{signer: "B"},
   330  				{signer: "A", checkpoint: []string{"A", "B"}},
   331  				{signer: "B", voted: "C", auth: true},
   332  			},
   333  			results: []string{"A", "B"},
   334  		}, {
   335  //
   336  			signers: []string{"A"},
   337  			votes: []testerVote{
   338  				{signer: "B"},
   339  			},
   340  			failure: errUnauthorizedSigner,
   341  		}, {
   342  //签署了recenty的授权签署者不应再次签署
   343  			signers: []string{"A", "B"},
   344  			votes: []testerVote{
   345  				{signer: "A"},
   346  				{signer: "A"},
   347  			},
   348  			failure: errRecentlySigned,
   349  		}, {
   350  //
   351  			epoch:   3,
   352  			signers: []string{"A", "B", "C"},
   353  			votes: []testerVote{
   354  				{signer: "A"},
   355  				{signer: "B"},
   356  				{signer: "A", checkpoint: []string{"A", "B", "C"}},
   357  				{signer: "A"},
   358  			},
   359  			failure: errRecentlySigned,
   360  		}, {
   361  //最近的签名不应在新的
   362  //批处理(https://github.com/ethereum/go-ethereum/issues/17593)。虽然这
   363  //似乎过于具体和奇怪,这是一个由双方意见分歧。
   364  			epoch:   3,
   365  			signers: []string{"A", "B", "C"},
   366  			votes: []testerVote{
   367  				{signer: "A"},
   368  				{signer: "B"},
   369  				{signer: "A", checkpoint: []string{"A", "B", "C"}},
   370  				{signer: "A", newbatch: true},
   371  			},
   372  			failure: errRecentlySigned,
   373  		},
   374  	}
   375  //运行场景并测试它们
   376  	for i, tt := range tests {
   377  //创建帐户池并生成初始签名者集
   378  		accounts := newTesterAccountPool()
   379  
   380  		signers := make([]common.Address, len(tt.signers))
   381  		for j, signer := range tt.signers {
   382  			signers[j] = accounts.address(signer)
   383  		}
   384  		for j := 0; j < len(signers); j++ {
   385  			for k := j + 1; k < len(signers); k++ {
   386  				if bytes.Compare(signers[j][:], signers[k][:]) > 0 {
   387  					signers[j], signers[k] = signers[k], signers[j]
   388  				}
   389  			}
   390  		}
   391  //使用初始签名者集创建Genesis块
   392  		genesis := &core.Genesis{
   393  			ExtraData: make([]byte, extraVanity+common.AddressLength*len(signers)+extraSeal),
   394  		}
   395  		for j, signer := range signers {
   396  			copy(genesis.ExtraData[extraVanity+j*common.AddressLength:], signer[:])
   397  		}
   398  //创建一个原始的区块链,注入Genesis
   399  		db := ethdb.NewMemDatabase()
   400  		genesis.Commit(db)
   401  
   402  //
   403  		config := *params.TestChainConfig
   404  		config.Clique = &params.CliqueConfig{
   405  			Period: 1,
   406  			Epoch:  tt.epoch,
   407  		}
   408  		engine := New(config.Clique, db)
   409  		engine.fakeDiff = true
   410  
   411  		blocks, _ := core.GenerateChain(&config, genesis.ToBlock(db), engine, db, len(tt.votes), func(j int, gen *core.BlockGen) {
   412  //
   413  			gen.SetCoinbase(accounts.address(tt.votes[j].voted))
   414  			if tt.votes[j].auth {
   415  				var nonce types.BlockNonce
   416  				copy(nonce[:], nonceAuthVote)
   417  				gen.SetNonce(nonce)
   418  			}
   419  		})
   420  //遍历块并分别密封它们
   421  		for j, block := range blocks {
   422  //获取标题并准备签名
   423  			header := block.Header()
   424  			if j > 0 {
   425  				header.ParentHash = blocks[j-1].Hash()
   426  			}
   427  			header.Extra = make([]byte, extraVanity+extraSeal)
   428  			if auths := tt.votes[j].checkpoint; auths != nil {
   429  				header.Extra = make([]byte, extraVanity+len(auths)*common.AddressLength+extraSeal)
   430  				accounts.checkpoint(header, auths)
   431  			}
   432  header.Difficulty = diffInTurn //忽略,我们只需要一个有效的数字
   433  
   434  //生成签名,将其嵌入头和块中
   435  			accounts.sign(header, tt.votes[j].signer)
   436  			blocks[j] = block.WithSeal(header)
   437  		}
   438  //将块拆分为单独的导入批次(Cornercase测试)
   439  		batches := [][]*types.Block{nil}
   440  		for j, block := range blocks {
   441  			if tt.votes[j].newbatch {
   442  				batches = append(batches, nil)
   443  			}
   444  			batches[len(batches)-1] = append(batches[len(batches)-1], block)
   445  		}
   446  //把所有的头条都传给小集团,确保理货成功。
   447  		chain, err := core.NewBlockChain(db, nil, &config, engine, vm.Config{}, nil)
   448  		if err != nil {
   449  			t.Errorf("test %d: failed to create test chain: %v", i, err)
   450  			continue
   451  		}
   452  		failed := false
   453  		for j := 0; j < len(batches)-1; j++ {
   454  			if k, err := chain.InsertChain(batches[j]); err != nil {
   455  				t.Errorf("test %d: failed to import batch %d, block %d: %v", i, j, k, err)
   456  				failed = true
   457  				break
   458  			}
   459  		}
   460  		if failed {
   461  			continue
   462  		}
   463  		if _, err = chain.InsertChain(batches[len(batches)-1]); err != tt.failure {
   464  			t.Errorf("test %d: failure mismatch: have %v, want %v", i, err, tt.failure)
   465  		}
   466  		if tt.failure != nil {
   467  			continue
   468  		}
   469  //未生成或请求失败,生成最终投票快照
   470  		head := blocks[len(blocks)-1]
   471  
   472  		snap, err := engine.snapshot(chain, head.NumberU64(), head.Hash(), nil)
   473  		if err != nil {
   474  			t.Errorf("test %d: failed to retrieve voting snapshot: %v", i, err)
   475  			continue
   476  		}
   477  //验证签名者的最终列表与预期列表
   478  		signers = make([]common.Address, len(tt.results))
   479  		for j, signer := range tt.results {
   480  			signers[j] = accounts.address(signer)
   481  		}
   482  		for j := 0; j < len(signers); j++ {
   483  			for k := j + 1; k < len(signers); k++ {
   484  				if bytes.Compare(signers[j][:], signers[k][:]) > 0 {
   485  					signers[j], signers[k] = signers[k], signers[j]
   486  				}
   487  			}
   488  		}
   489  		result := snap.signers()
   490  		if len(result) != len(signers) {
   491  			t.Errorf("test %d: signers mismatch: have %x, want %x", i, result, signers)
   492  			continue
   493  		}
   494  		for j := 0; j < len(result); j++ {
   495  			if !bytes.Equal(result[j][:], signers[j][:]) {
   496  				t.Errorf("test %d, signer %d: signer mismatch: have %x, want %x", i, j, result[j], signers[j])
   497  			}
   498  		}
   499  	}
   500  }
   501