@@ -16,7 +16,7 @@ use graph::{
1616 de:: { self , value, SeqAccess , Visitor } ,
1717 Deserialize , Deserializer ,
1818 } ,
19- serde_json, serde_regex, toml, Logger , NodeId , StoreError ,
19+ serde_json, serde_regex, toml, Logger , NodeId , StoreError , BLOCK_NUMBER_MAX ,
2020 } ,
2121} ;
2222use graph_chain_ethereum as ethereum;
@@ -459,13 +459,35 @@ pub struct ChainSection {
459459 pub ingestor : String ,
460460 #[ serde( flatten) ]
461461 pub chains : BTreeMap < String , Chain > ,
462+ /// The default for chains that don't set this explicitly. When running
463+ /// without a config file, we use `BLOCK_NUMBER_MAX` to turn off pruning
464+ /// the block cache
465+ #[ serde( default = "default_cache_size" ) ]
466+ pub cache_size : i32 ,
462467}
463468
464469impl ChainSection {
465470 fn validate ( & mut self ) -> Result < ( ) > {
466471 NodeId :: new ( & self . ingestor )
467472 . map_err ( |node| anyhow ! ( "invalid node id for ingestor {}" , node) ) ?;
468473 let reorg_threshold = ENV_VARS . reorg_threshold ( ) ;
474+
475+ if self . cache_size <= reorg_threshold {
476+ return Err ( anyhow ! (
477+ "default chains.cache_size ({}) must be greater than reorg_threshold ({})" ,
478+ self . cache_size,
479+ reorg_threshold
480+ ) ) ;
481+ }
482+
483+ // Apply section-level cache_size as default for chains that
484+ // don't set their own.
485+ for chain in self . chains . values_mut ( ) {
486+ if chain. cache_size == 0 {
487+ chain. cache_size = self . cache_size ;
488+ }
489+ }
490+
469491 for ( name, chain) in self . chains . iter_mut ( ) {
470492 chain. validate ( ) ?;
471493 if chain. cache_size <= reorg_threshold {
@@ -520,7 +542,12 @@ impl ChainSection {
520542 Self :: parse_networks ( & mut chains, Transport :: Rpc , & opt. ethereum_rpc ) ?;
521543 Self :: parse_networks ( & mut chains, Transport :: Ws , & opt. ethereum_ws ) ?;
522544 Self :: parse_networks ( & mut chains, Transport :: Ipc , & opt. ethereum_ipc ) ?;
523- Ok ( Self { ingestor, chains } )
545+ Ok ( Self {
546+ ingestor,
547+ chains,
548+ // When running without a config file, we do not prune the block cache
549+ cache_size : BLOCK_NUMBER_MAX ,
550+ } )
524551 }
525552
526553 pub fn providers ( & self ) -> Vec < String > {
@@ -599,7 +626,7 @@ impl ChainSection {
599626 polling_interval : default_polling_interval ( ) ,
600627 providers : vec ! [ ] ,
601628 amp : None ,
602- cache_size : default_cache_size ( ) ,
629+ cache_size : 0 ,
603630 } ) ;
604631 entry. providers . push ( provider) ;
605632 }
@@ -627,7 +654,7 @@ pub struct Chain {
627654 /// Number of blocks from chain head for which to keep block data
628655 /// cached. When `GRAPH_STORE_IGNORE_BLOCK_CACHE` is set, blocks
629656 /// older than this are treated as if they have no data.
630- #[ serde( default = "default_cache_size" ) ]
657+ #[ serde( default ) ]
631658 pub cache_size : i32 ,
632659}
633660
@@ -1319,7 +1346,7 @@ where
13191346#[ cfg( test) ]
13201347mod tests {
13211348
1322- use crate :: config:: { default_cache_size , default_polling_interval, ChainSection , Web3Rule } ;
1349+ use crate :: config:: { default_polling_interval, ChainSection , Web3Rule } ;
13231350
13241351 use super :: {
13251352 Chain , Config , FirehoseProvider , Provider , ProviderDetails , Shard , Transport , Web3Provider ,
@@ -1367,7 +1394,7 @@ mod tests {
13671394 polling_interval: default_polling_interval( ) ,
13681395 providers: vec![ ] ,
13691396 amp: None ,
1370- cache_size: default_cache_size ( ) ,
1397+ cache_size: 0 ,
13711398 } ,
13721399 actual
13731400 ) ;
@@ -1391,12 +1418,37 @@ mod tests {
13911418 polling_interval: default_polling_interval( ) ,
13921419 providers: vec![ ] ,
13931420 amp: None ,
1394- cache_size: default_cache_size ( ) ,
1421+ cache_size: 0 ,
13951422 } ,
13961423 actual
13971424 ) ;
13981425 }
13991426
1427+ #[ test]
1428+ fn chain_inherits_cache_size_from_section ( ) {
1429+ let mut section = toml:: from_str :: < ChainSection > (
1430+ r#"
1431+ ingestor = "block_ingestor_node"
1432+ cache_size = 1000
1433+ [mainnet]
1434+ shard = "primary"
1435+ provider = []
1436+ [sepolia]
1437+ shard = "primary"
1438+ provider = []
1439+ cache_size = 2000
1440+ "# ,
1441+ )
1442+ . unwrap ( ) ;
1443+
1444+ section. validate ( ) . unwrap ( ) ;
1445+
1446+ // mainnet inherits from section
1447+ assert_eq ! ( section. chains[ "mainnet" ] . cache_size, 1000 ) ;
1448+ // sepolia keeps its explicit value
1449+ assert_eq ! ( section. chains[ "sepolia" ] . cache_size, 2000 ) ;
1450+ }
1451+
14001452 #[ test]
14011453 fn it_works_on_deprecated_provider_from_toml ( ) {
14021454 let actual = toml:: from_str (
0 commit comments