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 }