gitee.com/liu-zhao234568/cntest@v1.0.0/consensus/ethash/ethash_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 "io/ioutil" 21 "math/big" 22 "math/rand" 23 "os" 24 "sync" 25 "testing" 26 "time" 27 28 "gitee.com/liu-zhao234568/cntest/common" 29 "gitee.com/liu-zhao234568/cntest/common/hexutil" 30 "gitee.com/liu-zhao234568/cntest/core/types" 31 ) 32 33 // Tests that ethash works correctly in test mode. 34 func TestTestMode(t *testing.T) { 35 header := &types.Header{Number: big.NewInt(1), Difficulty: big.NewInt(100)} 36 37 ethash := NewTester(nil, false) 38 defer ethash.Close() 39 40 results := make(chan *types.Block) 41 err := ethash.Seal(nil, types.NewBlockWithHeader(header), results, nil) 42 if err != nil { 43 t.Fatalf("failed to seal block: %v", err) 44 } 45 select { 46 case block := <-results: 47 header.Nonce = types.EncodeNonce(block.Nonce()) 48 header.MixDigest = block.MixDigest() 49 if err := ethash.verifySeal(nil, header, false); err != nil { 50 t.Fatalf("unexpected verification error: %v", err) 51 } 52 case <-time.NewTimer(4 * time.Second).C: 53 t.Error("sealing result timeout") 54 } 55 } 56 57 // This test checks that cache lru logic doesn't crash under load. 58 // It reproduces https://github.com/ethereum/go-ethereum/issues/14943 59 func TestCacheFileEvict(t *testing.T) { 60 tmpdir, err := ioutil.TempDir("", "ethash-test") 61 if err != nil { 62 t.Fatal(err) 63 } 64 defer os.RemoveAll(tmpdir) 65 66 config := Config{ 67 CachesInMem: 3, 68 CachesOnDisk: 10, 69 CacheDir: tmpdir, 70 PowMode: ModeTest, 71 } 72 e := New(config, nil, false) 73 defer e.Close() 74 75 workers := 8 76 epochs := 100 77 var wg sync.WaitGroup 78 wg.Add(workers) 79 for i := 0; i < workers; i++ { 80 go verifyTest(&wg, e, i, epochs) 81 } 82 wg.Wait() 83 } 84 85 func verifyTest(wg *sync.WaitGroup, e *Ethash, workerIndex, epochs int) { 86 defer wg.Done() 87 88 const wiggle = 4 * epochLength 89 r := rand.New(rand.NewSource(int64(workerIndex))) 90 for epoch := 0; epoch < epochs; epoch++ { 91 block := int64(epoch)*epochLength - wiggle/2 + r.Int63n(wiggle) 92 if block < 0 { 93 block = 0 94 } 95 header := &types.Header{Number: big.NewInt(block), Difficulty: big.NewInt(100)} 96 e.verifySeal(nil, header, false) 97 } 98 } 99 100 func TestRemoteSealer(t *testing.T) { 101 ethash := NewTester(nil, false) 102 defer ethash.Close() 103 104 api := &API{ethash} 105 if _, err := api.GetWork(); err != errNoMiningWork { 106 t.Error("expect to return an error indicate there is no mining work") 107 } 108 header := &types.Header{Number: big.NewInt(1), Difficulty: big.NewInt(100)} 109 block := types.NewBlockWithHeader(header) 110 sealhash := ethash.SealHash(header) 111 112 // Push new work. 113 results := make(chan *types.Block) 114 ethash.Seal(nil, block, results, nil) 115 116 var ( 117 work [4]string 118 err error 119 ) 120 if work, err = api.GetWork(); err != nil || work[0] != sealhash.Hex() { 121 t.Error("expect to return a mining work has same hash") 122 } 123 124 if res := api.SubmitWork(types.BlockNonce{}, sealhash, common.Hash{}); res { 125 t.Error("expect to return false when submit a fake solution") 126 } 127 // Push new block with same block number to replace the original one. 128 header = &types.Header{Number: big.NewInt(1), Difficulty: big.NewInt(1000)} 129 block = types.NewBlockWithHeader(header) 130 sealhash = ethash.SealHash(header) 131 ethash.Seal(nil, block, results, nil) 132 133 if work, err = api.GetWork(); err != nil || work[0] != sealhash.Hex() { 134 t.Error("expect to return the latest pushed work") 135 } 136 } 137 138 func TestHashrate(t *testing.T) { 139 var ( 140 hashrate = []hexutil.Uint64{100, 200, 300} 141 expect uint64 142 ids = []common.Hash{common.HexToHash("a"), common.HexToHash("b"), common.HexToHash("c")} 143 ) 144 ethash := NewTester(nil, false) 145 defer ethash.Close() 146 147 if tot := ethash.Hashrate(); tot != 0 { 148 t.Error("expect the result should be zero") 149 } 150 151 api := &API{ethash} 152 for i := 0; i < len(hashrate); i += 1 { 153 if res := api.SubmitHashrate(hashrate[i], ids[i]); !res { 154 t.Error("remote miner submit hashrate failed") 155 } 156 expect += uint64(hashrate[i]) 157 } 158 if tot := ethash.Hashrate(); tot != float64(expect) { 159 t.Error("expect total hashrate should be same") 160 } 161 } 162 163 func TestClosedRemoteSealer(t *testing.T) { 164 ethash := NewTester(nil, false) 165 time.Sleep(1 * time.Second) // ensure exit channel is listening 166 ethash.Close() 167 168 api := &API{ethash} 169 if _, err := api.GetWork(); err != errEthashStopped { 170 t.Error("expect to return an error to indicate ethash is stopped") 171 } 172 173 if res := api.SubmitHashrate(hexutil.Uint64(100), common.HexToHash("a")); res { 174 t.Error("expect to return false when submit hashrate to a stopped ethash") 175 } 176 }