github.com/halybang/go-ethereum@v1.0.5-0.20180325041310-3b262bc1367c/consensus/ethash/consensus.go (about)

     1  // Copyright 2018 Wanchain Foundation Ltd
     2  // Copyright 2017 The go-ethereum Authors
     3  // This file is part of the go-ethereum library.
     4  //
     5  // The go-ethereum 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-ethereum 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-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    17  
    18  package ethash
    19  
    20  import (
    21  	"bytes"
    22  	"errors"
    23  	"fmt"
    24  	"math/big"
    25  	//"runtime"
    26  	"time"
    27  
    28  	"github.com/wanchain/go-wanchain/common"
    29  	"github.com/wanchain/go-wanchain/common/math"
    30  	"github.com/wanchain/go-wanchain/consensus"
    31  	//"github.com/wanchain/go-wanchain/consensus/misc"
    32  	"github.com/wanchain/go-wanchain/accounts"
    33  	"github.com/wanchain/go-wanchain/core/state"
    34  	"github.com/wanchain/go-wanchain/core/types"
    35  	"github.com/wanchain/go-wanchain/crypto"
    36  	"github.com/wanchain/go-wanchain/crypto/sha3"
    37  	"github.com/wanchain/go-wanchain/log"
    38  	"github.com/wanchain/go-wanchain/params"
    39  	"github.com/wanchain/go-wanchain/rlp"
    40  	//set "gopkg.in/fatih/set.v0"
    41  	"runtime"
    42  )
    43  
    44  const (
    45  	checkpointInterval = 8192 // Number of blocks after which to save the signers state
    46  	//  checkpointInterval = 4 // Number of blocks after which to save the signers state, using small value for testing...
    47  )
    48  
    49  // Ethash proof-of-work protocol constants.
    50  var (
    51  	//frontierBlockReward  *big.Int = big.NewInt(5e+18) // Block reward in wei for successfully mining a block
    52  	byzantiumBlockReward *big.Int = big.NewInt(3e+18) // Block reward in wei for successfully mining a block upward from Byzantium
    53  	maxUncles                     = 0                 // Maximum number of uncles allowed in a single block
    54  	extraVanity                   = 32                // Fixed number of extra-data prefix bytes reserved for signer vanity
    55  	extraSeal                     = 65                // Fixed number of extra-data suffix bytes reserved for signer seal
    56  	allowedFutureBlockTime          = 15 * time.Second  // Max time from current time allowed for blocks, before they're considered future blocks
    57  
    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  	errLargeBlockTime    = errors.New("timestamp too big")
    66  	errZeroBlockTime     = errors.New("timestamp equals parent's")
    67  	errTooManyUncles     = errors.New("too many uncles")
    68  	errDuplicateUncle    = errors.New("duplicate uncle")
    69  	errUncleIsAncestor   = errors.New("uncle is ancestor")
    70  	errDanglingUncle     = errors.New("uncle's parent is not ancestor")
    71  	errNonceOutOfRange   = errors.New("nonce out of range")
    72  	errInvalidDifficulty = errors.New("non-positive difficulty")
    73  	errInvalidMixDigest  = errors.New("invalid mix digest")
    74  	errInvalidPoW        = errors.New("invalid proof-of-work")
    75  	errMissingSignature  = errors.New("extra data 65 byte suffix signature missing")
    76  	errUnauthorized      = errors.New("unauthorized signer")
    77  	errAuthorTooOften    = errors.New("signer too often")
    78  	errUsedSignerDescend = errors.New("disallow used signer descend")
    79  )
    80  
    81  // INFO: copied from consensus/clique/clique.go
    82  type SignerFn func(accounts.Account, []byte) ([]byte, error)
    83  
    84  // INFO: copied from consensus/clique/clique.go
    85  func sigHash(header *types.Header) (hash common.Hash) {
    86  	hasher := sha3.NewKeccak256()
    87  
    88  	rlp.Encode(hasher, []interface{}{
    89  		header.ParentHash,
    90  		header.UncleHash,
    91  		header.Coinbase,
    92  		header.Root,
    93  		header.TxHash,
    94  		header.ReceiptHash,
    95  		header.Bloom,
    96  		header.Difficulty,
    97  		header.Number,
    98  		header.GasLimit,
    99  		header.GasUsed,
   100  		header.Time,
   101  		header.Extra[:len(header.Extra)-extraSeal], // Yes, this will panic if extra is too short
   102  	})
   103  	hasher.Sum(hash[:0])
   104  	return hash
   105  }
   106  
   107  // INFO: copied from consensus/clique/clique.go
   108  // ecrecover extracts the Ethereum account address from a signed header.
   109  func ecrecover(header *types.Header) (common.Address, error) {
   110  	// Retrieve the signature from the header extra-data
   111  	if len(header.Extra) < extraSeal {
   112  		return common.Address{}, errMissingSignature
   113  	}
   114  	signature := header.Extra[len(header.Extra)-extraSeal:]
   115  
   116  	// Recover the public key and the Ethereum address
   117  	//log.Trace(fmt.Sprintf(header.String()))
   118  
   119  	pubkey, err := crypto.Ecrecover(sigHash(header).Bytes(), signature)
   120  	// log.Trace("ecrecover(): Seal hash", "Input hash", sigHash(header).String())
   121  	if err != nil {
   122  		return common.Address{}, err
   123  	}
   124  	var signer common.Address
   125  	copy(signer[:], crypto.Keccak256(pubkey[1:])[12:])
   126  
   127  	// The signer's address should match the coinbase address in Wanchain Release 1, shall we add a warning if it's not?
   128  	// log.Trace("ecrecover()", "recovered signer", signer)
   129  
   130  	return signer, nil
   131  }
   132  
   133  // INFO: copied from consensus/clique/clique.go
   134  // Author implements consensus.Engine, returning the header's coinbase as the
   135  // proof-of-work verified author of the block.
   136  func (ethash *Ethash) Author(header *types.Header) (common.Address, error) {
   137  	return header.Coinbase, nil
   138  }
   139  
   140  func (self *Ethash) Authorize(signer common.Address, signFn SignerFn) {
   141  	self.lock.Lock()
   142  	defer self.lock.Unlock()
   143  
   144  	self.signFn = signFn
   145  	self.signer = signer
   146  }
   147  
   148  // VerifyHeader checks whether a header conforms to the consensus rules of the
   149  // stock Ethereum ethash engine.
   150  func (ethash *Ethash) VerifyHeader(chain consensus.ChainReader, header *types.Header, seal bool) error {
   151  	// If we're running a full engine faking, accept any input as valid
   152  	if ethash.config.PowMode == ModeFullFake {
   153  		return nil
   154  	}
   155  	// Short circuit if the header is known, or it's parent not
   156  	number := header.Number.Uint64()
   157  	if chain.GetHeader(header.Hash(), number) != nil {
   158  		return nil
   159  	}
   160  	parent := chain.GetHeader(header.ParentHash, number-1)
   161  	if parent == nil {
   162  		return consensus.ErrUnknownAncestor
   163  	}
   164  	// Sanity checks passed, do a proper verification
   165  	parents := []*types.Header{parent}
   166  	return ethash.verifyHeader(chain, header, parents, false, seal)
   167  }
   168  
   169  func (ethash *Ethash) VerifyPPOWReorg(chain consensus.ChainReader, commonBlock *types.Block, oldChain []*types.Block, newChain []*types.Block) error {
   170  	s, err := ethash.snapshot(chain, commonBlock.NumberU64(), commonBlock.Hash(), nil)
   171  	if err != nil {
   172  		return err
   173  	}
   174  	oldSignerSet := make(map[common.Address]struct{})
   175  	newSignerSet := make(map[common.Address]struct{})
   176  	for signer := range s.UsedSigners {
   177  		oldSignerSet[signer] = struct{}{}
   178  		newSignerSet[signer] = struct{}{}
   179  	}
   180  
   181  	for _, b := range oldChain {
   182  		//using coinbase here, previously checked signature by node or verify headers
   183  		oldSignerSet[b.Coinbase()] = struct{}{}
   184  	}
   185  
   186  	for _, nb := range newChain {
   187  		newSignerSet[nb.Coinbase()] = struct{}{}
   188  	}
   189  
   190  	//TODO:PPOW how to make a reasonable choice
   191  	if len(newSignerSet) < (len(oldSignerSet) - 1) {
   192  		return errUsedSignerDescend
   193  	}
   194  
   195  	return nil
   196  }
   197  
   198  // VerifyHeaders is similar to VerifyHeader, but verifies a batch of headers
   199  // concurrently. The method returns a quit channel to abort the operations and
   200  // a results channel to retrieve the async verifications.
   201  func (ethash *Ethash) VerifyHeaders(chain consensus.ChainReader, headers []*types.Header, seals []bool) (chan<- struct{}, <-chan error) {
   202  	// If we're running a full engine faking, accept any input as valid
   203  	if ethash.config.PowMode == ModeFullFake || len(headers) == 0 {
   204  		abort, results := make(chan struct{}), make(chan error, len(headers))
   205  		for i := 0; i < len(headers); i++ {
   206  			results <- nil
   207  		}
   208  		return abort, results
   209  	}
   210  
   211  	// Spawn as many workers as allowed threads
   212  	//workers := runtime.GOMAXPROCS(0)
   213  	workers := 1
   214  	if len(headers) < workers {
   215  		workers = len(headers)
   216  	}
   217  
   218  	// Create a task channel and spawn the verifiers
   219  	var (
   220  		inputs = make(chan int)
   221  		done   = make(chan int, workers)
   222  		errors = make([]error, len(headers))
   223  		abort  = make(chan struct{})
   224  	)
   225  	for i := 0; i < workers; i++ {
   226  		go func() {
   227  			for index := range inputs {
   228  				errors[index] = ethash.verifyHeaderWorker(chain, headers, seals, index)
   229  				done <- index
   230  			}
   231  		}()
   232  	}
   233  
   234  	errorsOut := make(chan error, len(headers))
   235  	go func() {
   236  		defer close(inputs)
   237  		var (
   238  			in, out = 0, 0
   239  			checked = make([]bool, len(headers))
   240  			inputs  = inputs
   241  		)
   242  		for {
   243  			select {
   244  			case inputs <- in:
   245  				if in++; in == len(headers) {
   246  					// Reached end of headers. Stop sending to workers.
   247  					inputs = nil
   248  				}
   249  			case index := <-done:
   250  				for checked[index] = true; checked[out]; out++ {
   251  					errorsOut <- errors[out]
   252  					if out == len(headers)-1 {
   253  						return
   254  					}
   255  				}
   256  			case <-abort:
   257  				return
   258  			}
   259  		}
   260  	}()
   261  	return abort, errorsOut
   262  }
   263  
   264  func (ethash *Ethash) verifyHeaderWorker(chain consensus.ChainReader, headers []*types.Header, seals []bool, index int) error {
   265  	var parent *types.Header
   266  	if index == 0 {
   267  		parent = chain.GetHeader(headers[0].ParentHash, headers[0].Number.Uint64()-1)
   268  	} else if headers[index-1].Hash() == headers[index].ParentHash {
   269  		parent = headers[index-1]
   270  	}
   271  	if parent == nil {
   272  		return consensus.ErrUnknownAncestor
   273  	}
   274  	if chain.GetHeader(headers[index].Hash(), headers[index].Number.Uint64()) != nil {
   275  		return nil // known block
   276  	}
   277  
   278  	var parents []*types.Header
   279  	if index == 0 {
   280  		parents = []*types.Header{parent}
   281  	} else {
   282  		parents = headers[:index]
   283  	}
   284  	return ethash.verifyHeader(chain, headers[index], parents, false, seals[index])
   285  }
   286  
   287  // VerifyUncles verifies that the given block's uncles conform to the consensus
   288  // rules of the stock Ethereum ethash engine.
   289  func (ethash *Ethash) VerifyUncles(chain consensus.ChainReader, block *types.Block) error {
   290  	// If we're running a full engine faking, accept any input as valid
   291  	if ethash.config.PowMode == ModeFullFake {
   292  		return nil
   293  	}
   294  	// Verify that there are at most 2 uncles included in this block
   295  	if len(block.Uncles()) > maxUncles {
   296  		return errTooManyUncles
   297  	}
   298  	// Gather the set of past uncles and ancestors
   299  	//uncles, ancestors := set.New(), make(map[common.Hash]*types.Header)
   300  	//
   301  	//number, parent := block.NumberU64()-1, block.ParentHash()
   302  	//for i := 0; i < 7; i++ {
   303  	//	ancestor := chain.GetBlock(parent, number)
   304  	//	if ancestor == nil {
   305  	//		break
   306  	//	}
   307  	//	ancestors[ancestor.Hash()] = ancestor.Header()
   308  	//	for _, uncle := range ancestor.Uncles() {
   309  	//		uncles.Add(uncle.Hash())
   310  	//	}
   311  	//	parent, number = ancestor.ParentHash(), number-1
   312  	//}
   313  	//ancestors[block.Hash()] = block.Header()
   314  	//uncles.Add(block.Hash())
   315  	//
   316  	//// Verify each of the uncles that it's recent, but not an ancestor
   317  	//for _, uncle := range block.Uncles() {
   318  	//	// Make sure every uncle is rewarded only once
   319  	//	hash := uncle.Hash()
   320  	//	if uncles.Has(hash) {
   321  	//		return errDuplicateUncle
   322  	//	}
   323  	//	uncles.Add(hash)
   324  	//
   325  	//	// Make sure the uncle has a valid ancestry
   326  	//	if ancestors[hash] != nil {
   327  	//		return errUncleIsAncestor
   328  	//	}
   329  	//	if ancestors[uncle.ParentHash] == nil || uncle.ParentHash == block.ParentHash() {
   330  	//		return errDanglingUncle
   331  	//	}
   332  	//	//if err := ethash.verifyHeader(chain, uncle, ancestors[uncle.ParentHash], true, true); err != nil {
   333  	//	//	return err
   334  	//	//}
   335  	//}
   336  	return nil
   337  }
   338  
   339  // verifyHeader checks whether a header conforms to the consensus rules of the
   340  // stock Ethereum ethash engine.
   341  // See YP section 4.3.4. "Block Header Validity"
   342  func (ethash *Ethash) verifyHeader(chain consensus.ChainReader, header *types.Header, parents []*types.Header, uncle bool, seal bool) error {
   343  	if header.Number.Uint64() == 0 {
   344  		return nil
   345  	}
   346  	// Ensure that the header's extra-data section is of a reasonable size
   347  	parent := parents[len(parents)-1]
   348  	if uint64(len(header.Extra)) > params.MaximumExtraDataSize {
   349  		return fmt.Errorf("extra-data too long: %d > %d", len(header.Extra), params.MaximumExtraDataSize)
   350  	}
   351  	if len(header.Extra) != extraVanity+extraSeal {
   352  		return fmt.Errorf("extra-data size invalid: %d", len(header.Extra))
   353  	}
   354  	// Verify the header's timestamp
   355  	if uncle {
   356  		if header.Time.Cmp(math.MaxBig256) > 0 {
   357  			return errLargeBlockTime
   358  		}
   359  	} else {
   360  		if header.Time.Cmp(big.NewInt(time.Now().Add(allowedFutureBlockTime).Unix())) > 0 {
   361  			return consensus.ErrFutureBlock
   362  		}
   363  	}
   364  	if header.Time.Cmp(parent.Time) <= 0 {
   365  		return errZeroBlockTime
   366  	}
   367  	// Verify the block's difficulty based in it's timestamp and parent's difficulty
   368  	expected := ethash.CalcDifficulty(chain, header.Time.Uint64(), parent)
   369  
   370  	if expected.Cmp(header.Difficulty) != 0 {
   371  		return fmt.Errorf("invalid difficulty: have %v, want %v", header.Difficulty, expected)
   372  	}
   373  	// Verify that the gas limit is <= 2^63-1
   374  	cap := uint64(0x7fffffffffffffff)
   375  	if header.GasLimit.Uint64() > cap {
   376  		return fmt.Errorf("invalid gasLimit: have %v, max %v", header.GasLimit, cap)
   377  	}
   378  	// Verify that the gasUsed is <= gasLimit
   379  	if header.GasUsed.Cmp(header.GasLimit)>0 {
   380  		return fmt.Errorf("invalid gasUsed: have %d, gasLimit %d", header.GasUsed, header.GasLimit)
   381  	}
   382  
   383  	// Verify that the gas limit remains within allowed bounds
   384  	diff := int64(parent.GasLimit.Int64()) - int64(header.GasLimit.Int64())
   385  	if diff < 0 {
   386  		diff *= -1
   387  	}
   388  	limit := parent.GasLimit.Uint64() / params.GasLimitBoundDivisor.Uint64()
   389  
   390  	if uint64(diff) >= limit || header.GasLimit.Uint64() < params.MinGasLimit.Uint64() {
   391  		return fmt.Errorf("invalid gas limit: have %d, want %d += %d", header.GasLimit, parent.GasLimit, limit)
   392  	}
   393  	// Verify that the block number is parent's +1
   394  	if diff := new(big.Int).Sub(header.Number, parent.Number); diff.Cmp(big.NewInt(1)) != 0 {
   395  		return consensus.ErrInvalidNumber
   396  	}
   397  	// Verify the engine specific seal securing the block
   398  	if seal {
   399  		if err := ethash.VerifySeal(chain, header); err != nil {
   400  			return err
   401  		}
   402  	}
   403  
   404  	//if seal
   405  	if err := ethash.verifySignerIdentity(chain, header, parents); err != nil {
   406  		return err
   407  	}
   408  
   409  	// If all checks passed, validate any special fields for hard forks
   410  	//if err := misc.VerifyDAOHeaderExtraData(chain.Config(), header); err != nil {
   411  	//	return err
   412  	//}
   413  	//if err := misc.VerifyForkHashes(chain.Config(), header, uncle); err != nil {
   414  	//	return err
   415  	//}
   416  
   417  	return nil
   418  }
   419  
   420  // CalcDifficulty is the difficulty adjustment algorithm. It returns
   421  // the difficulty that a new block should have when created at time
   422  // given the parent block's time and difficulty.
   423  func (ethash *Ethash) CalcDifficulty(chain consensus.ChainReader, time uint64, parent *types.Header) *big.Int {
   424  	return CalcDifficulty(chain.Config(), time, parent)
   425  }
   426  // TODO (karalabe): Move the chain maker into this package and make this private!
   427  func CalcDifficulty(config *params.ChainConfig, time uint64, parent *types.Header) *big.Int {
   428  	//next := new(big.Int).Add(parent.Number, big1)
   429  	//
   430  	switch {
   431  	//case config.IsByzantium(next):
   432  	//	return calcDifficultyByzantium(time, parent)
   433  	//case config.IsHomestead(next):
   434  	//	return calcDifficultyHomestead(time, parent)
   435  	default:
   436  		//return calcDifficultyFrontier(time, parent)
   437  		return calcDifficultyByzantium(time, parent)
   438  	}
   439  }
   440  
   441  // verify does current coinbase valid for sign
   442  func (self *Ethash) verifySignerIdentity(chain consensus.ChainReader, header *types.Header, parents []*types.Header) error {
   443  	number := header.Number.Uint64()
   444  
   445  	s, err := self.snapshot(chain, number-1, header.ParentHash, parents)
   446  	if err != nil {
   447  		return err
   448  	}
   449  
   450  	if err = s.isLegal4Sign(header.Coinbase); err != nil {
   451  		return err
   452  	}
   453  
   454  	return nil
   455  }
   456  
   457  // INFO: copied from consensus/clique/clique.go , mostly
   458  // snapshot retrieves the signer status at a given point
   459  func (self *Ethash) snapshot(chain consensus.ChainReader, number uint64, hash common.Hash, parents []*types.Header) (*Snapshot, error) {
   460  	var (
   461  		headers []*types.Header
   462  		snap    *Snapshot
   463  	)
   464  
   465  	for snap == nil {
   466  		if s, ok := self.recents.Get(hash); ok {
   467  			snap = s.(*Snapshot)
   468  			break
   469  		}
   470  
   471  		if number%checkpointInterval == 0 {
   472  			if s, err := loadSnapShot(self.db, hash); err == nil {
   473  				snap = s
   474  				break
   475  			}
   476  		}
   477  
   478  		if number == 0 {
   479  			genesis := chain.GetHeaderByNumber(0)
   480  			// verify genesis hash match
   481  			if err := self.VerifyHeader(chain, genesis, false); err != nil {
   482  				return nil, err
   483  			}
   484  
   485  			signers := make([]common.Address, len(genesis.Extra)/common.AddressLength)
   486  			for i := 0; i < len(signers); i++ {
   487  				copy(signers[i][:], genesis.Extra[i*common.AddressLength:])
   488  			}
   489  			snap = newSnapshot(0, genesis.Hash(), signers)
   490  			if err := snap.store(self.db); err != nil {
   491  				return nil, err
   492  			}
   493  			break
   494  		}
   495  
   496  		var header *types.Header
   497  		if len(parents) > 0 {
   498  			header = parents[len(parents)-1]
   499  			if header.Hash() != hash || header.Number.Uint64() != number {
   500  				return nil, consensus.ErrUnknownAncestor
   501  			}
   502  			parents = parents[:len(parents)-1]
   503  		} else {
   504  			header = chain.GetHeader(hash, number)
   505  			if header == nil {
   506  				return nil, consensus.ErrUnknownAncestor
   507  			}
   508  		}
   509  		headers = append(headers, header)
   510  		number, hash = number-1, header.ParentHash
   511  	}
   512  
   513  	for i := 0; i < len(headers)/2; i++ {
   514  		headers[i], headers[len(headers)-1-i] = headers[len(headers)-1-i], headers[i]
   515  	}
   516  
   517  	snap, err := snap.apply(headers)
   518  	if err != nil {
   519  		return nil, err
   520  	}
   521  
   522  	self.recents.Add(snap.Hash, snap)
   523  
   524  	if snap.Number%checkpointInterval == 0 && len(headers) > 0 {
   525  		if err = snap.store(self.db); err != nil {
   526  			return nil, err
   527  		}
   528  		log.Trace("Stored ppow snapshot to disk", "number", snap.Number, "hash", snap.Hash)
   529  	}
   530  
   531  	return snap, err
   532  }
   533  
   534  // Some weird constants to avoid constant memory allocs for them.
   535  var (
   536  	expDiffPeriod = big.NewInt(100000)
   537  	big1          = big.NewInt(1)
   538  	big2          = big.NewInt(2)
   539  	big9          = big.NewInt(9)
   540  	big10         = big.NewInt(10)
   541  	bigMinus99    = big.NewInt(-99)
   542  	big2999999    = big.NewInt(2999999)
   543  )
   544  
   545  // calcDifficultyByzantium is the difficulty adjustment algorithm. It returns
   546  // the difficulty that a new block should have when created at time given the
   547  // parent block's time and difficulty. The calculation uses the Byzantium rules.
   548  func calcDifficultyByzantium(time uint64, parent *types.Header) *big.Int {
   549  	// https://github.com/ethereum/EIPs/issues/100.
   550  	// algorithm:
   551  	// diff = (parent_diff +
   552  	//         (parent_diff / 2048 * max((2 if len(parent.uncles) else 1) - ((timestamp - parent.timestamp) // 9), -99))
   553  	//        ) + 2^(periodCount - 2)
   554  
   555  	bigTime := new(big.Int).SetUint64(time)
   556  	bigParentTime := new(big.Int).Set(parent.Time)
   557  
   558  	// holds intermediate values to make the algo easier to read & audit
   559  	x := new(big.Int)
   560  	y := new(big.Int)
   561  
   562  	// (2 if len(parent_uncles) else 1) - (block_timestamp - parent_timestamp) // 9
   563  	x.Sub(bigTime, bigParentTime)
   564  	x.Div(x, big9)
   565  	if parent.UncleHash == types.EmptyUncleHash {
   566  		x.Sub(big1, x)
   567  	} else {
   568  		x.Sub(big2, x)
   569  	}
   570  	// max((2 if len(parent_uncles) else 1) - (block_timestamp - parent_timestamp) // 9, -99)
   571  	if x.Cmp(bigMinus99) < 0 {
   572  		x.Set(bigMinus99)
   573  	}
   574  	// parent_diff + (parent_diff / 2048 * max((2 if len(parent.uncles) else 1) - ((timestamp - parent.timestamp) // 9), -99))
   575  	y.Div(parent.Difficulty, params.DifficultyBoundDivisor)
   576  	x.Mul(y, x)
   577  	x.Add(parent.Difficulty, x)
   578  
   579  	// minimum difficulty can ever be (before exponential factor)
   580  	if x.Cmp(params.MinimumDifficulty) < 0 {
   581  		x.Set(params.MinimumDifficulty)
   582  	}
   583  /*
   584  	// calculate a fake block numer for the ice-age delay:
   585  	//   https://github.com/ethereum/EIPs/pull/669
   586  	//   fake_block_number = min(0, block.number - 3_000_000
   587  	fakeBlockNumber := new(big.Int)
   588  	if parent.Number.Cmp(big2999999) >= 0 {
   589  		fakeBlockNumber = fakeBlockNumber.Sub(parent.Number, big2999999) // Note, parent is 1 less than the actual block number
   590  	}
   591  	// for the exponential factor
   592  	periodCount := fakeBlockNumber
   593  	periodCount.Div(periodCount, expDiffPeriod)
   594  
   595  	// the exponential factor, commonly referred to as "the bomb"
   596  	// diff = diff + 2^(periodCount - 2)
   597  	if periodCount.Cmp(big1) > 0 {
   598  		y.Sub(periodCount, big2)
   599  		y.Exp(big2, y, nil)
   600  		x.Add(x, y)
   601  	}
   602  */
   603  	return x
   604  }
   605  
   606  // calcDifficultyHomestead is the difficulty adjustment algorithm. It returns
   607  // the difficulty that a new block should have when created at time given the
   608  // parent block's time and difficulty. The calculation uses the Homestead rules.
   609  func calcDifficultyHomestead(time uint64, parent *types.Header) *big.Int {
   610  	// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2.md
   611  	// algorithm:
   612  	// diff = (parent_diff +
   613  	//         (parent_diff / 2048 * max(1 - (block_timestamp - parent_timestamp) // 10, -99))
   614  	//        ) + 2^(periodCount - 2)
   615  
   616  	bigTime := new(big.Int).SetUint64(time)
   617  	bigParentTime := new(big.Int).Set(parent.Time)
   618  
   619  	// holds intermediate values to make the algo easier to read & audit
   620  	x := new(big.Int)
   621  	y := new(big.Int)
   622  
   623  	// 1 - (block_timestamp - parent_timestamp) // 10
   624  	x.Sub(bigTime, bigParentTime)
   625  	x.Div(x, big10)
   626  	x.Sub(big1, x)
   627  
   628  	// max(1 - (block_timestamp - parent_timestamp) // 10, -99)
   629  	if x.Cmp(bigMinus99) < 0 {
   630  		x.Set(bigMinus99)
   631  	}
   632  	// (parent_diff + parent_diff // 2048 * max(1 - (block_timestamp - parent_timestamp) // 10, -99))
   633  	y.Div(parent.Difficulty, params.DifficultyBoundDivisor)
   634  	x.Mul(y, x)
   635  	x.Add(parent.Difficulty, x)
   636  
   637  	// minimum difficulty can ever be (before exponential factor)
   638  	if x.Cmp(params.MinimumDifficulty) < 0 {
   639  		x.Set(params.MinimumDifficulty)
   640  	}
   641  	// for the exponential factor
   642  	periodCount := new(big.Int).Add(parent.Number, big1)
   643  	periodCount.Div(periodCount, expDiffPeriod)
   644  
   645  	// the exponential factor, commonly referred to as "the bomb"
   646  	// diff = diff + 2^(periodCount - 2)
   647  	if periodCount.Cmp(big1) > 0 {
   648  		y.Sub(periodCount, big2)
   649  		y.Exp(big2, y, nil)
   650  		x.Add(x, y)
   651  	}
   652  	return x
   653  }
   654  
   655  // calcDifficultyFrontier is the difficulty adjustment algorithm. It returns the
   656  // difficulty that a new block should have when created at time given the parent
   657  // block's time and difficulty. The calculation uses the Frontier rules.
   658  func calcDifficultyFrontier(time uint64, parent *types.Header) *big.Int {
   659  	diff := new(big.Int)
   660  	adjust := new(big.Int).Div(parent.Difficulty, params.DifficultyBoundDivisor)
   661  	bigTime := new(big.Int)
   662  	bigParentTime := new(big.Int)
   663  
   664  	bigTime.SetUint64(time)
   665  	bigParentTime.Set(parent.Time)
   666  
   667  	if bigTime.Sub(bigTime, bigParentTime).Cmp(params.DurationLimit) < 0 {
   668  		diff.Add(parent.Difficulty, adjust)
   669  	} else {
   670  		diff.Sub(parent.Difficulty, adjust)
   671  	}
   672  	if diff.Cmp(params.MinimumDifficulty) < 0 {
   673  		diff.Set(params.MinimumDifficulty)
   674  	}
   675  
   676  	periodCount := new(big.Int).Add(parent.Number, big1)
   677  	periodCount.Div(periodCount, expDiffPeriod)
   678  	if periodCount.Cmp(big1) > 0 {
   679  		// diff = diff + 2^(periodCount - 2)
   680  		expDiff := periodCount.Sub(periodCount, big2)
   681  		expDiff.Exp(big2, expDiff, nil)
   682  		diff.Add(diff, expDiff)
   683  		diff = math.BigMax(diff, params.MinimumDifficulty)
   684  	}
   685  	return diff
   686  }
   687  
   688  // VerifySeal implements consensus.Engine, checking whether the given block satisfies
   689  // the PoW difficulty requirements.
   690  func (ethash *Ethash) VerifySeal(chain consensus.ChainReader, header *types.Header) error {
   691  	// If we're running a fake PoW, accept any seal as valid
   692  	if ethash.config.PowMode == ModeFake || ethash.config.PowMode == ModeFullFake {
   693  		time.Sleep(ethash.fakeDelay)
   694  		if ethash.fakeFail == header.Number.Uint64() {
   695  			return errInvalidPoW
   696  		}
   697  		return nil
   698  	}
   699  
   700  	// If we're running a shared PoW, delegate verification to it
   701  	if ethash.shared != nil {
   702  		return ethash.shared.VerifySeal(chain, header)
   703  	}
   704  	// Sanity check that the block number is below the lookup table size (60M blocks)
   705  	number := header.Number.Uint64()
   706  	if number/epochLength >= maxEpoch {
   707  		// Go < 1.7 cannot calculate new cache/dataset sizes (no fast prime check)
   708  		return errNonceOutOfRange
   709  	}
   710  	// Ensure that we have a valid difficulty for the block
   711  	if header.Difficulty.Sign() <= 0 {
   712  		return errInvalidDifficulty
   713  	}
   714  	// Recompute the digest and PoW value and verify against the header
   715  	cache := ethash.cache(number)
   716  
   717  	size := datasetSize(number)
   718  	if ethash.config.PowMode == ModeTest {
   719  		size = 32 * 1024
   720  	}
   721  	digest, result := hashimotoLight(size, cache.cache, header.HashNoNonce().Bytes(), header.Nonce.Uint64())
   722  	// Caches are unmapped in a finalizer. Ensure that the cache stays live
   723  	// until after the call to hashimotoLight so it's not unmapped while being used.
   724  	runtime.KeepAlive(cache)
   725  
   726  	if !bytes.Equal(header.MixDigest[:], digest) {
   727  		return errInvalidMixDigest
   728  	}
   729  	target := new(big.Int).Div(maxUint256, header.Difficulty)
   730  	if new(big.Int).SetBytes(result).Cmp(target) > 0 {
   731  		return errInvalidPoW
   732  	}
   733  	return nil
   734  }
   735  
   736  // Prepare implements consensus.Engine, initializing the difficulty field of a
   737  // header to conform to the ethash protocol. The changes are done inline.
   738  func (ethash *Ethash) Prepare(chain consensus.ChainReader, header *types.Header, mining bool) error {
   739  	parent := chain.GetHeader(header.ParentHash, header.Number.Uint64()-1)
   740  	if parent == nil {
   741  		return consensus.ErrUnknownAncestor
   742  	}
   743  
   744  	if mining {
   745  		snap, err := ethash.snapshot(chain, parent.Number.Uint64(), parent.Hash(), nil)
   746  		if err != nil {
   747  			return err
   748  		}
   749  
   750  		err = snap.isLegal4Sign(header.Coinbase)
   751  		if err != nil {
   752  			return err
   753  		}
   754  	}
   755  
   756  	header.Difficulty = ethash.CalcDifficulty(chain, header.Time.Uint64(), parent)
   757  
   758  	if len(header.Extra) < extraVanity {
   759  		header.Extra = append(header.Extra, make([]byte, extraVanity-len(header.Extra))...)
   760  	}
   761  	header.Extra = header.Extra[:extraVanity]
   762  	header.Extra = append(header.Extra, make([]byte, extraSeal)...)
   763  
   764  	return nil
   765  }
   766  
   767  // Finalize implements consensus.Engine, accumulating the block and uncle rewards,
   768  // setting the final state and assembling the block.
   769  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) {
   770  	// Accumulate any block and uncle rewards and commit the final state root
   771  	AccumulateRewards(chain.Config(), state, header, uncles)
   772  	header.Root = state.IntermediateRoot(true /*chain.Config().IsEIP158(header.Number)*/)
   773  
   774  	// Header seems complete, assemble into a block and return
   775  	return types.NewBlock(header, txs, uncles, receipts), nil
   776  }
   777  
   778  // Some weird constants to avoid constant memory allocs for them.
   779  var (
   780  	big8  = big.NewInt(8)
   781  	big32 = big.NewInt(32)
   782  )
   783  
   784  // AccumulateRewards credits the coinbase of the given block with the mining
   785  // reward. The total reward consists of the static block reward and rewards for
   786  // included uncles. The coinbase of each uncle block is also rewarded.
   787  // TODO (karalabe): Move the chain maker into this package and make this private!
   788  func AccumulateRewards(config *params.ChainConfig, state *state.StateDB, header *types.Header, uncles []*types.Header) {
   789  	//if header.Number.Uint64() == 29900 {
   790  	//	fmt.Println("got 29900")
   791  	//}
   792  	// Select the correct block reward based on chain progression
   793  	//blockReward := frontierBlockReward
   794  	//if config.IsByzantium(header.Number) {
   795  	//	blockReward := byzantiumBlockReward
   796  	//}
   797  	// Accumulate the rewards for the miner and any included uncles
   798  	//reward := new(big.Int).Set(blockReward)
   799  	//r := new(big.Int)
   800  	//for _, uncle := range uncles {
   801  	//	r.Add(uncle.Number, big8)
   802  	//	r.Sub(r, header.Number)
   803  	//	r.Mul(r, blockReward)
   804  	//	r.Div(r, big8)
   805  	//	state.AddBalance(uncle.Coinbase, r)
   806  	//
   807  	//	r.Div(blockReward, big32)
   808  	//	reward.Add(reward, r)
   809  	//}
   810  	//state.AddBalance(header.Coinbase, reward)
   811  }