diff --git a/config/src/config/config_optimizer.rs b/config/src/config/config_optimizer.rs index a92c376636696..386c2730f7a10 100644 --- a/config/src/config/config_optimizer.rs +++ b/config/src/config/config_optimizer.rs @@ -96,6 +96,11 @@ impl ConfigOptimizer for NodeConfig { node_type: NodeType, chain_id: Option, ) -> Result { + // If config optimization is disabled, don't do anything! + if node_config.node_startup.skip_config_optimizer { + return Ok(false); + } + // Optimize only the relevant sub-configs let mut optimizers_with_modifications = vec![]; if IndexerConfig::optimize(node_config, local_config_yaml, node_type, chain_id)? { @@ -288,9 +293,47 @@ fn build_seed_peer( #[cfg(test)] mod tests { use super::*; - use crate::{config::NetworkConfig, network_id::NetworkId}; + use crate::{ + config::{node_startup_config::NodeStartupConfig, NetworkConfig}, + network_id::NetworkId, + }; use aptos_types::account_address::AccountAddress; + #[test] + fn test_disable_optimizer() { + // Create a default node config (with optimization enabled) + let mut node_config = NodeConfig::default(); + + // Optimize the node config for mainnet VFNs and verify modifications are made + let modified_config = NodeConfig::optimize( + &mut node_config, + &serde_yaml::from_str("{}").unwrap(), // An empty local config + NodeType::ValidatorFullnode, + Some(ChainId::mainnet()), + ) + .unwrap(); + assert!(modified_config); + + // Create a node config with the optimizer disabled + let mut node_config = NodeConfig { + node_startup: NodeStartupConfig { + skip_config_optimizer: true, + ..Default::default() + }, + ..Default::default() + }; + + // Optimize the node config for mainnet VFNs and verify no modifications are made + let modified_config = NodeConfig::optimize( + &mut node_config, + &serde_yaml::from_str("{}").unwrap(), // An empty local config + NodeType::ValidatorFullnode, + Some(ChainId::mainnet()), + ) + .unwrap(); + assert!(!modified_config); + } + #[test] fn test_optimize_public_network_config_mainnet() { // Create a public network config with no seeds diff --git a/config/src/config/config_sanitizer.rs b/config/src/config/config_sanitizer.rs index 15acc9ce48daf..df32e0ae23696 100644 --- a/config/src/config/config_sanitizer.rs +++ b/config/src/config/config_sanitizer.rs @@ -41,6 +41,11 @@ impl ConfigSanitizer for NodeConfig { node_type: NodeType, chain_id: Option, ) -> Result<(), Error> { + // If config sanitization is disabled, don't do anything! + if node_config.node_startup.skip_config_sanitizer { + return Ok(()); + } + // Sanitize all of the sub-configs AdminServiceConfig::sanitize(node_config, node_type, chain_id)?; ApiConfig::sanitize(node_config, node_type, chain_id)?; @@ -197,7 +202,40 @@ fn sanitize_validator_network_config( #[cfg(test)] mod tests { use super::*; - use crate::{config::NetworkConfig, network_id::NetworkId}; + use crate::{ + config::{node_startup_config::NodeStartupConfig, NetworkConfig}, + network_id::NetworkId, + }; + + #[test] + fn test_disable_config_sanitizer() { + // Create a default node config (with sanitization enabled) + let mut node_config = NodeConfig::default(); + + // Set a bad node config for mainnet + node_config.execution.paranoid_hot_potato_verification = false; + + // Sanitize the config and verify the sanitizer fails + let error = + NodeConfig::sanitize(&node_config, NodeType::Validator, Some(ChainId::mainnet())) + .unwrap_err(); + assert!(matches!(error, Error::ConfigSanitizerFailed(_, _))); + + // Create a node config with the sanitizer disabled + let mut node_config = NodeConfig { + node_startup: NodeStartupConfig { + skip_config_sanitizer: true, + ..Default::default() + }, + ..Default::default() + }; + + // Set a bad node config for mainnet + node_config.execution.paranoid_hot_potato_verification = false; + + // Sanitize the config and verify the sanitizer passes + NodeConfig::sanitize(&node_config, NodeType::Validator, Some(ChainId::mainnet())).unwrap(); + } #[test] fn test_sanitize_missing_pfn_network_configs() { diff --git a/config/src/config/mod.rs b/config/src/config/mod.rs index d357a11f33e03..199d9f2151d7d 100644 --- a/config/src/config/mod.rs +++ b/config/src/config/mod.rs @@ -22,10 +22,11 @@ mod inspection_service_config; mod jwk_consensus_config; mod logger_config; mod mempool_config; -mod netbench; +mod netbench_config; mod network_config; mod node_config; mod node_config_loader; +mod node_startup_config; mod override_node_config; mod peer_monitoring_config; mod persistable_config; @@ -53,7 +54,7 @@ pub use indexer_table_info_config::*; pub use inspection_service_config::*; pub use logger_config::*; pub use mempool_config::*; -pub use netbench::*; +pub use netbench_config::*; pub use network_config::*; pub use node_config::*; pub use node_config_loader::sanitize_node_config; diff --git a/config/src/config/netbench.rs b/config/src/config/netbench_config.rs similarity index 100% rename from config/src/config/netbench.rs rename to config/src/config/netbench_config.rs diff --git a/config/src/config/node_config.rs b/config/src/config/node_config.rs index a834eb2939455..f614527c86a95 100644 --- a/config/src/config/node_config.rs +++ b/config/src/config/node_config.rs @@ -4,8 +4,9 @@ use super::{DagConsensusConfig, IndexerTableInfoConfig}; use crate::{ config::{ - dkg_config::DKGConfig, jwk_consensus_config::JWKConsensusConfig, netbench::NetbenchConfig, - node_config_loader::NodeConfigLoader, persistable_config::PersistableConfig, + dkg_config::DKGConfig, jwk_consensus_config::JWKConsensusConfig, + netbench_config::NetbenchConfig, node_config_loader::NodeConfigLoader, + node_startup_config::NodeStartupConfig, persistable_config::PersistableConfig, utils::RootPath, AdminServiceConfig, ApiConfig, BaseConfig, ConsensusConfig, Error, ExecutionConfig, IndexerConfig, IndexerGrpcConfig, InspectionServiceConfig, LoggerConfig, MempoolConfig, NetworkConfig, PeerMonitoringServiceConfig, SafetyRulesTestConfig, @@ -67,6 +68,8 @@ pub struct NodeConfig { #[serde(default)] pub netbench: Option, #[serde(default)] + pub node_startup: NodeStartupConfig, + #[serde(default)] pub peer_monitoring_service: PeerMonitoringServiceConfig, #[serde(default)] pub state_sync: StateSyncConfig, diff --git a/config/src/config/node_startup_config.rs b/config/src/config/node_startup_config.rs new file mode 100644 index 0000000000000..b1232cac4d43c --- /dev/null +++ b/config/src/config/node_startup_config.rs @@ -0,0 +1,36 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Eq, Serialize)] +#[serde(default, deny_unknown_fields)] +pub struct NodeStartupConfig { + pub skip_config_optimizer: bool, // Whether or not to skip the config optimizer at startup + pub skip_config_sanitizer: bool, // Whether or not to skip the config sanitizer at startup +} + +#[allow(clippy::derivable_impls)] // Derive default manually (this is safer than guessing defaults) +impl Default for NodeStartupConfig { + fn default() -> Self { + Self { + skip_config_optimizer: false, + skip_config_sanitizer: false, + } + } +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn test_node_startup_config_default() { + // Create the default config + let config = NodeStartupConfig::default(); + + // Verify both fields are set to false + assert!(!config.skip_config_optimizer); + assert!(!config.skip_config_sanitizer); + } +}