github.com/phillinzzz/newBsc@v1.1.6/consensus/ethash/consensus_test.go (about) 1 // Copyright 2017 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum 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-ethereum 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-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package ethash 18 19 import ( 20 "encoding/binary" 21 "encoding/json" 22 "math/big" 23 "math/rand" 24 "os" 25 "path/filepath" 26 "testing" 27 28 "github.com/phillinzzz/newBsc/common" 29 "github.com/phillinzzz/newBsc/common/math" 30 "github.com/phillinzzz/newBsc/core/types" 31 "github.com/phillinzzz/newBsc/params" 32 ) 33 34 type diffTest struct { 35 ParentTimestamp uint64 36 ParentDifficulty *big.Int 37 CurrentTimestamp uint64 38 CurrentBlocknumber *big.Int 39 CurrentDifficulty *big.Int 40 } 41 42 func (d *diffTest) UnmarshalJSON(b []byte) (err error) { 43 var ext struct { 44 ParentTimestamp string 45 ParentDifficulty string 46 CurrentTimestamp string 47 CurrentBlocknumber string 48 CurrentDifficulty string 49 } 50 if err := json.Unmarshal(b, &ext); err != nil { 51 return err 52 } 53 54 d.ParentTimestamp = math.MustParseUint64(ext.ParentTimestamp) 55 d.ParentDifficulty = math.MustParseBig256(ext.ParentDifficulty) 56 d.CurrentTimestamp = math.MustParseUint64(ext.CurrentTimestamp) 57 d.CurrentBlocknumber = math.MustParseBig256(ext.CurrentBlocknumber) 58 d.CurrentDifficulty = math.MustParseBig256(ext.CurrentDifficulty) 59 60 return nil 61 } 62 63 func TestCalcDifficulty(t *testing.T) { 64 file, err := os.Open(filepath.Join("..", "..", "tests", "testdata", "BasicTests", "difficulty.json")) 65 if err != nil { 66 t.Skip(err) 67 } 68 defer file.Close() 69 70 tests := make(map[string]diffTest) 71 err = json.NewDecoder(file).Decode(&tests) 72 if err != nil { 73 t.Fatal(err) 74 } 75 76 config := ¶ms.ChainConfig{HomesteadBlock: big.NewInt(1150000)} 77 78 for name, test := range tests { 79 number := new(big.Int).Sub(test.CurrentBlocknumber, big.NewInt(1)) 80 diff := CalcDifficulty(config, test.CurrentTimestamp, &types.Header{ 81 Number: number, 82 Time: test.ParentTimestamp, 83 Difficulty: test.ParentDifficulty, 84 }) 85 if diff.Cmp(test.CurrentDifficulty) != 0 { 86 t.Error(name, "failed. Expected", test.CurrentDifficulty, "and calculated", diff) 87 } 88 } 89 } 90 91 func randSlice(min, max uint32) []byte { 92 var b = make([]byte, 4) 93 rand.Read(b) 94 a := binary.LittleEndian.Uint32(b) 95 size := min + a%(max-min) 96 out := make([]byte, size) 97 rand.Read(out) 98 return out 99 } 100 101 func TestDifficultyCalculators(t *testing.T) { 102 rand.Seed(2) 103 for i := 0; i < 5000; i++ { 104 // 1 to 300 seconds diff 105 var timeDelta = uint64(1 + rand.Uint32()%3000) 106 diffBig := big.NewInt(0).SetBytes(randSlice(2, 10)) 107 if diffBig.Cmp(params.MinimumDifficulty) < 0 { 108 diffBig.Set(params.MinimumDifficulty) 109 } 110 //rand.Read(difficulty) 111 header := &types.Header{ 112 Difficulty: diffBig, 113 Number: new(big.Int).SetUint64(rand.Uint64() % 50_000_000), 114 Time: rand.Uint64() - timeDelta, 115 } 116 if rand.Uint32()&1 == 0 { 117 header.UncleHash = types.EmptyUncleHash 118 } 119 bombDelay := new(big.Int).SetUint64(rand.Uint64() % 50_000_000) 120 for i, pair := range []struct { 121 bigFn func(time uint64, parent *types.Header) *big.Int 122 u256Fn func(time uint64, parent *types.Header) *big.Int 123 }{ 124 {FrontierDifficultyCalulator, CalcDifficultyFrontierU256}, 125 {HomesteadDifficultyCalulator, CalcDifficultyHomesteadU256}, 126 {DynamicDifficultyCalculator(bombDelay), MakeDifficultyCalculatorU256(bombDelay)}, 127 } { 128 time := header.Time + timeDelta 129 want := pair.bigFn(time, header) 130 have := pair.u256Fn(time, header) 131 if want.BitLen() > 256 { 132 continue 133 } 134 if want.Cmp(have) != 0 { 135 t.Fatalf("pair %d: want %x have %x\nparent.Number: %x\np.Time: %x\nc.Time: %x\nBombdelay: %v\n", i, want, have, 136 header.Number, header.Time, time, bombDelay) 137 } 138 } 139 } 140 } 141 142 func BenchmarkDifficultyCalculator(b *testing.B) { 143 x1 := makeDifficultyCalculator(big.NewInt(1000000)) 144 x2 := MakeDifficultyCalculatorU256(big.NewInt(1000000)) 145 h := &types.Header{ 146 ParentHash: common.Hash{}, 147 UncleHash: types.EmptyUncleHash, 148 Difficulty: big.NewInt(0xffffff), 149 Number: big.NewInt(500000), 150 Time: 1000000, 151 } 152 b.Run("big-frontier", func(b *testing.B) { 153 b.ReportAllocs() 154 for i := 0; i < b.N; i++ { 155 calcDifficultyFrontier(1000014, h) 156 } 157 }) 158 b.Run("u256-frontier", func(b *testing.B) { 159 b.ReportAllocs() 160 for i := 0; i < b.N; i++ { 161 CalcDifficultyFrontierU256(1000014, h) 162 } 163 }) 164 b.Run("big-homestead", func(b *testing.B) { 165 b.ReportAllocs() 166 for i := 0; i < b.N; i++ { 167 calcDifficultyHomestead(1000014, h) 168 } 169 }) 170 b.Run("u256-homestead", func(b *testing.B) { 171 b.ReportAllocs() 172 for i := 0; i < b.N; i++ { 173 CalcDifficultyHomesteadU256(1000014, h) 174 } 175 }) 176 b.Run("big-generic", func(b *testing.B) { 177 b.ReportAllocs() 178 for i := 0; i < b.N; i++ { 179 x1(1000014, h) 180 } 181 }) 182 b.Run("u256-generic", func(b *testing.B) { 183 b.ReportAllocs() 184 for i := 0; i < b.N; i++ { 185 x2(1000014, h) 186 } 187 }) 188 }