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 }