github.com/aigarnetwork/aigar@v0.0.0-20191115204914-d59a6eb70f8e/consensus/ethash/api.go (about)

     1  //  Copyright 2018 The go-ethereum Authors
     2  //  Copyright 2019 The go-aigar Authors
     3  //  This file is part of the go-aigar library.
     4  //
     5  //  The go-aigar library is free software: you can redistribute it and/or modify
     6  //  it under the terms of the GNU Lesser General Public License as published by
     7  //  the Free Software Foundation, either version 3 of the License, or
     8  //  (at your option) any later version.
     9  //
    10  //  The go-aigar library is distributed in the hope that it will be useful,
    11  //  but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    13  //  GNU Lesser General Public License for more details.
    14  //
    15  //  You should have received a copy of the GNU Lesser General Public License
    16  //  along with the go-aigar library. If not, see <http://www.gnu.org/licenses/>.
    17  
    18  package ethash
    19  
    20  import (
    21  	"errors"
    22  
    23  	"github.com/AigarNetwork/aigar/common"
    24  	"github.com/AigarNetwork/aigar/common/hexutil"
    25  	"github.com/AigarNetwork/aigar/core/types"
    26  )
    27  
    28  var errEthashStopped = errors.New("ethash stopped")
    29  
    30  // API exposes ethash related methods for the RPC interface.
    31  type API struct {
    32  	ethash *Ethash // Make sure the mode of ethash is normal.
    33  }
    34  
    35  // GetWork returns a work package for external miner.
    36  //
    37  // The work package consists of 3 strings:
    38  //   result[0] - 32 bytes hex encoded current block header pow-hash
    39  //   result[1] - 32 bytes hex encoded seed hash used for DAG
    40  //   result[2] - 32 bytes hex encoded boundary condition ("target"), 2^256/difficulty
    41  //   result[3] - hex encoded block number
    42  func (api *API) GetWork() ([4]string, error) {
    43  	if api.ethash.config.PowMode != ModeNormal && api.ethash.config.PowMode != ModeTest {
    44  		return [4]string{}, errors.New("not supported")
    45  	}
    46  
    47  	var (
    48  		workCh = make(chan [4]string, 1)
    49  		errc   = make(chan error, 1)
    50  	)
    51  
    52  	select {
    53  	case api.ethash.fetchWorkCh <- &sealWork{errc: errc, res: workCh}:
    54  	case <-api.ethash.exitCh:
    55  		return [4]string{}, errEthashStopped
    56  	}
    57  
    58  	select {
    59  	case work := <-workCh:
    60  		return work, nil
    61  	case err := <-errc:
    62  		return [4]string{}, err
    63  	}
    64  }
    65  
    66  // SubmitWork can be used by external miner to submit their POW solution.
    67  // It returns an indication if the work was accepted.
    68  // Note either an invalid solution, a stale work a non-existent work will return false.
    69  func (api *API) SubmitWork(nonce types.BlockNonce, hash, digest common.Hash) bool {
    70  	if api.ethash.config.PowMode != ModeNormal && api.ethash.config.PowMode != ModeTest {
    71  		return false
    72  	}
    73  
    74  	var errc = make(chan error, 1)
    75  
    76  	select {
    77  	case api.ethash.submitWorkCh <- &mineResult{
    78  		nonce:     nonce,
    79  		mixDigest: digest,
    80  		hash:      hash,
    81  		errc:      errc,
    82  	}:
    83  	case <-api.ethash.exitCh:
    84  		return false
    85  	}
    86  
    87  	err := <-errc
    88  	return err == nil
    89  }
    90  
    91  // SubmitHashrate can be used for remote miners to submit their hash rate.
    92  // This enables the node to report the combined hash rate of all miners
    93  // which submit work through this node.
    94  //
    95  // It accepts the miner hash rate and an identifier which must be unique
    96  // between nodes.
    97  func (api *API) SubmitHashRate(rate hexutil.Uint64, id common.Hash) bool {
    98  	if api.ethash.config.PowMode != ModeNormal && api.ethash.config.PowMode != ModeTest {
    99  		return false
   100  	}
   101  
   102  	var done = make(chan struct{}, 1)
   103  
   104  	select {
   105  	case api.ethash.submitRateCh <- &hashrate{done: done, rate: uint64(rate), id: id}:
   106  	case <-api.ethash.exitCh:
   107  		return false
   108  	}
   109  
   110  	// Block until hash rate submitted successfully.
   111  	<-done
   112  
   113  	return true
   114  }
   115  
   116  // GetHashrate returns the current hashrate for local CPU miner and remote miner.
   117  func (api *API) GetHashrate() uint64 {
   118  	return uint64(api.ethash.Hashrate())
   119  }