github.com/marconiprotocol/go-methereum-lite@v0.0.0-20190918214227-3cd8b06fcf99/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-ethereum 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-ethereum 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  	"bytes"
    21  	"errors"
    22  	"fmt"
    23  	"math/big"
    24  	"runtime"
    25  	"time"
    26  
    27  	mapset "github.com/deckarep/golang-set"
    28  	"github.com/MarconiProtocol/go-methereum-lite/common"
    29  	"github.com/MarconiProtocol/go-methereum-lite/common/math"
    30  	"github.com/MarconiProtocol/go-methereum-lite/consensus"
    31  	"github.com/MarconiProtocol/go-methereum-lite/consensus/misc"
    32  	"github.com/MarconiProtocol/go-methereum-lite/core/state"
    33  	"github.com/MarconiProtocol/go-methereum-lite/core/types"
    34  	"github.com/MarconiProtocol/go-methereum-lite/log"
    35  	"github.com/MarconiProtocol/go-methereum-lite/params"
    36  	"github.com/MarconiProtocol/go-methereum-lite/rlp"
    37  	"golang.org/x/crypto/sha3"
    38  	"github.com/MarconiProtocol/marconi-cryptonight"
    39  )
    40  
    41  // Ethash proof-of-work protocol constants.
    42  var (
    43  	SoftLaunchBlockReward           = big.NewInt(1e+18)                               // Block reward in wei for successfully mining a block during the soft launch period
    44  	MIP1BlockReward                 = big.NewInt(2e+18)                               // Block reward in wei for successfully mining a block upward from MIP1Block
    45  	MIP2BlockReward                 = big.NewInt(5e+18)                               // Block reward in wei for successfully mining a block upward from MIP2Block
    46  	// Note: big.NewInt(int64) overflows for higher digits, use SetString for 10 or higher block rewards
    47  	MIP3BlockReward, _              = new(big.Int).SetString("10000000000000000000", 10) // Block reward in wei for successfully mining a block upward from MIP3Block
    48  	MIP4BlockReward                 = big.NewInt(5e+18)                               // Block reward in wei for successfully mining a block upward from MIP4Block
    49  	DefaultBlockReward              = big.NewInt(3e+18)                               // Default block reward
    50  	maxUncles                       = 2                                                  // Maximum number of uncles allowed in a single block
    51  	allowedFutureBlockTime          = 15 * time.Second                                   // Max time from current time allowed for blocks, before they're considered future blocks
    52  )
    53  
    54  // Various error messages to mark blocks invalid. These should be private to
    55  // prevent engine specific errors from being referenced in the remainder of the
    56  // codebase, inherently breaking if the engine is swapped out. Please put common
    57  // error types into the consensus package.
    58  var (
    59  	errLargeBlockTime    = errors.New("timestamp too big")
    60  	errZeroBlockTime     = errors.New("timestamp equals parent's")
    61  	errTooManyUncles     = errors.New("too many uncles")
    62  	errDuplicateUncle    = errors.New("duplicate uncle")
    63  	errUncleIsAncestor   = errors.New("uncle is ancestor")
    64  	errDanglingUncle     = errors.New("uncle's parent is not ancestor")
    65  	errInvalidDifficulty = errors.New("non-positive difficulty")
    66  	errInvalidMixDigest  = errors.New("invalid mix digest")
    67  	errInvalidPoW        = errors.New("invalid proof-of-work")
    68  )
    69  
    70  // Author implements consensus.Engine, returning the header's coinbase as the
    71  // proof-of-work verified author of the block.
    72  func (ethash *Ethash) Author(header *types.Header) (common.Address, error) {
    73  	return header.Coinbase, nil
    74  }
    75  
    76  // VerifyHeader checks whether a header conforms to the consensus rules of the
    77  // stock Ethereum ethash engine.
    78  func (ethash *Ethash) VerifyHeader(chain consensus.ChainReader, header *types.Header, seal bool) error {
    79  	// If we're running a full engine faking, accept any input as valid
    80  	if ethash.config.PowMode == ModeFullFake {
    81  		return nil
    82  	}
    83  	// Short circuit if the header is known, or it's parent not
    84  	number := header.Number.Uint64()
    85  	if chain.GetHeader(header.Hash(), number) != nil {
    86  		return nil
    87  	}
    88  	parent := chain.GetHeader(header.ParentHash, number-1)
    89  	if parent == nil {
    90  		return consensus.ErrUnknownAncestor
    91  	}
    92  	// Sanity checks passed, do a proper verification
    93  	return ethash.verifyHeader(chain, header, parent, false, seal)
    94  }
    95  
    96  // VerifyHeaders is similar to VerifyHeader, but verifies a batch of headers
    97  // concurrently. The method returns a quit channel to abort the operations and
    98  // a results channel to retrieve the async verifications.
    99  func (ethash *Ethash) VerifyHeaders(chain consensus.ChainReader, headers []*types.Header, seals []bool) (chan<- struct{}, <-chan error) {
   100  	// If we're running a full engine faking, accept any input as valid
   101  	if ethash.config.PowMode == ModeFullFake || len(headers) == 0 {
   102  		abort, results := make(chan struct{}), make(chan error, len(headers))
   103  		for i := 0; i < len(headers); i++ {
   104  			results <- nil
   105  		}
   106  		return abort, results
   107  	}
   108  
   109  	// Spawn as many workers as allowed threads
   110  	workers := runtime.GOMAXPROCS(0)
   111  	if len(headers) < workers {
   112  		workers = len(headers)
   113  	}
   114  
   115  	// Create a task channel and spawn the verifiers
   116  	var (
   117  		inputs = make(chan int)
   118  		done   = make(chan int, workers)
   119  		errors = make([]error, len(headers))
   120  		abort  = make(chan struct{})
   121  	)
   122  	for i := 0; i < workers; i++ {
   123  		go func() {
   124  			for index := range inputs {
   125  				errors[index] = ethash.verifyHeaderWorker(chain, headers, seals, index)
   126  				done <- index
   127  			}
   128  		}()
   129  	}
   130  
   131  	errorsOut := make(chan error, len(headers))
   132  	go func() {
   133  		defer close(inputs)
   134  		var (
   135  			in, out = 0, 0
   136  			checked = make([]bool, len(headers))
   137  			inputs  = inputs
   138  		)
   139  		for {
   140  			select {
   141  			case inputs <- in:
   142  				if in++; in == len(headers) {
   143  					// Reached end of headers. Stop sending to workers.
   144  					inputs = nil
   145  				}
   146  			case index := <-done:
   147  				for checked[index] = true; checked[out]; out++ {
   148  					errorsOut <- errors[out]
   149  					if out == len(headers)-1 {
   150  						return
   151  					}
   152  				}
   153  			case <-abort:
   154  				return
   155  			}
   156  		}
   157  	}()
   158  	return abort, errorsOut
   159  }
   160  
   161  func (ethash *Ethash) verifyHeaderWorker(chain consensus.ChainReader, headers []*types.Header, seals []bool, index int) error {
   162  	var parent *types.Header
   163  	if index == 0 {
   164  		parent = chain.GetHeader(headers[0].ParentHash, headers[0].Number.Uint64()-1)
   165  	} else if headers[index-1].Hash() == headers[index].ParentHash {
   166  		parent = headers[index-1]
   167  	}
   168  	if parent == nil {
   169  		return consensus.ErrUnknownAncestor
   170  	}
   171  	if chain.GetHeader(headers[index].Hash(), headers[index].Number.Uint64()) != nil {
   172  		return nil // known block
   173  	}
   174  	return ethash.verifyHeader(chain, headers[index], parent, false, seals[index])
   175  }
   176  
   177  // VerifyUncles verifies that the given block's uncles conform to the consensus
   178  // rules of the stock Ethereum ethash engine.
   179  func (ethash *Ethash) VerifyUncles(chain consensus.ChainReader, block *types.Block) error {
   180  	// If we're running a full engine faking, accept any input as valid
   181  	if ethash.config.PowMode == ModeFullFake {
   182  		return nil
   183  	}
   184  	// Verify that there are at most 2 uncles included in this block
   185  	if len(block.Uncles()) > maxUncles {
   186  		return errTooManyUncles
   187  	}
   188  	// Gather the set of past uncles and ancestors
   189  	uncles, ancestors := mapset.NewSet(), make(map[common.Hash]*types.Header)
   190  
   191  	number, parent := block.NumberU64()-1, block.ParentHash()
   192  	for i := 0; i < 7; i++ {
   193  		ancestor := chain.GetBlock(parent, number)
   194  		if ancestor == nil {
   195  			break
   196  		}
   197  		ancestors[ancestor.Hash()] = ancestor.Header()
   198  		for _, uncle := range ancestor.Uncles() {
   199  			uncles.Add(uncle.Hash())
   200  		}
   201  		parent, number = ancestor.ParentHash(), number-1
   202  	}
   203  	ancestors[block.Hash()] = block.Header()
   204  	uncles.Add(block.Hash())
   205  
   206  	// Verify each of the uncles that it's recent, but not an ancestor
   207  	for _, uncle := range block.Uncles() {
   208  		// Make sure every uncle is rewarded only once
   209  		hash := uncle.Hash()
   210  		if uncles.Contains(hash) {
   211  			return errDuplicateUncle
   212  		}
   213  		uncles.Add(hash)
   214  
   215  		// Make sure the uncle has a valid ancestry
   216  		if ancestors[hash] != nil {
   217  			return errUncleIsAncestor
   218  		}
   219  		if ancestors[uncle.ParentHash] == nil || uncle.ParentHash == block.ParentHash() {
   220  			return errDanglingUncle
   221  		}
   222  		if err := ethash.verifyHeader(chain, uncle, ancestors[uncle.ParentHash], true, true); err != nil {
   223  			return err
   224  		}
   225  	}
   226  	return nil
   227  }
   228  
   229  // verifyHeader checks whether a header conforms to the consensus rules of the
   230  // stock Ethereum ethash engine.
   231  // See YP section 4.3.4. "Block Header Validity"
   232  func (ethash *Ethash) verifyHeader(chain consensus.ChainReader, header, parent *types.Header, uncle bool, seal bool) error {
   233  	// Ensure that the header's extra-data section is of a reasonable size
   234  	if uint64(len(header.Extra)) > params.MaximumExtraDataSize {
   235  		return fmt.Errorf("extra-data too long: %d > %d", len(header.Extra), params.MaximumExtraDataSize)
   236  	}
   237  	// Verify the header's timestamp
   238  	if uncle {
   239  		if header.Time.Cmp(math.MaxBig256) > 0 {
   240  			return errLargeBlockTime
   241  		}
   242  	} else {
   243  		if header.Time.Cmp(big.NewInt(time.Now().Add(allowedFutureBlockTime).Unix())) > 0 {
   244  			return consensus.ErrFutureBlock
   245  		}
   246  	}
   247  	if header.Time.Cmp(parent.Time) <= 0 {
   248  		return errZeroBlockTime
   249  	}
   250  	// Verify the block's difficulty based in it's timestamp and parent's difficulty
   251  	expected := ethash.CalcDifficulty(chain, header.Time.Uint64(), parent)
   252  
   253  	if expected.Cmp(header.Difficulty) != 0 {
   254  		return fmt.Errorf("invalid difficulty: have %v, want %v", header.Difficulty, expected)
   255  	}
   256  	// Verify that the gas limit is <= 2^63-1
   257  	cap := uint64(0x7fffffffffffffff)
   258  	if header.GasLimit > cap {
   259  		return fmt.Errorf("invalid gasLimit: have %v, max %v", header.GasLimit, cap)
   260  	}
   261  	// Verify that the gasUsed is <= gasLimit
   262  	if header.GasUsed > header.GasLimit {
   263  		return fmt.Errorf("invalid gasUsed: have %d, gasLimit %d", header.GasUsed, header.GasLimit)
   264  	}
   265  
   266  	// Verify that the gas limit remains within allowed bounds
   267  	diff := int64(parent.GasLimit) - int64(header.GasLimit)
   268  	if diff < 0 {
   269  		diff *= -1
   270  	}
   271  	limit := parent.GasLimit / params.GasLimitBoundDivisor
   272  
   273  	if uint64(diff) >= limit || header.GasLimit < params.MinGasLimit {
   274  		return fmt.Errorf("invalid gas limit: have %d, want %d += %d", header.GasLimit, parent.GasLimit, limit)
   275  	}
   276  	// Verify that the block number is parent's +1
   277  	if diff := new(big.Int).Sub(header.Number, parent.Number); diff.Cmp(big.NewInt(1)) != 0 {
   278  		return consensus.ErrInvalidNumber
   279  	}
   280  	// Verify the engine specific seal securing the block
   281  	if seal {
   282  		if err := ethash.VerifySeal(chain, header); err != nil {
   283  			return err
   284  		}
   285  	}
   286  	// If all checks passed, validate any special fields for hard forks
   287  	if err := misc.VerifyDAOHeaderExtraData(chain.Config(), header); err != nil {
   288  		return err
   289  	}
   290  	if err := misc.VerifyForkHashes(chain.Config(), header, uncle); err != nil {
   291  		return err
   292  	}
   293  	return nil
   294  }
   295  
   296  // CalcDifficulty is the difficulty adjustment algorithm. It returns
   297  // the difficulty that a new block should have when created at time
   298  // given the parent block's time and difficulty.
   299  func (ethash *Ethash) CalcDifficulty(chain consensus.ChainReader, time uint64, parent *types.Header) *big.Int {
   300  	return CalcDifficulty(chain.Config(), time, parent)
   301  }
   302  
   303  // CalcDifficulty is the difficulty adjustment algorithm. It returns
   304  // the difficulty that a new block should have when created at time
   305  // given the parent block's time and difficulty.
   306  func CalcDifficulty(config *params.ChainConfig, time uint64, parent *types.Header) *big.Int {
   307  	next := new(big.Int).Add(parent.Number, big1)
   308  	switch {
   309  	case config.IsByzantium(next):
   310  		return calcDifficultyByzantium(time, parent)
   311  	default:
   312  		// still use Byzantium's algorithm, but log an warning
   313  		log.Warn("CalcDifficulty found unknown release version in ChainConfig")
   314  		return calcDifficultyByzantium(time, parent)
   315  	}
   316  }
   317  
   318  // Some weird constants to avoid constant memory allocs for them.
   319  var (
   320  	big1          = big.NewInt(1)
   321  	big3          = big.NewInt(3)
   322  	big4          = big.NewInt(4)
   323  	big9          = big.NewInt(9)
   324  	bigMinus99    = big.NewInt(-99)
   325  )
   326  
   327  // calcDifficultyByzantium is the difficulty adjustment algorithm. It returns
   328  // the difficulty that a new block should have when created at time given the
   329  // parent block's time and difficulty. The calculation uses the Byzantium rules.
   330  func calcDifficultyByzantium(time uint64, parent *types.Header) *big.Int {
   331  	// The goal of this difficulty calculation is to stabilize the
   332  	// average block time even as hash power is added or removed from
   333  	// the network. Let T be the time between the new block and
   334  	// previous block. If T is short enough, we assume this indicates
   335  	// hashing power was added, so we increase the difficulty to make
   336  	// blocks take longer. If T is already close to our desired
   337  	// average block time, we leave the difficulty unchanged. If T is
   338  	// too long, then hashing power might have been removed, so we
   339  	// decrease the difficulty to get back to the desired average
   340  	// block time.
   341  	//
   342  	// Ethereum targets a ~14 second block time, while Marconi targets
   343  	// a ~32 second block time. Here's how the difficulty changes for
   344  	// Marconi:
   345  	//
   346  	// If block time is:    then difficulty change is:
   347  	//   0 to  8 sec          ~0.15% increase
   348  	//   9 to 17 sec          ~0.10% increase
   349  	//  18 to 26 sec          ~0.05% increase
   350  	//  27 to 35 sec          no change
   351  	//  36 to 44 sec          ~0.05% decrease
   352  	//  45 to 53 sec          ~0.10% decrease
   353  	//      ...                     ...
   354  	//    >= 918 sec          ~5.00% decrease
   355  	//
   356  	// Except in the case of uncles. When an uncle is present in the
   357  	// parent block, we shift the above buckets by 1 position so that
   358  	// it's more likely that the difficulty will increase. See
   359  	// https://gitlab.neji.vm.tc/marconi/EIPs/issues/100 for why the formula
   360  	// takes uncles into account.
   361  	//
   362  	// If we ignore uncles and the cap on decrease amount, the
   363  	// simplified mathematical formula is:
   364  	//
   365  	// difficulty = parent_difficulty + (3 - T/9) * parent_difficulty / 2048
   366  	//
   367  	// The full formula is:
   368  	//
   369  	// difficulty = parent_difficulty +
   370  	//   max(-99, (4 if uncles else 3) - T/9) * parent_difficulty / 2048
   371  
   372  	bigTime := new(big.Int).SetUint64(time)
   373  	bigParentTime := new(big.Int).Set(parent.Time)
   374  
   375  	// Holders for intermediate values.
   376  	x := new(big.Int)
   377  	y := new(big.Int)
   378  
   379  	// T/9
   380  	x.Sub(bigTime, bigParentTime)
   381  	x.Div(x, big9)
   382  	// (4 if uncles else 3) - T/9
   383  	if parent.UncleHash == types.EmptyUncleHash {
   384  		x.Sub(big3, x)
   385  	} else {
   386  		x.Sub(big4, x)
   387  	}
   388  	// max(-99, (4 if uncles else 3) - T/9)
   389  	if x.Cmp(bigMinus99) < 0 {
   390  		x.Set(bigMinus99)
   391  	}
   392  	// parent_difficulty + max(-99, (4 if uncles else 3) - T/9) * parent_difficulty / 2048
   393  	y.Div(parent.Difficulty, params.DifficultyBoundDivisor)
   394  	x.Mul(y, x)
   395  	x.Add(parent.Difficulty, x)
   396  
   397  	// Minimum the difficulty can ever be.
   398  	if x.Cmp(params.MinimumDifficulty) < 0 {
   399  		x.Set(params.MinimumDifficulty)
   400  	}
   401  
   402  	// TODO: determine if we need to have ice age logic which
   403  	// exponentially jacks up the difficulty after a certain number of
   404  	// blocks. Ice age is used in Ethereum to encourage users to
   405  	// moving to new hard forks. Adding the logic is simple, however
   406  	// it might be more preferable to incentivize upgrades in other
   407  	// ways.
   408  
   409  	return x
   410  }
   411  
   412  // VerifySeal implements consensus.Engine, checking whether the given block satisfies
   413  // the PoW difficulty requirements.
   414  func (ethash *Ethash) VerifySeal(chain consensus.ChainReader, header *types.Header) error {
   415  	return ethash.verifySeal(chain, header, false)
   416  }
   417  
   418  // verifySeal checks whether a block satisfies the PoW difficulty requirements,
   419  // either using the usual ethash cache for it, or alternatively using a full DAG
   420  // to make remote mining fast.
   421  func (ethash *Ethash) verifySeal(chain consensus.ChainReader, header *types.Header, fulldag bool) error {
   422  	// If we're running a fake PoW, accept any seal as valid
   423  	if ethash.config.PowMode == ModeFake || ethash.config.PowMode == ModeFullFake {
   424  		time.Sleep(ethash.fakeDelay)
   425  		if ethash.fakeFail == header.Number.Uint64() {
   426  			return errInvalidPoW
   427  		}
   428  		return nil
   429  	}
   430  	// If we're running a shared PoW, delegate verification to it
   431  	if ethash.shared != nil {
   432  		return ethash.shared.verifySeal(chain, header, fulldag)
   433  	}
   434  	// Ensure that we have a valid difficulty for the block
   435  	if header.Difficulty.Sign() <= 0 {
   436  		return errInvalidDifficulty
   437  	}
   438  	// Recompute the digest and PoW value and verify against the header
   439  	var digest []byte
   440  	var result []byte
   441  	if ethash.config.PowMode == ModeQuickTest {
   442  		digest, result = quickHash(ethash.SealHash(header).Bytes(), header.Nonce.Uint64())
   443  	} else if ethash.config.PowMode == ModeCryptonight {
   444  		digest, result = cryptonight.HashVariant4ForEthereumHeader(
   445  			ethash.SealHash(header).Bytes(), header.Nonce.Uint64(), header.Number.Uint64())
   446  	} else {
   447  		number := header.Number.Uint64()
   448  
   449  		// If fast-but-heavy PoW verification was requested, use an ethash dataset
   450  		if fulldag {
   451  			dataset := ethash.dataset(number, true)
   452  			if dataset.generated() {
   453  				digest, result = hashimotoFull(dataset.dataset, ethash.SealHash(header).Bytes(), header.Nonce.Uint64())
   454  
   455  				// Datasets are unmapped in a finalizer. Ensure that the dataset stays alive
   456  				// until after the call to hashimotoFull so it's not unmapped while being used.
   457  				runtime.KeepAlive(dataset)
   458  			} else {
   459  				// Dataset not yet generated, don't hang, use a cache instead
   460  				fulldag = false
   461  			}
   462  		}
   463  		// If slow-but-light PoW verification was requested (or DAG not yet ready), use an ethash cache
   464  		if !fulldag {
   465  			cache := ethash.cache(number)
   466  			size := datasetSize(number)
   467  			if ethash.config.PowMode == ModeTest {
   468  				size = 32 * 1024
   469  			}
   470  			digest, result = hashimotoLight(size, cache.cache, ethash.SealHash(header).Bytes(), header.Nonce.Uint64())
   471  
   472  			// Caches are unmapped in a finalizer. Ensure that the cache stays alive
   473  			// until after the call to hashimotoLight so it's not unmapped while being used.
   474  			runtime.KeepAlive(cache)
   475  		}
   476  	}
   477  	// Verify the calculated values against the ones provided in the header
   478  	if !bytes.Equal(header.MixDigest[:], digest) {
   479  		return errInvalidMixDigest
   480  	}
   481  	target := new(big.Int).Div(two256, header.Difficulty)
   482  	if new(big.Int).SetBytes(result).Cmp(target) > 0 {
   483  		return errInvalidPoW
   484  	}
   485  	return nil
   486  }
   487  
   488  // Prepare implements consensus.Engine, initializing the difficulty field of a
   489  // header to conform to the ethash protocol. The changes are done inline.
   490  func (ethash *Ethash) Prepare(chain consensus.ChainReader, header *types.Header) error {
   491  	parent := chain.GetHeader(header.ParentHash, header.Number.Uint64()-1)
   492  	if parent == nil {
   493  		return consensus.ErrUnknownAncestor
   494  	}
   495  	header.Difficulty = ethash.CalcDifficulty(chain, header.Time.Uint64(), parent)
   496  	return nil
   497  }
   498  
   499  // Finalize implements consensus.Engine, accumulating the block and uncle rewards,
   500  // setting the final state and assembling the block.
   501  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) {
   502  	// Accumulate any block and uncle rewards and commit the final state root
   503  	accumulateRewards(chain.Config(), state, header, uncles)
   504  	header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number))
   505  
   506  	// Header seems complete, assemble into a block and return
   507  	return types.NewBlock(header, txs, uncles, receipts), nil
   508  }
   509  
   510  // SealHash returns the hash of a block prior to it being sealed.
   511  func (ethash *Ethash) SealHash(header *types.Header) (hash common.Hash) {
   512  	hasher := sha3.NewLegacyKeccak256()
   513  
   514  	rlp.Encode(hasher, []interface{}{
   515  		header.ParentHash,
   516  		header.UncleHash,
   517  		header.Coinbase,
   518  		header.Root,
   519  		header.TxHash,
   520  		header.ReceiptHash,
   521  		header.Bloom,
   522  		header.Difficulty,
   523  		header.Number,
   524  		header.GasLimit,
   525  		header.GasUsed,
   526  		header.Time,
   527  		header.Extra,
   528  	})
   529  	hasher.Sum(hash[:0])
   530  	return hash
   531  }
   532  
   533  // Some weird constants to avoid constant memory allocs for them.
   534  var (
   535  	big8  = big.NewInt(8)
   536  	big32 = big.NewInt(32)
   537  )
   538  
   539  // AccumulateRewards credits the coinbase of the given block with the mining
   540  // reward. The total reward consists of the static block reward and rewards for
   541  // included uncles. The coinbase of each uncle block is also rewarded.
   542  func accumulateRewards(config *params.ChainConfig, state *state.StateDB, header *types.Header, uncles []*types.Header) {
   543  	// Select the correct block reward based on chain progression
   544  	blockReward := SoftLaunchBlockReward
   545  	if config.IsMIP5(header.Number) {
   546  		blockReward = DefaultBlockReward
   547  	} else if config.IsMIP4(header.Number) {
   548  		blockReward = MIP4BlockReward
   549  	} else if config.IsMIP3(header.Number) {
   550  		blockReward = MIP3BlockReward
   551  	} else if config.IsMIP2(header.Number) {
   552  		blockReward = MIP2BlockReward
   553  	} else if config.IsMIP1(header.Number) {
   554  		blockReward = MIP1BlockReward
   555  	}
   556  
   557  	// Accumulate the rewards for the miner and any included uncles
   558  	reward := new(big.Int).Set(blockReward)
   559  	r := new(big.Int)
   560  	for _, uncle := range uncles {
   561  		r.Add(uncle.Number, big8)
   562  		r.Sub(r, header.Number)
   563  		r.Mul(r, blockReward)
   564  		r.Div(r, big8)
   565  		// TODO pending Token Economy research, if we want to reduce rewards of uncle blocks, the calculations for 'r' needs to be updated
   566  		state.AddBalance(uncle.Coinbase, r)
   567  
   568  		r.Div(blockReward, big32)
   569  		reward.Add(reward, r)
   570  	}
   571  
   572  	state.AddBalance(header.Coinbase, reward)
   573  }