github.com/jonasnick/go-ethereum@v0.7.12-0.20150216215225-22176f05d387/pow/ezp/pow.go (about) 1 package ezp 2 3 import ( 4 "math/big" 5 "math/rand" 6 "time" 7 8 "github.com/jonasnick/go-ethereum/crypto" 9 "github.com/jonasnick/go-ethereum/crypto/sha3" 10 "github.com/jonasnick/go-ethereum/ethutil" 11 "github.com/jonasnick/go-ethereum/logger" 12 "github.com/jonasnick/go-ethereum/pow" 13 ) 14 15 var powlogger = logger.NewLogger("POW") 16 17 type EasyPow struct { 18 hash *big.Int 19 HashRate int64 20 turbo bool 21 } 22 23 func New() *EasyPow { 24 return &EasyPow{turbo: false} 25 } 26 27 func (pow *EasyPow) GetHashrate() int64 { 28 return pow.HashRate 29 } 30 31 func (pow *EasyPow) Turbo(on bool) { 32 pow.turbo = on 33 } 34 35 func (pow *EasyPow) Search(block pow.Block, stop <-chan struct{}) []byte { 36 r := rand.New(rand.NewSource(time.Now().UnixNano())) 37 hash := block.HashNoNonce() 38 diff := block.Difficulty() 39 //i := int64(0) 40 // TODO fix offset 41 i := rand.Int63() 42 starti := i 43 start := time.Now().UnixNano() 44 45 defer func() { pow.HashRate = 0 }() 46 47 // Make sure stop is empty 48 empty: 49 for { 50 select { 51 case <-stop: 52 default: 53 break empty 54 } 55 } 56 57 for { 58 select { 59 case <-stop: 60 return nil 61 default: 62 i++ 63 64 elapsed := time.Now().UnixNano() - start 65 hashes := ((float64(1e9) / float64(elapsed)) * float64(i-starti)) / 1000 66 pow.HashRate = int64(hashes) 67 68 sha := crypto.Sha3(big.NewInt(r.Int63()).Bytes()) 69 if verify(hash, diff, sha) { 70 return sha 71 } 72 } 73 74 if !pow.turbo { 75 time.Sleep(20 * time.Microsecond) 76 } 77 } 78 79 return nil 80 } 81 82 func (pow *EasyPow) Verify(block pow.Block) bool { 83 return Verify(block) 84 } 85 86 func verify(hash []byte, diff *big.Int, nonce []byte) bool { 87 sha := sha3.NewKeccak256() 88 89 d := append(hash, nonce...) 90 sha.Write(d) 91 92 verification := new(big.Int).Div(ethutil.BigPow(2, 256), diff) 93 res := ethutil.BigD(sha.Sum(nil)) 94 95 return res.Cmp(verification) <= 0 96 } 97 98 func Verify(block pow.Block) bool { 99 return verify(block.HashNoNonce(), block.Difficulty(), block.N()) 100 }