github.com/jeffallen/go-ethereum@v1.1.4-0.20150910155051-571d3236c49c/pow/ezp/pow.go (about) 1 // Copyright 2014 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 ezp 18 19 import ( 20 "encoding/binary" 21 "math/big" 22 "math/rand" 23 "time" 24 25 "github.com/ethereum/go-ethereum/common" 26 "github.com/ethereum/go-ethereum/crypto/sha3" 27 "github.com/ethereum/go-ethereum/logger" 28 "github.com/ethereum/go-ethereum/pow" 29 ) 30 31 var powlogger = logger.NewLogger("POW") 32 33 type EasyPow struct { 34 hash *big.Int 35 HashRate int64 36 turbo bool 37 } 38 39 func New() *EasyPow { 40 return &EasyPow{turbo: false} 41 } 42 43 func (pow *EasyPow) GetHashrate() int64 { 44 return pow.HashRate 45 } 46 47 func (pow *EasyPow) Turbo(on bool) { 48 pow.turbo = on 49 } 50 51 func (pow *EasyPow) Search(block pow.Block, stop <-chan struct{}) (uint64, []byte) { 52 r := rand.New(rand.NewSource(time.Now().UnixNano())) 53 hash := block.HashNoNonce() 54 diff := block.Difficulty() 55 //i := int64(0) 56 // TODO fix offset 57 i := rand.Int63() 58 starti := i 59 start := time.Now().UnixNano() 60 61 defer func() { pow.HashRate = 0 }() 62 63 // Make sure stop is empty 64 empty: 65 for { 66 select { 67 case <-stop: 68 default: 69 break empty 70 } 71 } 72 73 for { 74 select { 75 case <-stop: 76 return 0, nil 77 default: 78 i++ 79 80 elapsed := time.Now().UnixNano() - start 81 hashes := ((float64(1e9) / float64(elapsed)) * float64(i-starti)) / 1000 82 pow.HashRate = int64(hashes) 83 84 sha := uint64(r.Int63()) 85 if verify(hash, diff, sha) { 86 return sha, nil 87 } 88 } 89 90 if !pow.turbo { 91 time.Sleep(20 * time.Microsecond) 92 } 93 } 94 95 return 0, nil 96 } 97 98 func (pow *EasyPow) Verify(block pow.Block) bool { 99 return Verify(block) 100 } 101 102 func verify(hash common.Hash, diff *big.Int, nonce uint64) bool { 103 sha := sha3.NewKeccak256() 104 n := make([]byte, 8) 105 binary.PutUvarint(n, nonce) 106 sha.Write(n) 107 sha.Write(hash[:]) 108 verification := new(big.Int).Div(common.BigPow(2, 256), diff) 109 res := common.BigD(sha.Sum(nil)) 110 return res.Cmp(verification) <= 0 111 } 112 113 func Verify(block pow.Block) bool { 114 return verify(block.HashNoNonce(), block.Difficulty(), block.Nonce()) 115 }