github.com/bcskill/bcschain/v3@v3.4.9-beta2/consensus/clique/clique_test.go (about)

     1  package clique
     2  
     3  import (
     4  	"bytes"
     5  	"sort"
     6  	"testing"
     7  
     8  	"github.com/bcskill/bcschain/v3/common"
     9  )
    10  
    11  func TestExtraData(t *testing.T) {
    12  	for _, test := range []extraDataTest{
    13  		{
    14  			name:          "normal-voter-vote",
    15  			data:          []byte("vanity string!\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01#Eg\x89\xff"),
    16  			vanity:        "vanity string!",
    17  			candidate:     common.HexToAddress("0x123456789"),
    18  			voterElection: true,
    19  		},
    20  		{
    21  			name:          "normal-signer-vote",
    22  			data:          []byte("test\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01#Eg\x89\x00"),
    23  			vanity:        "test",
    24  			candidate:     common.HexToAddress("0x123456789"),
    25  			voterElection: false,
    26  		},
    27  		{
    28  			name:   "spaces-no-vote",
    29  			data:   []byte("  spaces   \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"),
    30  			vanity: "  spaces   ",
    31  		},
    32  	} {
    33  		t.Run(test.name, test.run)
    34  	}
    35  }
    36  
    37  type extraDataTest struct {
    38  	name          string
    39  	data          []byte
    40  	vanity        string
    41  	candidate     common.Address
    42  	voterElection bool
    43  }
    44  
    45  func (test *extraDataTest) run(t *testing.T) {
    46  	if vanity := string(bytes.TrimRight(ExtraVanity(test.data), "\x00")); vanity != test.vanity {
    47  		t.Errorf("expected vanity %q but got %q", test.vanity, vanity)
    48  	}
    49  	if ExtraHasVote(test.data) {
    50  		if test.candidate == (common.Address{}) {
    51  			t.Errorf("unexpected vote: %s voter election: %t", ExtraCandidate(test.data), ExtraIsVoterElection(test.data))
    52  		} else {
    53  			candidate, isVoter := ExtraCandidate(test.data), ExtraIsVoterElection(test.data)
    54  			if candidate != test.candidate {
    55  				t.Errorf("expected candidate %s but got %s", test.candidate.Hex(), candidate.Hex())
    56  			}
    57  			if isVoter != test.voterElection {
    58  				t.Errorf("expected voterElections %t but got %t", test.voterElection, isVoter)
    59  			}
    60  		}
    61  	} else {
    62  		if test.candidate != (common.Address{}) {
    63  			t.Errorf("expected vote but got none: %s voter election: %t", test.candidate.Hex(), test.voterElection)
    64  		}
    65  	}
    66  
    67  	var extra []byte
    68  	extra = append(extra, test.vanity...)
    69  	extra = ExtraEnsureVanity(extra)
    70  	if test.candidate != (common.Address{}) {
    71  		extra = ExtraAppendVote(extra, test.candidate, test.voterElection)
    72  	}
    73  	if !bytes.Equal(test.data, extra) {
    74  		t.Errorf("expected:\n\t%q\ngot:\n\t%q", test.data, extra)
    75  	}
    76  }
    77  
    78  func TestCalcDifficulty(t *testing.T) {
    79  	addrs := []common.Address{
    80  		common.StringToAddress("0abcdefghijklmnopqrs"),
    81  		common.StringToAddress("1abcdefghijklmnopqrs"),
    82  		common.StringToAddress("2abcdefghijklmnopqrs"),
    83  		common.StringToAddress("3abcdefghijklmnopqrs"),
    84  		common.StringToAddress("4abcdefghijklmnopqrs"),
    85  		common.StringToAddress("5abcdefghijklmnopqrs"),
    86  	}
    87  	for _, test := range []testCalcDifficulty{
    88  		// Genesis.
    89  		{
    90  			name: "3/genesis",
    91  			lastSigned: map[common.Address]uint64{
    92  				addrs[0]: 0,
    93  				addrs[1]: 0,
    94  				addrs[2]: 0,
    95  			},
    96  		},
    97  		{
    98  			name: "6/genesis",
    99  			lastSigned: map[common.Address]uint64{
   100  				addrs[0]: 0,
   101  				addrs[1]: 0,
   102  				addrs[2]: 0,
   103  				addrs[3]: 0,
   104  				addrs[4]: 0,
   105  				addrs[5]: 0,
   106  			},
   107  		},
   108  
   109  		// All signed.
   110  		{
   111  			name: "3/all-signed/in-turn",
   112  			lastSigned: map[common.Address]uint64{
   113  				addrs[0]: 1,
   114  				addrs[1]: 2,
   115  				addrs[2]: 3,
   116  			},
   117  		},
   118  		{
   119  			name: "3/all-signed/out-of-turn",
   120  			lastSigned: map[common.Address]uint64{
   121  				addrs[0]: 1,
   122  				addrs[1]: 4,
   123  				addrs[2]: 3,
   124  			},
   125  		},
   126  		{
   127  			name: "6/all-signed/in-turn",
   128  			lastSigned: map[common.Address]uint64{
   129  				addrs[0]: 1,
   130  				addrs[1]: 2,
   131  				addrs[2]: 3,
   132  				addrs[3]: 4,
   133  				addrs[4]: 5,
   134  				addrs[5]: 6,
   135  			},
   136  		},
   137  		{
   138  			name: "6/all-signed/out-of-turn",
   139  			lastSigned: map[common.Address]uint64{
   140  				addrs[0]: 9,
   141  				addrs[1]: 2,
   142  				addrs[2]: 7,
   143  				addrs[3]: 8,
   144  				addrs[4]: 5,
   145  				addrs[5]: 6,
   146  			},
   147  		},
   148  
   149  		// One new.
   150  		{
   151  			name: "3/one-new",
   152  			lastSigned: map[common.Address]uint64{
   153  				addrs[0]: 0,
   154  				addrs[1]: 4,
   155  				addrs[2]: 3,
   156  			},
   157  		},
   158  		{
   159  			name: "6/one-new",
   160  			lastSigned: map[common.Address]uint64{
   161  				addrs[0]: 1,
   162  				addrs[1]: 2,
   163  				addrs[2]: 3,
   164  				addrs[3]: 4,
   165  				addrs[4]: 5,
   166  				addrs[5]: 0,
   167  			},
   168  		},
   169  
   170  		// Multiple new.
   171  		{
   172  			name: "3/multiple-new",
   173  			lastSigned: map[common.Address]uint64{
   174  				addrs[0]: 0,
   175  				addrs[1]: 0,
   176  				addrs[2]: 3,
   177  			},
   178  		},
   179  		{
   180  			name: "6/multiple-new",
   181  			lastSigned: map[common.Address]uint64{
   182  				addrs[0]: 0,
   183  				addrs[1]: 0,
   184  				addrs[2]: 3,
   185  				addrs[3]: 0,
   186  				addrs[4]: 0,
   187  				addrs[5]: 0,
   188  			},
   189  		},
   190  	} {
   191  		t.Run(test.name, test.run)
   192  	}
   193  }
   194  
   195  type testCalcDifficulty struct {
   196  	name       string
   197  	lastSigned map[common.Address]uint64
   198  }
   199  
   200  func (test *testCalcDifficulty) run(t *testing.T) {
   201  	var signers []common.Address
   202  	for addr := range test.lastSigned {
   203  		signers = append(signers, addr)
   204  	}
   205  	sort.Slice(signers, func(i, j int) bool {
   206  		iAddr, jAddr := signers[i], signers[j]
   207  		iN, jN := test.lastSigned[iAddr], test.lastSigned[jAddr]
   208  		if iN != jN {
   209  			return iN < jN
   210  		}
   211  		return bytes.Compare(iAddr[:], jAddr[:]) < 0
   212  	})
   213  	for i, signer := range signers {
   214  		exp := len(signers) - i
   215  		if exp <= len(signers)/2 {
   216  			exp = 0
   217  		}
   218  		got := CalcDifficulty(test.lastSigned, signer)
   219  		if got != uint64(exp) {
   220  			t.Errorf("expected difficulty %d but got %d", exp, got)
   221  		}
   222  	}
   223  }