Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions CLI.md
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,8 @@ If the wallet holds the key pair for exactly one of the new chain's owners, that
* `--multi-leader-rounds <MULTI_LEADER_ROUNDS>` — The number of rounds in which every owner can propose blocks, i.e. the first round number in which only a single designated leader is allowed to propose blocks. "null" is equivalent to 2^32 - 1. Absence of the option leaves the current setting unchanged
* `--open-multi-leader-rounds` — Whether the multi-leader rounds are unrestricted, i.e. not limited to chain owners. This should only be `true` on chains with restrictive application permissions and an application-based mechanism to select block proposers
* `--fast-round-ms <FAST_ROUND_DURATION>` — The duration of the fast round, in milliseconds. "null" means the fast round will not time out. Absence of the option leaves the current setting unchanged
* `--base-timeout-ms <BASE_TIMEOUT>` — The duration of the first single-leader and all multi-leader rounds. Absence of the option leaves the current setting unchanged
* `--multi-leader-round-ms <MULTI_LEADER_ROUND_DURATION>` — The duration of every multi-leader round, in milliseconds. Absence of the option leaves the current setting unchanged
* `--base-timeout-ms <BASE_TIMEOUT>` — The duration of the first single-leader round, in milliseconds. Absence of the option leaves the current setting unchanged
* `--timeout-increment-ms <TIMEOUT_INCREMENT>` — The number of milliseconds by which the timeout increases after each single-leader round. Absence of the option leaves the current setting unchanged
* `--fallback-duration-ms <FALLBACK_DURATION>` — The age of an incoming tracked or protected message after which the validators start transitioning the chain to fallback mode, in milliseconds. Absence of the option leaves the current setting unchanged
* `--execute-operations <EXECUTE_OPERATIONS>` — A JSON list of applications allowed to execute operations on this chain. If set to null, all operations will be allowed. Otherwise, only operations from the specified applications are allowed, and no system operations. Absence of the option leaves current permissions unchanged
Expand Down Expand Up @@ -422,7 +423,8 @@ If the chain's current preferred owner is no longer one of the chain's owners an
* `--multi-leader-rounds <MULTI_LEADER_ROUNDS>` — The number of rounds in which every owner can propose blocks, i.e. the first round number in which only a single designated leader is allowed to propose blocks. "null" is equivalent to 2^32 - 1. Absence of the option leaves the current setting unchanged
* `--open-multi-leader-rounds` — Whether the multi-leader rounds are unrestricted, i.e. not limited to chain owners. This should only be `true` on chains with restrictive application permissions and an application-based mechanism to select block proposers
* `--fast-round-ms <FAST_ROUND_DURATION>` — The duration of the fast round, in milliseconds. "null" means the fast round will not time out. Absence of the option leaves the current setting unchanged
* `--base-timeout-ms <BASE_TIMEOUT>` — The duration of the first single-leader and all multi-leader rounds. Absence of the option leaves the current setting unchanged
* `--multi-leader-round-ms <MULTI_LEADER_ROUND_DURATION>` — The duration of every multi-leader round, in milliseconds. Absence of the option leaves the current setting unchanged
* `--base-timeout-ms <BASE_TIMEOUT>` — The duration of the first single-leader round, in milliseconds. Absence of the option leaves the current setting unchanged
* `--timeout-increment-ms <TIMEOUT_INCREMENT>` — The number of milliseconds by which the timeout increases after each single-leader round. Absence of the option leaves the current setting unchanged
* `--fallback-duration-ms <FALLBACK_DURATION>` — The age of an incoming tracked or protected message after which the validators start transitioning the chain to fallback mode, in milliseconds. Absence of the option leaves the current setting unchanged

Expand Down
2 changes: 1 addition & 1 deletion linera-base/src/identifiers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1342,7 +1342,7 @@ mod tests {
);
assert_eq!(
description.id().to_string(),
"372e43034b962ee04f8242bce87fa9cd405dd824a31b6673cef4d24b937d0de5"
"86152d19bd562045e3a9d500e49f005b38e1dc5416e58ca98b5207a958873701"
);
}

Expand Down
27 changes: 16 additions & 11 deletions linera-base/src/ownership.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,11 @@ pub struct TimeoutConfig {
/// The duration of the fast round.
#[debug(skip_if = Option::is_none)]
pub fast_round_duration: Option<TimeDelta>,
/// The duration of the first single-leader and all multi-leader rounds.
/// The duration of every multi-leader round. Multi-leader rounds use a fixed (typically
/// short) duration: a quorum of timeout votes is required to leave a multi-leader round,
/// so this controls the retry latency under multi-leader contention.
pub multi_leader_round_duration: TimeDelta,
/// The duration of the first single-leader round.
pub base_timeout: TimeDelta,
/// The duration by which the timeout increases after each single-leader round.
pub timeout_increment: TimeDelta,
Expand All @@ -52,6 +56,9 @@ impl Default for TimeoutConfig {
fn default() -> Self {
Self {
fast_round_duration: None,
// Multi-leader rounds are meant to be cooperative, so contention should be rare;
// when it does happen, a short round keeps the retry latency low.
multi_leader_round_duration: TimeDelta::from_secs(1),
base_timeout: TimeDelta::from_secs(10),
timeout_increment: TimeDelta::from_secs(1),
// This is `MAX` because the validators are not currently expected to start clients for
Expand Down Expand Up @@ -168,15 +175,9 @@ impl ChainOwnership {
/// Returns the duration of the given round.
pub fn round_timeout(&self, round: Round) -> Option<TimeDelta> {
let tc = &self.timeout_config;
if round.is_fast() && self.owners.is_empty() {
return None; // Fast round only times out if there are regular owners.
}
match round {
Round::Fast => tc.fast_round_duration,
Round::MultiLeader(r) if r.saturating_add(1) == self.multi_leader_rounds => {
Some(tc.base_timeout)
}
Round::MultiLeader(_) => None,
Round::MultiLeader(_) => Some(tc.multi_leader_round_duration),
Round::SingleLeader(r) | Round::Validator(r) => {
let increment = tc.timeout_increment.saturating_mul(u64::from(r));
Some(tc.base_timeout.saturating_add(increment))
Expand Down Expand Up @@ -269,6 +270,7 @@ mod tests {
open_multi_leader_rounds: false,
timeout_config: TimeoutConfig {
fast_round_duration: Some(TimeDelta::from_secs(5)),
multi_leader_round_duration: TimeDelta::from_secs(2),
base_timeout: TimeDelta::from_secs(10),
timeout_increment: TimeDelta::from_secs(1),
fallback_duration: TimeDelta::from_secs(60 * 60),
Expand All @@ -279,10 +281,13 @@ mod tests {
ownership.round_timeout(Round::Fast),
Some(TimeDelta::from_secs(5))
);
assert_eq!(ownership.round_timeout(Round::MultiLeader(8)), None);
assert_eq!(
ownership.round_timeout(Round::MultiLeader(9)),
Some(TimeDelta::from_secs(10))
ownership.round_timeout(Round::MultiLeader(0)),
Some(TimeDelta::from_secs(2))
);
assert_eq!(
ownership.round_timeout(Round::MultiLeader(8)),
Some(TimeDelta::from_secs(2))
);
assert_eq!(
ownership.round_timeout(Round::SingleLeader(0)),
Expand Down
2 changes: 2 additions & 0 deletions linera-base/src/unit_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ fn module_id_test_case() -> ModuleId {
fn timeout_config_test_case() -> TimeoutConfig {
TimeoutConfig {
fast_round_duration: Some(TimeDelta::from_micros(20)),
multi_leader_round_duration: TimeDelta::from_millis(500),
base_timeout: TimeDelta::from_secs(4),
timeout_increment: TimeDelta::from_millis(125),
fallback_duration: TimeDelta::from_secs(1_000),
Expand Down Expand Up @@ -148,6 +149,7 @@ fn chain_ownership_test_case() -> ChainOwnership {
open_multi_leader_rounds: false,
timeout_config: TimeoutConfig {
fast_round_duration: None,
multi_leader_round_duration: TimeDelta::from_secs(1),
base_timeout: TimeDelta::ZERO,
timeout_increment: TimeDelta::from_secs(3_600),
fallback_duration: TimeDelta::from_secs(10_000),
Expand Down
6 changes: 5 additions & 1 deletion linera-chain/src/data_types/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ use serde::{Deserialize, Serialize};
pub struct TimeoutConfigMetadata {
/// The duration of the fast round in milliseconds.
pub fast_round_ms: Option<String>,
/// The duration of the first single-leader and all multi-leader rounds in milliseconds.
/// The duration of every multi-leader round, in milliseconds.
pub multi_leader_round_ms: String,
/// The duration of the first single-leader round, in milliseconds.
pub base_timeout_ms: String,
/// The duration by which the timeout increases after each single-leader round in milliseconds.
pub timeout_increment_ms: String,
Expand All @@ -38,6 +40,8 @@ impl From<&TimeoutConfig> for TimeoutConfigMetadata {
fast_round_ms: config
.fast_round_duration
.map(|d| (d.as_micros() / 1000).to_string()),
multi_leader_round_ms: (config.multi_leader_round_duration.as_micros() / 1000)
.to_string(),
base_timeout_ms: (config.base_timeout.as_micros() / 1000).to_string(),
timeout_increment_ms: (config.timeout_increment.as_micros() / 1000).to_string(),
fallback_duration_ms: (config.fallback_duration.as_micros() / 1000).to_string(),
Expand Down
Loading
Loading