github.com/SmartMeshFoundation/Spectrum@v0.0.0-20220621030607-452a266fee1e/consensus/tribe/tribe.go (about)

     1  // Copyright 2018 The Spectrum Authors
     2  package tribe
     3  
     4  import (
     5  	"bytes"
     6  	"encoding/hex"
     7  	"errors"
     8  	"math/big"
     9  	"math/rand"
    10  	"time"
    11  
    12  	"crypto/ecdsa"
    13  	"fmt"
    14  
    15  	"github.com/SmartMeshFoundation/Spectrum/accounts"
    16  	"github.com/SmartMeshFoundation/Spectrum/accounts/abi/bind"
    17  	"github.com/SmartMeshFoundation/Spectrum/common"
    18  	"github.com/SmartMeshFoundation/Spectrum/common/math"
    19  	"github.com/SmartMeshFoundation/Spectrum/consensus"
    20  	"github.com/SmartMeshFoundation/Spectrum/consensus/misc"
    21  	"github.com/SmartMeshFoundation/Spectrum/core/state"
    22  	"github.com/SmartMeshFoundation/Spectrum/core/types"
    23  	"github.com/SmartMeshFoundation/Spectrum/crypto"
    24  	"github.com/SmartMeshFoundation/Spectrum/crypto/sha3"
    25  	"github.com/SmartMeshFoundation/Spectrum/ethdb"
    26  	"github.com/SmartMeshFoundation/Spectrum/log"
    27  	"github.com/SmartMeshFoundation/Spectrum/params"
    28  	"github.com/SmartMeshFoundation/Spectrum/rlp"
    29  	"github.com/SmartMeshFoundation/Spectrum/rpc"
    30  	lru "github.com/hashicorp/golang-lru"
    31  )
    32  
    33  // sigHash returns the hash which is used as input for the proof-of-authority
    34  // signing. It is the hash of the entire header apart from the 65 byte signature
    35  // contained at the end of the extra data.
    36  //
    37  // Note, the method requires the extra data to be at least 65 bytes, otherwise it
    38  // panics. This is done to avoid accidentally using both forms (signature present
    39  // or not), which could be abused to produce different hashes for the same header.
    40  func sigHash(header *types.Header) (hash common.Hash) {
    41  	hasher := sha3.NewKeccak256()
    42  
    43  	err := rlp.Encode(hasher, []interface{}{
    44  		header.ParentHash,
    45  		header.UncleHash,
    46  		header.Coinbase,
    47  		header.Root,
    48  		header.TxHash,
    49  		header.ReceiptHash,
    50  		header.Bloom,
    51  		header.Difficulty,
    52  		header.Number,
    53  		header.GasLimit,
    54  		header.GasUsed,
    55  		header.Time,
    56  		header.Extra[:len(header.Extra)-65], // Yes, this will panic if extra is too short
    57  		header.MixDigest,
    58  		header.Nonce,
    59  	})
    60  	if err != nil {
    61  		panic(err)
    62  	}
    63  	hasher.Sum(hash[:0])
    64  	return hash
    65  }
    66  
    67  func ecrecoverPubkey(header *types.Header, signature []byte) ([]byte, error) {
    68  	pubkey, err := crypto.Ecrecover(sigHash(header).Bytes(), signature)
    69  	return pubkey, err
    70  }
    71  
    72  // ecrecover extracts the Ethereum account address from a signed header.
    73  func ecrecover(header *types.Header, t *Tribe) (common.Address, error) {
    74  	// XXXX : 掐头去尾 ,约定创世区块只能指定一个签名人,因为第一个块要部署合约
    75  	extraVanity := extraVanityFn(header.Number)
    76  	if header.Number.Uint64() == 0 {
    77  		signer := common.Address{}
    78  		copy(signer[:], header.Extra[extraVanity:])
    79  		t.Status.loadSigners([]*Signer{{signer, 3}})
    80  		return signer, nil
    81  	}
    82  	sigcache := t.sigcache
    83  
    84  	// If the signature's already cached, return that
    85  	hash := header.Hash()
    86  	if sigcache != nil {
    87  		if address, known := sigcache.Get(hash); known {
    88  			return address.(common.Address), nil
    89  		}
    90  	}
    91  	// Retrieve the signature from the header extra-data
    92  	if len(header.Extra) < extraSeal {
    93  		return common.Address{}, errMissingSignature
    94  	}
    95  	// Recover the public key and the Ethereum address
    96  	pubkey, err := ecrecoverPubkey(header, header.Extra[len(header.Extra)-extraSeal:])
    97  
    98  	//pubkey, err := crypto.Ecrecover(sigHash(header).Bytes(), signature)
    99  	if err != nil {
   100  		return common.Address{}, err
   101  	}
   102  	var signer common.Address
   103  	copy(signer[:], crypto.Keccak256(pubkey[1:])[12:])
   104  	if sigcache != nil {
   105  		sigcache.Add(hash, signer)
   106  	}
   107  
   108  	return signer, nil
   109  }
   110  
   111  // signers set to the ones provided by the user.
   112  func New(accman *accounts.Manager, config *params.TribeConfig, _ ethdb.Database) *Tribe {
   113  	status := NewTribeStatus()
   114  	sigcache, err := lru.NewARC(historyLimit)
   115  	if err != nil {
   116  		panic(err)
   117  	}
   118  	conf := *config
   119  	if conf.Period <= 0 {
   120  		conf.Period = blockPeriod
   121  	}
   122  	tribe := &Tribe{
   123  		accman:   accman,
   124  		config:   &conf,
   125  		Status:   status,
   126  		sigcache: sigcache,
   127  	}
   128  	status.SetTribe(tribe)
   129  	return tribe
   130  }
   131  
   132  func (t *Tribe) Init() {
   133  	go func() {
   134  		t.lock.Lock()
   135  		defer t.lock.Unlock()
   136  		if t.isInit {
   137  			return
   138  		}
   139  		<-params.InitTribeStatus
   140  		rtn := params.SendToMsgBox("GetNodeKey")
   141  		success := <-rtn
   142  		t.Status.nodeKey = success.Entity.(*ecdsa.PrivateKey)
   143  		if params.InitTribe != nil {
   144  			close(params.InitTribe)
   145  		}
   146  		t.isInit = true
   147  		log.Info("init tribe.status success.")
   148  	}()
   149  }
   150  func (t *Tribe) GetConfig() *params.TribeConfig {
   151  	return t.config
   152  }
   153  func (t *Tribe) SetConfig(config *params.TribeConfig) {
   154  	t.config = config
   155  }
   156  
   157  // Author implements consensus.Engine, returning the Ethereum address recovered
   158  // from the signature in the header's extra-data section.
   159  func (t *Tribe) Author(header *types.Header) (common.Address, error) {
   160  	var (
   161  		coinbase common.Address
   162  		err      error
   163  	)
   164  	if header.Coinbase == coinbase {
   165  		coinbase, err = ecrecover(header, t)
   166  	} else {
   167  		coinbase = header.Coinbase
   168  	}
   169  	log.Debug("<<Tribe.Author>>", "num", header.Number, "coinbase", coinbase.Hex())
   170  	return coinbase, err
   171  }
   172  
   173  // VerifyHeader checks whether a header conforms to the consensus rules.
   174  func (t *Tribe) VerifyHeader(chain consensus.ChainReader, header *types.Header, seal bool) error {
   175  	err := t.verifyHeader(chain, header, nil)
   176  	if err == nil {
   177  		//p := chain.GetHeaderByHash(header.ParentHash)
   178  		//t.Status.LoadSignersFromChief(p.Hash(), p.Number)
   179  	}
   180  	return err
   181  }
   182  
   183  // VerifyHeaders is similar to VerifyHeader, but verifies a batch of headers. The
   184  // method returns a quit channel to abort the operations and a results channel to
   185  // retrieve the async verifications (the order is that of the input slice).
   186  func (t *Tribe) VerifyHeaders(chain consensus.ChainReader, headers []*types.Header, seals []bool) (chan<- struct{}, <-chan error) {
   187  	abort := make(chan struct{})
   188  	results := make(chan error)
   189  	log.Debug("==> VerifyHeaders ", "currentNum", chain.CurrentHeader().Number.Int64(), "headers.len", len(headers))
   190  	go func() {
   191  		for i, header := range headers {
   192  			err := t.verifyHeader(chain, header, headers[:i])
   193  			select {
   194  			case <-abort:
   195  				return
   196  			case results <- err:
   197  			}
   198  		}
   199  	}()
   200  	return abort, results
   201  }
   202  
   203  // verifyHeader checks whether a header conforms to the consensus rules.The
   204  // caller may optionally pass in a batch of parents (ascending order) to avoid
   205  // looking those up from the database. This is useful for concurrently verifying
   206  // a batch of new headers.
   207  func (t *Tribe) verifyHeader(chain consensus.ChainReader, header *types.Header, parents []*types.Header) (err error) {
   208  	defer func() {
   209  		if err != nil {
   210  			log.Info(fmt.Sprintf("verifyHeader err return number=%s,err=%s", header.Number, err))
   211  		}
   212  	}()
   213  	if header.Number == nil {
   214  		return errUnknownBlock
   215  	}
   216  	extraVanity := extraVanityFn(header.Number)
   217  	number := header.Number.Uint64()
   218  
   219  	// Don't waste time checking blocks from the future
   220  	if header.Time.Cmp(big.NewInt(time.Now().Unix())) > 0 {
   221  		return consensus.ErrFutureBlock
   222  	}
   223  	// Nonces must be 0x00..0 or 0xff..f, zeroes enforced on checkpoints
   224  	if !bytes.Equal(header.Nonce[:], nonceSync) && !bytes.Equal(header.Nonce[:], nonceAsync) {
   225  		return errInvalidNonce
   226  	}
   227  
   228  	// Check that the extra-data contains both the vanity and signature
   229  	if len(header.Extra) < extraVanity {
   230  		return errMissingVanity
   231  	}
   232  	if len(header.Extra) < extraVanity+extraSeal {
   233  		return errMissingSignature
   234  	}
   235  	// Ensure that the mix digest is zero as we don't have fork protection currently
   236  	if header.MixDigest != (common.Hash{}) {
   237  		return errInvalidMixDigest
   238  	}
   239  	// Ensure that the block doesn't contain any uncles which are meaningless in PoA
   240  	if header.UncleHash != uncleHash {
   241  		return errInvalidUncleHash
   242  	}
   243  	// Ensure that the block's difficulty is meaningful (may not be correct at this point)
   244  	if number > 0 && !params.IsBeforeChief100block(header.Number) {
   245  		if ci := params.GetChiefInfo(header.Number); ci != nil {
   246  			switch ci.Version {
   247  			case "1.0.0":
   248  				//TODO max value is a var ???
   249  				if header.Difficulty == nil || header.Difficulty.Cmp(big.NewInt(6)) > 0 || header.Difficulty.Cmp(diffNoTurn) < 0 {
   250  					log.Error("** verifyHeader ERROR CHIEF.v1.0.0 **", "diff", header.Difficulty.String(), "err", errInvalidDifficulty)
   251  					return errInvalidDifficulty
   252  				}
   253  			default:
   254  				if header.Difficulty == nil || (header.Difficulty.Cmp(diffInTurnMain) != 0 && header.Difficulty.Cmp(diffInTurn) != 0 && header.Difficulty.Cmp(diffNoTurn) != 0) {
   255  					log.Error("** verifyHeader ERROR **", "diff", header.Difficulty.String(), "err", errInvalidDifficulty)
   256  					return errInvalidDifficulty
   257  				}
   258  			}
   259  		}
   260  	}
   261  	// If all checks passed, validate any special fields for hard forks
   262  	if err := misc.VerifyForkHashes(chain.Config(), header, false); err != nil {
   263  		return err
   264  	}
   265  	// All basic checks passed, verify cascading fields
   266  	err = t.verifyCascadingFields(chain, header, parents)
   267  	if err != nil {
   268  		log.Error("verifyCascadingFields", "num", header.Number.Int64(), "err", err)
   269  	}
   270  	return err
   271  }
   272  
   273  // verifyCascadingFields verifies all the header fields that are not standalone,
   274  // rather depend on a batch of previous headers. The caller may optionally pass
   275  // in a batch of parents (ascending order) to avoid looking those up from the
   276  // database. This is useful for concurrently verifying a batch of new headers.
   277  func (t *Tribe) verifyCascadingFields(chain consensus.ChainReader, header *types.Header, parents []*types.Header) (err error) {
   278  	// The genesis block is the always valid dead-end
   279  	number := header.Number.Uint64()
   280  	if number == 0 {
   281  		return nil
   282  	}
   283  	// Ensure that the block's timestamp isn't too close to it's parent
   284  	var parent *types.Header
   285  
   286  	verifyTime := func() error {
   287  		if params.IsSIP002Block(header.Number) {
   288  			// first verification
   289  			// second verification block time in validateSigner function
   290  			// the min limit period is config.Period - 1
   291  			if parent.Time.Uint64()+(t.config.Period-1) > header.Time.Uint64() {
   292  				return ErrInvalidTimestampSIP002
   293  			}
   294  		} else {
   295  			if parent.Time.Uint64()+t.config.Period > header.Time.Uint64() {
   296  				return ErrInvalidTimestamp
   297  			}
   298  		}
   299  		return nil
   300  	}
   301  
   302  	if len(parents) > 0 {
   303  		parent = parents[len(parents)-1]
   304  		if err := verifyTime(); err != nil {
   305  			return err
   306  		}
   307  	} else {
   308  		parent = chain.GetHeader(header.ParentHash, number-1)
   309  		if parent == nil || parent.Time == nil {
   310  			e := errors.New(fmt.Sprintf("nil_parent_current_num=%d", header.Number.Int64()))
   311  			log.Error("-->bad_block-->", "err", e)
   312  			return e
   313  		}
   314  		if err := verifyTime(); err != nil {
   315  			return err
   316  		}
   317  	}
   318  	if parent == nil || parent.Number.Uint64() != number-1 || parent.Hash() != header.ParentHash {
   319  		return consensus.ErrUnknownAncestor
   320  	}
   321  
   322  	/* TODO timestamp unit second , how to do this logic ?
   323  	if header.Difficulty.Cmp(diffNoTurn) == 0 && parent.Time.Uint64()+t.config.Period == header.Time.Uint64() {
   324  		return ErrInvalidTimestamp
   325  	}
   326  	*/
   327  
   328  	// Verify that the gas limit is <= 2^63-1
   329  	if header.GasLimit.Cmp(math.MaxBig63) > 0 {
   330  		return fmt.Errorf("invalid gasLimit: have %v, max %v", header.GasLimit, math.MaxBig63)
   331  	}
   332  	// Verify that the gasUsed is <= gasLimit
   333  	if header.GasUsed.Cmp(header.GasLimit) > 0 {
   334  		return fmt.Errorf("invalid gasUsed: have %v, gasLimit %v", header.GasUsed, header.GasLimit)
   335  	}
   336  
   337  	// Verify that the gas limit remains within allowed bounds
   338  	diff := new(big.Int).Set(parent.GasLimit)
   339  	diff = diff.Sub(diff, header.GasLimit)
   340  	diff.Abs(diff)
   341  
   342  	limit := new(big.Int).Set(parent.GasLimit)
   343  	limit = limit.Div(limit, params.GasLimitBoundDivisor)
   344  
   345  	minGasLimit := params.MinGasLimit
   346  
   347  	/*
   348  		//sip004区块硬分叉开始,提升区块最小的gaslimit
   349  		sip004Block := params.MainnetChainConfig.Sip004Block
   350  		if params.IsTestnet() {
   351  			sip004Block = params.TestnetChainConfig.Sip004Block
   352  		} else if params.IsDevnet() {
   353  			sip004Block = params.DevnetChainConfig.Sip004Block
   354  		}
   355  
   356  		if header.Number.Cmp(sip004Block) >= 0 {
   357  			minGasLimit = params.Sip004GasLimit
   358  		}
   359  
   360  		if header.Number.Cmp(sip004Block) != 0 && (diff.Cmp(limit) >= 0 || header.GasLimit.Cmp(minGasLimit) < 0) {
   361  			return fmt.Errorf("invalid gas limit: have %v, want %v += %v", header.GasLimit, parent.GasLimit, limit)
   362  		}
   363  	*/
   364  
   365  	if params.IsSIP004Block(header.Number) {
   366  		minGasLimit = params.Sip004GasLimit
   367  	}
   368  
   369  	if !params.EqualSIP004Block(header.Number) && (diff.Cmp(limit) >= 0 || header.GasLimit.Cmp(minGasLimit) < 0) {
   370  		return fmt.Errorf("invalid gas limit: have %v, want %v += %v", header.GasLimit, parent.GasLimit, limit)
   371  	}
   372  
   373  	// Verify that the block number is parent's +1
   374  	if diff := new(big.Int).Sub(header.Number, parent.Number); diff.Cmp(big.NewInt(1)) != 0 {
   375  		return consensus.ErrInvalidNumber
   376  	}
   377  
   378  	return
   379  }
   380  
   381  // VerifyUncles implements consensus.Engine, always returning an error for any
   382  // uncles as this consensus mechanism doesn't permit uncles.
   383  func (t *Tribe) VerifyUncles(chain consensus.ChainReader, block *types.Block) error {
   384  	if len(block.Uncles()) > 0 {
   385  		return errors.New("uncles not allowed")
   386  	}
   387  	return nil
   388  }
   389  
   390  // VerifySeal implements consensus.Engine, checking whether the signature contained
   391  // in the header satisfies the consensus protocol requirements.
   392  // don't support remote miner agent, these code never reached
   393  func (t *Tribe) VerifySeal(chain consensus.ChainReader, header *types.Header) error {
   394  	panic("never reach")
   395  	e := t.verifySeal(chain, header, nil)
   396  	if e != nil {
   397  		log.Error("Tribe.VerifySeal", "err", e)
   398  	}
   399  	return e
   400  }
   401  
   402  func (t *Tribe) verifySeal(chain consensus.ChainReader, header *types.Header, parents []*types.Header) error {
   403  	// Verifying the genesis block is not supported
   404  	number := header.Number.Int64()
   405  	if number == 0 {
   406  		return errUnknownBlock
   407  	}
   408  	// Resolve the authorization key and check against signers
   409  	signer, err := ecrecover(header, t)
   410  	if err != nil {
   411  		return err
   412  	}
   413  	log.Debug("verifySeal", "number", number, "signer", signer.Hex())
   414  
   415  	if !t.Status.validateSigner(chain.GetHeaderByHash(header.ParentHash), header, signer) {
   416  		return errUnauthorized
   417  	}
   418  
   419  	if number > CHIEF_NUMBER && !params.IsBeforeChief100block(header.Number) {
   420  		difficulty := t.Status.InTurnForVerifyDiffculty(number, header.ParentHash, signer)
   421  		if difficulty.Cmp(header.Difficulty) != 0 {
   422  			log.Error("** verifySeal ERROR **", "diff", header.Difficulty.String(), "err", errInvalidDifficulty)
   423  			return errInvalidDifficulty
   424  		}
   425  	}
   426  	return nil
   427  }
   428  
   429  // Prepare implements consensus.Engine, preparing all the consensus fields of the
   430  // header for running the transactions on top.
   431  func (t *Tribe) Prepare(chain consensus.ChainReader, header *types.Header) error {
   432  	//t.Status.LoadStatusFromChief(header.ParentHash, header.Number)
   433  	err := t.Status.LoadStatusFromChief(header.ParentHash, header.Number)
   434  	if err != nil {
   435  		return err
   436  	}
   437  	number := header.Number.Uint64()
   438  	if f, _, err := params.AnmapBindInfo(t.Status.GetMinerAddress(), chain.CurrentHeader().Hash()); err == nil && f != common.HexToAddress("0x") {
   439  		header.Coinbase = f
   440  	} else {
   441  		header.Coinbase = t.Status.GetMinerAddress()
   442  	}
   443  	header.Nonce = types.BlockNonce{}
   444  	copy(header.Nonce[:], nonceAsync)
   445  
   446  	// Extra : append sig to last 65 bytes >>>>
   447  	if params.IsSIP100Block(header.Number) {
   448  		header.Extra = make([]byte, _extraVrf+extraSeal)
   449  		// append vrf to header.Extra before sign
   450  		parentHeader := chain.GetHeaderByHash(header.ParentHash)
   451  		msg := append(parentHeader.Number.Bytes(), parentHeader.Extra[:32]...)
   452  		vrfnp, err := crypto.SimpleVRF2Bytes(t.Status.nodeKey, msg)
   453  		log.Debug("Tribe.Prepare --> params.GetVRFByHash", "err", err, "hash", header.ParentHash.Hex(), "vrfn", hex.EncodeToString(vrfnp[:32]))
   454  		//vr, err := crypto.SimpleVRF2Bytes(t.Status.nodeKey, header.ParentHash.Bytes())
   455  		if err != nil {
   456  			panic(err)
   457  		}
   458  
   459  		copy(header.Extra[:len(header.Extra)-extraSeal], vrfnp)
   460  		log.Debug("prepare_vrf", "num", header.Number, "parent_hash", header.ParentHash.Hex())
   461  		log.Debug("prepare_vrf", "num", header.Number, "miner", crypto.PubkeyToAddress(t.Status.nodeKey.PublicKey).Hex())
   462  		log.Debug("prepare_vrf", "num", header.Number, "err", err, "vrf", hex.EncodeToString(vrfnp))
   463  		log.Debug("prepare_vrf", "num", header.Number, "extra", hex.EncodeToString(header.Extra))
   464  	} else {
   465  		extraVanity := extraVanityFn(header.Number)
   466  		log.Debug("fix extra", "extra-len", len(header.Extra), "extraVanity", extraVanity)
   467  		if len(header.Extra) < extraVanity {
   468  			header.Extra = append(header.Extra, bytes.Repeat([]byte{0x00}, extraVanity-len(header.Extra))...)
   469  		}
   470  		header.Extra = header.Extra[:extraVanity]
   471  		header.Extra = append(header.Extra, make([]byte, extraSeal)...)
   472  	}
   473  	// Extra : append sig to last 65 bytes <<<<
   474  
   475  	// Mix digest is reserved for now, set to empty
   476  	header.MixDigest = common.Hash{}
   477  
   478  	// Ensure the timestamp has the correct delay
   479  	parent := chain.GetHeader(header.ParentHash, number-1)
   480  	if parent == nil {
   481  		return consensus.ErrUnknownAncestor
   482  	}
   483  	// Set the correct difficulty
   484  	header.Difficulty = t.CalcDifficulty(chain, header.Time.Uint64(), parent)
   485  	if params.IsSIP002Block(header.Number) {
   486  		//modify by liangc : change period rule
   487  		header.Time = new(big.Int).Add(parent.Time, new(big.Int).SetUint64(t.GetPeriod(header, nil)))
   488  	} else {
   489  		header.Time = new(big.Int).Add(parent.Time, new(big.Int).SetUint64(t.config.Period))
   490  	}
   491  	if header.Time.Int64() < time.Now().Unix() {
   492  		header.Time = big.NewInt(time.Now().Unix())
   493  	}
   494  	return nil
   495  }
   496  
   497  /*
   498  这个数值是经验书数值,统计了过去一万块后得到的,
   499  1. 在chief100以后此数值不起作用,
   500  2. 在chief100之前,最好通过estimateGas来估算
   501  */
   502  var chiefGasLimit = big.NewInt(4712388)
   503  var chiefGasPrice = big.NewInt(18000000000)
   504  
   505  /*
   506  获取要插入的chief Tx
   507  1.0之后是通过vrf来选择下一轮出块人
   508  1.0之前因为没有奖励,所以是现有signer任意指定候选人
   509  */
   510  func (t *Tribe) GetChiefUpdateTx(chain consensus.ChainReader, header *types.Header, state *state.StateDB) *types.Transaction {
   511  	if header.Number.Cmp(big.NewInt(CHIEF_NUMBER)) <= 0 {
   512  		return nil
   513  	}
   514  	parentHash := header.ParentHash
   515  	parentNumber := new(big.Int).Set(header.Number)
   516  	parentNumber.Sub(parentNumber, big.NewInt(1))
   517  	var vrf *big.Int
   518  	if params.IsSIP100Block(parentNumber) {
   519  		vrf = new(big.Int).SetBytes(header.Extra[:32])
   520  	}
   521  	nextRoundSigner := params.Chief100GetNextRoundSigner(parentHash, parentNumber, vrf)
   522  	nonce := state.GetNonce(t.Status.GetMinerAddress())
   523  	txData, err := hex.DecodeString("1c1b8772000000000000000000000000") //这个是4字节chiefUpdate函数标识以及12字节的0
   524  	if err != nil {
   525  		panic(err)
   526  	}
   527  	txData = append(txData, nextRoundSigner[:]...)
   528  	rawTx := types.NewTransaction(nonce, params.GetChiefInfo(header.Number).Addr, big.NewInt(0), chiefGasLimit, chiefGasPrice, txData)
   529  	auth := bind.NewKeyedTransactor(t.Status.getNodekey())
   530  	signedTx, err := auth.Signer(types.NewEIP155Signer(chain.Config().ChainId), auth.From, rawTx)
   531  	if err != nil {
   532  		panic(fmt.Sprintf("sign tx:%s", err))
   533  	}
   534  	return signedTx
   535  }
   536  
   537  // Finalize implements consensus.Engine, ensuring no uncles are set, nor block
   538  // rewards given, and returns the final block.
   539  func (t *Tribe) Finalize(chain consensus.ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) {
   540  	// Accumulate any block and uncle rewards and commit the final state root
   541  	accumulateRewards(chain.Config(), state, header)
   542  	//destroy SmartMeshFoundation 12% balance
   543  	destroySmartMeshFoundation12Balance(chain.Config(), state, header)
   544  
   545  	header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number))
   546  	//there is no uncle in triple
   547  	header.UncleHash = types.CalcUncleHash(nil)
   548  	return types.NewBlock(header, txs, nil, receipts), nil
   549  }
   550  
   551  // Seal implements consensus.Engine, attempting to create a sealed block using
   552  // the local signing credentials.
   553  func (t *Tribe) Seal(chain consensus.ChainReader, block *types.Block, stop <-chan struct{}) (*types.Block, error) {
   554  	if block.Number().Cmp(big.NewInt(CHIEF_NUMBER)) <= 0 {
   555  		return nil, errors.New("never mining block before #3")
   556  	}
   557  	if err := t.Status.ValidateBlock(chain.GetBlock(block.ParentHash(), block.NumberU64()-1), block, false); err != nil {
   558  		log.Error("Tribe_Seal", "number", block.Number().Int64(), "err", err)
   559  		//log.Error("Tribe_Seal", "retry", atomic.LoadUint32(&t.SealErrorCounter), "number", block.Number().Int64(), "err", err)
   560  		return nil, err
   561  	}
   562  	//atomic.StoreUint32(&t.SealErrorCounter, 0)
   563  	header := block.Header()
   564  	// Sealing the genesis block is not supported
   565  	number := header.Number.Int64()
   566  	// For 0-period chains, refuse to seal empty blocks (no reward but would spin sealing)
   567  	if len(block.Transactions()) == 0 {
   568  		panic("at least one chief update tx")
   569  	}
   570  
   571  	if !t.Status.validateSigner(chain.GetHeaderByHash(block.ParentHash()), block.Header(), t.Status.GetMinerAddress()) {
   572  		return nil, errUnauthorized
   573  	}
   574  
   575  	now := time.Now()
   576  	delay := time.Unix(header.Time.Int64(), 0).Sub(now)
   577  	//fmt.Println(" ---->", "diff", header.Difficulty, "header.time=", header.Time.Int64(), "now=", now.Unix(), "delay=", delay)
   578  	log.Info(fmt.Sprintf("Seal -> num=%d, diff=%d, miner=%s, delay=%d", number, header.Difficulty, header.Coinbase.Hex(), delay))
   579  
   580  	if !params.IsSIP100Block(header.Number) && header.Difficulty.Cmp(diffNoTurn) == 0 {
   581  		wiggle := time.Duration(len(t.Status.Signers)/2+1) * wiggleTime
   582  		delay += time.Duration(rand.Int63n(int64(wiggle)))
   583  	}
   584  	select {
   585  	case <-stop:
   586  		log.Warn(fmt.Sprintf("🐦 cancel -> num=%d, diff=%d, miner=%s, delay=%d", number, header.Difficulty, header.Coinbase.Hex(), delay))
   587  		return nil, nil
   588  	case <-time.After(delay):
   589  	}
   590  
   591  	// Sign all the things!
   592  	hash := sigHash(header).Bytes()
   593  	sighash, err := crypto.Sign(hash, t.Status.nodeKey)
   594  	if err != nil {
   595  		return nil, err
   596  	}
   597  	copy(header.Extra[len(header.Extra)-extraSeal:], sighash)
   598  	blk := block.WithSeal(header)
   599  	return blk, nil
   600  }
   601  
   602  // CalcDifficulty is the difficulty adjustment algorithm. It returns the difficulty
   603  // that a new block should have based on the previous blocks in the chain and the
   604  // current signer.
   605  func (t *Tribe) CalcDifficulty(chain consensus.ChainReader, time uint64, parent *types.Header) *big.Int {
   606  	log.Debug("CalcDifficulty", "ParentNumber", parent.Number.Int64(), "CurrentNumber:", chain.CurrentHeader().Number.Int64())
   607  	currentNumber := new(big.Int).Add(parent.Number, big.NewInt(1))
   608  	if ci := params.GetChiefInfo(currentNumber); ci != nil {
   609  		switch ci.Version {
   610  		case "1.0.0":
   611  			return t.Status.InTurnForCalcDiffcultyChief100(t.Status.GetMinerAddress(), parent)
   612  		}
   613  	}
   614  	return t.Status.InTurnForCalcDifficulty(t.Status.GetMinerAddress(), parent)
   615  }
   616  
   617  // APIs implements consensus.Engine, returning the user facing RPC API to allow
   618  // controlling the signer voting.
   619  func (t *Tribe) APIs(chain consensus.ChainReader) []rpc.API {
   620  	return []rpc.API{{
   621  		Namespace: "tribe",
   622  		Version:   "0.0.1",
   623  		Service:   &API{accman: t.accman, chain: chain, tribe: t},
   624  		Public:    false,
   625  	}}
   626  }
   627  
   628  /*
   629  GetPeriodChief100: 计算出块节点对应的延时时间
   630  依据:
   631  普通节点替补出块规则调整为当前常委会出块节点替补出块,当前常委会出块节点替补出块规则调整为常委会节点列表顺序替补出块,出块难度依次递减。
   632  当普通节点出块时,难度为6->5->4->3->2->1;当常委会节点出块时,难度为6->5->4->3->2。每次替补出块时间都顺延4秒,
   633  下一个区块将在当前区块产生以后的14秒+ 以后产生。
   634  总共只有5个常委会节点,其排序固定
   635  signers:[0,...,16] 0号对应的是常委会节点,1-16对应的是普通出块节点
   636  场景1:
   637  假设`header`中的块该signers[3]出,
   638  如果signers[3]出,则延时14秒,否则只能由其他常委会节点替代
   639  假设当前signers[0]对应的是常委2,那么如果常委2出则延时18,常委3出则延时22,...,如果常委1出则延时34
   640  场景2:
   641  假设`header`中的块该signers[0]出,
   642  如果signers[0]出,则延时14秒,否则只能由其他常委会节点替代
   643  假设当前signers[0]对应的是常委2,那么常委3出则延时18,常委4出则延时22,...常委1出则延时30
   644  替补节点最多5个
   645  */
   646  func (t *Tribe) GetPeriodChief100(header *types.Header, signers []*Signer) (p uint64) {
   647  	var (
   648  		// 14 , 18 , 22 , 26 , 30 , 34 , 38(无出块资格的节点)
   649  		signature               = header.Extra[len(header.Extra)-extraSeal:]
   650  		err                     error
   651  		miner                   common.Address
   652  		empty                   = make([]byte, len(signature))
   653  		Main, Subs, Other, Else = t.config.Period - 1, t.config.Period + 3, t.config.Period + 7, t.config.Period - 1 + 4*6
   654  		number                  = header.Number
   655  	)
   656  
   657  	p = Else
   658  	if bytes.Equal(signature, empty) {
   659  		miner = t.Status.GetMinerAddress()
   660  	} else {
   661  		miner, err = ecrecover(header, t)
   662  		if err != nil {
   663  			log.Error("ecrecover on getPeriod", "header", header, "err", err)
   664  			return
   665  		}
   666  	}
   667  
   668  	if signers == nil {
   669  		signers = t.Status.Signers
   670  	}
   671  	sl := len(signers)
   672  	if sl == 0 {
   673  		log.Error("GetPeriod_signers_cannot_empty")
   674  		return
   675  	}
   676  
   677  	// normal
   678  	idx_m := number.Int64() % int64(sl)
   679  	if miner == signers[idx_m].Address {
   680  		p = Main
   681  		return
   682  	}
   683  
   684  	// first leader
   685  	if miner == signers[0].Address {
   686  		p = Subs
   687  		return
   688  	}
   689  
   690  	// other leader
   691  	if leaders, err := leaderSort(signers[0].Address, t.Status.Leaders); err == nil {
   692  		for i, leader := range leaders {
   693  			if miner == leader && number.Int64()%int64(sl) == 0 {
   694  				p = Subs + uint64(i)*(Subs-Main)
   695  				return
   696  			} else if miner == leader {
   697  				p = Other + uint64(i)*(Subs-Main)
   698  				return
   699  			}
   700  		}
   701  	}
   702  
   703  	return
   704  }
   705  
   706  func (t *Tribe) GetPeriod(header *types.Header, signers []*Signer) (p uint64) {
   707  	if ci := params.GetChiefInfo(header.Number); ci != nil {
   708  		switch ci.Version {
   709  		case "1.0.0":
   710  			p = t.GetPeriodChief100(header, signers)
   711  			log.Debug("<<GetPeriodSIP005>>", "num", header.Number, "period", p)
   712  			return
   713  		}
   714  	}
   715  	// 14 , 18 , 22(random add 0~4.5s)
   716  	signature := header.Extra[len(header.Extra)-extraSeal:]
   717  	var (
   718  		err   error
   719  		miner common.Address
   720  		empty = make([]byte, len(signature))
   721  		/*
   722  			替补出块按照顺序依次增加4秒的延迟
   723  		*/
   724  		Main, Subs, Other = t.config.Period - 1, t.config.Period + 3, t.config.Period + 7
   725  		number            = header.Number
   726  	)
   727  
   728  	p = Other
   729  	if bytes.Equal(signature, empty) {
   730  		miner = t.Status.GetMinerAddress()
   731  	} else {
   732  		miner, err = ecrecover(header, t)
   733  		if err != nil {
   734  			log.Error("ecrecover on getPeriod", "header", header, "err", err)
   735  			return
   736  		}
   737  	}
   738  
   739  	if number.Int64() <= 3 {
   740  		p = Subs
   741  		return
   742  	}
   743  
   744  	if signers == nil {
   745  		signers = t.Status.Signers
   746  	}
   747  
   748  	sl := len(signers)
   749  	if sl == 0 {
   750  		log.Error("GetPeriod_signers_cannot_empty")
   751  		p = Other
   752  		return
   753  	}
   754  
   755  	idx_m, idx_s := number.Int64()%int64(sl), (number.Int64()+1)%int64(sl)
   756  
   757  	if miner == signers[idx_m].Address {
   758  		p = Main
   759  		return
   760  	}
   761  
   762  	if miner == signers[idx_s].Address {
   763  		p = Subs
   764  		return
   765  	}
   766  
   767  	return
   768  }
   769  
   770  // AccumulateRewards credits the coinbase of the given block with the mining
   771  // reward. The total reward consists of the static block reward and rewards for
   772  // included uncles. The coinbase of each uncle block is also rewarded.
   773  // add by liangc : no reward
   774  func accumulateRewards(config *params.ChainConfig, state *state.StateDB, header *types.Header) {
   775  	if config.Chief100Block == nil || header.Number.Cmp(config.Chief100Block) < 0 {
   776  		return
   777  	}
   778  	// Select the correct block reward based on chain progression
   779  	blockReward := new(big.Int).Set(Chief100BlockReward)
   780  
   781  	// Accumulate the rewards for the miner and any included uncles
   782  	number := new(big.Int).Set(header.Number)
   783  	number = number.Sub(number, config.Chief100Block)
   784  	number = number.Div(number, big.NewInt(int64(BlockRewardReducedInterval)))
   785  	blockReward = blockReward.Rsh(blockReward, uint(number.Int64()))
   786  	state.AddBalance(header.Coinbase, blockReward)
   787  }
   788  
   789  //
   790  //销毁基金会账户12% token
   791  //Destroy 12% token of Foundation Account
   792  
   793  func destroySmartMeshFoundation12Balance(config *params.ChainConfig, state *state.StateDB, header *types.Header) {
   794  	if !params.IsDevnet() && !params.IsTestnet() && config.Chief100Block != nil && header.Number.Cmp(config.Chief100Block) == 0 {
   795  		ob := state.GetBalance(SmartMeshFoundationAccount)
   796  		if ob.Cmp(SmartMeshFoundationAccountDestroyBalance) >= 0 {
   797  			state.SubBalance(SmartMeshFoundationAccount, SmartMeshFoundationAccountDestroyBalance)
   798  		} else {
   799  			state.SubBalance(SmartMeshFoundationAccount, ob)
   800  		}
   801  
   802  	}
   803  }