From 82999599f5207bde2a7cd7116689408dd8b1f15e Mon Sep 17 00:00:00 2001 From: Asmaa Magdoub Date: Wed, 21 Aug 2024 07:38:44 +0300 Subject: [PATCH] feat(consensus): add TimeoutsConfig --- config/papyrus/default_config.json | 15 +++++ crates/papyrus_config/src/converters.rs | 9 +++ ...fig__config_test__dump_default_config.snap | 21 +++++++ .../papyrus_consensus/run_consensus.py | 33 +++++++++++ .../papyrus_consensus/src/config.rs | 59 ++++++++++++++++++- 5 files changed, 136 insertions(+), 1 deletion(-) diff --git a/config/papyrus/default_config.json b/config/papyrus/default_config.json index 9a0f2ddcb0..91bf379532 100644 --- a/config/papyrus/default_config.json +++ b/config/papyrus/default_config.json @@ -129,6 +129,21 @@ "privacy": "Public", "value": "consensus_test_sync" }, + "consensus.timeouts.precommit_timeout": { + "description": "The timeout (seconds) for a precommit.", + "privacy": "Public", + "value": 1.0 + }, + "consensus.timeouts.prevote_timeout": { + "description": "The timeout (seconds) for a prevote.", + "privacy": "Public", + "value": 1.0 + }, + "consensus.timeouts.proposal_timeout": { + "description": "The timeout (seconds) for a proposal.", + "privacy": "Public", + "value": 3.0 + }, "consensus.validator_id": { "description": "A required param! The validator id of the node.", "param_type": "String", diff --git a/crates/papyrus_config/src/converters.rs b/crates/papyrus_config/src/converters.rs index 6cfb27995a..8bac0f1520 100644 --- a/crates/papyrus_config/src/converters.rs +++ b/crates/papyrus_config/src/converters.rs @@ -48,6 +48,15 @@ where Ok(Duration::from_secs(secs)) } +/// Deserializes float seconds to duration object. +pub fn deserialize_float_seconds_to_duration<'de, D>(de: D) -> Result +where + D: Deserializer<'de>, +{ + let secs: f64 = Deserialize::deserialize(de)?; + Ok(Duration::from_secs_f64(secs)) +} + /// Serializes a map to "k1:v1 k2:v2" string structure. pub fn serialize_optional_map(optional_map: &Option>) -> String { match optional_map { diff --git a/crates/papyrus_node/src/config/snapshots/papyrus_node__config__config_test__dump_default_config.snap b/crates/papyrus_node/src/config/snapshots/papyrus_node__config__config_test__dump_default_config.snap index b4a60c52ca..b8fe974fb6 100644 --- a/crates/papyrus_node/src/config/snapshots/papyrus_node__config__config_test__dump_default_config.snap +++ b/crates/papyrus_node/src/config/snapshots/papyrus_node__config__config_test__dump_default_config.snap @@ -153,6 +153,27 @@ expression: dumped_default_config "value": "consensus_test_sync", "privacy": "Public" }, + "consensus.timeouts.precommit_timeout": { + "description": "The timeout (seconds) for a precommit.", + "value": { + "$serde_json::private::Number": "1.0" + }, + "privacy": "Public" + }, + "consensus.timeouts.prevote_timeout": { + "description": "The timeout (seconds) for a prevote.", + "value": { + "$serde_json::private::Number": "1.0" + }, + "privacy": "Public" + }, + "consensus.timeouts.proposal_timeout": { + "description": "The timeout (seconds) for a proposal.", + "value": { + "$serde_json::private::Number": "3.0" + }, + "privacy": "Public" + }, "consensus.validator_id": { "description": "A required param! The validator id of the node.", "param_type": "String", diff --git a/crates/sequencing/papyrus_consensus/run_consensus.py b/crates/sequencing/papyrus_consensus/run_consensus.py index fbeb3a0ed5..d2cf6ed58e 100644 --- a/crates/sequencing/papyrus_consensus/run_consensus.py +++ b/crates/sequencing/papyrus_consensus/run_consensus.py @@ -139,6 +139,9 @@ def build_node(data_dir, logs_dir, i, papryus_args): f"--rpc.server_address 127.0.0.1:{find_free_port()} " f"--monitoring_gateway.server_address 127.0.0.1:{monitoring_gateway_server_port} " f"--consensus.test.#is_none false " + f"--consensus.timeouts.proposal_timeout {papryus_args.proposal_timeout} " + f"--consensus.timeouts.prevote_timeout {papryus_args.prevote_timeout} " + f"--consensus.timeouts.precommit_timeout {papryus_args.precommit_timeout} " f"--consensus.test.cache_size {papryus_args.cache_size} " f"--consensus.test.random_seed {papryus_args.random_seed} " f"--consensus.test.drop_probability {papryus_args.drop_probability} " @@ -190,6 +193,9 @@ def __init__( base_layer_node_url, num_validators, db_dir, + proposal_timeout, + prevote_timeout, + precommit_timeout, cache_size, random_seed, drop_probability, @@ -198,6 +204,9 @@ def __init__( self.base_layer_node_url = base_layer_node_url self.num_validators = num_validators self.db_dir = db_dir + self.proposal_timeout = proposal_timeout + self.prevote_timeout = prevote_timeout + self.precommit_timeout = precommit_timeout self.cache_size = cache_size self.random_seed = random_seed self.drop_probability = drop_probability @@ -265,6 +274,27 @@ def main(papyrus_args, run_consensus_args): help="Time in seconds to check for height stagnation.", ) parser.add_argument("--duration", type=int, required=False, default=None) + parser.add_argument( + "--proposal_timeout", + type=float, + required=False, + default=3, + help="The timeout (seconds) for a proposal.", + ) + parser.add_argument( + "--prevote_timeout", + type=float, + required=False, + default=1, + help="The timeout (seconds) for a prevote.", + ) + parser.add_argument( + "--precommit_timeout", + type=float, + required=False, + default=1, + help="The timeout (seconds) for a precommit.", + ) parser.add_argument( "--cache_size", type=int, @@ -299,6 +329,9 @@ def main(papyrus_args, run_consensus_args): base_layer_node_url=args.base_layer_node_url, num_validators=args.num_validators, db_dir=args.db_dir, + proposal_timeout=args.proposal_timeout, + prevote_timeout=args.prevote_timeout, + precommit_timeout=args.precommit_timeout, cache_size=args.cache_size, random_seed=args.random_seed, drop_probability=args.drop_probability, diff --git a/crates/sequencing/papyrus_consensus/src/config.rs b/crates/sequencing/papyrus_consensus/src/config.rs index ad133c19ac..1f49b03c4b 100644 --- a/crates/sequencing/papyrus_consensus/src/config.rs +++ b/crates/sequencing/papyrus_consensus/src/config.rs @@ -5,8 +5,12 @@ use std::collections::BTreeMap; use std::time::Duration; -use papyrus_config::converters::deserialize_seconds_to_duration; +use papyrus_config::converters::{ + deserialize_float_seconds_to_duration, + deserialize_seconds_to_duration, +}; use papyrus_config::dumping::{ + append_sub_config_name, ser_optional_sub_config, ser_param, ser_required_param, @@ -33,6 +37,8 @@ pub struct ConsensusConfig { /// The delay (seconds) before starting consensus to give time for network peering. #[serde(deserialize_with = "deserialize_seconds_to_duration")] pub consensus_delay: Duration, + /// Timeouts configuration for consensus. + pub timeouts: TimeoutsConfig, /// Test configuration for consensus. pub test: Option, } @@ -71,6 +77,7 @@ impl SerializeConfig for ConsensusConfig { ParamPrivacyInput::Public, ), ]); + config.extend(append_sub_config_name(self.timeouts.dump(), "timeouts")); config.extend(ser_optional_sub_config(&self.test, "test")); config } @@ -84,6 +91,7 @@ impl Default for ConsensusConfig { start_height: BlockNumber::default(), num_validators: 4, consensus_delay: Duration::from_secs(5), + timeouts: TimeoutsConfig::default(), test: None, } } @@ -152,3 +160,52 @@ impl Default for ConsensusTestConfig { } } } + +/// Configuration for consensus timeouts. +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)] +pub struct TimeoutsConfig { + /// The timeout for a proposal. + #[serde(deserialize_with = "deserialize_float_seconds_to_duration")] + pub proposal_timeout: Duration, + /// The timeout for a prevote. + #[serde(deserialize_with = "deserialize_float_seconds_to_duration")] + pub prevote_timeout: Duration, + /// The timeout for a precommit. + #[serde(deserialize_with = "deserialize_float_seconds_to_duration")] + pub precommit_timeout: Duration, +} + +impl SerializeConfig for TimeoutsConfig { + fn dump(&self) -> BTreeMap { + BTreeMap::from_iter([ + ser_param( + "proposal_timeout", + &self.proposal_timeout.as_secs_f64(), + "The timeout (seconds) for a proposal.", + ParamPrivacyInput::Public, + ), + ser_param( + "prevote_timeout", + &self.prevote_timeout.as_secs_f64(), + "The timeout (seconds) for a prevote.", + ParamPrivacyInput::Public, + ), + ser_param( + "precommit_timeout", + &self.precommit_timeout.as_secs_f64(), + "The timeout (seconds) for a precommit.", + ParamPrivacyInput::Public, + ), + ]) + } +} + +impl Default for TimeoutsConfig { + fn default() -> Self { + Self { + proposal_timeout: Duration::from_secs_f64(3.0), + prevote_timeout: Duration::from_secs_f64(1.0), + precommit_timeout: Duration::from_secs_f64(1.0), + } + } +}