@@ -13,6 +13,9 @@ const ENABLE_ON_VALIDATORS: bool = true;
1313const ENABLE_ON_VALIDATOR_FULLNODES : bool = true ;
1414const ENABLE_ON_PUBLIC_FULLNODES : bool = false ;
1515
16+ // Maximum number of pending blocks for test networks (e.g., devnet)
17+ const MAX_NUM_PENDING_BLOCKS_FOR_TEST_NETWORKS : u64 = 300 ;
18+
1619#[ derive( Clone , Copy , Debug , Deserialize , PartialEq , Serialize ) ]
1720#[ serde( default , deny_unknown_fields) ]
1821pub struct ConsensusObserverConfig {
@@ -66,17 +69,17 @@ impl Default for ConsensusObserverConfig {
6669 max_parallel_serialization_tasks : num_cpus:: get ( ) , // Default to the number of CPUs
6770 network_request_timeout_ms : 5_000 , // 5 seconds
6871 garbage_collection_interval_ms : 60_000 , // 60 seconds
69- max_num_pending_blocks : 100 , // 100 blocks
70- progress_check_interval_ms : 5_000 , // 5 seconds
71- max_concurrent_subscriptions : 2 , // 2 streams should be sufficient
72- max_subscription_sync_timeout_ms : 15_000 , // 15 seconds
73- max_subscription_timeout_ms : 15_000 , // 15 seconds
74- subscription_peer_change_interval_ms : 180_000 , // 3 minutes
75- subscription_refresh_interval_ms : 600_000 , // 10 minutes
76- observer_fallback_duration_ms : 600_000 , // 10 minutes
77- observer_fallback_startup_period_ms : 60_000 , // 60 seconds
78- observer_fallback_progress_threshold_ms : 10_000 , // 10 seconds
79- observer_fallback_sync_lag_threshold_ms : 15_000 , // 15 seconds
72+ max_num_pending_blocks : 150 , // 150 blocks (sufficient for existing production networks)
73+ progress_check_interval_ms : 5_000 , // 5 seconds
74+ max_concurrent_subscriptions : 2 , // 2 streams should be sufficient
75+ max_subscription_sync_timeout_ms : 15_000 , // 15 seconds
76+ max_subscription_timeout_ms : 15_000 , // 15 seconds
77+ subscription_peer_change_interval_ms : 180_000 , // 3 minutes
78+ subscription_refresh_interval_ms : 600_000 , // 10 minutes
79+ observer_fallback_duration_ms : 600_000 , // 10 minutes
80+ observer_fallback_startup_period_ms : 60_000 , // 60 seconds
81+ observer_fallback_progress_threshold_ms : 10_000 , // 10 seconds
82+ observer_fallback_sync_lag_threshold_ms : 15_000 , // 15 seconds
8083 }
8184 }
8285}
@@ -93,7 +96,7 @@ impl ConfigOptimizer for ConsensusObserverConfig {
9396 node_config : & mut NodeConfig ,
9497 local_config_yaml : & Value ,
9598 node_type : NodeType ,
96- _chain_id : Option < ChainId > ,
99+ chain_id : Option < ChainId > ,
97100 ) -> Result < bool , Error > {
98101 let consensus_observer_config = & mut node_config. consensus_observer ;
99102 let local_observer_config_yaml = & local_config_yaml[ "consensus_observer" ] ;
@@ -134,6 +137,139 @@ impl ConfigOptimizer for ConsensusObserverConfig {
134137 } ,
135138 }
136139
140+ // Optimize the max number of pending blocks to accommodate increased block rates.
141+ // Note: we currently only do this for test networks (e.g., devnet).
142+ if let Some ( chain_id) = chain_id {
143+ if local_observer_config_yaml[ "max_num_pending_blocks" ] . is_null ( )
144+ && !chain_id. is_testnet ( )
145+ && !chain_id. is_mainnet ( )
146+ {
147+ consensus_observer_config. max_num_pending_blocks =
148+ MAX_NUM_PENDING_BLOCKS_FOR_TEST_NETWORKS ;
149+ modified_config = true ;
150+ }
151+ }
152+
137153 Ok ( modified_config)
138154 }
139155}
156+
157+ #[ cfg( test) ]
158+ mod tests {
159+ use super :: * ;
160+
161+ #[ test]
162+ fn test_enable_on_validators ( ) {
163+ // Create a node config with consensus observer and publisher disabled
164+ let mut node_config = create_observer_config ( false , false ) ;
165+
166+ // Optimize the config and verify modifications are made
167+ let modified_config = ConsensusObserverConfig :: optimize (
168+ & mut node_config,
169+ & serde_yaml:: from_str ( "{}" ) . unwrap ( ) , // An empty local config,
170+ NodeType :: Validator ,
171+ Some ( ChainId :: mainnet ( ) ) ,
172+ )
173+ . unwrap ( ) ;
174+ assert ! ( modified_config) ;
175+
176+ // Verify the optimized observer and publisher settings
177+ assert ! ( !node_config. consensus_observer. observer_enabled) ;
178+ assert ! ( node_config. consensus_observer. publisher_enabled) ;
179+ }
180+
181+ #[ test]
182+ fn test_enable_on_validator_fullnodes ( ) {
183+ // Create a node config with consensus observer and publisher disabled
184+ let mut node_config = create_observer_config ( false , false ) ;
185+
186+ // Optimize the config and verify modifications are made
187+ let modified_config = ConsensusObserverConfig :: optimize (
188+ & mut node_config,
189+ & serde_yaml:: from_str ( "{}" ) . unwrap ( ) , // An empty local config,
190+ NodeType :: ValidatorFullnode ,
191+ Some ( ChainId :: mainnet ( ) ) ,
192+ )
193+ . unwrap ( ) ;
194+ assert ! ( modified_config) ;
195+
196+ // Verify the optimized observer and publisher settings
197+ assert ! ( node_config. consensus_observer. observer_enabled) ;
198+ assert ! ( node_config. consensus_observer. publisher_enabled) ;
199+ }
200+
201+ #[ test]
202+ fn test_enable_on_public_fullnodes ( ) {
203+ // Create a node config with consensus observer and publisher disabled
204+ let mut node_config = create_observer_config ( false , false ) ;
205+
206+ // Optimize the config and verify no modifications are made
207+ let modified_config = ConsensusObserverConfig :: optimize (
208+ & mut node_config,
209+ & serde_yaml:: from_str ( "{}" ) . unwrap ( ) , // An empty local config,
210+ NodeType :: PublicFullnode ,
211+ Some ( ChainId :: mainnet ( ) ) ,
212+ )
213+ . unwrap ( ) ;
214+ assert ! ( !modified_config) ;
215+
216+ // Verify the optimized observer and publisher settings
217+ assert ! ( !node_config. consensus_observer. observer_enabled) ;
218+ assert ! ( !node_config. consensus_observer. publisher_enabled) ;
219+ }
220+
221+ #[ test]
222+ fn test_max_num_pending_blocks_mainnet ( ) {
223+ // Create a node config with consensus observer and publisher enabled
224+ let mut node_config = create_observer_config ( true , true ) ;
225+ node_config. consensus_observer . max_num_pending_blocks = 112 ;
226+
227+ // Optimize the config and verify no modifications are made
228+ let modified_config = ConsensusObserverConfig :: optimize (
229+ & mut node_config,
230+ & serde_yaml:: from_str ( "{}" ) . unwrap ( ) , // An empty local config,
231+ NodeType :: PublicFullnode ,
232+ Some ( ChainId :: mainnet ( ) ) ,
233+ )
234+ . unwrap ( ) ;
235+ assert ! ( !modified_config) ;
236+
237+ // Verify the max number of pending blocks remains unchanged
238+ assert_eq ! ( node_config. consensus_observer. max_num_pending_blocks, 112 ) ;
239+ }
240+
241+ #[ test]
242+ fn test_max_num_pending_blocks_devnet ( ) {
243+ // Create a node config with consensus observer and publisher enabled
244+ let mut node_config = create_observer_config ( true , true ) ;
245+ node_config. consensus_observer . max_num_pending_blocks = 112 ;
246+
247+ // Optimize the config and verify modifications are made
248+ let modified_config = ConsensusObserverConfig :: optimize (
249+ & mut node_config,
250+ & serde_yaml:: from_str ( "{}" ) . unwrap ( ) , // An empty local config,
251+ NodeType :: PublicFullnode ,
252+ Some ( ChainId :: new ( 22 ) ) , // Test devnet chain ID
253+ )
254+ . unwrap ( ) ;
255+ assert ! ( modified_config) ;
256+
257+ // Verify the max number of pending blocks has been changed
258+ assert_eq ! (
259+ node_config. consensus_observer. max_num_pending_blocks,
260+ MAX_NUM_PENDING_BLOCKS_FOR_TEST_NETWORKS
261+ ) ;
262+ }
263+
264+ /// Creates a node config with the given consensus observer settings
265+ fn create_observer_config ( enable_observer : bool , enable_publisher : bool ) -> NodeConfig {
266+ NodeConfig {
267+ consensus_observer : ConsensusObserverConfig {
268+ observer_enabled : enable_observer,
269+ publisher_enabled : enable_publisher,
270+ ..Default :: default ( )
271+ } ,
272+ ..Default :: default ( )
273+ }
274+ }
275+ }
0 commit comments