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  }