github.com/hhwill/poc-eth@v0.0.0-20240218063348-3bb107c90dbf/consensus/ethpoc/poc.go (about)

     1  package ethpoc
     2  
     3  import (
     4  	"sync"
     5  	"time"
     6  
     7  	"github.com/ethereum/go-ethereum/accounts"
     8  	"github.com/ethereum/go-ethereum/common"
     9  	"github.com/ethereum/go-ethereum/consensus"
    10  	"github.com/ethereum/go-ethereum/core"
    11  	"github.com/ethereum/go-ethereum/core/types"
    12  	"github.com/ethereum/go-ethereum/rpc"
    13  	"golang.org/x/net/context"
    14  	"github.com/ethereum/go-ethereum/params"
    15  )
    16  
    17  type Mode uint
    18  
    19  const (
    20  	ModeNormal   Mode = iota
    21  	ModeShared
    22  	ModeTest
    23  	ModeFake
    24  	ModeFullFake
    25  )
    26  
    27  // Config are the configuration parameters of the ethPoc.
    28  type Config struct {
    29  	PocMode Mode
    30  }
    31  
    32  // sealTask wraps a seal block with relative result channel for remote sealer thread.
    33  type sealTask struct {
    34  	block   *types.Block
    35  	results chan<- *types.Block
    36  }
    37  
    38  // hashrate wraps the hash rate submitted by the remote sealer.
    39  type hashrate struct {
    40  	//id   common.Hash
    41  	ping time.Time
    42  	rate uint64
    43  
    44  	done chan struct{}
    45  }
    46  
    47  //type sealTask struct {
    48  //	ReqProTime uint64   `json:"reqProTime"`
    49  //	Number     *big.Int `json:"number"`
    50  //	BaseTarget *big.Int `json:"baseTarget"`
    51  //	GenSign    []byte   `json:"genSign"`
    52  //}
    53  
    54  type mineResult struct {
    55  	hash    common.Hash
    56  	nonce   uint64
    57  	plotter uint64
    58  	number  uint64
    59  
    60  	errc chan [2]string
    61  }
    62  
    63  // sealWork wraps a seal work package for remote sealer.
    64  type sealWork struct {
    65  	errc chan error
    66  	res  chan [5]string
    67  }
    68  
    69  // EthPoc is a consensus engine based on proof-of-Capacity implementing the ethpoc
    70  // algorithm.
    71  type EthPoc struct {
    72  	config Config
    73  
    74  	blockChain  *core.BlockChain
    75  	chainConfig *params.ChainConfig
    76  
    77  	am *accounts.Manager
    78  
    79  	// Remote sealer related fields
    80  	threads      int              // Number of threads to mine on if mining
    81  	workCh       chan *sealTask   // Notification channel to push new work and relative result channel to remote sealer
    82  	fetchWorkCh  chan *sealWork   // Channel used for remote sealer to fetch mining work
    83  	submitWorkCh chan *mineResult // Channel used for remote sealer to submit their mining result
    84  	fetchRateCh  chan chan uint64 // Channel used to gather submitted hash rate for local or remote sealer.
    85  	//submitRateCh chan *hashrate   // Channel used for remote sealer to submit their mining hashrate
    86  
    87  	ctx        context.Context
    88  	cancelFunc context.CancelFunc
    89  
    90  	// The fields below are hooks for testing
    91  	//shared    *Ethash       // Shared PoW verifier to avoid cache regeneration
    92  	fakeFail  uint64        // Block number which fails PoW check even in fake mode
    93  	fakeDelay time.Duration // Time delay to sleep for before returning from verify
    94  
    95  	update chan struct{} // Notification channel to update mining parameters
    96  
    97  	lock      sync.Mutex      // Ensures thread safety for the in-memory caches and mining fields
    98  	closeOnce sync.Once       // Ensures exit channel will not be closed twice.
    99  	exitCh    chan chan error // Notification channel to exiting backend threads
   100  }
   101  
   102  // New creates a full sized ethPoc PoW scheme and starts a background thread for
   103  // remote mining, also optionally notifying a batch of remote services of new work
   104  // packages.
   105  func New(chainConfig *params.ChainConfig, am *accounts.Manager, config Config, notify []string, noverify bool) *EthPoc {
   106  	ethPoc := &EthPoc{
   107  		am:           am,
   108  		chainConfig:  chainConfig,
   109  		config:       config,
   110  		workCh:       make(chan *sealTask),
   111  		fetchWorkCh:  make(chan *sealWork),
   112  		submitWorkCh: make(chan *mineResult),
   113  		fetchRateCh:  make(chan chan uint64),
   114  		//submitRateCh: make(chan *hashrate),
   115  		exitCh: make(chan chan error),
   116  	}
   117  
   118  	ethPoc.ctx, ethPoc.cancelFunc = context.WithCancel(context.Background())
   119  
   120  	go ethPoc.remote(notify, noverify)
   121  	return ethPoc
   122  }
   123  
   124  func (ethPoc *EthPoc) SetBlockChain(blockChain *core.BlockChain) {
   125  	ethPoc.blockChain = blockChain
   126  }
   127  
   128  // NewTester creates a small sized ethPoc PoW scheme useful only for testing
   129  // purposes.
   130  func NewTester(notify []string, noverify bool) *EthPoc {
   131  	ethPoc := &EthPoc{
   132  		config:       Config{PocMode: ModeTest},
   133  		workCh:       make(chan *sealTask),
   134  		fetchWorkCh:  make(chan *sealWork),
   135  		submitWorkCh: make(chan *mineResult),
   136  		fetchRateCh:  make(chan chan uint64),
   137  		exitCh:       make(chan chan error),
   138  	}
   139  	go ethPoc.remote(notify, noverify)
   140  	return ethPoc
   141  }
   142  
   143  // NewFaker creates a ethPoc consensus engine with a fake PoW scheme that accepts
   144  // all blocks' seal as valid, though they still have to conform to the Ethereum
   145  // consensus rules.
   146  func NewFaker() *EthPoc {
   147  	return &EthPoc{
   148  		config: Config{
   149  			PocMode: ModeFake,
   150  		},
   151  	}
   152  }
   153  
   154  // NewFakeFailer creates a ethPoc consensus engine with a fake PoW scheme that
   155  // accepts all blocks as valid apart from the single one specified, though they
   156  // still have to conform to the Ethereum consensus rules.
   157  func NewFakeFailer(fail uint64) *EthPoc {
   158  	return &EthPoc{
   159  		config: Config{
   160  			PocMode: ModeFake,
   161  		},
   162  		fakeFail: fail,
   163  	}
   164  }
   165  
   166  // NewFakeDelayer creates a ethPoc consensus engine with a fake PoW scheme that
   167  // accepts all blocks as valid, but delays verifications by some time, though
   168  // they still have to conform to the Ethereum consensus rules.
   169  func NewFakeDelayer(delay time.Duration) *EthPoc {
   170  	return &EthPoc{
   171  		config: Config{
   172  			PocMode: ModeFake,
   173  		},
   174  		fakeDelay: delay,
   175  	}
   176  }
   177  
   178  // NewFullFaker creates an ethPoc consensus engine with a full fake scheme that
   179  // accepts all blocks as valid, without checking any consensus rules whatsoever.
   180  func NewFullFaker() *EthPoc {
   181  	return &EthPoc{
   182  		config: Config{
   183  			PocMode: ModeFullFake,
   184  		},
   185  	}
   186  }
   187  
   188  // Close closes the exit channel to notify all backend threads exiting.
   189  func (ethPoc *EthPoc) Close() error {
   190  	var err error
   191  	ethPoc.closeOnce.Do(func() {
   192  		// Short circuit if the exit channel is not allocated.
   193  		if ethPoc.exitCh == nil {
   194  			return
   195  		}
   196  		errc := make(chan error)
   197  		ethPoc.exitCh <- errc
   198  		err = <-errc
   199  		close(ethPoc.exitCh)
   200  	})
   201  	return err
   202  }
   203  
   204  func (ethPoc *EthPoc) SetThreads(threads int) {
   205  	ethPoc.lock.Lock()
   206  	defer ethPoc.lock.Unlock()
   207  
   208  	// Update the threads and ping any running seal to pull in any changes
   209  	ethPoc.threads = threads
   210  	select {
   211  	case ethPoc.update <- struct{}{}:
   212  	default:
   213  	}
   214  }
   215  
   216  // Hashrate implements PoW, returning the measured rate of the search invocations
   217  // per second over the last minute.
   218  // Note the returned hashrate includes local hashrate, but also includes the total
   219  // hashrate of all remote miner.
   220  //func (ethPoc *EthPoc) Hashrate() float64 {
   221  //	// Short circuit if we are run the ethPoc in normal/test mode.
   222  //	if ethPoc.config.PocMode != ModeNormal && ethPoc.config.PocMode != ModeTest {
   223  //		return ethPoc.hashrate.Rate1()
   224  //	}
   225  //	var res = make(chan uint64, 1)
   226  //
   227  //	select {
   228  //	case ethPoc.fetchRateCh <- res:
   229  //	case <-ethPoc.exitCh:
   230  //		// Return local hashrate only if ethPoc is stopped.
   231  //		return ethPoc.hashrate.Rate1()
   232  //	}
   233  //
   234  //	// Gather total submitted hash rate of remote sealers.
   235  //	return ethPoc.hashrate.Rate1() + float64(<-res)
   236  //}
   237  
   238  // APIs implements consensus.Engine, returning the user facing RPC APIs.
   239  func (ethPoc *EthPoc) APIs(chain consensus.ChainReader) []rpc.API {
   240  	// In order to ensure backward compatibility, we exposes ethPoc RPC APIs
   241  	// to both eth and ethPoc namespaces.
   242  	return []rpc.API{
   243  		{
   244  			Namespace: "eth",
   245  			Version:   "1.0",
   246  			Service:   &API{ethPoc},
   247  			Public:    true,
   248  		},
   249  		{
   250  			Namespace: "ethPoc",
   251  			Version:   "1.0",
   252  			Service:   &API{ethPoc},
   253  			Public:    true,
   254  		},
   255  	}
   256  }
   257  
   258  // SeedHash is the seed to use for generating a verification cache and the mining
   259  // dataset.
   260  //func SeedHash(block uint64) []byte {
   261  //	return seedHash(block)
   262  //}