github.com/klaytn/klaytn@v1.12.1/consensus/istanbul/core/vrank_test.go (about) 1 // Copyright 2023 The klaytn Authors 2 // This file is part of the klaytn library. 3 // 4 // The klaytn library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The klaytn library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the klaytn library. If not, see <http://www.gnu.org/licenses/>. 16 17 package core 18 19 import ( 20 "encoding/hex" 21 "math/big" 22 "sort" 23 "testing" 24 "time" 25 26 "github.com/klaytn/klaytn/common" 27 "github.com/klaytn/klaytn/consensus/istanbul" 28 "github.com/klaytn/klaytn/consensus/istanbul/validator" 29 "github.com/stretchr/testify/assert" 30 ) 31 32 func genCommitteeFromAddrs(addrs []common.Address) istanbul.Validators { 33 committee := []istanbul.Validator{} 34 for _, addr := range addrs { 35 committee = append(committee, validator.New(addr)) 36 } 37 return committee 38 } 39 40 func TestVrank(t *testing.T) { 41 var ( 42 N = 6 43 quorum = 4 44 addrs, _ = genValidators(N) 45 committee = genCommitteeFromAddrs(addrs) 46 view = istanbul.View{Sequence: big.NewInt(0), Round: big.NewInt(0)} 47 msg = &istanbul.Subject{View: &view} 48 vrank = NewVrank(view, committee) 49 50 expectedAssessList []uint8 51 expectedLateCommits []time.Duration 52 ) 53 54 sort.Sort(committee) 55 for i := 0; i < quorum; i++ { 56 vrank.AddCommit(msg, committee[i]) 57 expectedAssessList = append(expectedAssessList, vrankArrivedEarly) 58 } 59 vrank.HandleCommitted(view.Sequence) 60 for i := quorum; i < N; i++ { 61 vrank.AddCommit(msg, committee[i]) 62 expectedAssessList = append(expectedAssessList, vrankArrivedLate) 63 expectedLateCommits = append(expectedLateCommits, vrank.commitArrivalTimeMap[committee[i].Address()]) 64 } 65 66 bitmap, late := vrank.Bitmap(), vrank.LateCommits() 67 assert.Equal(t, hex.EncodeToString(compress(expectedAssessList)), bitmap) 68 assert.Equal(t, expectedLateCommits, late) 69 } 70 71 func TestVrankAssessBatch(t *testing.T) { 72 arr := []time.Duration{0, 4, 1, vrankNotArrivedPlaceholder, 2} 73 threshold := time.Duration(2) 74 expected := []uint8{ 75 vrankArrivedEarly, vrankArrivedLate, vrankArrivedEarly, vrankNotArrived, vrankArrivedEarly, 76 } 77 assert.Equal(t, expected, assessBatch(arr, threshold)) 78 } 79 80 func TestVrankSerialize(t *testing.T) { 81 var ( 82 N = 6 83 addrs, _ = genValidators(N) 84 committee = genCommitteeFromAddrs(addrs) 85 timeMap = make(map[common.Address]time.Duration) 86 expected = make([]time.Duration, len(addrs)) 87 ) 88 89 sort.Sort(committee) 90 for i, val := range committee { 91 t := time.Duration((i * 100) * int(time.Millisecond)) 92 timeMap[val.Address()] = t 93 expected[i] = t 94 } 95 96 assert.Equal(t, expected, serialize(committee, timeMap)) 97 } 98 99 func TestVrankCompress(t *testing.T) { 100 tcs := []struct { 101 input []uint8 102 expected []byte 103 }{ 104 { 105 input: []uint8{2}, 106 expected: []byte{0b10_000000}, 107 }, 108 { 109 input: []uint8{2, 1}, 110 expected: []byte{0b10_01_0000}, 111 }, 112 { 113 input: []uint8{0, 2, 1}, 114 expected: []byte{0b00_10_01_00}, 115 }, 116 { 117 input: []uint8{0, 2, 1, 1}, 118 expected: []byte{0b00_10_01_01}, 119 }, 120 { 121 input: []uint8{1, 2, 1, 2, 1}, 122 expected: []byte{0b01_10_01_10, 0b01_000000}, 123 }, 124 { 125 input: []uint8{1, 2, 1, 2, 1, 2}, 126 expected: []byte{0b01_10_01_10, 0b01_10_0000}, 127 }, 128 { 129 input: []uint8{1, 2, 1, 2, 1, 2, 1}, 130 expected: []byte{0b01_10_01_10, 0b01_10_01_00}, 131 }, 132 { 133 input: []uint8{1, 2, 1, 2, 1, 2, 0, 2}, 134 expected: []byte{0b01_10_01_10, 0b01_10_00_10}, 135 }, 136 { 137 input: []uint8{1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1}, 138 expected: []byte{0b01011010, 0b01011010, 0b01011010, 0b01011010, 0b01010000}, 139 }, 140 } 141 for i, tc := range tcs { 142 assert.Equal(t, tc.expected, compress(tc.input), "tc %d failed", i) 143 } 144 }