github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/consensus/hotstuff/pacemaker/timeout/config.go (about)

     1  package timeout
     2  
     3  import (
     4  	"time"
     5  
     6  	"github.com/onflow/flow-go/consensus/hotstuff/model"
     7  )
     8  
     9  // Config contains the configuration parameters for a Truncated Exponential Backoff,
    10  // as implemented by the `timeout.Controller`
    11  //   - On timeout: increase timeout by multiplicative factor `TimeoutAdjustmentFactor`. This
    12  //     results in exponentially growing timeout duration on multiple subsequent timeouts.
    13  //   - On progress: decrease timeout by multiplicative factor `TimeoutAdjustmentFactor.
    14  //
    15  // Config is implemented such that it can be passed by value, while still supporting updates of
    16  // `BlockRateDelayMS` at runtime (all configs share the same memory holding `BlockRateDelayMS`).
    17  type Config struct {
    18  	// MinReplicaTimeout is the minimum the timeout can decrease to [MILLISECONDS]
    19  	MinReplicaTimeout float64
    20  	// MaxReplicaTimeout is the maximum value the timeout can increase to [MILLISECONDS]
    21  	MaxReplicaTimeout float64
    22  	// TimeoutAdjustmentFactor: MULTIPLICATIVE factor for increasing timeout when view
    23  	// change was triggered by a TC (unhappy path) or decreasing the timeout on progress
    24  	TimeoutAdjustmentFactor float64
    25  	// HappyPathMaxRoundFailures is the number of rounds without progress where we still consider being
    26  	// on hot path of execution. After exceeding this value we will start increasing timeout values.
    27  	HappyPathMaxRoundFailures uint64
    28  	// MaxTimeoutObjectRebroadcastInterval is the maximum value for timeout object rebroadcast interval [MILLISECONDS]
    29  	MaxTimeoutObjectRebroadcastInterval float64
    30  }
    31  
    32  var DefaultConfig = NewDefaultConfig()
    33  
    34  // NewDefaultConfig returns a default timeout configuration.
    35  // We explicitly provide a method here, which demonstrates in-code how
    36  // to compute standard values from some basic quantities.
    37  func NewDefaultConfig() Config {
    38  	// minReplicaTimeout is the lower bound on the replica's timeout value, this is also the initial timeout with what replicas
    39  	// will start their execution.
    40  	// If HotStuff is running at full speed, 1200ms should be enough. However, we add some buffer.
    41  	// This value is for instant message delivery.
    42  	minReplicaTimeout := 3 * time.Second
    43  	maxReplicaTimeout := 1 * time.Minute
    44  	timeoutAdjustmentFactorFactor := 1.2
    45  	// after 6 successively failed rounds, the pacemaker leaves the hot path and starts increasing timeouts (recovery mode)
    46  	happyPathMaxRoundFailures := uint64(6)
    47  	maxRebroadcastInterval := 5 * time.Second
    48  
    49  	conf, err := NewConfig(minReplicaTimeout, maxReplicaTimeout, timeoutAdjustmentFactorFactor, happyPathMaxRoundFailures, maxRebroadcastInterval)
    50  	if err != nil {
    51  		// we check in a unit test that this does not happen
    52  		panic("Default config is not compliant with timeout Config requirements")
    53  	}
    54  
    55  	return conf
    56  }
    57  
    58  // NewConfig creates a new TimoutConfig.
    59  //   - minReplicaTimeout: minimal timeout value for replica round [Milliseconds]
    60  //     Consistency requirement: must be non-negative
    61  //   - maxReplicaTimeout: maximal timeout value for replica round [Milliseconds]
    62  //     Consistency requirement: must be non-negative and cannot be smaller than minReplicaTimeout
    63  //   - timeoutAdjustmentFactor: multiplicative factor for adjusting timeout duration
    64  //     Consistency requirement: must be strictly larger than 1
    65  //   - happyPathMaxRoundFailures: number of successive failed rounds after which we will start increasing timeouts
    66  //   - blockRateDelay: a delay to delay the proposal broadcasting [Milliseconds]
    67  //     Consistency requirement: must be non-negative
    68  //
    69  // Returns `model.ConfigurationError` is any of the consistency requirements is violated.
    70  func NewConfig(minReplicaTimeout time.Duration, maxReplicaTimeout time.Duration, timeoutAdjustmentFactor float64, happyPathMaxRoundFailures uint64, maxRebroadcastInterval time.Duration) (Config, error) {
    71  	if minReplicaTimeout <= 0 {
    72  		return Config{}, model.NewConfigurationErrorf("minReplicaTimeout must be a positive number[milliseconds]")
    73  	}
    74  	if maxReplicaTimeout < minReplicaTimeout {
    75  		return Config{}, model.NewConfigurationErrorf("maxReplicaTimeout cannot be smaller than minReplicaTimeout")
    76  	}
    77  	if timeoutAdjustmentFactor <= 1 {
    78  		return Config{}, model.NewConfigurationErrorf("timeoutAdjustmentFactor must be strictly bigger than 1")
    79  	}
    80  	if maxRebroadcastInterval <= 0 {
    81  		return Config{}, model.NewConfigurationErrorf("maxRebroadcastInterval must be a positive number [milliseconds]")
    82  	}
    83  
    84  	tc := Config{
    85  		MinReplicaTimeout:                   float64(minReplicaTimeout.Milliseconds()),
    86  		MaxReplicaTimeout:                   float64(maxReplicaTimeout.Milliseconds()),
    87  		TimeoutAdjustmentFactor:             timeoutAdjustmentFactor,
    88  		HappyPathMaxRoundFailures:           happyPathMaxRoundFailures,
    89  		MaxTimeoutObjectRebroadcastInterval: float64(maxRebroadcastInterval.Milliseconds()),
    90  	}
    91  	return tc, nil
    92  }