github.com/onflow/flow-go@v0.33.17/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 blockRateDelay := 0 * time.Millisecond 48 maxRebroadcastInterval := 5 * time.Second 49 50 conf, err := NewConfig(minReplicaTimeout+blockRateDelay, maxReplicaTimeout, timeoutAdjustmentFactorFactor, happyPathMaxRoundFailures, maxRebroadcastInterval) 51 if err != nil { 52 // we check in a unit test that this does not happen 53 panic("Default config is not compliant with timeout Config requirements") 54 } 55 56 return conf 57 } 58 59 // NewConfig creates a new TimoutConfig. 60 // - minReplicaTimeout: minimal timeout value for replica round [Milliseconds] 61 // Consistency requirement: must be non-negative 62 // - maxReplicaTimeout: maximal timeout value for replica round [Milliseconds] 63 // Consistency requirement: must be non-negative and cannot be smaller than minReplicaTimeout 64 // - timeoutAdjustmentFactor: multiplicative factor for adjusting timeout duration 65 // Consistency requirement: must be strictly larger than 1 66 // - happyPathMaxRoundFailures: number of successive failed rounds after which we will start increasing timeouts 67 // - blockRateDelay: a delay to delay the proposal broadcasting [Milliseconds] 68 // Consistency requirement: must be non-negative 69 // 70 // Returns `model.ConfigurationError` is any of the consistency requirements is violated. 71 func NewConfig(minReplicaTimeout time.Duration, maxReplicaTimeout time.Duration, timeoutAdjustmentFactor float64, happyPathMaxRoundFailures uint64, maxRebroadcastInterval time.Duration) (Config, error) { 72 if minReplicaTimeout <= 0 { 73 return Config{}, model.NewConfigurationErrorf("minReplicaTimeout must be a positive number[milliseconds]") 74 } 75 if maxReplicaTimeout < minReplicaTimeout { 76 return Config{}, model.NewConfigurationErrorf("maxReplicaTimeout cannot be smaller than minReplicaTimeout") 77 } 78 if timeoutAdjustmentFactor <= 1 { 79 return Config{}, model.NewConfigurationErrorf("timeoutAdjustmentFactor must be strictly bigger than 1") 80 } 81 if maxRebroadcastInterval <= 0 { 82 return Config{}, model.NewConfigurationErrorf("maxRebroadcastInterval must be a positive number [milliseconds]") 83 } 84 85 tc := Config{ 86 MinReplicaTimeout: float64(minReplicaTimeout.Milliseconds()), 87 MaxReplicaTimeout: float64(maxReplicaTimeout.Milliseconds()), 88 TimeoutAdjustmentFactor: timeoutAdjustmentFactor, 89 HappyPathMaxRoundFailures: happyPathMaxRoundFailures, 90 MaxTimeoutObjectRebroadcastInterval: float64(maxRebroadcastInterval.Milliseconds()), 91 } 92 return tc, nil 93 }