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

     1  package ethpoc
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"math/big"
     7  	"runtime"
     8  	"time"
     9  
    10  	"encoding/binary"
    11  
    12  	"github.com/ethereum/go-ethereum/common"
    13  	"github.com/ethereum/go-ethereum/common/math"
    14  	"github.com/ethereum/go-ethereum/consensus"
    15  	"github.com/ethereum/go-ethereum/consensus/misc"
    16  	"github.com/ethereum/go-ethereum/core/state"
    17  	"github.com/ethereum/go-ethereum/core/types"
    18  	"github.com/ethereum/go-ethereum/params"
    19  	"github.com/ethereum/go-ethereum/rlp"
    20  	"github.com/moonfruit/go-shabal"
    21  	"golang.org/x/crypto/sha3"
    22  )
    23  
    24  // EthPoc proof-of-work protocol constants.
    25  var (
    26  	FrontierBlockReward              = big.NewInt(5e+18) // Block reward in wei for successfully mining a block
    27  	ByzantiumBlockReward             = big.NewInt(3e+18) // Block reward in wei for successfully mining a block upward from Byzantium
    28  	ConstantinopleBlockReward        = big.NewInt(2e+18) // Block reward in wei for successfully mining a block upward from Constantinople
    29  	maxUncles                        = 2                 // Maximum number of uncles allowed in a single block
    30  	allowedFutureBlockTime           = 15 * time.Second  // Max time from current time allowed for blocks, before they're considered future blocks
    31  	INITIAL_BASE_TARGET       uint64 = 18325193796
    32  	MAX_BASE_TARGET           uint64 = 18325193796
    33  	ADJUST_BLOCK_NUMBER       uint64 = 2700
    34  	BLOCK_INTERVAL            uint64 = 60 * 3
    35  
    36  	HASH_SIZE        = 32
    37  	HASHES_PER_SCOOP = 2
    38  	SCOOP_SIZE       = HASHES_PER_SCOOP * HASH_SIZE
    39  	SCOOPS_PER_PLOT  = 4096 // original 1MB/plot = 16384
    40  	PLOT_SIZE        = SCOOPS_PER_PLOT * SCOOP_SIZE
    41  	HASH_CAP         = 4096
    42  
    43  	YEAR_TIME            uint64 = 60 * 60 * 24 * 365
    44  	EACH_NUMBER_OF_4YEAR        = 4 * YEAR_TIME / BLOCK_INTERVAL
    45  
    46  	// calcDifficultyConstantinople is the difficulty adjustment algorithm for Constantinople.
    47  	// It returns the difficulty that a new block should have when created at time given the
    48  	// parent block's time and difficulty. The calculation uses the Byzantium rules, but with
    49  	// bomb offset 5M.
    50  	// Specification EIP-1234: https://eips.ethereum.org/EIPS/eip-1234
    51  	calcDifficultyConstantinople = makeDifficultyCalculator(big.NewInt(5000000))
    52  
    53  	// calcDifficultyByzantium is the difficulty adjustment algorithm. It returns
    54  	// the difficulty that a new block should have when created at time given the
    55  	// parent block's time and difficulty. The calculation uses the Byzantium rules.
    56  	// Specification EIP-649: https://eips.ethereum.org/EIPS/eip-649
    57  	calcDifficultyByzantium = makeDifficultyCalculator(big.NewInt(3000000))
    58  )
    59  
    60  // Various error messages to mark blocks invalid. These should be private to
    61  // prevent engine specific errors from being referenced in the remainder of the
    62  // codebase, inherently breaking if the engine is swapped out. Please put common
    63  // error types into the consensus package.
    64  var (
    65  	errZeroBlockTime     = errors.New("timestamp equals parent's")
    66  	errTooManyUncles     = errors.New("too many uncles")
    67  	errDuplicateUncle    = errors.New("duplicate uncle")
    68  	errUncleIsAncestor   = errors.New("uncle is ancestor")
    69  	errDanglingUncle     = errors.New("uncle's parent is not ancestor")
    70  	errInvalidDifficulty = errors.New("non-positive difficulty")
    71  	errInvalidMixDigest  = errors.New("invalid mix digest")
    72  	errInvalidPoW        = errors.New("invalid proof-of-work")
    73  )
    74  
    75  // Author implements consensus.Engine, returning the header's coinbase as the
    76  // proof-of-work verified author of the block.
    77  func (ethPoc *EthPoc) Author(header *types.Header) (common.Address, error) {
    78  	return header.Coinbase, nil
    79  }
    80  
    81  // VerifyHeader checks whether a header conforms to the consensus rules of the
    82  // stock Ethereum EthPoc engine.
    83  func (ethPoc *EthPoc) VerifyHeader(chain consensus.ChainReader, header *types.Header, seal bool) error {
    84  	// If we're running a full engine faking, accept any input as valid
    85  	if ethPoc.config.PocMode == ModeFullFake {
    86  		return nil
    87  	}
    88  	// Short circuit if the header is known, or it's parent not
    89  	number := header.Number.Uint64()
    90  	if chain.GetHeader(header.Hash(), number) != nil {
    91  		return nil
    92  	}
    93  	parent := chain.GetHeader(header.ParentHash, number-1)
    94  	if parent == nil {
    95  		return consensus.ErrUnknownAncestor
    96  	}
    97  	// Sanity checks passed, do a proper verification
    98  	return ethPoc.verifyHeader(chain, header, parent, false, seal)
    99  }
   100  
   101  // VerifyHeaders is similar to VerifyHeader, but verifies a batch of headers
   102  // concurrently. The method returns a quit channel to abort the operations and
   103  // a results channel to retrieve the async verifications.
   104  func (ethPoc *EthPoc) VerifyHeaders(chain consensus.ChainReader, headers []*types.Header, seals []bool) (chan<- struct{}, <-chan error) {
   105  	// If we're running a full engine faking, accept any input as valid
   106  	if ethPoc.config.PocMode == ModeFullFake || len(headers) == 0 {
   107  		abort, results := make(chan struct{}), make(chan error, len(headers))
   108  		for i := 0; i < len(headers); i++ {
   109  			results <- nil
   110  		}
   111  		return abort, results
   112  	}
   113  
   114  	// Spawn as many workers as allowed threads
   115  	workers := runtime.GOMAXPROCS(0)
   116  	if len(headers) < workers {
   117  		workers = len(headers)
   118  	}
   119  
   120  	// Create a task channel and spawn the verifiers
   121  	var (
   122  		inputs = make(chan int)
   123  		done   = make(chan int, workers)
   124  		errors = make([]error, len(headers))
   125  		abort  = make(chan struct{})
   126  	)
   127  	for i := 0; i < workers; i++ {
   128  		go func() {
   129  			for index := range inputs {
   130  				errors[index] = ethPoc.verifyHeaderWorker(chain, headers, seals, index)
   131  				done <- index
   132  			}
   133  		}()
   134  	}
   135  
   136  	errorsOut := make(chan error, len(headers))
   137  	go func() {
   138  		defer close(inputs)
   139  		var (
   140  			in, out = 0, 0
   141  			checked = make([]bool, len(headers))
   142  			inputs  = inputs
   143  		)
   144  		for {
   145  			select {
   146  			case inputs <- in:
   147  				if in++; in == len(headers) {
   148  					// Reached end of headers. Stop sending to workers.
   149  					inputs = nil
   150  				}
   151  			case index := <-done:
   152  				for checked[index] = true; checked[out]; out++ {
   153  					errorsOut <- errors[out]
   154  					if out == len(headers)-1 {
   155  						return
   156  					}
   157  				}
   158  			case <-abort:
   159  				return
   160  			}
   161  		}
   162  	}()
   163  	return abort, errorsOut
   164  }
   165  
   166  func (ethPoc *EthPoc) verifyHeaderWorker(chain consensus.ChainReader, headers []*types.Header, seals []bool, index int) error {
   167  	var parent *types.Header
   168  	if index == 0 {
   169  		parent = chain.GetHeader(headers[0].ParentHash, headers[0].Number.Uint64()-1)
   170  	} else if headers[index-1].Hash() == headers[index].ParentHash {
   171  		parent = headers[index-1]
   172  	}
   173  	if parent == nil {
   174  		return consensus.ErrUnknownAncestor
   175  	}
   176  	if chain.GetHeader(headers[index].Hash(), headers[index].Number.Uint64()) != nil {
   177  		return nil // known block
   178  	}
   179  	return ethPoc.verifyHeader(chain, headers[index], parent, false, seals[index])
   180  }
   181  
   182  // VerifyUncles verifies that the given block's uncles conform to the consensus
   183  // rules of the stock Ethereum EthPoc engine.
   184  func (ethPoc *EthPoc) VerifyUncles(chain consensus.ChainReader, block *types.Block) error {
   185  
   186  	if len(block.Uncles()) > 0 {
   187  		return errTooManyUncles
   188  	}
   189  	return nil
   190  }
   191  
   192  // verifyHeader checks whether a header conforms to the consensus rules of the
   193  // stock Ethereum EthPoc engine.
   194  // See YP section 4.3.4. "Block Header Validity"
   195  func (ethPoc *EthPoc) verifyHeader(chain consensus.ChainReader, header, parent *types.Header, uncle bool, seal bool) error {
   196  	// Ensure that the header's extra-data section is of a reasonable size
   197  	if uint64(len(header.Extra)) > params.MaximumExtraDataSize {
   198  		return fmt.Errorf("extra-data too long: %d > %d", len(header.Extra), params.MaximumExtraDataSize)
   199  	}
   200  	// Verify the header's timestamp
   201  	if !uncle {
   202  		if header.Time > uint64(time.Now().Add(allowedFutureBlockTime).Unix()) {
   203  			return consensus.ErrFutureBlock
   204  		}
   205  	}
   206  	if header.Time <= parent.Time {
   207  		return errZeroBlockTime
   208  	}
   209  	// Verify the block's difficulty based in it's timestamp and parent's difficulty
   210  	expected := ethPoc.CalcDifficulty(chain, header.Time, parent)
   211  
   212  	if expected.Cmp(header.Difficulty) != 0 {
   213  		return fmt.Errorf("invalid difficulty: have %v, want %v", header.Difficulty, expected)
   214  	}
   215  	// Verify that the gas limit is <= 2^63-1
   216  	cap := uint64(0x7fffffffffffffff)
   217  	if header.GasLimit > cap {
   218  		return fmt.Errorf("invalid gasLimit: have %v, max %v", header.GasLimit, cap)
   219  	}
   220  	// Verify that the gasUsed is <= gasLimit
   221  	if header.GasUsed > header.GasLimit {
   222  		return fmt.Errorf("invalid gasUsed: have %d, gasLimit %d", header.GasUsed, header.GasLimit)
   223  	}
   224  
   225  	// Verify that the gas limit remains within allowed bounds
   226  	diff := int64(parent.GasLimit) - int64(header.GasLimit)
   227  	if diff < 0 {
   228  		diff *= -1
   229  	}
   230  	limit := parent.GasLimit / params.GasLimitBoundDivisor
   231  
   232  	if uint64(diff) >= limit || header.GasLimit < params.MinGasLimit {
   233  		return fmt.Errorf("invalid gas limit: have %d, want %d += %d", header.GasLimit, parent.GasLimit, limit)
   234  	}
   235  	// Verify that the block number is parent's +1
   236  	if diff := new(big.Int).Sub(header.Number, parent.Number); diff.Cmp(big.NewInt(1)) != 0 {
   237  		return consensus.ErrInvalidNumber
   238  	}
   239  	// Verify the engine specific seal securing the block
   240  	if seal {
   241  		if err := ethPoc.VerifySeal(chain, header); err != nil {
   242  			return err
   243  		}
   244  	}
   245  	// If all checks passed, validate any special fields for hard forks
   246  	if err := misc.VerifyDAOHeaderExtraData(chain.Config(), header); err != nil {
   247  		return err
   248  	}
   249  	if err := misc.VerifyForkHashes(chain.Config(), header, uncle); err != nil {
   250  		return err
   251  	}
   252  	return nil
   253  }
   254  
   255  // CalcDifficulty is the difficulty adjustment algorithm. It returns
   256  // the difficulty that a new block should have when created at time
   257  // given the parent block's time and difficulty.
   258  func (ethPoc *EthPoc) CalcDifficulty(chain consensus.ChainReader, time uint64, parent *types.Header) *big.Int {
   259  	return CalcDifficulty(chain, chain.Config(), time, parent)
   260  }
   261  
   262  // CalcDifficulty is the difficulty adjustment algorithm. It returns
   263  // the difficulty that a new block should have when created at time
   264  // given the parent block's time and difficulty.
   265  func CalcDifficulty(chain consensus.ChainReader, config *params.ChainConfig, time uint64, parent *types.Header) *big.Int {
   266  	next := new(big.Int).Add(parent.Number, big1)
   267  	switch {
   268  	case config.IsConstantinople(next):
   269  		return calcDifficultyConstantinople(time, parent)
   270  	case config.IsByzantium(next):
   271  		return calcDifficultyByzantium(time, parent)
   272  	case config.IsHomestead(next):
   273  		return calcDifficultyHomestead(time, parent)
   274  	default:
   275  		return calcBaseTarget(chain, time, parent)
   276  	}
   277  }
   278  
   279  // Some weird constants to avoid constant memory allocs for them.
   280  var (
   281  	expDiffPeriod = big.NewInt(100000)
   282  	big1          = big.NewInt(1)
   283  	big2          = big.NewInt(2)
   284  	big9          = big.NewInt(9)
   285  	big10         = big.NewInt(10)
   286  	bigMinus99    = big.NewInt(-99)
   287  )
   288  
   289  // makeDifficultyCalculator creates a difficultyCalculator with the given bomb-delay.
   290  // the difficulty is calculated with Byzantium rules, which differs from Homestead in
   291  // how uncles affect the calculation
   292  func makeDifficultyCalculator(bombDelay *big.Int) func(time uint64, parent *types.Header) *big.Int {
   293  	// Note, the calculations below looks at the parent number, which is 1 below
   294  	// the block number. Thus we remove one from the delay given
   295  	bombDelayFromParent := new(big.Int).Sub(bombDelay, big1)
   296  	return func(time uint64, parent *types.Header) *big.Int {
   297  		// https://github.com/ethereum/EIPs/issues/100.
   298  		// algorithm:
   299  		// diff = (parent_diff +
   300  		//         (parent_diff / 2048 * max((2 if len(parent.uncles) else 1) - ((timestamp - parent.timestamp) // 9), -99))
   301  		//        ) + 2^(periodCount - 2)
   302  
   303  		bigTime := new(big.Int).SetUint64(time)
   304  		bigParentTime := new(big.Int).SetUint64(parent.Time)
   305  
   306  		// holds intermediate values to make the algo easier to read & audit
   307  		x := new(big.Int)
   308  		y := new(big.Int)
   309  
   310  		// (2 if len(parent_uncles) else 1) - (block_timestamp - parent_timestamp) // 9
   311  		x.Sub(bigTime, bigParentTime)
   312  		x.Div(x, big9)
   313  		if parent.UncleHash == types.EmptyUncleHash {
   314  			x.Sub(big1, x)
   315  		} else {
   316  			x.Sub(big2, x)
   317  		}
   318  		// max((2 if len(parent_uncles) else 1) - (block_timestamp - parent_timestamp) // 9, -99)
   319  		if x.Cmp(bigMinus99) < 0 {
   320  			x.Set(bigMinus99)
   321  		}
   322  		// parent_diff + (parent_diff / 2048 * max((2 if len(parent.uncles) else 1) - ((timestamp - parent.timestamp) // 9), -99))
   323  		y.Div(parent.Difficulty, params.DifficultyBoundDivisor)
   324  		x.Mul(y, x)
   325  		x.Add(parent.Difficulty, x)
   326  
   327  		// minimum difficulty can ever be (before exponential factor)
   328  		if x.Cmp(params.MinimumDifficulty) < 0 {
   329  			x.Set(params.MinimumDifficulty)
   330  		}
   331  		// calculate a fake block number for the ice-age delay
   332  		// Specification: https://eips.ethereum.org/EIPS/eip-1234
   333  		fakeBlockNumber := new(big.Int)
   334  		if parent.Number.Cmp(bombDelayFromParent) >= 0 {
   335  			fakeBlockNumber = fakeBlockNumber.Sub(parent.Number, bombDelayFromParent)
   336  		}
   337  		// for the exponential factor
   338  		periodCount := fakeBlockNumber
   339  		periodCount.Div(periodCount, expDiffPeriod)
   340  
   341  		// the exponential factor, commonly referred to as "the bomb"
   342  		// diff = diff + 2^(periodCount - 2)
   343  		if periodCount.Cmp(big1) > 0 {
   344  			y.Sub(periodCount, big2)
   345  			y.Exp(big2, y, nil)
   346  			x.Add(x, y)
   347  		}
   348  		return x
   349  	}
   350  }
   351  
   352  // calcDifficultyHomestead is the difficulty adjustment algorithm. It returns
   353  // the difficulty that a new block should have when created at time given the
   354  // parent block's time and difficulty. The calculation uses the Homestead rules.
   355  func calcDifficultyHomestead(time uint64, parent *types.Header) *big.Int {
   356  	// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2.md
   357  	// algorithm:
   358  	// diff = (parent_diff +
   359  	//         (parent_diff / 2048 * max(1 - (block_timestamp - parent_timestamp) // 10, -99))
   360  	//        ) + 2^(periodCount - 2)
   361  
   362  	bigTime := new(big.Int).SetUint64(time)
   363  	bigParentTime := new(big.Int).SetUint64(parent.Time)
   364  
   365  	// holds intermediate values to make the algo easier to read & audit
   366  	x := new(big.Int)
   367  	y := new(big.Int)
   368  
   369  	// 1 - (block_timestamp - parent_timestamp) // 10
   370  	x.Sub(bigTime, bigParentTime)
   371  	x.Div(x, big10)
   372  	x.Sub(big1, x)
   373  
   374  	// max(1 - (block_timestamp - parent_timestamp) // 10, -99)
   375  	if x.Cmp(bigMinus99) < 0 {
   376  		x.Set(bigMinus99)
   377  	}
   378  	// (parent_diff + parent_diff // 2048 * max(1 - (block_timestamp - parent_timestamp) // 10, -99))
   379  	y.Div(parent.Difficulty, params.DifficultyBoundDivisor)
   380  	x.Mul(y, x)
   381  	x.Add(parent.Difficulty, x)
   382  
   383  	// minimum difficulty can ever be (before exponential factor)
   384  	if x.Cmp(params.MinimumDifficulty) < 0 {
   385  		x.Set(params.MinimumDifficulty)
   386  	}
   387  	// for the exponential factor
   388  	periodCount := new(big.Int).Add(parent.Number, big1)
   389  	periodCount.Div(periodCount, expDiffPeriod)
   390  
   391  	// the exponential factor, commonly referred to as "the bomb"
   392  	// diff = diff + 2^(periodCount - 2)
   393  	if periodCount.Cmp(big1) > 0 {
   394  		y.Sub(periodCount, big2)
   395  		y.Exp(big2, y, nil)
   396  		x.Add(x, y)
   397  	}
   398  	return x
   399  }
   400  
   401  // calcDifficultyFrontier is the difficulty adjustment algorithm. It returns the
   402  // difficulty that a new block should have when created at time given the parent
   403  // block's time and difficulty. The calculation uses the Frontier rules.
   404  func calcDifficultyFrontier(time uint64, parent *types.Header) *big.Int {
   405  	diff := new(big.Int)
   406  	adjust := new(big.Int).Div(parent.Difficulty, params.DifficultyBoundDivisor)
   407  	bigTime := new(big.Int)
   408  	bigParentTime := new(big.Int)
   409  
   410  	bigTime.SetUint64(time)
   411  	bigParentTime.SetUint64(parent.Time)
   412  
   413  	if bigTime.Sub(bigTime, bigParentTime).Cmp(params.DurationLimit) < 0 {
   414  		diff.Add(parent.Difficulty, adjust)
   415  	} else {
   416  		diff.Sub(parent.Difficulty, adjust)
   417  	}
   418  	if diff.Cmp(params.MinimumDifficulty) < 0 {
   419  		diff.Set(params.MinimumDifficulty)
   420  	}
   421  
   422  	periodCount := new(big.Int).Add(parent.Number, big1)
   423  	periodCount.Div(periodCount, expDiffPeriod)
   424  	if periodCount.Cmp(big1) > 0 {
   425  		// diff = diff + 2^(periodCount - 2)
   426  		expDiff := periodCount.Sub(periodCount, big2)
   427  		expDiff.Exp(big2, expDiff, nil)
   428  		diff.Add(diff, expDiff)
   429  		diff = math.BigMax(diff, params.MinimumDifficulty)
   430  	}
   431  	return diff
   432  }
   433  
   434  func calcBaseTarget(chain consensus.ChainReader, time uint64, parent *types.Header) *big.Int {
   435  	number := parent.Number.Uint64()
   436  	if number < 4 {
   437  		return new(big.Int).SetUint64(INITIAL_BASE_TARGET)
   438  	} else if number < ADJUST_BLOCK_NUMBER {
   439  		avgBaseTaget := new(big.Int).Set(parent.Difficulty)
   440  		var header *types.Header
   441  		for i := 1; i < 4; i++ {
   442  			header = chain.GetHeaderByNumber(number - uint64(i))
   443  			avgBaseTaget = new(big.Int).Add(avgBaseTaget, header.Difficulty)
   444  		}
   445  		avgBaseTaget = new(big.Int).Div(avgBaseTaget, big.NewInt(4))
   446  		durTime := parent.Time - header.Time
   447  		newTarget := new(big.Int).Div(new(big.Int).Mul(avgBaseTaget, new(big.Int).SetUint64(durTime)), new(big.Int).SetUint64(BLOCK_INTERVAL*4)).Uint64()
   448  		hisTaget := avgBaseTaget.Uint64()
   449  		if newTarget > MAX_BASE_TARGET {
   450  			newTarget = MAX_BASE_TARGET
   451  		}
   452  		if newTarget < hisTaget*9/10 {
   453  			newTarget = hisTaget * 9 / 10
   454  		}
   455  		if newTarget == 0 {
   456  			newTarget = 1
   457  		}
   458  
   459  		if newTarget > hisTaget*11/10 {
   460  			newTarget = hisTaget * 11 / 10
   461  		}
   462  		if newTarget > MAX_BASE_TARGET {
   463  			newTarget = MAX_BASE_TARGET
   464  		}
   465  		fmt.Printf("New target diffculty %d\n", newTarget)
   466  		return new(big.Int).SetUint64(newTarget)
   467  
   468  	} else {
   469  		avgBaseTaget := new(big.Int).Set(parent.Difficulty)
   470  		var header *types.Header
   471  		for i := 1; i < 24; i++ {
   472  			header = chain.GetHeaderByNumber(number - uint64(i))
   473  			avgBaseTaget = new(big.Int).Add(avgBaseTaget, header.Difficulty)
   474  		}
   475  		avgBaseTaget = new(big.Int).Div(avgBaseTaget, big.NewInt(24))
   476  		durTime := parent.Time - header.Time
   477  		newTarget := new(big.Int).Div(new(big.Int).Mul(avgBaseTaget, new(big.Int).SetUint64(durTime)), new(big.Int).SetUint64(BLOCK_INTERVAL*24)).Uint64()
   478  
   479  		hisTaget := avgBaseTaget.Uint64()
   480  		if newTarget > MAX_BASE_TARGET {
   481  			newTarget = MAX_BASE_TARGET
   482  		}
   483  
   484  		if newTarget < hisTaget*8/10 {
   485  			newTarget = hisTaget * 8 / 10
   486  		}
   487  		if newTarget == 0 {
   488  			newTarget = 1
   489  		}
   490  
   491  		if newTarget > hisTaget*12/10 {
   492  			newTarget = hisTaget * 12 / 10
   493  		}
   494  		if newTarget > MAX_BASE_TARGET {
   495  			newTarget = MAX_BASE_TARGET
   496  		}
   497  		fmt.Printf("New target diffculty %d\n", newTarget)
   498  		return new(big.Int).SetUint64(newTarget)
   499  	}
   500  
   501  }
   502  
   503  // VerifySeal implements consensus.Engine, checking whether the given block satisfies
   504  // the PoW difficulty requirements.
   505  func (ethPoc *EthPoc) VerifySeal(chain consensus.ChainReader, header *types.Header) error {
   506  	number := header.Number.Uint64()
   507  	parent := chain.GetHeader(header.ParentHash, number-1)
   508  	if parent == nil {
   509  		return consensus.ErrUnknownAncestor
   510  	}
   511  
   512  	genSign := header.MixDigest.Bytes()
   513  	scoop := int(calculateScoop(genSign, number))
   514  	deadLine := calculateDeadline(header.PlotterID, header.Nonce, scoop, genSign, header.Difficulty)
   515  	return ethPoc.verifySeal(chain, parent.Time, deadLine, header, false)
   516  }
   517  
   518  // verifySeal checks whether a block satisfies the PoW difficulty requirements,
   519  // either using the usual EthPoc cache for it, or alternatively using a full DAG
   520  // to make remote mining fast.
   521  func (ethPoc *EthPoc) verifySeal(chain consensus.ChainReader, pTime uint64, deadLine *big.Int, header *types.Header, fulldag bool) error {
   522  
   523  	if header.Time > deadLine.Uint64()+pTime {
   524  		return nil
   525  	}
   526  	//return nil
   527  
   528  	//TODO:checkout nonce
   529  	return errors.New("DeadLine error")
   530  }
   531  
   532  func calculateDeadline(plotter uint64, nonce types.BlockNonce, scoop int, newGenSig []byte, baseTarget *big.Int) *big.Int {
   533  	hit := calculateHit(plotter, nonce, scoop, newGenSig)
   534  	return new(big.Int).Div(hit, baseTarget)
   535  }
   536  
   537  func calculateGenSign(lastGenSig []byte, lastGenId uint64) []byte {
   538  	baseBuf := make([]byte, HASH_SIZE+8)
   539  	copy(baseBuf[0:HASH_SIZE], lastGenSig)
   540  	binary.BigEndian.PutUint64(baseBuf[HASH_SIZE:HASH_SIZE+8], lastGenId)
   541  
   542  	sl := shabal.NewShabal256()
   543  	sl.Write(baseBuf)
   544  	return sl.Sum(nil)
   545  }
   546  
   547  func calculateScoop(genSig []byte, number uint64) int64 {
   548  	baseBuf := make([]byte, HASH_SIZE+8)
   549  	copy(baseBuf[0:HASH_SIZE], genSig)
   550  	binary.BigEndian.PutUint64(baseBuf[HASH_SIZE:], number)
   551  
   552  	sl := shabal.NewShabal256()
   553  	sl.Write(baseBuf)
   554  	hash := sl.Sum(nil)
   555  
   556  	return new(big.Int).Mod(new(big.Int).SetBytes(hash), big.NewInt(int64(SCOOPS_PER_PLOT))).Int64()
   557  }
   558  
   559  func calculateHit(plotter uint64, nonce types.BlockNonce, scoop int, newGenSig []byte) *big.Int {
   560  	data := miningPlot(plotter, nonce)
   561  	sl := shabal.NewShabal256()
   562  	sl.Write(newGenSig)
   563  	sl.Write(data[scoop*SCOOP_SIZE : scoop*SCOOP_SIZE+SCOOP_SIZE])
   564  	hash := sl.Sum(nil)
   565  
   566  	b := make([]byte, 8)
   567  	for i := 0; i < 8; i++ {
   568  		copy(b[i:], hash[7-i:7-i+1])
   569  	}
   570  
   571  	return new(big.Int).SetBytes(b)
   572  }
   573  
   574  func miningPlot(plotter uint64, nonce types.BlockNonce) []byte {
   575  	baseBuf := make([]byte, 16)
   576  	binary.BigEndian.PutUint64(baseBuf[0:8], plotter)
   577  	binary.BigEndian.PutUint64(baseBuf[8:16], nonce.Uint64())
   578  
   579  	sl := shabal.NewShabal256()
   580  
   581  	plotBuf := make([]byte, PLOT_SIZE+len(baseBuf))
   582  	copy(plotBuf[PLOT_SIZE:], baseBuf[0:])
   583  	for i := PLOT_SIZE; i > 0; i -= HASH_SIZE {
   584  		index := PLOT_SIZE + len(baseBuf) - i
   585  		if index > HASH_CAP {
   586  			index = HASH_CAP
   587  		}
   588  		sl.Write(plotBuf[i : i+index])
   589  		copy(plotBuf[i-HASH_SIZE:i], sl.Sum(nil))
   590  	}
   591  
   592  	sl.Write(plotBuf)
   593  	finalHash := sl.Sum(nil)
   594  
   595  	data := make([]byte, PLOT_SIZE)
   596  	for i := 0; i < PLOT_SIZE; i++ {
   597  		data[i] = (byte)(plotBuf[i] ^ finalHash[i%HASH_SIZE])
   598  	}
   599  
   600  	hashBuffer := make([]byte, HASH_SIZE)
   601  	revPos := PLOT_SIZE - HASH_SIZE
   602  	for pos := 32; pos < (PLOT_SIZE / 2); pos += 64 {
   603  		copy(hashBuffer, data[pos:pos+HASH_SIZE])
   604  		copy(data[pos:pos+HASH_SIZE], data[revPos:revPos+HASH_SIZE])
   605  		copy(data[revPos:revPos+HASH_SIZE], hashBuffer[0:HASH_SIZE])
   606  		revPos -= 64 //move backwards
   607  	}
   608  	return data
   609  }
   610  
   611  // Prepare implements consensus.Engine, initializing the difficulty field of a
   612  // header to conform to the EthPoc protocol. The changes are done inline.
   613  func (ethPoc *EthPoc) Prepare(chain consensus.ChainReader, header *types.Header) error {
   614  	parent := chain.GetHeader(header.ParentHash, header.Number.Uint64()-1)
   615  	if parent == nil {
   616  		return consensus.ErrUnknownAncestor
   617  	}
   618  
   619  	hash := calculateGenSign(parent.MixDigest.Bytes(), header.PlotterID)
   620  	header.MixDigest = common.BytesToHash(hash)
   621  	header.Difficulty = ethPoc.CalcDifficulty(chain, header.Time, parent)
   622  	return nil
   623  }
   624  
   625  // Finalize implements consensus.Engine, accumulating the block and uncle rewards,
   626  // setting the final state and assembling the block.
   627  func (ethPoc *EthPoc) Finalize(chain consensus.ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header) {
   628  	// Accumulate any block and uncle rewards and commit the final state root
   629  	accumulateRewards(chain.Config(), state, header, uncles)
   630  	header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number))
   631  }
   632  
   633  
   634  // Finalize implements consensus.Engine, accumulating the block and uncle rewards,
   635  // setting the final state and assembling the block.
   636  func (ethPoc *EthPoc) FinalizeAndAssemble(chain consensus.ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) {
   637  	// Accumulate any block and uncle rewards and commit the final state root
   638  	accumulateRewards(chain.Config(), state, header, uncles)
   639  	header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number))
   640  
   641  	// Header seems complete, assemble into a block and return
   642  	return types.NewBlock(header, txs, uncles, receipts), nil
   643  }
   644  
   645  
   646  // SealHash returns the hash of a block prior to it being sealed.
   647  func (ethPoc *EthPoc) SealHash(header *types.Header) (hash common.Hash) {
   648  	hasher := sha3.NewLegacyKeccak256()
   649  
   650  	rlp.Encode(hasher, []interface{}{
   651  		header.ParentHash,
   652  		header.UncleHash,
   653  		header.Coinbase,
   654  		header.Root,
   655  		header.TxHash,
   656  		header.ReceiptHash,
   657  		header.Bloom,
   658  		header.Difficulty,
   659  		header.Number,
   660  		header.GasLimit,
   661  		header.GasUsed,
   662  		header.Extra,
   663  	})
   664  	hasher.Sum(hash[:0])
   665  	return hash
   666  }
   667  
   668  // Some weird constants to avoid constant memory allocs for them.
   669  var (
   670  	big8  = big.NewInt(8)
   671  	big32 = big.NewInt(32)
   672  )
   673  
   674  // AccumulateRewards credits the coinbase of the given block with the mining
   675  // reward. The total reward consists of the static block reward and rewards for
   676  // included uncles. The coinbase of each uncle block is also rewarded.
   677  func accumulateRewards(config *params.ChainConfig, state *state.StateDB, header *types.Header, uncles []*types.Header) {
   678  	//TODO:change reward
   679  	if len(uncles) > 0 {
   680  		return
   681  	}
   682  	// Select the correct block reward based on chain progression
   683  	initReward := FrontierBlockReward
   684  	rewardYears := new(big.Int).Div(header.Number, new(big.Int).SetUint64(EACH_NUMBER_OF_4YEAR))
   685  
   686  	if rewardYears.Uint64() > 33 {
   687  		return
   688  	}
   689  	blockReward := new(big.Int).Div(initReward, new(big.Int).Exp(big.NewInt(2), rewardYears, big.NewInt(0)))
   690  	state.AddBalance(header.Coinbase, blockReward)
   691  }