github.com/gnolang/gno@v0.0.0-20240520182011-228e9d0192ce/tm2/pkg/bft/consensus/config/config.go (about) 1 package config 2 3 import ( 4 "errors" 5 "path/filepath" 6 "time" 7 ) 8 9 // ----------------------------------------------------------------------------- 10 // ConsensusConfig 11 12 const ( 13 defaultWALDir = "wal" 14 ) 15 16 // ConsensusConfig defines the configuration for the Tendermint consensus service, 17 // including timeouts and details about the WAL and the block structure. 18 type ConsensusConfig struct { 19 RootDir string `toml:"home"` 20 WALPath string `toml:"wal_file"` 21 WALDisabled bool `toml:"-"` 22 walFile string // overrides WalPath if set 23 24 TimeoutPropose time.Duration `toml:"timeout_propose"` 25 TimeoutProposeDelta time.Duration `toml:"timeout_propose_delta"` 26 TimeoutPrevote time.Duration `toml:"timeout_prevote"` 27 TimeoutPrevoteDelta time.Duration `toml:"timeout_prevote_delta"` 28 TimeoutPrecommit time.Duration `toml:"timeout_precommit"` 29 TimeoutPrecommitDelta time.Duration `toml:"timeout_precommit_delta"` 30 TimeoutCommit time.Duration `toml:"timeout_commit"` 31 32 // Make progress as soon as we have all the precommits (as if TimeoutCommit = 0) 33 SkipTimeoutCommit bool `toml:"skip_timeout_commit" comment:"Make progress as soon as we have all the precommits (as if TimeoutCommit = 0)"` 34 35 // EmptyBlocks mode and possible interval between empty blocks 36 CreateEmptyBlocks bool `toml:"create_empty_blocks" comment:"EmptyBlocks mode and possible interval between empty blocks"` 37 CreateEmptyBlocksInterval time.Duration `toml:"create_empty_blocks_interval"` 38 39 // Reactor sleep duration parameters 40 PeerGossipSleepDuration time.Duration `toml:"peer_gossip_sleep_duration" comment:"Reactor sleep duration parameters"` 41 PeerQueryMaj23SleepDuration time.Duration `toml:"peer_query_maj23_sleep_duration"` 42 } 43 44 // DefaultConsensusConfig returns a default configuration for the consensus service 45 func DefaultConsensusConfig() *ConsensusConfig { 46 return &ConsensusConfig{ 47 WALPath: filepath.Join(defaultWALDir, "cs.wal", "wal"), 48 TimeoutPropose: 3000 * time.Millisecond, 49 TimeoutProposeDelta: 500 * time.Millisecond, 50 TimeoutPrevote: 1000 * time.Millisecond, 51 TimeoutPrevoteDelta: 500 * time.Millisecond, 52 TimeoutPrecommit: 1000 * time.Millisecond, 53 TimeoutPrecommitDelta: 500 * time.Millisecond, 54 TimeoutCommit: 5000 * time.Millisecond, 55 SkipTimeoutCommit: false, 56 CreateEmptyBlocks: true, 57 CreateEmptyBlocksInterval: 0 * time.Second, 58 PeerGossipSleepDuration: 100 * time.Millisecond, 59 PeerQueryMaj23SleepDuration: 2000 * time.Millisecond, 60 } 61 } 62 63 // TestConsensusConfig returns a configuration for testing the consensus service 64 func TestConsensusConfig() *ConsensusConfig { 65 cfg := DefaultConsensusConfig() 66 cfg.TimeoutPropose = 500 * time.Millisecond 67 cfg.TimeoutProposeDelta = 1 * time.Millisecond 68 cfg.TimeoutPrevote = 100 * time.Millisecond 69 cfg.TimeoutPrevoteDelta = 1 * time.Millisecond 70 cfg.TimeoutPrecommit = 100 * time.Millisecond 71 cfg.TimeoutPrecommitDelta = 1 * time.Millisecond 72 cfg.TimeoutCommit = 100 * time.Millisecond 73 cfg.SkipTimeoutCommit = true 74 cfg.PeerGossipSleepDuration = 5 * time.Millisecond 75 cfg.PeerQueryMaj23SleepDuration = 250 * time.Millisecond 76 return cfg 77 } 78 79 // WaitForTxs returns true if the consensus should wait for transactions before entering the propose step 80 func (cfg *ConsensusConfig) WaitForTxs() bool { 81 return !cfg.CreateEmptyBlocks || cfg.CreateEmptyBlocksInterval > 0 82 } 83 84 // Propose returns the amount of time to wait for a proposal 85 func (cfg *ConsensusConfig) Propose(round int) time.Duration { 86 return time.Duration( 87 cfg.TimeoutPropose.Nanoseconds()+cfg.TimeoutProposeDelta.Nanoseconds()*int64(round), 88 ) * time.Nanosecond 89 } 90 91 // Prevote returns the amount of time to wait for straggler votes after receiving any +2/3 prevotes 92 func (cfg *ConsensusConfig) Prevote(round int) time.Duration { 93 return time.Duration( 94 cfg.TimeoutPrevote.Nanoseconds()+cfg.TimeoutPrevoteDelta.Nanoseconds()*int64(round), 95 ) * time.Nanosecond 96 } 97 98 // Precommit returns the amount of time to wait for straggler votes after receiving any +2/3 precommits 99 func (cfg *ConsensusConfig) Precommit(round int) time.Duration { 100 return time.Duration( 101 cfg.TimeoutPrecommit.Nanoseconds()+cfg.TimeoutPrecommitDelta.Nanoseconds()*int64(round), 102 ) * time.Nanosecond 103 } 104 105 // Commit returns the amount of time to wait for straggler votes after receiving +2/3 precommits for a single block (ie. a commit). 106 func (cfg *ConsensusConfig) Commit(t time.Time) time.Time { 107 return t.Add(cfg.TimeoutCommit) 108 } 109 110 // WalFile returns the full path to the write-ahead log file 111 func (cfg *ConsensusConfig) WalFile() string { 112 if cfg.walFile != "" { 113 return cfg.walFile 114 } 115 116 return filepath.Join(cfg.RootDir, cfg.WALPath) 117 } 118 119 // SetWalFile sets the path to the write-ahead log file 120 func (cfg *ConsensusConfig) SetWalFile(walFile string) { 121 cfg.walFile = walFile 122 } 123 124 // ValidateBasic performs basic validation (checking param bounds, etc.) and 125 // returns an error if any check fails. 126 func (cfg *ConsensusConfig) ValidateBasic() error { 127 if cfg.TimeoutPropose < 0 { 128 return errors.New("timeout_propose can't be negative") 129 } 130 if cfg.TimeoutProposeDelta < 0 { 131 return errors.New("timeout_propose_delta can't be negative") 132 } 133 if cfg.TimeoutPrevote < 0 { 134 return errors.New("timeout_prevote can't be negative") 135 } 136 if cfg.TimeoutPrevoteDelta < 0 { 137 return errors.New("timeout_prevote_delta can't be negative") 138 } 139 if cfg.TimeoutPrecommit < 0 { 140 return errors.New("timeout_precommit can't be negative") 141 } 142 if cfg.TimeoutPrecommitDelta < 0 { 143 return errors.New("timeout_precommit_delta can't be negative") 144 } 145 if cfg.TimeoutCommit < 0 { 146 return errors.New("timeout_commit can't be negative") 147 } 148 if cfg.CreateEmptyBlocksInterval < 0 { 149 return errors.New("create_empty_blocks_interval can't be negative") 150 } 151 if cfg.PeerGossipSleepDuration < 0 { 152 return errors.New("peer_gossip_sleep_duration can't be negative") 153 } 154 if cfg.PeerQueryMaj23SleepDuration < 0 { 155 return errors.New("peer_query_maj23_sleep_duration can't be negative") 156 } 157 return nil 158 }