github.com/Bytom/bytom@v1.1.2-0.20210127130405-ae40204c0b09/cmd/miner/main.go (about)

     1  package main
     2  
     3  import (
     4  	"encoding/json"
     5  	"log"
     6  	"os"
     7  
     8  	"github.com/bytom/bytom/api"
     9  	"github.com/bytom/bytom/consensus"
    10  	"github.com/bytom/bytom/consensus/difficulty"
    11  	"github.com/bytom/bytom/protocol/bc"
    12  	"github.com/bytom/bytom/protocol/bc/types"
    13  	"github.com/bytom/bytom/util"
    14  )
    15  
    16  const (
    17  	maxNonce = ^uint64(0) // 2^64 - 1
    18  	isCrazy  = true
    19  	esHR     = 1 //estimated Hashrate
    20  )
    21  
    22  var (
    23  	lastNonce  = ^uint64(0)
    24  	lastHeight = uint64(0)
    25  )
    26  
    27  // do proof of work
    28  func doWork(bh *types.BlockHeader, seed *bc.Hash) bool {
    29  	log.Println("Start from nonce:", lastNonce+1)
    30  	for i := uint64(lastNonce + 1); i <= uint64(lastNonce+consensus.TargetSecondsPerBlock*esHR) && i <= maxNonce; i++ {
    31  		bh.Nonce = i
    32  		// log.Printf("nonce = %v\n", i)
    33  		headerHash := bh.Hash()
    34  		if difficulty.CheckProofOfWork(&headerHash, seed, bh.Bits) {
    35  			log.Printf("Mining succeed! Proof hash: %v\n", headerHash.String())
    36  			return true
    37  		}
    38  	}
    39  	log.Println("Stop at nonce:", bh.Nonce)
    40  	lastNonce = bh.Nonce
    41  	return false
    42  }
    43  
    44  func getBlockHeaderByHeight(height uint64) {
    45  	type Req struct {
    46  		BlockHeight uint64 `json:"block_height"`
    47  	}
    48  
    49  	type Resp struct {
    50  		BlockHeader *types.BlockHeader `json:"block_header"`
    51  		Reward      uint64             `json:"reward"`
    52  	}
    53  
    54  	data, _ := util.ClientCall("/get-block-header", Req{BlockHeight: height})
    55  	rawData, err := json.Marshal(data)
    56  	if err != nil {
    57  		log.Fatalln(err)
    58  	}
    59  
    60  	resp := &Resp{}
    61  	if err = json.Unmarshal(rawData, resp); err != nil {
    62  		log.Fatalln(err)
    63  	}
    64  	log.Println("Reward:", resp.Reward)
    65  }
    66  
    67  func main() {
    68  	for true {
    69  		data, _ := util.ClientCall("/get-work", nil)
    70  		if data == nil {
    71  			os.Exit(1)
    72  		}
    73  		rawData, err := json.Marshal(data)
    74  		if err != nil {
    75  			log.Fatalln(err)
    76  		}
    77  		resp := &api.GetWorkResp{}
    78  		if err = json.Unmarshal(rawData, resp); err != nil {
    79  			log.Fatalln(err)
    80  		}
    81  
    82  		log.Println("Mining at height:", resp.BlockHeader.Height)
    83  		if lastHeight != resp.BlockHeader.Height {
    84  			lastNonce = ^uint64(0)
    85  		}
    86  		if doWork(resp.BlockHeader, resp.Seed) {
    87  			util.ClientCall("/submit-work", &api.SubmitWorkReq{BlockHeader: resp.BlockHeader})
    88  			getBlockHeaderByHeight(resp.BlockHeader.Height)
    89  		}
    90  
    91  		lastHeight = resp.BlockHeader.Height
    92  		if !isCrazy {
    93  			return
    94  		}
    95  	}
    96  }