github.com/kisexp/xdchain@v0.0.0-20211206025815-490d6b732aa7/consensus/istanbul/config.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 istanbul
    18  
    19  import (
    20  	"math/big"
    21  	"sync"
    22  
    23  	"github.com/naoina/toml"
    24  )
    25  
    26  type ProposerPolicyId uint64
    27  
    28  const (
    29  	RoundRobin ProposerPolicyId = iota
    30  	Sticky
    31  )
    32  
    33  // ProposerPolicy represents the Validator Proposer Policy
    34  type ProposerPolicy struct {
    35  	Id         ProposerPolicyId    // Could be RoundRobin or Sticky
    36  	By         ValidatorSortByFunc // func that defines how the ValidatorSet should be sorted
    37  	registry   []ValidatorSet      // Holds the ValidatorSet for a given block height
    38  	registryMU *sync.Mutex         // Mutex to lock access to changes to Registry
    39  }
    40  
    41  // NewRoundRobinProposerPolicy returns a RoundRobin ProposerPolicy with ValidatorSortByString as default sort function
    42  func NewRoundRobinProposerPolicy() *ProposerPolicy {
    43  	return NewProposerPolicy(RoundRobin)
    44  }
    45  
    46  // NewStickyProposerPolicy return a Sticky ProposerPolicy with ValidatorSortByString as default sort function
    47  func NewStickyProposerPolicy() *ProposerPolicy {
    48  	return NewProposerPolicy(Sticky)
    49  }
    50  
    51  func NewProposerPolicy(id ProposerPolicyId) *ProposerPolicy {
    52  	return NewProposerPolicyByIdAndSortFunc(id, ValidatorSortByString())
    53  }
    54  
    55  func NewProposerPolicyByIdAndSortFunc(id ProposerPolicyId, by ValidatorSortByFunc) *ProposerPolicy {
    56  	return &ProposerPolicy{Id: id, By: by, registryMU: new(sync.Mutex)}
    57  }
    58  
    59  type proposerPolicyToml struct {
    60  	Id ProposerPolicyId
    61  }
    62  
    63  func (p *ProposerPolicy) MarshalTOML() ([]byte, error) {
    64  	pp := &proposerPolicyToml{Id: p.Id}
    65  	return toml.Marshal(pp)
    66  }
    67  
    68  func (p *ProposerPolicy) UnmarshalTOML(input []byte) error {
    69  	var pp proposerPolicyToml
    70  	err := toml.Unmarshal(input, &pp)
    71  	if err != nil {
    72  		return err
    73  	}
    74  	p.Id = pp.Id
    75  	p.By = ValidatorSortByString()
    76  	return nil
    77  }
    78  
    79  // Use sets the ValidatorSortByFunc for the given ProposerPolicy and sorts the validatorSets according to it
    80  func (p *ProposerPolicy) Use(v ValidatorSortByFunc) {
    81  	p.By = v
    82  
    83  	for _, validatorSet := range p.registry {
    84  		validatorSet.SortValidators()
    85  	}
    86  }
    87  
    88  // RegisterValidatorSet stores the given ValidatorSet in the policy registry
    89  func (p *ProposerPolicy) RegisterValidatorSet(valSet ValidatorSet) {
    90  	p.registryMU.Lock()
    91  	defer p.registryMU.Unlock()
    92  
    93  	if len(p.registry) == 0 {
    94  		p.registry = []ValidatorSet{valSet}
    95  	} else {
    96  		p.registry = append(p.registry, valSet)
    97  	}
    98  }
    99  
   100  // ClearRegistry removes any ValidatorSet from the ProposerPolicy registry
   101  func (p *ProposerPolicy) ClearRegistry() {
   102  	p.registryMU.Lock()
   103  	defer p.registryMU.Unlock()
   104  
   105  	p.registry = nil
   106  }
   107  
   108  type Config struct {
   109  	// 每个IBFT或 QBFT回合的最小请求超时(以毫秒为单位)。请求超时是如果前一轮没有完成,IBFT 触发新一轮的超时时间。随着超时被更频繁地命中,此时间段会增加。
   110  	RequestTimeout         uint64          `toml:",omitempty"` // The timeout for each Istanbul round in milliseconds.
   111  	// 出块时间 (两个连续块的时间戳之间的默认最小差异(以秒为单位))
   112  	BlockPeriod            uint64          `toml:",omitempty"` // Default minimum difference between two consecutive block's timestamps in second
   113  	ProposerPolicy         *ProposerPolicy `toml:",omitempty"` // The policy for proposer selection
   114  	// 检查点和重置未决投票之前的块数
   115  	Epoch                  uint64          `toml:",omitempty"` // The number of blocks after which to checkpoint and reset the pending votes
   116  	Ceil2Nby3Block         *big.Int        `toml:",omitempty"` // Number of confirmations required to move from one state to next [2F + 1 to Ceil(2N/3)]
   117  	// 在它们被认为是未来的块之前允许块的当前时间的最长时间(以秒为单位)
   118  	// 从当前时间开始,块被视为未来块之前允许的最长时间,以秒为单位。这允许节点稍微不同步而不会收到“未来挖掘太远”消息。默认值为 0。
   119  	AllowedFutureBlockTime uint64          `toml:",omitempty"` // Max time (in seconds) from current time allowed for blocks, before they're considered future blocks
   120  	TestQBFTBlock          *big.Int        `toml:",omitempty"` // Fork block at which block confirmations are done using qbft consensus instead of ibft
   121  }
   122  
   123  var DefaultConfig = &Config{
   124  	RequestTimeout:         10000,
   125  	BlockPeriod:            1,
   126  	ProposerPolicy:         NewRoundRobinProposerPolicy(),
   127  	Epoch:                  30000,
   128  	Ceil2Nby3Block:         big.NewInt(0),
   129  	AllowedFutureBlockTime: 0,
   130  	TestQBFTBlock:          big.NewInt(0),
   131  }
   132  
   133  // QBFTBlockNumber returns the qbftBlock fork block number, returns -1 if qbftBlock is not defined
   134  func (c Config) QBFTBlockNumber() int64 {
   135  	if c.TestQBFTBlock == nil {
   136  		return -1
   137  	}
   138  	return c.TestQBFTBlock.Int64()
   139  }
   140  
   141  // IsQBFTConsensusAt checks if qbft consensus is enabled for the block height identified by the given header
   142  func (c *Config) IsQBFTConsensusAt(blockNumber *big.Int) bool {
   143  	// If qbftBlock is not defined in genesis qbft consensus is not used
   144  	if c.TestQBFTBlock == nil {
   145  		return false
   146  	}
   147  
   148  	if c.TestQBFTBlock.Uint64() == 0 {
   149  		return true
   150  	}
   151  
   152  	if blockNumber.Cmp(c.TestQBFTBlock) >= 0 {
   153  		return true
   154  	}
   155  	return false
   156  }