From 56db437dbd3b0815f69b5d21f669a931dd3dfa18 Mon Sep 17 00:00:00 2001 From: Guy Nir Date: Sun, 12 Jan 2025 15:20:21 +0200 Subject: [PATCH] feat(consensus): add config to Context --- config/papyrus/default_config.json | 15 ++++++ crates/papyrus_node/src/config/mod.rs | 5 ++ crates/papyrus_node/src/config/pointers.rs | 1 + ...fig__config_test__dump_default_config.snap | 19 +++++++ crates/papyrus_node/src/run.rs | 32 +++++++----- .../sequencing/papyrus_consensus/src/types.rs | 49 ++++++++++++++++++- .../src/papyrus_consensus_context.rs | 6 ++- .../src/papyrus_consensus_context_test.rs | 4 +- 8 files changed, 114 insertions(+), 17 deletions(-) diff --git a/config/papyrus/default_config.json b/config/papyrus/default_config.json index 9aac78a33a..63638d5c32 100644 --- a/config/papyrus/default_config.json +++ b/config/papyrus/default_config.json @@ -204,6 +204,21 @@ "privacy": "Public", "value": "0x64" }, + "context.batcher_build_buffer": { + "description": "The buffer size for the batcher when building proposals.", + "privacy": "Public", + "value": 100 + }, + "context.chain_id": { + "description": "The chain id of the Starknet chain.", + "pointer_target": "chain_id", + "privacy": "Public" + }, + "context.num_validators": { + "description": "The number of validators.", + "privacy": "Public", + "value": 1 + }, "monitoring_gateway.collect_metrics": { "description": "If true, collect and return metrics in the monitoring gateway.", "pointer_target": "collect_metrics", diff --git a/crates/papyrus_node/src/config/mod.rs b/crates/papyrus_node/src/config/mod.rs index ebc02e1b0c..81ecef7cef 100644 --- a/crates/papyrus_node/src/config/mod.rs +++ b/crates/papyrus_node/src/config/mod.rs @@ -9,6 +9,7 @@ use std::io::{BufWriter, Write}; use std::mem::discriminant; use std::ops::IndexMut; use std::path::{Path, PathBuf}; +use std::task::Context; use std::time::Duration; use std::{env, fs, io}; @@ -26,6 +27,7 @@ use papyrus_config::dumping::{ use papyrus_config::loading::load_and_process_config; use papyrus_config::{ConfigError, ParamPath, ParamPrivacyInput, SerializedParam}; use papyrus_consensus::config::ConsensusConfig; +use papyrus_consensus::types::ContextConfig; use papyrus_monitoring_gateway::MonitoringGatewayConfig; use papyrus_network::NetworkConfig; use papyrus_p2p_sync::client::{P2pSyncClient, P2pSyncClientConfig}; @@ -64,6 +66,7 @@ pub struct NodeConfig { // TODO(yair): Change NodeConfig to have an option of enum of SyncConfig or P2pSyncConfig. pub p2p_sync: Option, pub consensus: Option, + pub context: ContextConfig, // TODO(shahak): Make network non-optional once it's developed enough. pub network: Option, pub collect_profiling_metrics: bool, @@ -82,6 +85,7 @@ impl Default for NodeConfig { sync: Some(SyncConfig::default()), p2p_sync: None, consensus: None, + context: ContextConfig::default(), network: None, collect_profiling_metrics: false, } @@ -99,6 +103,7 @@ impl SerializeConfig for NodeConfig { ser_optional_sub_config(&self.sync, "sync"), ser_optional_sub_config(&self.p2p_sync, "p2p_sync"), ser_optional_sub_config(&self.consensus, "consensus"), + append_sub_config_name(self.context.dump(), "context"), ser_optional_sub_config(&self.network, "network"), BTreeMap::from_iter([ser_param( "collect_profiling_metrics", diff --git a/crates/papyrus_node/src/config/pointers.rs b/crates/papyrus_node/src/config/pointers.rs index 56a89fce08..ee8a18d5d4 100644 --- a/crates/papyrus_node/src/config/pointers.rs +++ b/crates/papyrus_node/src/config/pointers.rs @@ -59,6 +59,7 @@ pub static CONFIG_POINTERS: LazyLock = LazyLock::new(|| { ), set_pointing_param_paths(&[ "consensus.chain_id", + "context.chain_id", "consensus.network_config.chain_id", "network.chain_id", "rpc.chain_id", 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 0b74be563a..ea0e438164 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 @@ -246,6 +246,25 @@ expression: dumped_default_config "value": "0x64", "privacy": "Public" }, + "context.batcher_build_buffer": { + "description": "The buffer size for the batcher when building proposals.", + "value": { + "$serde_json::private::Number": "100" + }, + "privacy": "Public" + }, + "context.chain_id": { + "description": "The chain id of the Starknet chain.", + "value": "SN_MAIN", + "privacy": "Public" + }, + "context.num_validators": { + "description": "The number of validators.", + "value": { + "$serde_json::private::Number": "1" + }, + "privacy": "Public" + }, "monitoring_gateway.collect_metrics": { "description": "If true, collect and return metrics in the monitoring gateway.", "value": false, diff --git a/crates/papyrus_node/src/run.rs b/crates/papyrus_node/src/run.rs index 9f4ef10a52..3523f469a5 100644 --- a/crates/papyrus_node/src/run.rs +++ b/crates/papyrus_node/src/run.rs @@ -15,6 +15,7 @@ use papyrus_config::presentation::get_config_presentation; use papyrus_config::validators::config_validate; use papyrus_consensus::config::ConsensusConfig; use papyrus_consensus::stream_handler::StreamHandler; +use papyrus_consensus::types::ContextConfig; use papyrus_consensus_orchestrator::papyrus_consensus_context::PapyrusConsensusContext; use papyrus_monitoring_gateway::MonitoringServer; use papyrus_network::gossipsub_impl::Topic; @@ -179,19 +180,23 @@ fn spawn_monitoring_server( } fn spawn_consensus( - config: Option<&ConsensusConfig>, + consensus_config: Option<&ConsensusConfig>, + context_config: ContextConfig, storage_reader: StorageReader, network_manager: Option<&mut NetworkManager>, ) -> anyhow::Result>> { - let (Some(config), Some(network_manager)) = (config, network_manager) else { + let (Some(consensus_config), Some(network_manager)) = (consensus_config, network_manager) + else { info!("Consensus is disabled."); return Ok(tokio::spawn(future::pending())); }; - let config = config.clone(); - debug!("Consensus configuration: {config:?}"); + let consensus_config = consensus_config.clone(); + debug!("Consensus configuration: {consensus_config:?}"); - let network_channels = network_manager - .register_broadcast_topic(Topic::new(config.network_topic.clone()), BUFFER_SIZE)?; + let network_channels = network_manager.register_broadcast_topic( + Topic::new(consensus_config.network_topic.clone()), + BUFFER_SIZE, + )?; let proposal_network_channels: BroadcastTopicChannels< StreamMessage, > = network_manager.register_broadcast_topic(Topic::new(NETWORK_TOPIC), BUFFER_SIZE)?; @@ -205,23 +210,23 @@ fn spawn_consensus( StreamHandler::get_channels(inbound_network_receiver, outbound_network_sender); let context = PapyrusConsensusContext::new( + context_config, storage_reader.clone(), network_channels.broadcast_topic_client.clone(), outbound_internal_sender, - config.num_validators, None, ); Ok(tokio::spawn(async move { Ok(papyrus_consensus::run_consensus( context, - config.start_height, + consensus_config.start_height, // TODO(Asmaa): replace with the correct value. - config.start_height, - config.validator_id, - config.consensus_delay, - config.timeouts.clone(), - config.sync_retry_interval, + consensus_config.start_height, + consensus_config.validator_id, + consensus_config.consensus_delay, + consensus_config.timeouts.clone(), + consensus_config.sync_retry_interval, network_channels.into(), inbound_internal_receiver, ) @@ -357,6 +362,7 @@ async fn run_threads( } else { spawn_consensus( config.consensus.as_ref(), + config.context.clone(), resources.storage_reader.clone(), resources.maybe_network_manager.as_mut(), )? diff --git a/crates/sequencing/papyrus_consensus/src/types.rs b/crates/sequencing/papyrus_consensus/src/types.rs index 5eb10a426c..4a73e9d859 100644 --- a/crates/sequencing/papyrus_consensus/src/types.rs +++ b/crates/sequencing/papyrus_consensus/src/types.rs @@ -1,10 +1,13 @@ //! Types for interfacing between consensus and the node. +use std::collections::BTreeMap; use std::fmt::Debug; use std::time::Duration; use async_trait::async_trait; use futures::channel::{mpsc, oneshot}; +use papyrus_config::dumping::{ser_param, SerializeConfig}; +use papyrus_config::{ParamPath, ParamPrivacyInput, SerializedParam}; use papyrus_network::network_manager::{ BroadcastTopicChannels, BroadcastTopicClient, @@ -13,8 +16,10 @@ use papyrus_network::network_manager::{ use papyrus_network_types::network_types::BroadcastedMessageMetadata; use papyrus_protobuf::consensus::{ProposalFin, ProposalInit, Vote}; use papyrus_protobuf::converters::ProtobufConversionError; +use serde::{Deserialize, Serialize}; use starknet_api::block::{BlockHash, BlockNumber}; -use starknet_api::core::ContractAddress; +use starknet_api::core::{ChainId, ContractAddress}; +use validator::Validate; /// Used to identify the node by consensus. /// 1. This ID is derived from the id registered with Starknet's L2 staking contract. @@ -25,6 +30,48 @@ pub type ValidatorId = ContractAddress; pub type Round = u32; pub type ProposalContentId = BlockHash; +/// Configuration for the Context struct. +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Validate)] +pub struct ContextConfig { + /// The buffer size for the batcher when building proposals. + pub batcher_build_buffer: usize, + /// The number of validators. + pub num_validators: u64, + /// The chain id of the Starknet chain. + pub chain_id: ChainId, +} + +impl SerializeConfig for ContextConfig { + fn dump(&self) -> BTreeMap { + BTreeMap::from_iter([ + ser_param( + "batcher_build_buffer", + &self.batcher_build_buffer, + "The buffer size for the batcher when building proposals.", + ParamPrivacyInput::Public, + ), + ser_param( + "num_validators", + &self.num_validators, + "The number of validators.", + ParamPrivacyInput::Public, + ), + ser_param( + "chain_id", + &self.chain_id, + "The chain id of the Starknet chain.", + ParamPrivacyInput::Public, + ), + ]) + } +} + +impl Default for ContextConfig { + fn default() -> Self { + Self { batcher_build_buffer: 100, num_validators: 1, chain_id: ChainId::Mainnet } + } +} + /// Interface for consensus to call out to the node. /// /// Function calls should be assumed to not be cancel safe. diff --git a/crates/sequencing/papyrus_consensus_orchestrator/src/papyrus_consensus_context.rs b/crates/sequencing/papyrus_consensus_orchestrator/src/papyrus_consensus_context.rs index 2e0c127b3a..fdea914153 100644 --- a/crates/sequencing/papyrus_consensus_orchestrator/src/papyrus_consensus_context.rs +++ b/crates/sequencing/papyrus_consensus_orchestrator/src/papyrus_consensus_context.rs @@ -18,6 +18,7 @@ use futures::{SinkExt, StreamExt}; use papyrus_consensus::types::{ ConsensusContext, ConsensusError, + ContextConfig, ProposalContentId, Round, ValidatorId, @@ -46,6 +47,7 @@ type HeightToIdToContent = BTreeMap, network_proposal_sender: mpsc::Sender<(HeightAndRound, mpsc::Receiver)>, @@ -59,13 +61,15 @@ pub struct PapyrusConsensusContext { impl PapyrusConsensusContext { pub fn new( + config: ContextConfig, storage_reader: StorageReader, network_broadcast_client: BroadcastTopicClient, network_proposal_sender: mpsc::Sender<(HeightAndRound, mpsc::Receiver)>, - num_validators: u64, sync_broadcast_sender: Option>, ) -> Self { + let num_validators = config.num_validators; Self { + _config: config, storage_reader, network_broadcast_client, network_proposal_sender, diff --git a/crates/sequencing/papyrus_consensus_orchestrator/src/papyrus_consensus_context_test.rs b/crates/sequencing/papyrus_consensus_orchestrator/src/papyrus_consensus_context_test.rs index 0bdb8ccc20..3fb75130e4 100644 --- a/crates/sequencing/papyrus_consensus_orchestrator/src/papyrus_consensus_context_test.rs +++ b/crates/sequencing/papyrus_consensus_orchestrator/src/papyrus_consensus_context_test.rs @@ -3,7 +3,7 @@ use std::time::Duration; use futures::channel::{mpsc, oneshot}; use futures::StreamExt; use papyrus_consensus::stream_handler::StreamHandler; -use papyrus_consensus::types::ConsensusContext; +use papyrus_consensus::types::{ConsensusContext, ContextConfig}; use papyrus_network::network_manager::test_utils::{ mock_register_broadcast_topic, BroadcastNetworkMock, @@ -142,10 +142,10 @@ fn test_setup() let sync_channels = mock_register_broadcast_topic().unwrap(); let papyrus_context = PapyrusConsensusContext::new( + ContextConfig::default(), storage_reader.clone(), network_channels.subscriber_channels.broadcast_topic_client, outbound_internal_sender, - 4, Some(sync_channels.subscriber_channels.broadcast_topic_client), ); (block, papyrus_context, network_channels.mock_network, sync_channels.mock_network)