func (pow *Full) Search(block pow.Block, stop <-chan struct{}) (nonce uint64, mixDigest []byte) { dag := pow.getDAG(block.NumberU64()) r := rand.New(rand.NewSource(time.Now().UnixNano())) diff := block.Difficulty() i := int64(0) starti := i start := time.Now().UnixNano() previousHashrate := int32(0) nonce = uint64(r.Int63()) hash := hashToH256(block.HashNoNonce()) target := new(big.Int).Div(minDifficulty, diff) for { select { case <-stop: atomic.AddInt32(&pow.hashRate, -previousHashrate) return 0, nil default: i++ // we don't have to update hash rate on every nonce, so update after // first nonce check and then after 2^X nonces if i == 2 || ((i % (1 << 16)) == 0) { elapsed := time.Now().UnixNano() - start hashes := (float64(1e9) / float64(elapsed)) * float64(i-starti) hashrateDiff := int32(hashes) - previousHashrate previousHashrate = int32(hashes) atomic.AddInt32(&pow.hashRate, hashrateDiff) } ret := C.ethash_full_compute(dag.ptr, hash, C.uint64_t(nonce)) result := h256ToHash(ret.result).Big() // TODO: disagrees with the spec https://github.com/ethereum/wiki/wiki/Ethash#mining if ret.success && result.Cmp(target) <= 0 { mixDigest = C.GoBytes(unsafe.Pointer(&ret.mix_hash), C.int(32)) atomic.AddInt32(&pow.hashRate, -previousHashrate) return nonce, mixDigest } nonce += 1 } if !pow.turbo { time.Sleep(20 * time.Microsecond) } } }
func (pow *Full) Search(block pow.Block, stop <-chan struct{}) (nonce uint64, mixDigest []byte) { dag := pow.getDAG(block.NumberU64()) r := rand.New(rand.NewSource(time.Now().UnixNano())) diff := block.Difficulty() i := int64(0) starti := i start := time.Now().UnixNano() nonce = uint64(r.Int63()) hash := hashToH256(block.HashNoNonce()) target := new(big.Int).Div(minDifficulty, diff) for { select { case <-stop: pow.hashRate = 0 return 0, nil default: i++ elapsed := time.Now().UnixNano() - start hashes := ((float64(1e9) / float64(elapsed)) * float64(i-starti)) / 1000 pow.hashRate = int64(hashes) ret := C.ethash_full_compute(dag.ptr, hash, C.uint64_t(nonce)) result := h256ToHash(ret.result).Big() // TODO: disagrees with the spec https://github.com/ethereum/wiki/wiki/Ethash#mining if ret.success && result.Cmp(target) <= 0 { mixDigest = C.GoBytes(unsafe.Pointer(&ret.mix_hash), C.int(32)) return nonce, mixDigest } nonce += 1 } if !pow.turbo { time.Sleep(20 * time.Microsecond) } } }