github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/consensus/ethash/ethash_test.go (about) 1 2 //<developer> 3 // <name>linapex 曹一峰</name> 4 // <email>linapex@163.com</email> 5 // <wx>superexc</wx> 6 // <qqgroup>128148617</qqgroup> 7 // <url>https://jsq.ink</url> 8 // <role>pku engineer</role> 9 // <date>2019-03-16 19:16:34</date> 10 //</624450075128500224> 11 12 13 package ethash 14 15 import ( 16 "io/ioutil" 17 "math/big" 18 "math/rand" 19 "os" 20 "sync" 21 "testing" 22 "time" 23 24 "github.com/ethereum/go-ethereum/common" 25 "github.com/ethereum/go-ethereum/common/hexutil" 26 "github.com/ethereum/go-ethereum/core/types" 27 ) 28 29 //测试ethash在测试模式下是否正常工作。 30 func TestTestMode(t *testing.T) { 31 header := &types.Header{Number: big.NewInt(1), Difficulty: big.NewInt(100)} 32 33 ethash := NewTester(nil, false) 34 defer ethash.Close() 35 36 results := make(chan *types.Block) 37 err := ethash.Seal(nil, types.NewBlockWithHeader(header), results, nil) 38 if err != nil { 39 t.Fatalf("failed to seal block: %v", err) 40 } 41 select { 42 case block := <-results: 43 header.Nonce = types.EncodeNonce(block.Nonce()) 44 header.MixDigest = block.MixDigest() 45 if err := ethash.VerifySeal(nil, header); err != nil { 46 t.Fatalf("unexpected verification error: %v", err) 47 } 48 case <-time.NewTimer(time.Second).C: 49 t.Error("sealing result timeout") 50 } 51 } 52 53 //此测试检查高速缓存LRU逻辑在负载下是否崩溃。 54 //它复制了https://github.com/ethereum/go-ethereum/issues/14943 55 func TestCacheFileEvict(t *testing.T) { 56 tmpdir, err := ioutil.TempDir("", "ethash-test") 57 if err != nil { 58 t.Fatal(err) 59 } 60 defer os.RemoveAll(tmpdir) 61 e := New(Config{CachesInMem: 3, CachesOnDisk: 10, CacheDir: tmpdir, PowMode: ModeTest}, nil, false) 62 defer e.Close() 63 64 workers := 8 65 epochs := 100 66 var wg sync.WaitGroup 67 wg.Add(workers) 68 for i := 0; i < workers; i++ { 69 go verifyTest(&wg, e, i, epochs) 70 } 71 wg.Wait() 72 } 73 74 func verifyTest(wg *sync.WaitGroup, e *Ethash, workerIndex, epochs int) { 75 defer wg.Done() 76 77 const wiggle = 4 * epochLength 78 r := rand.New(rand.NewSource(int64(workerIndex))) 79 for epoch := 0; epoch < epochs; epoch++ { 80 block := int64(epoch)*epochLength - wiggle/2 + r.Int63n(wiggle) 81 if block < 0 { 82 block = 0 83 } 84 header := &types.Header{Number: big.NewInt(block), Difficulty: big.NewInt(100)} 85 e.VerifySeal(nil, header) 86 } 87 } 88 89 func TestRemoteSealer(t *testing.T) { 90 ethash := NewTester(nil, false) 91 defer ethash.Close() 92 93 api := &API{ethash} 94 if _, err := api.GetWork(); err != errNoMiningWork { 95 t.Error("expect to return an error indicate there is no mining work") 96 } 97 header := &types.Header{Number: big.NewInt(1), Difficulty: big.NewInt(100)} 98 block := types.NewBlockWithHeader(header) 99 sealhash := ethash.SealHash(header) 100 101 //推动新的工作。 102 results := make(chan *types.Block) 103 ethash.Seal(nil, block, results, nil) 104 105 var ( 106 work [4]string 107 err error 108 ) 109 if work, err = api.GetWork(); err != nil || work[0] != sealhash.Hex() { 110 t.Error("expect to return a mining work has same hash") 111 } 112 113 if res := api.SubmitWork(types.BlockNonce{}, sealhash, common.Hash{}); res { 114 t.Error("expect to return false when submit a fake solution") 115 } 116 //用相同的块号推新块以替换原来的块。 117 header = &types.Header{Number: big.NewInt(1), Difficulty: big.NewInt(1000)} 118 block = types.NewBlockWithHeader(header) 119 sealhash = ethash.SealHash(header) 120 ethash.Seal(nil, block, results, nil) 121 122 if work, err = api.GetWork(); err != nil || work[0] != sealhash.Hex() { 123 t.Error("expect to return the latest pushed work") 124 } 125 } 126 127 func TestHashRate(t *testing.T) { 128 var ( 129 hashrate = []hexutil.Uint64{100, 200, 300} 130 expect uint64 131 ids = []common.Hash{common.HexToHash("a"), common.HexToHash("b"), common.HexToHash("c")} 132 ) 133 ethash := NewTester(nil, false) 134 defer ethash.Close() 135 136 if tot := ethash.Hashrate(); tot != 0 { 137 t.Error("expect the result should be zero") 138 } 139 140 api := &API{ethash} 141 for i := 0; i < len(hashrate); i += 1 { 142 if res := api.SubmitHashRate(hashrate[i], ids[i]); !res { 143 t.Error("remote miner submit hashrate failed") 144 } 145 expect += uint64(hashrate[i]) 146 } 147 if tot := ethash.Hashrate(); tot != float64(expect) { 148 t.Error("expect total hashrate should be same") 149 } 150 } 151 152 func TestClosedRemoteSealer(t *testing.T) { 153 ethash := NewTester(nil, false) 154 time.Sleep(1 * time.Second) //确保出口频道正在收听 155 ethash.Close() 156 157 api := &API{ethash} 158 if _, err := api.GetWork(); err != errEthashStopped { 159 t.Error("expect to return an error to indicate ethash is stopped") 160 } 161 162 if res := api.SubmitHashRate(hexutil.Uint64(100), common.HexToHash("a")); res { 163 t.Error("expect to return false when submit hashrate to a stopped ethash") 164 } 165 } 166