github.com/klaytn/klaytn@v1.10.2/consensus/istanbul/backend/engine.go (about)

     1  // Modifications Copyright 2018 The klaytn Authors
     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  // This file is derived from quorum/consensus/istanbul/backend/engine.go (2018/06/04).
    19  // Modified and improved for the klaytn development.
    20  
    21  package backend
    22  
    23  import (
    24  	"bytes"
    25  	"encoding/hex"
    26  	"encoding/json"
    27  	"errors"
    28  	"math/big"
    29  	"time"
    30  
    31  	lru "github.com/hashicorp/golang-lru"
    32  	"github.com/klaytn/klaytn/blockchain/state"
    33  	"github.com/klaytn/klaytn/blockchain/types"
    34  	"github.com/klaytn/klaytn/common"
    35  	"github.com/klaytn/klaytn/common/hexutil"
    36  	"github.com/klaytn/klaytn/consensus"
    37  	"github.com/klaytn/klaytn/consensus/istanbul"
    38  	istanbulCore "github.com/klaytn/klaytn/consensus/istanbul/core"
    39  	"github.com/klaytn/klaytn/consensus/istanbul/validator"
    40  	"github.com/klaytn/klaytn/consensus/misc"
    41  	"github.com/klaytn/klaytn/crypto/sha3"
    42  	"github.com/klaytn/klaytn/networks/rpc"
    43  	"github.com/klaytn/klaytn/reward"
    44  	"github.com/klaytn/klaytn/rlp"
    45  )
    46  
    47  const (
    48  	// checkpointInterval = 1024 // Number of blocks after which to save the vote snapshot to the database
    49  	// inmemorySnapshots  = 128  // Number of recent vote snapshots to keep in memory
    50  	// inmemoryPeers      = 40
    51  	// inmemoryMessages   = 1024
    52  
    53  	checkpointInterval = 1024 // Number of blocks after which to save the vote snapshot to the database
    54  	inmemorySnapshots  = 496  // Number of recent vote snapshots to keep in memory
    55  	inmemoryPeers      = 200
    56  	inmemoryMessages   = 4096
    57  
    58  	allowedFutureBlockTime = 1 * time.Second // Max time from current time allowed for blocks, before they're considered future blocks
    59  )
    60  
    61  var (
    62  	// errInvalidProposal is returned when a prposal is malformed.
    63  	errInvalidProposal = errors.New("invalid proposal")
    64  	// errInvalidSignature is returned when given signature is not signed by given
    65  	// address.
    66  	errInvalidSignature = errors.New("invalid signature")
    67  	// errUnknownBlock is returned when the list of validators is requested for a block
    68  	// that is not part of the local blockchain.
    69  	errUnknownBlock = errors.New("unknown block")
    70  	// errUnauthorized is returned if a header is signed by a non authorized entity.
    71  	errUnauthorized = errors.New("unauthorized")
    72  	// errInvalidBlockScore is returned if the BlockScore of a block is not 1
    73  	errInvalidBlockScore = errors.New("invalid blockscore")
    74  	// errInvalidExtraDataFormat is returned when the extra data format is incorrect
    75  	errInvalidExtraDataFormat = errors.New("invalid extra data format")
    76  	// errInvalidTimestamp is returned if the timestamp of a block is lower than the previous block's timestamp + the minimum block period.
    77  	errInvalidTimestamp = errors.New("invalid timestamp")
    78  	// errInvalidVotingChain is returned if an authorization list is attempted to
    79  	// be modified via out-of-range or non-contiguous headers.
    80  	errInvalidVotingChain = errors.New("invalid voting chain")
    81  	// errInvalidVote is returned if a nonce value is something else that the two
    82  	// allowed constants of 0x00..0 or 0xff..f.
    83  	errInvalidVote = errors.New("vote nonce not 0x00..0 or 0xff..f")
    84  	// errInvalidCommittedSeals is returned if the committed seal is not signed by any of parent validators.
    85  	errInvalidCommittedSeals = errors.New("invalid committed seals")
    86  	// errEmptyCommittedSeals is returned if the field of committed seals is zero.
    87  	errEmptyCommittedSeals = errors.New("zero committed seals")
    88  	// errMismatchTxhashes is returned if the TxHash in header is mismatch.
    89  	errMismatchTxhashes = errors.New("mismatch transactions hashes")
    90  )
    91  
    92  var (
    93  	defaultBlockScore = big.NewInt(1)
    94  	now               = time.Now
    95  
    96  	nonceAuthVote = hexutil.MustDecode("0xffffffffffffffff") // Magic nonce number to vote on adding a new validator
    97  	nonceDropVote = hexutil.MustDecode("0x0000000000000000") // Magic nonce number to vote on removing a validator.
    98  
    99  	inmemoryBlocks             = 2048 // Number of blocks to precompute validators' addresses
   100  	inmemoryValidatorsPerBlock = 30   // Approximate number of validators' addresses from ecrecover
   101  	signatureAddresses, _      = lru.NewARC(inmemoryBlocks * inmemoryValidatorsPerBlock)
   102  )
   103  
   104  // cacheSignatureAddresses extracts the address from the given data and signature and cache them for later usage.
   105  func cacheSignatureAddresses(data []byte, sig []byte) (common.Address, error) {
   106  	sigStr := hex.EncodeToString(sig)
   107  	if addr, ok := signatureAddresses.Get(sigStr); ok {
   108  		return addr.(common.Address), nil
   109  	}
   110  	addr, err := istanbul.GetSignatureAddress(data, sig)
   111  	if err != nil {
   112  		return common.Address{}, err
   113  	}
   114  	signatureAddresses.Add(sigStr, addr)
   115  	return addr, err
   116  }
   117  
   118  // Author retrieves the Klaytn address of the account that minted the given block.
   119  func (sb *backend) Author(header *types.Header) (common.Address, error) {
   120  	return ecrecover(header)
   121  }
   122  
   123  // CanVerifyHeadersConcurrently returns true if concurrent header verification possible, otherwise returns false.
   124  func (sb *backend) CanVerifyHeadersConcurrently() bool {
   125  	return false
   126  }
   127  
   128  // PreprocessHeaderVerification prepares header verification for heavy computation before synchronous header verification such as ecrecover.
   129  func (sb *backend) PreprocessHeaderVerification(headers []*types.Header) (chan<- struct{}, <-chan error) {
   130  	abort := make(chan struct{})
   131  	results := make(chan error, inmemoryBlocks)
   132  	go func() {
   133  		for _, header := range headers {
   134  			err := sb.computeSignatureAddrs(header)
   135  
   136  			select {
   137  			case <-abort:
   138  				return
   139  			case results <- err:
   140  			}
   141  		}
   142  	}()
   143  	return abort, results
   144  }
   145  
   146  // computeSignatureAddrs computes the addresses of signer and validators and caches them.
   147  func (sb *backend) computeSignatureAddrs(header *types.Header) error {
   148  	_, err := ecrecover(header)
   149  	if err != nil {
   150  		return err
   151  	}
   152  
   153  	// Retrieve the signature from the header extra-data
   154  	istanbulExtra, err := types.ExtractIstanbulExtra(header)
   155  	if err != nil {
   156  		return err
   157  	}
   158  
   159  	proposalSeal := istanbulCore.PrepareCommittedSeal(header.Hash())
   160  	for _, seal := range istanbulExtra.CommittedSeal {
   161  		_, err := cacheSignatureAddresses(proposalSeal, seal)
   162  		if err != nil {
   163  			return errInvalidSignature
   164  		}
   165  	}
   166  	return nil
   167  }
   168  
   169  // VerifyHeader checks whether a header conforms to the consensus rules of a
   170  // given engine. Verifying the seal may be done optionally here, or explicitly
   171  // via the VerifySeal method.
   172  func (sb *backend) VerifyHeader(chain consensus.ChainReader, header *types.Header, seal bool) error {
   173  	var parent []*types.Header
   174  	if header.Number.Sign() == 0 {
   175  		// If current block is genesis, the parent is also genesis
   176  		parent = append(parent, chain.GetHeaderByNumber(0))
   177  	} else {
   178  		parent = append(parent, chain.GetHeader(header.ParentHash, header.Number.Uint64()-1))
   179  	}
   180  	return sb.verifyHeader(chain, header, parent)
   181  }
   182  
   183  // verifyHeader checks whether a header conforms to the consensus rules.The
   184  // caller may optionally pass in a batch of parents (ascending order) to avoid
   185  // looking those up from the database. This is useful for concurrently verifying
   186  // a batch of new headers.
   187  func (sb *backend) verifyHeader(chain consensus.ChainReader, header *types.Header, parents []*types.Header) error {
   188  	if header.Number == nil {
   189  		return errUnknownBlock
   190  	}
   191  
   192  	// Header verify before/after magma fork
   193  	if chain.Config().IsMagmaForkEnabled(header.Number) {
   194  		// the kip71Config used when creating the block number is a previous block config.
   195  		blockNum := header.Number.Uint64()
   196  		pset, err := sb.governance.EffectiveParams(blockNum)
   197  		if err != nil {
   198  			return err
   199  		}
   200  
   201  		kip71 := pset.ToKIP71Config()
   202  		if err := misc.VerifyMagmaHeader(parents[len(parents)-1], header, kip71); err != nil {
   203  			return err
   204  		}
   205  	} else if header.BaseFee != nil {
   206  		return consensus.ErrInvalidBaseFee
   207  	}
   208  
   209  	// Don't waste time checking blocks from the future
   210  	if header.Time.Cmp(big.NewInt(now().Add(allowedFutureBlockTime).Unix())) > 0 {
   211  		return consensus.ErrFutureBlock
   212  	}
   213  
   214  	// Ensure that the extra data format is satisfied
   215  	if _, err := types.ExtractIstanbulExtra(header); err != nil {
   216  		return errInvalidExtraDataFormat
   217  	}
   218  	// Ensure that the block's blockscore is meaningful (may not be correct at this point)
   219  	if header.BlockScore == nil || header.BlockScore.Cmp(defaultBlockScore) != 0 {
   220  		return errInvalidBlockScore
   221  	}
   222  
   223  	return sb.verifyCascadingFields(chain, header, parents)
   224  }
   225  
   226  // verifyCascadingFields verifies all the header fields that are not standalone,
   227  // rather depend on a batch of previous headers. The caller may optionally pass
   228  // in a batch of parents (ascending order) to avoid looking those up from the
   229  // database. This is useful for concurrently verifying a batch of new headers.
   230  func (sb *backend) verifyCascadingFields(chain consensus.ChainReader, header *types.Header, parents []*types.Header) error {
   231  	// The genesis block is the always valid dead-end
   232  	number := header.Number.Uint64()
   233  	if number == 0 {
   234  		return nil
   235  	}
   236  	// Ensure that the block's timestamp isn't too close to it's parent
   237  	var parent *types.Header
   238  	if len(parents) > 0 {
   239  		parent = parents[len(parents)-1]
   240  	} else {
   241  		parent = chain.GetHeader(header.ParentHash, number-1)
   242  	}
   243  	if parent == nil || parent.Number.Uint64() != number-1 || parent.Hash() != header.ParentHash {
   244  		return consensus.ErrUnknownAncestor
   245  	}
   246  	if parent.Time.Uint64()+sb.config.BlockPeriod > header.Time.Uint64() {
   247  		return errInvalidTimestamp
   248  	}
   249  	if err := sb.verifySigner(chain, header, parents); err != nil {
   250  		return err
   251  	}
   252  
   253  	// At every epoch governance data will come in block header. Verify it.
   254  	pset, err := sb.governance.EffectiveParams(number)
   255  	if err != nil {
   256  		return err
   257  	}
   258  	pendingBlockNum := new(big.Int).Add(chain.CurrentHeader().Number, common.Big1)
   259  	if number%pset.Epoch() == 0 && len(header.Governance) > 0 && pendingBlockNum.Cmp(header.Number) == 0 {
   260  		if err := sb.governance.VerifyGovernance(header.Governance); err != nil {
   261  			return err
   262  		}
   263  	}
   264  	return sb.verifyCommittedSeals(chain, header, parents)
   265  }
   266  
   267  // VerifyHeaders is similar to VerifyHeader, but verifies a batch of headers
   268  // concurrently. The method returns a quit channel to abort the operations and
   269  // a results channel to retrieve the async verifications (the order is that of
   270  // the input slice).
   271  func (sb *backend) VerifyHeaders(chain consensus.ChainReader, headers []*types.Header, seals []bool) (chan<- struct{}, <-chan error) {
   272  	abort := make(chan struct{})
   273  	results := make(chan error, len(headers))
   274  	go func() {
   275  		for i, header := range headers {
   276  			err := sb.verifyHeader(chain, header, headers[:i])
   277  
   278  			select {
   279  			case <-abort:
   280  				return
   281  			case results <- err:
   282  			}
   283  		}
   284  	}()
   285  	return abort, results
   286  }
   287  
   288  // verifySigner checks whether the signer is in parent's validator set
   289  func (sb *backend) verifySigner(chain consensus.ChainReader, header *types.Header, parents []*types.Header) error {
   290  	// Verifying the genesis block is not supported
   291  	number := header.Number.Uint64()
   292  	if number == 0 {
   293  		return errUnknownBlock
   294  	}
   295  
   296  	// Retrieve the snapshot needed to verify this header and cache it
   297  	snap, err := sb.snapshot(chain, number-1, header.ParentHash, parents, true)
   298  	if err != nil {
   299  		return err
   300  	}
   301  
   302  	// resolve the authorization key and check against signers
   303  	signer, err := ecrecover(header)
   304  	if err != nil {
   305  		return err
   306  	}
   307  
   308  	// Signer should be in the validator set of previous block's extraData.
   309  	if _, v := snap.ValSet.GetByAddress(signer); v == nil {
   310  		return errUnauthorized
   311  	}
   312  	return nil
   313  }
   314  
   315  // verifyCommittedSeals checks whether every committed seal is signed by one of the parent's validators
   316  func (sb *backend) verifyCommittedSeals(chain consensus.ChainReader, header *types.Header, parents []*types.Header) error {
   317  	number := header.Number.Uint64()
   318  	// We don't need to verify committed seals in the genesis block
   319  	if number == 0 {
   320  		return nil
   321  	}
   322  
   323  	// Retrieve the snapshot needed to verify this header and cache it
   324  	snap, err := sb.snapshot(chain, number-1, header.ParentHash, parents, true)
   325  	if err != nil {
   326  		return err
   327  	}
   328  
   329  	extra, err := types.ExtractIstanbulExtra(header)
   330  	if err != nil {
   331  		return err
   332  	}
   333  	// The length of Committed seals should be larger than 0
   334  	if len(extra.CommittedSeal) == 0 {
   335  		return errEmptyCommittedSeals
   336  	}
   337  
   338  	validators := snap.ValSet.Copy()
   339  	// Check whether the committed seals are generated by parent's validators
   340  	validSeal := 0
   341  	proposalSeal := istanbulCore.PrepareCommittedSeal(header.Hash())
   342  	// 1. Get committed seals from current header
   343  	for _, seal := range extra.CommittedSeal {
   344  		// 2. Get the original address by seal and parent block hash
   345  		addr, err := cacheSignatureAddresses(proposalSeal, seal)
   346  		if err != nil {
   347  			return errInvalidSignature
   348  		}
   349  		// Every validator can have only one seal. If more than one seals are signed by a
   350  		// validator, the validator cannot be found and errInvalidCommittedSeals is returned.
   351  		if validators.RemoveValidator(addr) {
   352  			validSeal += 1
   353  		} else {
   354  			return errInvalidCommittedSeals
   355  		}
   356  	}
   357  
   358  	// The length of validSeal should be larger than number of faulty node + 1
   359  	if validSeal <= 2*snap.ValSet.F() {
   360  		return errInvalidCommittedSeals
   361  	}
   362  
   363  	return nil
   364  }
   365  
   366  // VerifySeal checks whether the crypto seal on a header is valid according to
   367  // the consensus rules of the given engine.
   368  func (sb *backend) VerifySeal(chain consensus.ChainReader, header *types.Header) error {
   369  	// get parent header and ensure the signer is in parent's validator set
   370  	number := header.Number.Uint64()
   371  	if number == 0 {
   372  		return errUnknownBlock
   373  	}
   374  
   375  	// ensure that the blockscore equals to defaultBlockScore
   376  	if header.BlockScore.Cmp(defaultBlockScore) != 0 {
   377  		return errInvalidBlockScore
   378  	}
   379  	return sb.verifySigner(chain, header, nil)
   380  }
   381  
   382  // Prepare initializes the consensus fields of a block header according to the
   383  // rules of a particular engine. The changes are executed inline.
   384  func (sb *backend) Prepare(chain consensus.ChainReader, header *types.Header) error {
   385  	// unused fields, force to set to empty
   386  	header.Rewardbase = sb.rewardbase
   387  
   388  	// copy the parent extra data as the header extra data
   389  	number := header.Number.Uint64()
   390  	parent := chain.GetHeader(header.ParentHash, number-1)
   391  	if parent == nil {
   392  		return consensus.ErrUnknownAncestor
   393  	}
   394  	// use the same blockscore for all blocks
   395  	header.BlockScore = defaultBlockScore
   396  
   397  	// Assemble the voting snapshot
   398  	snap, err := sb.snapshot(chain, number-1, header.ParentHash, nil, true)
   399  	if err != nil {
   400  		return err
   401  	}
   402  
   403  	// If it reaches the Epoch, governance config will be added to block header
   404  	pset, err := sb.governance.EffectiveParams(number)
   405  	if err != nil {
   406  		return err
   407  	}
   408  	if number%pset.Epoch() == 0 {
   409  		if g := sb.governance.GetGovernanceChange(); g != nil {
   410  			if data, err := json.Marshal(g); err != nil {
   411  				logger.Error("Failed to encode governance changes!! Possible configuration mismatch!! ")
   412  			} else {
   413  				if header.Governance, err = rlp.EncodeToBytes(data); err != nil {
   414  					logger.Error("Failed to encode governance data for the header", "num", number)
   415  				} else {
   416  					logger.Info("Put governanceData", "num", number, "data", hex.EncodeToString(header.Governance))
   417  				}
   418  			}
   419  		}
   420  	}
   421  
   422  	// if there is a vote to attach, attach it to the header
   423  	header.Vote = sb.governance.GetEncodedVote(sb.address, number)
   424  	if len(header.Vote) > 0 {
   425  		logger.Info("Put voteData", "num", number, "data", hex.EncodeToString(header.Vote))
   426  	}
   427  
   428  	// add validators (council list) in snapshot to extraData's validators section
   429  	extra, err := prepareExtra(header, snap.validators())
   430  	if err != nil {
   431  		return err
   432  	}
   433  	header.Extra = extra
   434  
   435  	// set header's timestamp
   436  	header.Time = new(big.Int).Add(parent.Time, new(big.Int).SetUint64(sb.config.BlockPeriod))
   437  	header.TimeFoS = parent.TimeFoS
   438  	if header.Time.Int64() < time.Now().Unix() {
   439  		t := time.Now()
   440  		header.Time = big.NewInt(t.Unix())
   441  		header.TimeFoS = uint8((t.UnixNano() / 1000 / 1000 / 10) % 100)
   442  	}
   443  	return nil
   444  }
   445  
   446  // Finalize runs any post-transaction state modifications (e.g. block rewards)
   447  // and assembles the final block.
   448  //
   449  // Note, the block header and state database might be updated to reflect any
   450  // consensus rules that happen at finalization (e.g. block rewards).
   451  func (sb *backend) Finalize(chain consensus.ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction,
   452  	receipts []*types.Receipt,
   453  ) (*types.Block, error) {
   454  	// We can assure that if the magma hard forked block should have the field of base fee
   455  	if chain.Config().IsMagmaForkEnabled(header.Number) {
   456  		if header.BaseFee == nil {
   457  			logger.Error("Magma hard forked block should have baseFee", "blockNum", header.Number.Uint64())
   458  			return nil, errors.New("Invalid Magma block without baseFee")
   459  		}
   460  	} else if header.BaseFee != nil {
   461  		logger.Error("A block before Magma hardfork shouldn't have baseFee", "blockNum", header.Number.Uint64())
   462  		return nil, consensus.ErrInvalidBaseFee
   463  	}
   464  
   465  	var rewardSpec *reward.RewardSpec
   466  
   467  	rules := chain.Config().Rules(header.Number)
   468  	pset, err := sb.governance.EffectiveParams(header.Number.Uint64())
   469  	if err != nil {
   470  		return nil, err
   471  	}
   472  
   473  	// If sb.chain is nil, it means backend is not initialized yet.
   474  	if sb.chain != nil && !reward.IsRewardSimple(pset) {
   475  		// TODO-Klaytn Let's redesign below logic and remove dependency between block reward and istanbul consensus.
   476  
   477  		lastHeader := chain.CurrentHeader()
   478  		valSet := sb.getValidators(lastHeader.Number.Uint64(), lastHeader.Hash())
   479  
   480  		// Determine and update Rewardbase when mining. When mining, state root is not yet determined and will be determined at the end of this Finalize below.
   481  		if common.EmptyHash(header.Root) {
   482  			var logMsg string
   483  			_, nodeValidator := valSet.GetByAddress(sb.address)
   484  			if nodeValidator == nil || (nodeValidator.RewardAddress() == common.Address{}) {
   485  				logMsg = "No reward address for nodeValidator. Use node's rewardbase."
   486  			} else {
   487  				// use reward address of current node.
   488  				// only a block made by proposer will be accepted. However, due to round change any node can be the proposer of a block.
   489  				// so need to write reward address of current node to receive reward when it becomes proposer.
   490  				// if current node does not become proposer, the block will be abandoned
   491  				header.Rewardbase = nodeValidator.RewardAddress()
   492  				logMsg = "Use reward address for nodeValidator."
   493  			}
   494  			logger.Trace(logMsg, "header.Number", header.Number.Uint64(), "node address", sb.address, "rewardbase", header.Rewardbase)
   495  		}
   496  
   497  		rewardSpec, err = reward.CalcDeferredReward(header, rules, pset)
   498  	} else {
   499  		rewardSpec, err = reward.CalcDeferredRewardSimple(header, rules, pset)
   500  	}
   501  
   502  	if err != nil {
   503  		return nil, err
   504  	}
   505  
   506  	reward.DistributeBlockReward(state, rewardSpec.Rewards)
   507  
   508  	// Only on the KIP-103 hardfork block, the following logic should be executed
   509  	if chain.Config().IsKIP103ForkBlock(header.Number) {
   510  		// RebalanceTreasury can modify the global state (state),
   511  		// so the existing state db should be used to apply the rebalancing result.
   512  		c := &Kip103ContractCaller{state, chain, header}
   513  		result, err := RebalanceTreasury(state, chain, header, c)
   514  		if err != nil {
   515  			logger.Error("failed to execute treasury rebalancing (KIP-103). State not changed", "err", err)
   516  		} else {
   517  			memo, err := json.Marshal(result)
   518  			if err != nil {
   519  				logger.Warn("failed to marshal KIP-103 result", "err", err, "result", result)
   520  			}
   521  			logger.Info("successfully executed treasury rebalancing (KIP-103)", "memo", string(memo))
   522  		}
   523  	}
   524  	header.Root = state.IntermediateRoot(true)
   525  
   526  	// Assemble and return the final block for sealing
   527  	return types.NewBlock(header, txs, receipts), nil
   528  }
   529  
   530  // Seal generates a new block for the given input block with the local miner's
   531  // seal place on top.
   532  func (sb *backend) Seal(chain consensus.ChainReader, block *types.Block, stop <-chan struct{}) (*types.Block, error) {
   533  	// update the block header timestamp and signature and propose the block to core engine
   534  	header := block.Header()
   535  	number := header.Number.Uint64()
   536  
   537  	// Bail out if we're unauthorized to sign a block
   538  	snap, err := sb.snapshot(chain, number-1, header.ParentHash, nil, true)
   539  	if err != nil {
   540  		return nil, err
   541  	}
   542  	if _, v := snap.ValSet.GetByAddress(sb.address); v == nil {
   543  		return nil, errUnauthorized
   544  	}
   545  
   546  	parent := chain.GetHeader(header.ParentHash, number-1)
   547  	if parent == nil {
   548  		return nil, consensus.ErrUnknownAncestor
   549  	}
   550  	block, err = sb.updateBlock(parent, block)
   551  	if err != nil {
   552  		return nil, err
   553  	}
   554  
   555  	// wait for the timestamp of header, use this to adjust the block period
   556  	delay := time.Unix(block.Header().Time.Int64(), 0).Sub(now())
   557  	select {
   558  	case <-time.After(delay):
   559  	case <-stop:
   560  		return nil, nil
   561  	}
   562  
   563  	// get the proposed block hash and clear it if the seal() is completed.
   564  	sb.sealMu.Lock()
   565  	sb.proposedBlockHash = block.Hash()
   566  	clear := func() {
   567  		sb.proposedBlockHash = common.Hash{}
   568  		sb.sealMu.Unlock()
   569  	}
   570  	defer clear()
   571  
   572  	// post block into Istanbul engine
   573  	go sb.EventMux().Post(istanbul.RequestEvent{
   574  		Proposal: block,
   575  	})
   576  
   577  	for {
   578  		select {
   579  		case result := <-sb.commitCh:
   580  			if result == nil {
   581  				return nil, nil
   582  			}
   583  			// if the block hash and the hash from channel are the same,
   584  			// return the result. Otherwise, keep waiting the next hash.
   585  			block = types.SetRoundToBlock(block, result.Round)
   586  			if block.Hash() == result.Block.Hash() {
   587  				return result.Block, nil
   588  			}
   589  		case <-stop:
   590  			return nil, nil
   591  		}
   592  	}
   593  }
   594  
   595  // update timestamp and signature of the block based on its number of transactions
   596  func (sb *backend) updateBlock(parent *types.Header, block *types.Block) (*types.Block, error) {
   597  	header := block.Header()
   598  	// sign the hash
   599  	seal, err := sb.Sign(sigHash(header).Bytes())
   600  	if err != nil {
   601  		return nil, err
   602  	}
   603  
   604  	err = writeSeal(header, seal)
   605  	if err != nil {
   606  		return nil, err
   607  	}
   608  
   609  	return block.WithSeal(header), nil
   610  }
   611  
   612  func (sb *backend) CalcBlockScore(chain consensus.ChainReader, time uint64, parent *types.Header) *big.Int {
   613  	return big.NewInt(0)
   614  }
   615  
   616  // APIs returns the RPC APIs this consensus engine provides.
   617  func (sb *backend) APIs(chain consensus.ChainReader) []rpc.API {
   618  	return []rpc.API{
   619  		{
   620  			Namespace: "istanbul",
   621  			Version:   "1.0",
   622  			Service:   &API{chain: chain, istanbul: sb},
   623  			Public:    true,
   624  		}, {
   625  			Namespace: "klay",
   626  			Version:   "1.0",
   627  			Service:   &APIExtension{chain: chain, istanbul: sb},
   628  			Public:    true,
   629  		},
   630  	}
   631  }
   632  
   633  // SetChain sets chain of the Istanbul backend
   634  func (sb *backend) SetChain(chain consensus.ChainReader) {
   635  	sb.chain = chain
   636  }
   637  
   638  // Start implements consensus.Istanbul.Start
   639  func (sb *backend) Start(chain consensus.ChainReader, currentBlock func() *types.Block, hasBadBlock func(hash common.Hash) bool) error {
   640  	sb.coreMu.Lock()
   641  	defer sb.coreMu.Unlock()
   642  	if sb.coreStarted {
   643  		return istanbul.ErrStartedEngine
   644  	}
   645  
   646  	// clear previous data
   647  	sb.proposedBlockHash = common.Hash{}
   648  	if sb.commitCh != nil {
   649  		close(sb.commitCh)
   650  	}
   651  	sb.commitCh = make(chan *types.Result, 1)
   652  
   653  	sb.SetChain(chain)
   654  	sb.currentBlock = currentBlock
   655  	sb.hasBadBlock = hasBadBlock
   656  
   657  	if err := sb.core.Start(); err != nil {
   658  		return err
   659  	}
   660  
   661  	sb.coreStarted = true
   662  	return nil
   663  }
   664  
   665  // Stop implements consensus.Istanbul.Stop
   666  func (sb *backend) Stop() error {
   667  	sb.coreMu.Lock()
   668  	defer sb.coreMu.Unlock()
   669  	if !sb.coreStarted {
   670  		return istanbul.ErrStoppedEngine
   671  	}
   672  	if err := sb.core.Stop(); err != nil {
   673  		return err
   674  	}
   675  	sb.coreStarted = false
   676  	return nil
   677  }
   678  
   679  // initSnapshot initializes and stores a new Snapshot.
   680  func (sb *backend) initSnapshot(chain consensus.ChainReader) (*Snapshot, error) {
   681  	genesis := chain.GetHeaderByNumber(0)
   682  	if err := sb.VerifyHeader(chain, genesis, false); err != nil {
   683  		return nil, err
   684  	}
   685  	istanbulExtra, err := types.ExtractIstanbulExtra(genesis)
   686  	if err != nil {
   687  		return nil, err
   688  	}
   689  
   690  	pset, err := sb.governance.EffectiveParams(0)
   691  	if err != nil {
   692  		return nil, err
   693  	}
   694  	valSet := validator.NewValidatorSet(istanbulExtra.Validators, nil,
   695  		istanbul.ProposerPolicy(pset.Policy()),
   696  		pset.CommitteeSize(), chain)
   697  	snap := newSnapshot(sb.governance, 0, genesis.Hash(), valSet, chain.Config())
   698  
   699  	if err := snap.store(sb.db); err != nil {
   700  		return nil, err
   701  	}
   702  	logger.Trace("Stored genesis voting snapshot to disk")
   703  	return snap, nil
   704  }
   705  
   706  // getPrevHeaderAndUpdateParents returns previous header to find stored Snapshot object and drops the last element of the parents parameter.
   707  func getPrevHeaderAndUpdateParents(chain consensus.ChainReader, number uint64, hash common.Hash, parents *[]*types.Header) *types.Header {
   708  	var header *types.Header
   709  	if len(*parents) > 0 {
   710  		// If we have explicit parents, pick from there (enforced)
   711  		header = (*parents)[len(*parents)-1]
   712  		if header.Hash() != hash || header.Number.Uint64() != number {
   713  			return nil
   714  		}
   715  		*parents = (*parents)[:len(*parents)-1]
   716  	} else {
   717  		// No explicit parents (or no more left), reach out to the database
   718  		header = chain.GetHeader(hash, number)
   719  		if header == nil {
   720  			return nil
   721  		}
   722  	}
   723  	return header
   724  }
   725  
   726  // CreateSnapshot does not return a snapshot but creates a new snapshot at a given point in time.
   727  func (sb *backend) CreateSnapshot(chain consensus.ChainReader, number uint64, hash common.Hash, parents []*types.Header) error {
   728  	if _, err := sb.snapshot(chain, number, hash, parents, true); err != nil {
   729  		return err
   730  	}
   731  	if err := sb.governance.UpdateParams(number); err != nil {
   732  		return err
   733  	}
   734  	return nil
   735  }
   736  
   737  // GetConsensusInfo returns consensus information regarding the given block number.
   738  func (sb *backend) GetConsensusInfo(block *types.Block) (consensus.ConsensusInfo, error) {
   739  	blockNumber := block.NumberU64()
   740  	if blockNumber == 0 {
   741  		return consensus.ConsensusInfo{}, nil
   742  	}
   743  
   744  	round := block.Header().Round()
   745  	view := &istanbul.View{
   746  		Sequence: new(big.Int).Set(block.Number()),
   747  		Round:    new(big.Int).SetInt64(int64(round)),
   748  	}
   749  
   750  	// get the proposer of this block.
   751  	proposer, err := ecrecover(block.Header())
   752  	if err != nil {
   753  		return consensus.ConsensusInfo{}, err
   754  	}
   755  
   756  	// get the snapshot of the previous block.
   757  	parentHash := block.ParentHash()
   758  	snap, err := sb.snapshot(sb.chain, blockNumber-1, parentHash, nil, false)
   759  	if err != nil {
   760  		logger.Error("Failed to get snapshot.", "hash", snap.Hash, "err", err)
   761  		return consensus.ConsensusInfo{}, errInternalError
   762  	}
   763  
   764  	// get origin proposer at 0 round.
   765  	originProposer := common.Address{}
   766  	lastProposer := sb.GetProposer(blockNumber - 1)
   767  
   768  	newValSet := snap.ValSet.Copy()
   769  	newValSet.CalcProposer(lastProposer, 0)
   770  	originProposer = newValSet.GetProposer().Address()
   771  
   772  	// get the committee list of this block at the view (blockNumber, round)
   773  	committee := snap.ValSet.SubListWithProposer(parentHash, proposer, view)
   774  	committeeAddrs := make([]common.Address, len(committee))
   775  	for i, v := range committee {
   776  		committeeAddrs[i] = v.Address()
   777  	}
   778  
   779  	// verify the committee list of the block using istanbul
   780  	//proposalSeal := istanbulCore.PrepareCommittedSeal(block.Hash())
   781  	//extra, err := types.ExtractIstanbulExtra(block.Header())
   782  	//istanbulAddrs := make([]common.Address, len(committeeAddrs))
   783  	//for i, seal := range extra.CommittedSeal {
   784  	//	addr, err := istanbul.GetSignatureAddress(proposalSeal, seal)
   785  	//	istanbulAddrs[i] = addr
   786  	//	if err != nil {
   787  	//		return proposer, []common.Address{}, err
   788  	//	}
   789  	//
   790  	//	var found bool = false
   791  	//	for _, v := range committeeAddrs {
   792  	//		if addr == v {
   793  	//			found = true
   794  	//			break
   795  	//		}
   796  	//	}
   797  	//	if found == false {
   798  	//		logger.Trace("validator is different!", "snap", committeeAddrs, "istanbul", istanbulAddrs)
   799  	//		return proposer, committeeAddrs, errors.New("validator set is different from Istanbul engine!!")
   800  	//	}
   801  	//}
   802  
   803  	cInfo := consensus.ConsensusInfo{
   804  		Proposer:       proposer,
   805  		OriginProposer: originProposer,
   806  		Committee:      committeeAddrs,
   807  		Round:          round,
   808  	}
   809  
   810  	return cInfo, nil
   811  }
   812  
   813  // snapshot retrieves the authorization snapshot at a given point in time.
   814  func (sb *backend) snapshot(chain consensus.ChainReader, number uint64, hash common.Hash, parents []*types.Header, writable bool) (*Snapshot, error) {
   815  	// Search for a snapshot in memory or on disk for checkpoints
   816  	var (
   817  		headers []*types.Header
   818  		snap    *Snapshot
   819  	)
   820  
   821  	for snap == nil {
   822  		// If an in-memory snapshot was found, use that
   823  		if s, ok := sb.recents.Get(hash); ok {
   824  			snap = s.(*Snapshot)
   825  			break
   826  		}
   827  		// If an on-disk checkpoint snapshot can be found, use that
   828  		if number%checkpointInterval == 0 {
   829  			if s, err := loadSnapshot(sb.db, hash); err == nil {
   830  				logger.Trace("Loaded voting snapshot form disk", "number", number, "hash", hash)
   831  				snap = s
   832  				break
   833  			}
   834  		}
   835  		// If we're at block zero, make a snapshot
   836  		if number == 0 {
   837  			var err error
   838  			if snap, err = sb.initSnapshot(chain); err != nil {
   839  				return nil, err
   840  			}
   841  			break
   842  		}
   843  		// No snapshot for this header, gather the header and move backward
   844  		if header := getPrevHeaderAndUpdateParents(chain, number, hash, &parents); header == nil {
   845  			return nil, consensus.ErrUnknownAncestor
   846  		} else {
   847  			headers = append(headers, header)
   848  			number, hash = number-1, header.ParentHash
   849  		}
   850  	}
   851  	// Previous snapshot found, apply any pending headers on top of it
   852  	for i := 0; i < len(headers)/2; i++ {
   853  		headers[i], headers[len(headers)-1-i] = headers[len(headers)-1-i], headers[i]
   854  	}
   855  	pset, err := sb.governance.EffectiveParams(number)
   856  	if err != nil {
   857  		return nil, err
   858  	}
   859  	snap, err = snap.apply(headers, sb.governance, sb.address, pset.Policy(), chain, writable)
   860  	if err != nil {
   861  		return nil, err
   862  	}
   863  
   864  	// If we've generated a new checkpoint snapshot, save to disk
   865  	if writable && snap.Number%checkpointInterval == 0 && len(headers) > 0 {
   866  		if sb.governance.CanWriteGovernanceState(snap.Number) {
   867  			sb.governance.WriteGovernanceState(snap.Number, true)
   868  		}
   869  		if err = snap.store(sb.db); err != nil {
   870  			return nil, err
   871  		}
   872  		logger.Trace("Stored voting snapshot to disk", "number", snap.Number, "hash", snap.Hash)
   873  	}
   874  
   875  	sb.recents.Add(snap.Hash, snap)
   876  	return snap, err
   877  }
   878  
   879  // FIXME: Need to update this for Istanbul
   880  // sigHash returns the hash which is used as input for the Istanbul
   881  // signing. It is the hash of the entire header apart from the 65 byte signature
   882  // contained at the end of the extra data.
   883  //
   884  // Note, the method requires the extra data to be at least 65 bytes, otherwise it
   885  // panics. This is done to avoid accidentally using both forms (signature present
   886  // or not), which could be abused to produce different hashes for the same header.
   887  func sigHash(header *types.Header) (hash common.Hash) {
   888  	hasher := sha3.NewKeccak256()
   889  
   890  	// Clean seal is required for calculating proposer seal.
   891  	rlp.Encode(hasher, types.IstanbulFilteredHeader(header, false))
   892  	hasher.Sum(hash[:0])
   893  	return hash
   894  }
   895  
   896  // ecrecover extracts the Klaytn account address from a signed header.
   897  func ecrecover(header *types.Header) (common.Address, error) {
   898  	// Retrieve the signature from the header extra-data
   899  	istanbulExtra, err := types.ExtractIstanbulExtra(header)
   900  	if err != nil {
   901  		return common.Address{}, err
   902  	}
   903  	addr, err := cacheSignatureAddresses(sigHash(header).Bytes(), istanbulExtra.Seal)
   904  	if err != nil {
   905  		return addr, err
   906  	}
   907  
   908  	return addr, nil
   909  }
   910  
   911  // prepareExtra returns a extra-data of the given header and validators
   912  func prepareExtra(header *types.Header, vals []common.Address) ([]byte, error) {
   913  	var buf bytes.Buffer
   914  
   915  	// compensate the lack bytes if header.Extra is not enough IstanbulExtraVanity bytes.
   916  	if len(header.Extra) < types.IstanbulExtraVanity {
   917  		header.Extra = append(header.Extra, bytes.Repeat([]byte{0x00}, types.IstanbulExtraVanity-len(header.Extra))...)
   918  	}
   919  	buf.Write(header.Extra[:types.IstanbulExtraVanity])
   920  
   921  	ist := &types.IstanbulExtra{
   922  		Validators:    vals,
   923  		Seal:          []byte{},
   924  		CommittedSeal: [][]byte{},
   925  	}
   926  
   927  	payload, err := rlp.EncodeToBytes(&ist)
   928  	if err != nil {
   929  		return nil, err
   930  	}
   931  
   932  	return append(buf.Bytes(), payload...), nil
   933  }
   934  
   935  // writeSeal writes the extra-data field of the given header with the given seals.
   936  // suggest to rename to writeSeal.
   937  func writeSeal(h *types.Header, seal []byte) error {
   938  	if len(seal)%types.IstanbulExtraSeal != 0 {
   939  		return errInvalidSignature
   940  	}
   941  
   942  	istanbulExtra, err := types.ExtractIstanbulExtra(h)
   943  	if err != nil {
   944  		return err
   945  	}
   946  
   947  	istanbulExtra.Seal = seal
   948  	payload, err := rlp.EncodeToBytes(&istanbulExtra)
   949  	if err != nil {
   950  		return err
   951  	}
   952  
   953  	h.Extra = append(h.Extra[:types.IstanbulExtraVanity], payload...)
   954  	return nil
   955  }
   956  
   957  // writeCommittedSeals writes the extra-data field of a block header with given committed seals.
   958  func writeCommittedSeals(h *types.Header, committedSeals [][]byte) error {
   959  	if len(committedSeals) == 0 {
   960  		return errInvalidCommittedSeals
   961  	}
   962  
   963  	for _, seal := range committedSeals {
   964  		if len(seal) != types.IstanbulExtraSeal {
   965  			return errInvalidCommittedSeals
   966  		}
   967  	}
   968  
   969  	istanbulExtra, err := types.ExtractIstanbulExtra(h)
   970  	if err != nil {
   971  		return err
   972  	}
   973  
   974  	istanbulExtra.CommittedSeal = make([][]byte, len(committedSeals))
   975  	copy(istanbulExtra.CommittedSeal, committedSeals)
   976  
   977  	payload, err := rlp.EncodeToBytes(&istanbulExtra)
   978  	if err != nil {
   979  		return err
   980  	}
   981  
   982  	h.Extra = append(h.Extra[:types.IstanbulExtraVanity], payload...)
   983  	return nil
   984  }