github.com/n1ghtfa1l/go-vnt@v0.6.4-alpha.6/consensus/dpos/dpos_test.go (about) 1 // Copyright 2019 The go-vnt Authors 2 // This file is part of the go-vnt library. 3 // 4 // The go-vnt 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 go-vnt 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 go-vnt library. If not, see <http://www.gnu.org/licenses/>. 16 17 package dpos 18 19 import ( 20 "math/big" 21 "testing" 22 23 "github.com/vntchain/go-vnt/common" 24 "github.com/vntchain/go-vnt/core/types" 25 "github.com/vntchain/go-vnt/core/vm/election" 26 "github.com/vntchain/go-vnt/params" 27 ) 28 29 func TestUpdateTime(t *testing.T) { 30 ti := big.NewInt(10000) 31 encoded := encodeUpdateTime(ti) 32 var up updateTime 33 copy(up[:], encoded[:]) 34 ret := up.bigInt() 35 if ret.Cmp(ti) != 0 { 36 t.Errorf("updateTime encode and decode error") 37 } 38 } 39 40 func TestNeedUpdateWitnesses(t *testing.T) { 41 cfg := ¶ms.DposConfig{ 42 WitnessesNum: 3, 43 Period: 2, 44 } 45 46 dp := New(cfg, nil) 47 48 tests := []struct { 49 cur int64 50 last int64 51 ret bool 52 }{ 53 {1, 0, false}, 54 {10, 0, false}, 55 {17, 0, false}, 56 {18, 0, true}, 57 {19, 0, true}, 58 {20, 0, true}, 59 {21, 0, true}, 60 {-1, 0, false}, 61 {-10, 0, false}, 62 {-100, 0, false}, 63 } 64 65 for i, ts := range tests { 66 if dp.needUpdateWitnesses(big.NewInt(ts.cur), big.NewInt(ts.last)) != ts.ret { 67 t.Errorf("test:%d, failed. cur = %d, last = %d, want=%v\n", i, ts.cur, ts.last, ts.ret) 68 } 69 } 70 } 71 72 func TestUpdatedWitnessCheckByTime(t *testing.T) { 73 cfg := ¶ms.DposConfig{ 74 WitnessesNum: 4, 75 Period: 2, 76 } 77 78 dp := New(cfg, nil) 79 80 updatedHeader := &types.Header{Time: big.NewInt(103023930)} 81 updatedHeader.Extra = make([]byte, updateTimeLen) 82 copy(updatedHeader.Extra, encodeUpdateTime(updatedHeader.Time)) 83 84 noneUpdatedHeader := &types.Header{Time: big.NewInt(103023930)} 85 noneUpdatedHeader.Extra = make([]byte, updateTimeLen) 86 copy(noneUpdatedHeader.Extra, encodeUpdateTime(big.NewInt(203930394))) 87 88 tests := []struct { 89 header *types.Header 90 ret bool 91 }{ 92 {updatedHeader, true}, 93 {noneUpdatedHeader, false}, 94 } 95 96 for i, ts := range tests { 97 if dp.updatedWitnessCheckByTime(ts.header) != ts.ret { 98 t.Errorf("test: %d failed", i) 99 } 100 } 101 } 102 103 func TestCurHeightBonus(t *testing.T) { 104 blkNr1 := big.NewInt(100) 105 blkNr2 := big.NewInt(57304000) 106 blkNr3 := big.NewInt(104608000) 107 108 tests := []struct { 109 nr *big.Int 110 bonus *big.Int 111 }{ 112 {blkNr1, big.NewInt(0).Set(VortexBlockReward)}, 113 {blkNr2, big.NewInt(0).Div(big.NewInt(0).Set(VortexBlockReward), big.NewInt(2))}, 114 {blkNr3, big.NewInt(0).Div(big.NewInt(0).Set(VortexBlockReward), big.NewInt(4))}, 115 } 116 117 for i, ts := range tests { 118 if ret := curHeightBonus(ts.nr, VortexBlockReward); ret.Cmp(ts.bonus) != 0 { 119 t.Errorf("test: %d failed, want: %s, get: %s", i, ts.bonus.String(), ret.String()) 120 } 121 } 122 } 123 124 func TestCalcVoteBounty(t *testing.T) { 125 cfg := ¶ms.DposConfig{ 126 WitnessesNum: 4, 127 Period: 2, 128 } 129 130 dp := New(cfg, nil) 131 132 // 情况1:人不够,但都是active 133 // 情况2:人不够,有inactive 134 // 情况3:没投票 135 ca1 := election.Candidate{ 136 Owner: common.BytesToAddress([]byte{1}), 137 VoteCount: big.NewInt(0), 138 Registered: true, 139 Bind: true, 140 } 141 ca2 := election.Candidate{ 142 Owner: common.BytesToAddress([]byte{2}), 143 VoteCount: big.NewInt(0), 144 Registered: true, 145 Bind: true, 146 } 147 ca3 := election.Candidate{ 148 Owner: common.BytesToAddress([]byte{3}), 149 VoteCount: big.NewInt(0), 150 Registered: true, 151 Bind: true, 152 } 153 ca4 := election.Candidate{ 154 Owner: common.BytesToAddress([]byte{4}), 155 VoteCount: big.NewInt(0), 156 Registered: true, 157 Bind: true, 158 } 159 ca5 := election.Candidate{ 160 Owner: common.BytesToAddress([]byte{5}), 161 VoteCount: big.NewInt(0), 162 Registered: false, 163 } 164 ca6 := election.Candidate{ 165 Owner: common.BytesToAddress([]byte{5}), 166 VoteCount: big.NewInt(0), 167 Registered: true, 168 Bind: true, 169 } 170 171 candis1 := election.CandidateList{ca1, ca2, ca3} 172 candis2 := election.CandidateList{ca1, ca2, ca3, ca5} 173 candis3 := election.CandidateList{ca2, ca3, ca4, ca6} 174 175 failTests := []election.CandidateList{candis1, candis2, candis3} 176 allBonus := big.NewInt(100) 177 rewardsExpEmpty := make(map[common.Address]*big.Int) 178 for i, ts := range failTests { 179 dp.calcVoteBounty(ts, allBonus, rewardsExpEmpty) 180 if len(rewardsExpEmpty) != 0 { 181 t.Errorf("test: %d, want: reward is empty, get: len(rewardsExpEmpty)=%v", i, len(rewardsExpEmpty)) 182 } 183 } 184 185 // 情况4:人够,按比例分配,其中1个inactive 186 ca1.VoteCount = big.NewInt(10) 187 ca2.VoteCount = big.NewInt(40) 188 ca3.VoteCount = big.NewInt(20) 189 ca4.VoteCount = big.NewInt(30) 190 ca5.VoteCount = big.NewInt(15) 191 candis4 := election.CandidateList{ca1, ca2, ca3, ca4, ca5} 192 rewardsExpNoneEmpty := make(map[common.Address]*big.Int) 193 rewardsExpNoneEmpty[ca1.Owner] = big.NewInt(3) // ca1有3个的已有激励 194 dp.calcVoteBounty(candis4, allBonus, rewardsExpNoneEmpty) 195 if len(rewardsExpNoneEmpty) == 0 { 196 t.Errorf("want: rewardsExpNoneEmpty, get: len(rewardsExpNoneEmpty) == 0") 197 } 198 for i, ca := range candis4 { 199 if !ca.Active() { 200 continue 201 } 202 caBonus := rewardsExpNoneEmpty[ca.Owner] 203 if caBonus == nil { 204 t.Errorf("can %d, want bonus: %s, get: nil", i, ca.VoteCount.String()) 205 continue 206 } 207 if ca.Owner == ca1.Owner { 208 // ca1的已有激励不能被覆盖 209 if ca.VoteCount.Add(ca.VoteCount, big.NewInt(3)).Cmp(caBonus) != 0 { 210 t.Errorf("can %d, want bonus: %s+3, get: %s", i, ca.VoteCount.String(), caBonus.String()) 211 } 212 } else { 213 if ca.VoteCount.Cmp(caBonus) != 0 { 214 t.Errorf("can %d, want bonus: %s, get: %s", i, ca.VoteCount.String(), caBonus.String()) 215 } 216 } 217 218 } 219 }