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  }