github.com/klaytn/klaytn@v1.10.2/blockchain/types/derivesha/mux.go (about)

     1  // Modifications Copyright 2018 The klaytn Authors
     2  // Copyright 2015 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  // This file is derived from core/types/derive_sha.go (2018/06/04).
    19  // Modified and improved for the klaytn development.
    20  
    21  package derivesha
    22  
    23  import (
    24  	"math/big"
    25  
    26  	"github.com/klaytn/klaytn/blockchain/types"
    27  	"github.com/klaytn/klaytn/common"
    28  	"github.com/klaytn/klaytn/log"
    29  	"github.com/klaytn/klaytn/params"
    30  )
    31  
    32  type IDeriveSha interface {
    33  	DeriveSha(list types.DerivableList) common.Hash
    34  }
    35  
    36  type GovernanceEngine interface {
    37  	EffectiveParams(num uint64) (*params.GovParamSet, error)
    38  }
    39  
    40  var (
    41  	config     *params.ChainConfig
    42  	gov        GovernanceEngine
    43  	impls      map[int]IDeriveSha
    44  	emptyRoots map[int]common.Hash
    45  
    46  	logger = log.NewModuleLogger(log.Blockchain)
    47  )
    48  
    49  func init() {
    50  	impls = map[int]IDeriveSha{
    51  		types.ImplDeriveShaOriginal: DeriveShaOrig{},
    52  		types.ImplDeriveShaSimple:   DeriveShaSimple{},
    53  		types.ImplDeriveShaConcat:   DeriveShaConcat{},
    54  	}
    55  
    56  	emptyRoots = make(map[int]common.Hash)
    57  	for implType, impl := range impls {
    58  		emptyRoots[implType] = impl.DeriveSha(types.Transactions{})
    59  	}
    60  }
    61  
    62  func InitDeriveSha(chainConfig *params.ChainConfig, govEngine GovernanceEngine) {
    63  	config = chainConfig
    64  	gov = govEngine
    65  	types.DeriveSha = DeriveShaMux
    66  	types.EmptyRootHash = EmptyRootHashMux
    67  	logger.Info("InitDeriveSha", "initial", config.DeriveShaImpl, "withGov", gov != nil)
    68  }
    69  
    70  func DeriveShaMux(list types.DerivableList, num *big.Int) common.Hash {
    71  	return impls[getType(num)].DeriveSha(list)
    72  }
    73  
    74  func EmptyRootHashMux(num *big.Int) common.Hash {
    75  	return emptyRoots[getType(num)]
    76  }
    77  
    78  func getType(num *big.Int) int {
    79  	implType := config.DeriveShaImpl
    80  
    81  	// gov == nil if blockchain.InitDeriveSha() is used, in genesis block manipulation
    82  	// and unit tests. gov != nil if blockchain.InitDeriveShaWithGov is used,
    83  	// in ordinary blockchain processing.
    84  	if gov != nil {
    85  		if pset, err := gov.EffectiveParams(num.Uint64()); err != nil {
    86  			logger.Crit("Cannot determine DeriveShaImpl", "num", num.Uint64(), "err", err)
    87  		} else {
    88  			implType = pset.DeriveShaImpl()
    89  		}
    90  	}
    91  
    92  	if _, ok := impls[implType]; ok {
    93  		return implType
    94  	} else {
    95  		logger.Error("Unrecognized deriveShaImpl, falling back to default impl", "impl", implType)
    96  		return int(params.DefaultDeriveShaImpl)
    97  	}
    98  }