github.com/waltonchain/waltonchain_gwtc_src@v1.1.4-0.20201225072101-8a298c95a819/consensus/ethash/consensus.go (about)

     1  // Copyright 2017 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-wtc library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-wtc library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package ethash
    18  
    19  import (
    20  	// "encoding/binary"
    21  	"bytes"
    22  	"crypto/sha256"
    23  	"errors"
    24  	"fmt"
    25  	"math/big"
    26  	"runtime"
    27  	"time"
    28  
    29  	"github.com/wtc/go-wtc/common"
    30  	"github.com/wtc/go-wtc/common/math"
    31  	"github.com/wtc/go-wtc/consensus"
    32  	"github.com/wtc/go-wtc/consensus/misc"
    33  	"github.com/wtc/go-wtc/core/state"
    34  	"github.com/wtc/go-wtc/core/types"
    35  	"github.com/wtc/go-wtc/params"
    36  	set "gopkg.in/fatih/set.v0"
    37  )
    38  
    39  // Ethash proof-of-work protocol constants.
    40  var (
    41  	frontierBlockReward  *big.Int = big.NewInt(5e+18) // Block reward in wei for successfully mining a block
    42  	byzantiumBlockReward *big.Int = big.NewInt(3e+18) // Block reward in wei for successfully mining a block upward from Byzantium
    43  	maxUncles                     = 2                 // Maximum number of uncles allowed in a single block
    44  )
    45  
    46  // Various error messages to mark blocks invalid. These should be private to
    47  // prevent engine specific errors from being referenced in the remainder of the
    48  // codebase, inherently breaking if the engine is swapped out. Please put common
    49  // error types into the consensus package.
    50  var (
    51  	errLargeBlockTime    = errors.New("timestamp too big")
    52  	errZeroBlockTime     = errors.New("timestamp equals parent's")
    53  	errTooManyUncles     = errors.New("too many uncles")
    54  	errDuplicateUncle    = errors.New("duplicate uncle")
    55  	errUncleIsAncestor   = errors.New("uncle is ancestor")
    56  	errDanglingUncle     = errors.New("uncle's parent is not ancestor")
    57  	errNonceOutOfRange   = errors.New("nonce out of range")
    58  	errInvalidDifficulty = errors.New("non-positive difficulty")
    59  	errInvalidMixDigest  = errors.New("invalid mix digest")
    60  	errInvalidPoW        = errors.New("invalid proof-of-work")
    61  )
    62  
    63  // Author implements consensus.Engine, returning the header's coinbase as the
    64  // proof-of-work verified author of the block.
    65  func (ethash *Ethash) Author(header *types.Header) (common.Address, error) {
    66  	return header.Coinbase, nil
    67  }
    68  
    69  // VerifyHeader checks whether a header conforms to the consensus rules of the
    70  // WTC consensus engine.
    71  func (ethash *Ethash) VerifyHeader(chain consensus.ChainReader, header *types.Header, seal bool) error {
    72  	// If we're running a full engine faking, accept any input as valid
    73  	if ethash.fakeFull {
    74  		return nil
    75  	}
    76  	// Short circuit if the header is known, or it's parent not
    77  	number := header.Number.Uint64()
    78  	if chain.GetHeader(header.Hash(), number) != nil {
    79  		return nil
    80  	}
    81  	parent := chain.GetHeader(header.ParentHash, number-1)
    82  	if parent == nil {
    83  		return consensus.ErrUnknownAncestor
    84  	}
    85  	// Sanity checks passed, do a proper verification
    86  	return ethash.verifyHeader(chain, header, parent, false, seal)
    87  }
    88  
    89  // VerifyHeaders is similar to VerifyHeader, but verifies a batch of headers
    90  // concurrently. The method returns a quit channel to abort the operations and
    91  // a results channel to retrieve the async verifications.
    92  func (ethash *Ethash) VerifyHeaders(chain consensus.ChainReader, headers []*types.Header, seals []bool) (chan<- struct{}, <-chan error) {
    93  	// If we're running a full engine faking, accept any input as valid
    94  	if ethash.fakeFull || len(headers) == 0 {
    95  		abort, results := make(chan struct{}), make(chan error, len(headers))
    96  		for i := 0; i < len(headers); i++ {
    97  			results <- nil
    98  		}
    99  		return abort, results
   100  	}
   101  
   102  	// Spawn as many workers as allowed threads
   103  	workers := runtime.GOMAXPROCS(0)
   104  	if len(headers) < workers {
   105  		workers = len(headers)
   106  	}
   107  
   108  	// Create a task channel and spawn the verifiers
   109  	var (
   110  		inputs = make(chan int)
   111  		done   = make(chan int, workers)
   112  		errors = make([]error, len(headers))
   113  		abort  = make(chan struct{})
   114  	)
   115  	for i := 0; i < workers; i++ {
   116  		go func() {
   117  			for index := range inputs {
   118  				errors[index] = ethash.verifyHeaderWorker(chain, headers, seals, index)
   119  				done <- index
   120  			}
   121  		}()
   122  	}
   123  
   124  	errorsOut := make(chan error, len(headers))
   125  	go func() {
   126  		defer close(inputs)
   127  		var (
   128  			in, out = 0, 0
   129  			checked = make([]bool, len(headers))
   130  			inputs  = inputs
   131  		)
   132  		for {
   133  			select {
   134  			case inputs <- in:
   135  				if in++; in == len(headers) {
   136  					// Reached end of headers. Stop sending to workers.
   137  					inputs = nil
   138  				}
   139  			case index := <-done:
   140  				for checked[index] = true; checked[out]; out++ {
   141  					errorsOut <- errors[out]
   142  					if out == len(headers)-1 {
   143  						return
   144  					}
   145  				}
   146  			case <-abort:
   147  				return
   148  			}
   149  		}
   150  	}()
   151  	return abort, errorsOut
   152  }
   153  
   154  func (ethash *Ethash) verifyHeaderWorker(chain consensus.ChainReader, headers []*types.Header, seals []bool, index int) error {
   155  	var parent *types.Header
   156  	if index == 0 {
   157  		parent = chain.GetHeader(headers[0].ParentHash, headers[0].Number.Uint64()-1)
   158  	} else if headers[index-1].Hash() == headers[index].ParentHash {
   159  		parent = headers[index-1]
   160  	}
   161  	if parent == nil {
   162  		return consensus.ErrUnknownAncestor
   163  	}
   164  	if chain.GetHeader(headers[index].Hash(), headers[index].Number.Uint64()) != nil {
   165  		return nil // known block
   166  	}
   167  	return ethash.verifyHeader(chain, headers[index], parent, false, seals[index])
   168  }
   169  
   170  // VerifyUncles verifies that the given block's uncles conform to the consensus
   171  // rules of the WTC consensus engine.
   172  func (ethash *Ethash) VerifyUncles(chain consensus.ChainReader, block *types.Block) error {
   173  	// If we're running a full engine faking, accept any input as valid
   174  	if ethash.fakeFull {
   175  		return nil
   176  	}
   177  	// Verify that there are at most 2 uncles included in this block
   178  	if len(block.Uncles()) > maxUncles {
   179  		return errTooManyUncles
   180  	}
   181  	// Gather the set of past uncles and ancestors
   182  	uncles, ancestors := set.New(), make(map[common.Hash]*types.Header)
   183  
   184  	number, parent := block.NumberU64()-1, block.ParentHash()
   185  	for i := 0; i < 7; i++ {
   186  		ancestor := chain.GetBlock(parent, number)
   187  		if ancestor == nil {
   188  			break
   189  		}
   190  		ancestors[ancestor.Hash()] = ancestor.Header()
   191  		for _, uncle := range ancestor.Uncles() {
   192  			uncles.Add(uncle.Hash())
   193  		}
   194  		parent, number = ancestor.ParentHash(), number-1
   195  	}
   196  	ancestors[block.Hash()] = block.Header()
   197  	uncles.Add(block.Hash())
   198  
   199  	// Verify each of the uncles that it's recent, but not an ancestor
   200  	for _, uncle := range block.Uncles() {
   201  		// Make sure every uncle is rewarded only once
   202  		hash := uncle.Hash()
   203  		if uncles.Has(hash) {
   204  			return errDuplicateUncle
   205  		}
   206  		uncles.Add(hash)
   207  
   208  		// Make sure the uncle has a valid ancestry
   209  		if ancestors[hash] != nil {
   210  			return errUncleIsAncestor
   211  		}
   212  		if ancestors[uncle.ParentHash] == nil || uncle.ParentHash == block.ParentHash() {
   213  			return errDanglingUncle
   214  		}
   215  		if err := ethash.verifyHeader(chain, uncle, ancestors[uncle.ParentHash], true, true); err != nil {
   216  			return err
   217  		}
   218  	}
   219  	return nil
   220  }
   221  
   222  // verifyHeader checks whether a header conforms to the consensus rules of the
   223  // WTC consensus engine.
   224  // See YP section 4.3.4. "Block Header Validity"
   225  func (ethash *Ethash) verifyHeader(chain consensus.ChainReader, header, parent *types.Header, uncle bool, seal bool) error {
   226  	// Ensure that the header's extra-data section is of a reasonable size
   227  	if uint64(len(header.Extra)) > params.MaximumExtraDataSize {
   228  		return fmt.Errorf("extra-data too long: %d > %d", len(header.Extra), params.MaximumExtraDataSize)
   229  	}
   230  	// Verify the header's timestamp
   231  	if uncle {
   232  		if header.Time.Cmp(math.MaxBig256) > 0 {
   233  			return errLargeBlockTime
   234  		}
   235  	} else {
   236  		if header.Time.Cmp(big.NewInt(time.Now().Unix())) > 0 {
   237  			return consensus.ErrFutureBlock
   238  		}
   239  	}
   240  	if header.Time.Cmp(parent.Time) <= 0 {
   241  		return errZeroBlockTime
   242  	}
   243  	// Verify the block's difficulty based in it's timestamp and parent's difficulty
   244  	expected := CalcDifficulty(chain.Config(), header.Time.Uint64(), parent)
   245  	if expected.Cmp(header.Difficulty) != 0 {
   246  		return fmt.Errorf("invalid difficulty: have %v, want %v", header.Difficulty, expected)
   247  	}
   248  	// Verify that the gas limit is <= 2^63-1
   249  	if header.GasLimit.Cmp(math.MaxBig63) > 0 {
   250  		return fmt.Errorf("invalid gasLimit: have %v, max %v", header.GasLimit, math.MaxBig63)
   251  	}
   252  	// Verify that the gasUsed is <= gasLimit
   253  	if header.GasUsed.Cmp(header.GasLimit) > 0 {
   254  		return fmt.Errorf("invalid gasUsed: have %v, gasLimit %v", header.GasUsed, header.GasLimit)
   255  	}
   256  
   257  	// Verify that the gas limit remains within allowed bounds
   258  	diff := new(big.Int).Set(parent.GasLimit)
   259  	diff = diff.Sub(diff, header.GasLimit)
   260  	diff.Abs(diff)
   261  
   262  	limit := new(big.Int).Set(parent.GasLimit)
   263  	limit = limit.Div(limit, params.GasLimitBoundDivisor)
   264  
   265  	next := new(big.Int).Add(parent.Number, big.NewInt(1))
   266  	if next.Cmp(params.HardForkV3) >= 0 {
   267  		if diff.Cmp(limit) >= 0 || header.GasLimit.Cmp(params.MinGasLimitV3) < 0 {
   268  			return fmt.Errorf("invalid gas limit: have %v, want %v += %v", header.GasLimit, parent.GasLimit, limit)
   269  		}
   270  	} else {
   271  		if diff.Cmp(limit) >= 0 || header.GasLimit.Cmp(params.MinGasLimit) < 0 {
   272  			return fmt.Errorf("invalid gas limit: have %v, want %v += %v", header.GasLimit, parent.GasLimit, limit)
   273  		}
   274  	}
   275  	// Verify that the block number is parent's +1
   276  	if diff := new(big.Int).Sub(header.Number, parent.Number); diff.Cmp(big.NewInt(1)) != 0 {
   277  		return consensus.ErrInvalidNumber
   278  	}
   279  	// Verify the engine specific seal securing the block
   280  	if seal {
   281  		if err := ethash.VerifySeal(chain, header, false, big.NewInt(0)); err != nil {
   282  			return err
   283  		}
   284  	}
   285  	if err := misc.VerifyForkHashes(chain.Config(), header, uncle); err != nil {
   286  		return err
   287  	}
   288  	return nil
   289  }
   290  
   291  // CalcDifficulty is the difficulty adjustment algorithm. It returns
   292  // the difficulty that a new block should have when created at time
   293  // given the parent block's time and difficulty.
   294  func CalcDifficulty(config *params.ChainConfig, time uint64, parent *types.Header) *big.Int {
   295  	next := new(big.Int).Add(parent.Number, big1)
   296  
   297  	if next.Cmp(params.HardForkV3) >= 0 {
   298  		return calcDifficultyPhaseTwo(time, parent)
   299  	} else {
   300  		return calcDifficultyPhaseOne(time, parent)
   301  	}
   302  }
   303  
   304  // Some weird constants to avoid constant memory allocs for them.
   305  var (
   306  	expDiffPeriod = big.NewInt(100000)
   307  	big1          = big.NewInt(1)
   308  	big2          = big.NewInt(2)
   309  	big3          = big.NewInt(3)
   310  	big5          = big.NewInt(5)
   311  	big6          = big.NewInt(6)
   312  	big9          = big.NewInt(9)
   313  	big10         = big.NewInt(10)
   314  	big60         = big.NewInt(60)
   315  	bigMinus99    = big.NewInt(-99)
   316  	big2999999    = big.NewInt(2999999)
   317  )
   318  
   319  // calcDifficultyByzantium is the difficulty adjustment algorithm. It returns
   320  // the difficulty that a new block should have when created at time given the
   321  // parent block's time and difficulty. The calculation uses the Byzantium rules.
   322  func calcDifficultyByzantium(time uint64, parent *types.Header) *big.Int {
   323  	// https://github.com/wtc/EIPs/issues/100.
   324  	// algorithm:
   325  	// diff = (parent_diff +
   326  	//         (parent_diff / 2048 * max((2 if len(parent.uncles) else 1) - ((timestamp - parent.timestamp) // 9), -99))
   327  	//        ) + 2^(periodCount - 2)
   328  
   329  	bigTime := new(big.Int).SetUint64(time)
   330  	bigParentTime := new(big.Int).Set(parent.Time)
   331  
   332  	// holds intermediate values to make the algo easier to read & audit
   333  	x := new(big.Int)
   334  	y := new(big.Int)
   335  
   336  	// (2 if len(parent_uncles) else 1) - (block_timestamp - parent_timestamp) // 9
   337  	x.Sub(bigTime, bigParentTime)
   338  	x.Div(x, big9)
   339  	if parent.UncleHash == types.EmptyUncleHash {
   340  		x.Sub(big1, x)
   341  	} else {
   342  		x.Sub(big2, x)
   343  	}
   344  	// max((2 if len(parent_uncles) else 1) - (block_timestamp - parent_timestamp) // 9, -99)
   345  	if x.Cmp(bigMinus99) < 0 {
   346  		x.Set(bigMinus99)
   347  	}
   348  	// (parent_diff + parent_diff // 2048 * max(1 - (block_timestamp - parent_timestamp) // 10, -99))
   349  	y.Div(parent.Difficulty, params.DifficultyBoundDivisor)
   350  	x.Mul(y, x)
   351  	x.Add(parent.Difficulty, x)
   352  
   353  	// minimum difficulty can ever be (before exponential factor)
   354  	if x.Cmp(params.MinimumDifficulty) < 0 {
   355  		x.Set(params.MinimumDifficulty)
   356  	}
   357  	// calculate a fake block numer for the ice-age delay:
   358  	//   https://github.com/ethereum/EIPs/pull/669
   359  	//   fake_block_number = min(0, block.number - 3_000_000
   360  	fakeBlockNumber := new(big.Int)
   361  	if parent.Number.Cmp(big2999999) >= 0 {
   362  		fakeBlockNumber = fakeBlockNumber.Sub(parent.Number, big2999999) // Note, parent is 1 less than the actual block number
   363  	}
   364  	// for the exponential factor
   365  	periodCount := fakeBlockNumber
   366  	periodCount.Div(periodCount, expDiffPeriod)
   367  
   368  	// the exponential factor, commonly referred to as "the bomb"
   369  	// diff = diff + 2^(periodCount - 2)
   370  	if periodCount.Cmp(big1) > 0 {
   371  		y.Sub(periodCount, big2)
   372  		y.Exp(big2, y, nil)
   373  		x.Add(x, y)
   374  	}
   375  	return x
   376  }
   377  
   378  func calcDifficultyPhaseTwo(time uint64, parent *types.Header) *big.Int {
   379  	// diff = parent_diff + (parent_diff / 1024 * max(8 - (block_timestamp - parent_timestamp)/8, -99))
   380  
   381  	currentBlockTime := new(big.Int).SetUint64(time)
   382  	bigParentTime := new(big.Int).Set(parent.Time)
   383  
   384  	// holds intermediate values to make the algo easier to read & audit
   385  	x := new(big.Int)
   386  	y := new(big.Int)
   387  
   388  	// block_timestamp - parent_timestamp
   389  	x.Sub(currentBlockTime, bigParentTime)
   390  
   391  	// fine tune
   392  	if x.Cmp(big.NewInt(5)) >= 0 {
   393  		x.Sub(x, big.NewInt(3))
   394  	}
   395  
   396  	// 8 - (block_timestamp - parent_timestamp) / 8
   397  	x.Div(x, big8)
   398  	x.Sub(big3, x)
   399  
   400  	// max(6 - (block_timestamp - parent_timestamp) / 8, -99)
   401  	if x.Cmp(bigMinus99) < 0 {
   402  		x.Set(bigMinus99)
   403  	}
   404  	// diff = parent_diff + (parent_diff / 1024 * max(8 - (block_timestamp - parent_timestamp)/8, -99))
   405  	y.Div(parent.Difficulty, params.DifficultyBoundDivisor)
   406  	x.Mul(y, x)
   407  	x.Add(parent.Difficulty, x)
   408  
   409  	// minimum difficulty can ever be (before exponential factor)
   410  	if x.Cmp(params.MinimumDifficulty) < 0 {
   411  		x.Set(params.MinimumDifficulty)
   412  	}
   413  
   414  	return x
   415  }
   416  
   417  func calcDifficultyPhaseOne(time uint64, parent *types.Header) *big.Int {
   418  	// algorithm:
   419  	// diff = parent_diff +
   420  	//        (parent_diff / 2048 * max(6 - (block_timestamp - parent_timestamp) // 10, -99))
   421  	//
   422  	//logger := log.New("epoch", epoch)
   423  	bigTime := new(big.Int).SetUint64(time)
   424  	bigParentTime := new(big.Int).Set(parent.Time)
   425  
   426  	// holds intermediate values to make the algo easier to read & audit
   427  	x := new(big.Int)
   428  	y := new(big.Int)
   429  
   430  	// 6 - (block_timestamp - parent_timestamp) // 10
   431  	x.Sub(bigTime, bigParentTime)
   432  	x.Div(x, big10)
   433  	x.Sub(big3, x)
   434  	// max(6 - (block_timestamp - parent_timestamp) // 10, -99)
   435  	if x.Cmp(bigMinus99) < 0 {
   436  		x.Set(bigMinus99)
   437  	}
   438  	// (parent_diff + parent_diff // 2048 * max(6 - (block_timestamp - parent_timestamp) // 10, -99))
   439  	y.Div(parent.Difficulty, params.DifficultyBoundDivisor)
   440  	x.Mul(y, x)
   441  	x.Add(parent.Difficulty, x)
   442  
   443  	// minimum difficulty can ever be (before exponential factor)
   444  	if x.Cmp(params.MinimumDifficulty) < 0 {
   445  		x.Set(params.MinimumDifficulty)
   446  	}
   447  
   448  	return x
   449  }
   450  
   451  // calcDifficultyHomestead is the difficulty adjustment algorithm. It returns
   452  // the difficulty that a new block should have when created at time given the
   453  // parent block's time and difficulty. The calculation uses the Homestead rules.
   454  func calcDifficultyHomestead(time uint64, parent *types.Header) *big.Int {
   455  	// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2.mediawiki
   456  	// algorithm:
   457  	// diff = (parent_diff +
   458  	//         (parent_diff / 2048 * max(1 - (block_timestamp - parent_timestamp) // 10, -99))
   459  	//        ) + 2^(periodCount - 2)
   460  
   461  	bigTime := new(big.Int).SetUint64(time)
   462  	bigParentTime := new(big.Int).Set(parent.Time)
   463  
   464  	// holds intermediate values to make the algo easier to read & audit
   465  	x := new(big.Int)
   466  	y := new(big.Int)
   467  
   468  	// 1 - (block_timestamp - parent_timestamp) // 10
   469  	x.Sub(bigTime, bigParentTime)
   470  	x.Div(x, big10)
   471  	x.Sub(big1, x)
   472  
   473  	// max(1 - (block_timestamp - parent_timestamp) // 10, -99)
   474  	if x.Cmp(bigMinus99) < 0 {
   475  		x.Set(bigMinus99)
   476  	}
   477  	// (parent_diff + parent_diff // 2048 * max(1 - (block_timestamp - parent_timestamp) // 10, -99))
   478  	y.Div(parent.Difficulty, params.DifficultyBoundDivisor)
   479  	x.Mul(y, x)
   480  	x.Add(parent.Difficulty, x)
   481  
   482  	// minimum difficulty can ever be (before exponential factor)
   483  	if x.Cmp(params.MinimumDifficulty) < 0 {
   484  		x.Set(params.MinimumDifficulty)
   485  	}
   486  	// for the exponential factor
   487  	periodCount := new(big.Int).Add(parent.Number, big1)
   488  	periodCount.Div(periodCount, expDiffPeriod)
   489  
   490  	// the exponential factor, commonly referred to as "the bomb"
   491  	// diff = diff + 2^(periodCount - 2)
   492  	if periodCount.Cmp(big1) > 0 {
   493  		y.Sub(periodCount, big2)
   494  		y.Exp(big2, y, nil)
   495  		x.Add(x, y)
   496  	}
   497  	return x
   498  }
   499  
   500  // calcDifficultyFrontier is the difficulty adjustment algorithm. It returns the
   501  // difficulty that a new block should have when created at time given the parent
   502  // block's time and difficulty. The calculation uses the Frontier rules.
   503  func calcDifficultyFrontier(time uint64, parent *types.Header) *big.Int {
   504  	diff := new(big.Int)
   505  	adjust := new(big.Int).Div(parent.Difficulty, params.DifficultyBoundDivisor)
   506  	bigTime := new(big.Int)
   507  	bigParentTime := new(big.Int)
   508  
   509  	bigTime.SetUint64(time)
   510  	bigParentTime.Set(parent.Time)
   511  
   512  	if bigTime.Sub(bigTime, bigParentTime).Cmp(params.DurationLimit) < 0 {
   513  		diff.Add(parent.Difficulty, adjust)
   514  	} else {
   515  		diff.Sub(parent.Difficulty, adjust)
   516  	}
   517  	if diff.Cmp(params.MinimumDifficulty) < 0 {
   518  		diff.Set(params.MinimumDifficulty)
   519  	}
   520  
   521  	periodCount := new(big.Int).Add(parent.Number, big1)
   522  	periodCount.Div(periodCount, expDiffPeriod)
   523  	if periodCount.Cmp(big1) > 0 {
   524  		// diff = diff + 2^(periodCount - 2)
   525  		expDiff := periodCount.Sub(periodCount, big2)
   526  		expDiff.Exp(big2, expDiff, nil)
   527  		diff.Add(diff, expDiff)
   528  		diff = math.BigMax(diff, params.MinimumDifficulty)
   529  	}
   530  	return diff
   531  }
   532  
   533  // VerifySeal implements consensus.Engine, checking whether the given block satisfies
   534  // the PoW difficulty requirements.
   535  func (ethash *Ethash) VerifySeal(chain consensus.ChainReader, header *types.Header, posShareCheck bool, difficulty *big.Int) error {
   536  	// fmt.Printf("YWQ:posShareCheck:%d\n", posShareCheck)
   537  
   538  	if header.Number.Cmp(params.HardForkV2) == 0 {
   539  		if header.Difficulty.Cmp(params.HardForkV2diff) != 0 {
   540  			fmt.Printf("YWQ:errInvalidDifficulty block lock!\n")
   541  			return errInvalidDifficulty
   542  		}
   543  	}
   544  
   545  	var orderHash []byte
   546  	if header.Number.Cmp(params.HardForkV1) >= 0 {
   547  		if header.Number.Cmp(params.HardForkV3) >= 0 {
   548  			set := header.Number.Bytes()
   549  			origin := sha256.New()
   550  			origin.Write(set)
   551  			origin.Write([]byte("HardForkV3"))
   552  			orderHash = origin.Sum(nil)
   553  		} else if header.Number.Cmp(params.HardForkV2) >= 0 {
   554  			set := header.Number.Bytes()
   555  			origin := sha256.New()
   556  			origin.Write(set)
   557  			orderHash = origin.Sum([]byte("HardForkV2"))
   558  		} else {
   559  			set := header.Number.Bytes()
   560  			origin := sha256.New()
   561  			origin.Write(set)
   562  			orderHash = origin.Sum(nil)
   563  		}
   564  	} else {
   565  		orderHash = header.HashNoNonce().Bytes()
   566  	}
   567  
   568  	// If we're running a fake PoW, accept any seal as valid
   569  	if ethash.fakeMode {
   570  		time.Sleep(ethash.fakeDelay)
   571  		if ethash.fakeFail == header.Number.Uint64() {
   572  			fmt.Printf("YWQ:fakeMode, errInvalidPoW\n")
   573  			return errInvalidPoW
   574  		}
   575  		return nil
   576  	}
   577  	// If we're running a shared PoW, delegate verification to it
   578  	if ethash.shared != nil {
   579  		fmt.Printf("YWQ:ethash.shared\n")
   580  		return ethash.shared.VerifySeal(chain, header, false, big.NewInt(0))
   581  	}
   582  	// Sanity check that the block number is below the lookup table size (60M blocks)
   583  	number := header.Number.Uint64()
   584  	if number/epochLength >= uint64(len(cacheSizes)) {
   585  		// Go < 1.7 cannot calculate new cache/dataset sizes (no fast prime check)
   586  		fmt.Printf("YWQ:errNonceOutOfRange\n")
   587  		return errNonceOutOfRange
   588  	}
   589  	// Ensure that we have a valid difficulty for the block
   590  	if !posShareCheck && header.Difficulty.Sign() <= 0 {
   591  		fmt.Printf("YWQ:errInvalidDifficulty\n")
   592  		return errInvalidDifficulty
   593  	}
   594  	// Recompute the digest and PoW value and verify against the header
   595  	/*cache := ethash.cache(number)
   596  
   597  	size := datasetSize(number)
   598  	if ethash.tester {
   599  		size = 32 * 1024
   600  	}*/
   601  	//digest, result := hashimotoLight(size, cache, header.HashNoNonce().Bytes(), header.Nonce.Uint64())
   602  	//-----------------------------------------------
   603  
   604  	order := getX11Order(orderHash, 11)
   605  	digest, result := myx11(header.HashNoNonce().Bytes(), header.Nonce.Uint64(), order)
   606  	if !bytes.Equal(header.MixDigest[:], digest) {
   607  		fmt.Printf("YWQ:errInvalidMixDigest\n")
   608  		return errInvalidMixDigest
   609  	}
   610  	// target := new(big.Int).Div(maxUint256, header.Difficulty)
   611  
   612  	target := new(big.Int)
   613  	if posShareCheck {
   614  		target = new(big.Int).Div(maxUint256, difficulty)
   615  	} else {
   616  		target = new(big.Int).Div(maxUint256, header.Difficulty)
   617  	}
   618  
   619  	// targetOrigin := target
   620  
   621  	var bn_txnumber *big.Int
   622  	if header.Number.Cmp(params.HardForkV1) >= 0 {
   623  	} else {
   624  		bn_txnumber = new(big.Int).Mul(new(big.Int).SetUint64(header.TxNumber), big.NewInt(5e+18))
   625  		bn_txnumber = Sqrt(bn_txnumber, 6)
   626  	}
   627  
   628  	if header.Number.Cmp(params.HardForkV2) >= 0 {
   629  		balance, _, _, _ := chain.GetBalanceAndCoinAgeByHeaderHash(header.Coinbase)
   630  		target = TargetDiff(balance, target)
   631  	} else {
   632  		coinage := header.CoinAge
   633  		bn_coinage := new(big.Int).Mul(coinage, big.NewInt(1))
   634  		bn_coinage = Sqrt(bn_coinage, 6)
   635  		if bn_coinage.Cmp(big.NewInt(0)) > 0 {
   636  			target.Mul(bn_coinage, target)
   637  		}
   638  		// fmt.Printf("X11 coinage: %d\n", coinage)
   639  		// fmt.Printf("X11 bn_coinage: %d\n", bn_coinage)
   640  	}
   641  
   642  	if header.Number.Cmp(params.HardForkV1) >= 0 {
   643  	} else {
   644  		if bn_txnumber.Cmp(big.NewInt(0)) > 0 {
   645  			target.Mul(bn_txnumber, target)
   646  		}
   647  	}
   648  
   649  	// fmt.Printf("X11 order    : %s\n", order)
   650  	// fmt.Printf("X11 targeto  : %x\n", FullTo32(targetOrigin.Bytes()))
   651  	// fmt.Printf("X11 targetd  : %x\n", FullTo32(target.Bytes()))
   652  	// fmt.Printf("X11 targetdiv: %d\n", new(big.Int).Div(target, targetOrigin))
   653  	// fmt.Printf("X11 result   : %x\n", result)
   654  	// fmt.Printf("X11 miner    : %x\n", header.Coinbase)
   655  
   656  	// fmt.Printf("X11 order    : %s\n", order)
   657  	// fmt.Printf("X11 targeto  : %x\n", FullTo32(new(big.Int).Div(maxUint256, header.Difficulty).Bytes()))
   658  	// fmt.Printf("X11 targetd  : %x\n", FullTo32(target.Bytes()))
   659  	// fmt.Printf("X11 targetdiv: %d\n", new(big.Int).Div(target, new(big.Int).Div(maxUint256, header.Difficulty)))
   660  	// fmt.Printf("X11 result   : %x\n", result)
   661  	// fmt.Printf("X11 miner    : %x\n", header.Coinbase)
   662  
   663  	if Compare(result, FullTo32(target.Bytes()), 32) > 0 {
   664  		// fmt.Printf("YWQ:FullTo32  errInvalidPoW\n")
   665  		return errInvalidPoW
   666  	}
   667  	return nil
   668  }
   669  
   670  // Prepare implements consensus.Engine, initializing the difficulty field of a
   671  // header to conform to the ethash protocol. The changes are done inline.
   672  func (ethash *Ethash) Prepare(chain consensus.ChainReader, header *types.Header) error {
   673  	parent := chain.GetHeader(header.ParentHash, header.Number.Uint64()-1)
   674  	if parent == nil {
   675  		return consensus.ErrUnknownAncestor
   676  	}
   677  	header.Difficulty = CalcDifficulty(chain.Config(), header.Time.Uint64(), parent)
   678  
   679  	return nil
   680  }
   681  
   682  // Finalize implements consensus.Engine, accumulating the block and uncle rewards,
   683  // setting the final state and assembling the block.
   684  func (ethash *Ethash) Finalize(chain consensus.ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) {
   685  	// Accumulate any block and uncle rewards and commit the final state root
   686  	AccumulateRewards(state, header, uncles)
   687  	header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number))
   688  
   689  	// Header seems complete, assemble into a block and return
   690  	return types.NewBlock(header, txs, uncles, receipts), nil
   691  }
   692  
   693  // Some weird constants to avoid constant memory allocs for them.
   694  var (
   695  	big8  = big.NewInt(8)
   696  	big32 = big.NewInt(32)
   697  )
   698  
   699  // AccumulateRewards credits the coinbase of the given block with the mining
   700  // reward. The total reward consists of the static block reward and rewards for
   701  // included uncles. The coinbase of each uncle block is also rewarded.
   702  // TODO (karalabe): Move the chain maker into this package and make this private!
   703  func AccumulateRewards(state *state.StateDB, header *types.Header, uncles []*types.Header) {
   704  	balance := state.GetBalance(header.Coinbase)
   705  	reward := getReward(header.Number, balance)
   706  
   707  	state.AddBalance(header.Coinbase, reward, header.Number, header.Time)
   708  	state.SetCoinAge(header.Coinbase, big.NewInt(0))
   709  }
   710  
   711  func getReward(block, balance *big.Int) *big.Int {
   712  	oneyear := big.NewInt(2 * 60 * 24 * 365)
   713  	var reward *big.Int
   714  	big5000 := new(big.Int).Mul(params.AddedRewardForMN, big.NewInt(1e+18))
   715  	years := new(big.Int).Div(block, oneyear).Int64()
   716  
   717  	if block.Int64() <= 40000 {
   718  		reward = big.NewInt(1e+17)
   719  	} else if block.Int64() > 40000 && block.Int64() <= 100000 {
   720  		reward = big.NewInt(1e+18)
   721  	} else if block.Int64() > 100000 && block.Int64() <= 200000 {
   722  		reward = big.NewInt(2e+18)
   723  	} else if years < 2 {
   724  		reward = big.NewInt(25e+17)
   725  		if balance.Cmp(big5000) >= 0 {
   726  			reward = reward.Add(reward, big.NewInt(5e+17))
   727  		}
   728  	} else {
   729  		var discount float64 = 100000
   730  		y := years / 2
   731  		for i := 0; int64(i) < y; i++ {
   732  			discount = discount * 0.75
   733  		}
   734  
   735  		reward = big.NewInt(25e+17)
   736  		if balance.Cmp(big5000) >= 0 {
   737  			reward = reward.Add(reward, big.NewInt(5e+17))
   738  		}
   739  
   740  		reward = new(big.Int).Div(reward, big.NewInt(100000))
   741  		reward = new(big.Int).Mul(reward, big.NewInt(int64(discount)))
   742  	}
   743  
   744  	return reward
   745  }