diff --git a/core/src/event/config.rs b/core/src/event/config.rs index 5f1f476d..17055129 100644 --- a/core/src/event/config.rs +++ b/core/src/event/config.rs @@ -27,7 +27,6 @@ pub struct ContractEventProcessingConfig { pub project_path: PathBuf, pub indexer_name: String, pub contract_name: String, - pub info_log_name: String, pub topic_id: B256, pub event_name: String, pub config: Config, @@ -46,6 +45,10 @@ pub struct ContractEventProcessingConfig { } impl ContractEventProcessingConfig { + pub fn info_log_name(&self) -> String { + format!("{}::{}::{}", self.contract_name, self.event_name, self.network_contract.network) + } + pub fn to_event_filter(&self) -> Result { match &self.network_contract.indexing_contract_setup { IndexingContractSetup::Address(details) => RindexerEventFilter::new_address_filter( @@ -153,7 +156,7 @@ impl FactoryEventProcessingConfig { } pub fn info_log_name(&self) -> String { - format!("{}::{}", self.contract_name, self.event.name) + format!("{}::{}::{}", self.contract_name, self.event.name, self.network_contract.network) } } @@ -214,7 +217,7 @@ impl EventProcessingConfig { pub fn info_log_name(&self) -> String { match self { - Self::ContractEventProcessing(config) => config.info_log_name.clone(), + Self::ContractEventProcessing(config) => config.info_log_name().clone(), Self::FactoryEventProcessing(config) => config.info_log_name(), } } diff --git a/core/src/indexer/fetch_logs.rs b/core/src/indexer/fetch_logs.rs index ec4f92b5..fbfa50dd 100644 --- a/core/src/indexer/fetch_logs.rs +++ b/core/src/indexer/fetch_logs.rs @@ -40,12 +40,7 @@ pub fn fetch_logs_stream( // This is per network contract-event, so it should be relatively small. let channel_size = config.config().buffer.unwrap_or(4); - debug!( - "{}::{} Configured with {} event buffer", - config.info_log_name(), - config.network_contract().network, - channel_size - ); + debug!("{} Configured with {} event buffer", config.info_log_name(), channel_size); let (tx, rx) = mpsc::channel(channel_size); @@ -67,9 +62,8 @@ pub fn fetch_logs_stream( )); if random_ratio(1, 20) { warn!( - "{}::{} - {} - max block range of {} applied - indexing will be slower than providers supplying the optimal ranges - https://rindexer.xyz/docs/references/rpc-node-providers#rpc-node-providers", + "{} - {} - max block range of {} applied - indexing will be slower than providers supplying the optimal ranges - https://rindexer.xyz/docs/references/rpc-node-providers#rpc-node-providers", config.info_log_name(), - config.network_contract().network, IndexingEventProgressStatus::Syncing.log(), max_block_range_limitation.unwrap() ); @@ -91,7 +85,6 @@ pub fn fetch_logs_stream( max_block_range_limitation, snapshot_to_block, &config.info_log_name(), - &config.network_contract().network, ) .await; @@ -100,9 +93,8 @@ pub fn fetch_logs_stream( if let Some(range) = max_block_range_limitation { if range.to::() < 5000 && random_ratio(1, 20) { warn!( - "{}::{} - RPC PROVIDER IS SLOW - Slow indexing mode enabled, max block range limitation: {} blocks - we advise using a faster provider who can predict the next block ranges.", + "{} - RPC PROVIDER IS SLOW - Slow indexing mode enabled, max block range limitation: {} blocks - we advise using a faster provider who can predict the next block ranges.", &config.info_log_name(), - &config.network_contract().network, range ); } @@ -125,9 +117,8 @@ pub fn fetch_logs_stream( } info!( - "{}::{} - {} - Finished indexing historic events", + "{} - {} - Finished indexing historic events", &config.info_log_name(), - &config.network_contract().network, IndexingEventProgressStatus::Completed.log() ); @@ -144,7 +135,6 @@ pub fn fetch_logs_stream( current_filter, &config.info_log_name(), config.network_contract().disable_logs_bloom_checks, - &config.network_contract().network, original_max_limit, ) .await; @@ -170,15 +160,13 @@ async fn fetch_historic_logs_stream( max_block_range_limitation: Option, snapshot_to_block: U64, info_log_name: &str, - network: &str, ) -> Option { let from_block = current_filter.from_block(); let to_block = current_filter.to_block(); debug!( - "{}::{} - {} - Process historic events - blocks: {} - {}", + "{} - {} - Process historic events - blocks: {} - {}", info_log_name, - network, IndexingEventProgressStatus::Syncing.log(), from_block, to_block @@ -210,9 +198,8 @@ async fn fetch_historic_logs_stream( if tx.capacity() == 0 { debug!( - "{}::{} - {} - Log channel full, waiting for events to be processed.", + "{} - {} - Log channel full, waiting for events to be processed.", info_log_name, - network, IndexingEventProgressStatus::Syncing.log(), ); } @@ -235,9 +222,8 @@ async fn fetch_historic_logs_stream( if !logs_empty { info!( - "{}::{} - {} - Fetched {} logs between: {} - {}", + "{} - {} - Fetched {} logs between: {} - {}", info_log_name, - network, IndexingEventProgressStatus::Syncing.log(), logs.len(), from_block, @@ -272,9 +258,8 @@ async fn fetch_historic_logs_stream( ); debug!( - "{}::{} - No events between {} - {}. Searching next {} blocks.", + "{} - No events between {} - {}. Searching next {} blocks.", info_log_name, - network, from_block, to_block, new_to_block - next_from_block @@ -339,7 +324,6 @@ async fn fetch_historic_logs_stream( // to get information on what the ideal block range should be. if let Some(retry_result) = retry_with_block_range( info_log_name, - network, &err, from_block, to_block, @@ -350,9 +334,8 @@ async fn fetch_historic_logs_stream( // Log if we "overshrink" if retry_result.to - retry_result.from < U64::from(1000) { debug!( - "{}::{} - {} - Over-fetched {} to {}. Shrunk ({}): {} to {}{}", + "{} - {} - Over-fetched {} to {}. Shrunk ({}): {} to {}{}", info_log_name, - network, IndexingEventProgressStatus::Syncing.log(), from_block, to_block, @@ -378,8 +361,7 @@ async fn fetch_historic_logs_stream( // Handle deserialization, networking, and other non-rpc related errors. error!( - "[{}] - {} - {} - Unexpected error fetching logs in range {} - {}. Retry fetching {} - {}: {:?}", - network, + "{} - {} - Unexpected error fetching logs in range {} - {}. Retry fetching {} - {}: {:?}", info_log_name, IndexingEventProgressStatus::Syncing.log(), from_block, @@ -413,7 +395,6 @@ async fn live_indexing_stream( mut current_filter: RindexerEventFilter, info_log_name: &str, disable_logs_bloom_checks: bool, - network: &str, original_max_limit: Option, ) { let mut last_seen_block_number = last_seen_block_number; @@ -427,11 +408,10 @@ async fn live_indexing_stream( // Spawn a separate task to handle notifications if let Some(notifications) = chain_state_notification { let info_log_name = info_log_name.to_string(); - let network = network.to_string(); tokio::spawn(async move { let mut notifications_clone = notifications.subscribe(); while let Ok(notification) = notifications_clone.recv().await { - handle_chain_notification(notification, &info_log_name, &network); + handle_chain_notification(notification, &info_log_name); } }); } @@ -468,9 +448,8 @@ async fn live_indexing_stream( ); if last_no_new_block_log_time.elapsed() >= log_no_new_block_interval { info!( - "{}::{} - {} - No new blocks published in the last 5 minutes - latest block number {}", + "{} - {} - No new blocks published in the last 5 minutes - latest block number {}", info_log_name, - network, IndexingEventProgressStatus::Live.log(), last_seen_block_number, ); @@ -497,18 +476,16 @@ async fn live_indexing_stream( // therefore, we log an error as means RCP state is not in sync with the blockchain if is_outside_reorg_range { error!( - "{}::{} - {} - LIVE INDEXING STEAM - RPC has gone back on latest block: rpc returned {}, last seen: {}", + "{} - {} - LIVE INDEXING STEAM - RPC has gone back on latest block: rpc returned {}, last seen: {}", info_log_name, - network, IndexingEventProgressStatus::Live.log(), latest_block_number, from_block ); } else { info!( - "{}::{} - {} - LIVE INDEXING STEAM - RPC has gone back on latest block: rpc returned {}, last seen: {}", + "{} - {} - LIVE INDEXING STEAM - RPC has gone back on latest block: rpc returned {}, last seen: {}", info_log_name, - network, IndexingEventProgressStatus::Live.log(), latest_block_number, from_block @@ -516,9 +493,8 @@ async fn live_indexing_stream( } } else { info!( - "{}::{} - {} - LIVE INDEXING STEAM - not in safe reorg block range yet block: {} > range: {}", + "{} - {} - LIVE INDEXING STEAM - not in safe reorg block range yet block: {} > range: {}", info_log_name, - network, IndexingEventProgressStatus::Live.log(), from_block, safe_block_number @@ -599,9 +575,8 @@ async fn live_indexing_stream( if tx.capacity() == 0 { warn!( - "{}::{} - {} - Log channel full, live indexer will wait for events to be processed.", + "{} - {} - Log channel full, live indexer will wait for events to be processed.", info_log_name, - network, IndexingEventProgressStatus::Live.log(), ); } @@ -631,9 +606,8 @@ async fn live_indexing_stream( .await { error!( - "{}::{} - {} - Failed to send logs to stream consumer! Err: {}", + "{} - {} - Failed to send logs to stream consumer! Err: {}", info_log_name, - network, IndexingEventProgressStatus::Live.log(), e ); @@ -647,13 +621,12 @@ async fn live_indexing_stream( current_filter = current_filter .set_from_block(to_block + U64::from(1)); debug!( - "{}::{} - {} - No events found between blocks {} - {}", - info_log_name, - network, - IndexingEventProgressStatus::Live.log(), - from_block, - to_block, - ); + "{} - {} - No events found between blocks {} - {}", + info_log_name, + IndexingEventProgressStatus::Live.log(), + from_block, + to_block, + ); } else if let Some(last_log) = last_log { if let Some(last_log_block_number) = last_log.block_number @@ -669,7 +642,6 @@ async fn live_indexing_stream( Err(err) => { if let Some(retry_result) = retry_with_block_range( info_log_name, - network, &err, from_block, to_block, @@ -678,9 +650,8 @@ async fn live_indexing_stream( .await { debug!( - "{}::{} - {} - Overfetched from {} to {} - shrinking to block range: from {} to {}", + "{} - {} - Overfetched from {} to {} - shrinking to block range: from {} to {}", info_log_name, - network, IndexingEventProgressStatus::Live.log(), from_block, to_block, @@ -694,9 +665,8 @@ async fn live_indexing_stream( halved_block_number(to_block, from_block); error!( - "{}::{} - {} - Unexpected error fetching logs in range {} - {}. Retry fetching {} - {}: {:?}", + "{} - {} - Unexpected error fetching logs in range {} - {}. Retry fetching {} - {}: {:?}", info_log_name, - network, IndexingEventProgressStatus::Live.log(), from_block, to_block, @@ -747,7 +717,6 @@ struct RetryWithBlockRangeResult { /// Attempts to retry with a new block range based on the error message. async fn retry_with_block_range( info_log_name: &str, - network: &str, error: &ProviderError, from_block: U64, to_block: U64, @@ -788,8 +757,8 @@ async fn retry_with_block_range( ) { if from > to { warn!( - "{}::{} Alchemy returned a negative block range {} to {}. Inverting.", - info_log_name, network, from, to + "{} Alchemy returned a negative block range {} to {}. Inverting.", + info_log_name, from, to ); // Negative range fixed by inverting. @@ -809,8 +778,8 @@ async fn retry_with_block_range( }); } else { info!( - "{}::{} Failed to parse block numbers {} and {}", - info_log_name, network, start_block_str, end_block_str + "{} Failed to parse block numbers {} and {}", + info_log_name, start_block_str, end_block_str ); } } @@ -916,8 +885,8 @@ async fn retry_with_block_range( let mut next_to_block = from_block + block_range.value(); warn!( - "{}::{} Computed a fallback block range {:?}. Provider did not provide information in error: {:?}", - info_log_name,network, block_range, error_message + "{} Computed a fallback block range {:?}. Provider did not provide information in error: {:?}", + info_log_name, block_range, error_message ); if next_to_block == to_block { @@ -926,7 +895,10 @@ async fn retry_with_block_range( } if next_to_block < from_block { - error!("{}::{} Computed a negative fallback block range. Overriding to single block fetch.",info_log_name,network); + error!( + "{} Computed a negative fallback block range. Overriding to single block fetch.", + info_log_name + ); return Some(RetryWithBlockRangeResult { from: from_block, diff --git a/core/src/indexer/native_transfer.rs b/core/src/indexer/native_transfer.rs index d8464213..5d124957 100644 --- a/core/src/indexer/native_transfer.rs +++ b/core/src/indexer/native_transfer.rs @@ -119,11 +119,10 @@ pub async fn native_transfer_block_fetch( // Spawn a separate task to handle notifications if let Some(notifications) = chain_state_notification { // Subscribe to notifications for this network - let network_clone = network.clone(); let mut notifications_clone = notifications.subscribe(); tokio::spawn(async move { while let Ok(notification) = notifications_clone.recv().await { - handle_chain_notification(notification, "NativeTransfer", &network_clone); + handle_chain_notification(notification, "NativeTransfer"); } }); } diff --git a/core/src/indexer/process.rs b/core/src/indexer/process.rs index aa5fbb45..53925bf3 100644 --- a/core/src/indexer/process.rs +++ b/core/src/indexer/process.rs @@ -42,13 +42,27 @@ pub enum ProcessEventError { ProviderCallError(#[from] ProviderError), } -pub async fn process_event( +/// Processes an event that doesn't have dependencies. +/// First processes historical logs, then starts live indexing if the event is configured for live indexing. +/// This function returns immediately without waiting for the indexing to complete. +pub async fn process_non_blocking_event( config: EventProcessingConfig, - block_until_indexed: bool, ) -> Result<(), ProcessEventError> { - debug!("{} - Processing events", config.info_log_name()); + debug!("{} - Processing non blocking event", config.info_log_name()); + + process_event_logs(Arc::new(config), false, false).await?; + + Ok(()) +} + +/// Processes historical logs for a blocking event that has dependencies. +/// This function waits for the indexing to complete before returning. +pub async fn process_blocking_event_historical_data( + config: Arc, +) -> Result<(), Box> { + debug!("{} - Processing blocking event historical data", config.info_log_name()); - process_event_logs(Arc::new(config), false, block_until_indexed).await?; + process_event_logs(config, true, true).await?; Ok(()) } @@ -191,9 +205,10 @@ async fn process_contract_events_with_dependencies( let task = tokio::spawn({ let live_indexing_events = Arc::clone(&live_indexing_events); async move { - // forces live indexing off as it has to handle it a bit differently - process_event_logs(Arc::clone(&event_processing_config), true, true) - .await?; + process_blocking_event_historical_data(Arc::clone( + &event_processing_config, + )) + .await?; if event_processing_config.live_indexing() { let network_contract = event_processing_config.network_contract(); @@ -275,7 +290,7 @@ async fn live_indexing_for_contract_event_dependencies( EventDependenciesIndexingConfig { cached_provider, events, network }: EventDependenciesIndexingConfig, ) { debug!( - "Live indexing events on {} - {}", + "Live indexing events on {} in order: {}", network, events .iter() @@ -359,12 +374,11 @@ async fn live_indexing_for_contract_event_dependencies( >= log_no_new_block_interval { info!( - "{}::{} - {} - No new blocks published in the last 5 minutes - latest block number {}", - &config.info_log_name(), - &config.network_contract().network, - IndexingEventProgressStatus::Live.log(), - latest_block_number - ); + "{} - {} - No new blocks published in the last 5 minutes - latest block number {}", + &config.info_log_name(), + IndexingEventProgressStatus::Live.log(), + latest_block_number + ); ordering_live_indexing_details.last_no_new_block_log_time = Instant::now(); *ordering_live_indexing_details_map .get(&config.id()) @@ -396,18 +410,16 @@ async fn live_indexing_for_contract_event_dependencies( // therefore, we log an error as means RCP state is not in sync with the blockchain if is_outside_reorg_range { error!( - "{}::{} - {} - RPC has gone back on latest block: rpc returned {}, last seen: {}", + "{} - {} - RPC has gone back on latest block: rpc returned {}, last seen: {}", &config.info_log_name(), - &config.network_contract().network, IndexingEventProgressStatus::Live.log(), latest_block_number, from_block ); } else { info!( - "{}::{} - {} - RPC has gone back on latest block: rpc returned {}, last seen: {}", + "{} - {} - RPC has gone back on latest block: rpc returned {}, last seen: {}", &config.info_log_name(), - &config.network_contract().network, IndexingEventProgressStatus::Live.log(), latest_block_number, from_block @@ -417,9 +429,8 @@ async fn live_indexing_for_contract_event_dependencies( continue; } else { info!( - "{}::{} - {} - not in safe reorg block range yet block: {} > range: {}", + "{} - {} - not in safe reorg block range yet block: {} > range: {}", &config.info_log_name(), - &config.network_contract().network, IndexingEventProgressStatus::Live.log(), from_block, safe_block_number @@ -438,16 +449,14 @@ async fn live_indexing_for_contract_event_dependencies( ) { debug!( - "{}::{} - {} - Skipping block {} as it's not relevant", + "{} - {} - Skipping block {} as it's not relevant", &config.info_log_name(), - &config.network_contract().network, IndexingEventProgressStatus::Live.log(), from_block ); debug!( - "{}::{} - {} - Did not need to hit RPC as no events in {} block - LogsBloom for block checked", + "{} - {} - Did not need to hit RPC as no events in {} block - LogsBloom for block checked", &config.info_log_name(), - &config.network_contract().network, IndexingEventProgressStatus::Live.log(), from_block ); @@ -477,9 +486,8 @@ async fn live_indexing_for_contract_event_dependencies( match cached_provider.get_logs(&ordering_live_indexing_details.filter).await { Ok(logs) => { debug!( - "{}::{} - {} - Live id {} topic_id {}, Logs: {} from {} to {}", + "{} - {} - Live id {} topic_id {}, Logs: {} from {} to {}", &config.info_log_name(), - &config.network_contract().network, IndexingEventProgressStatus::Live.log(), &config.id(), &config.topic_id(), @@ -489,9 +497,8 @@ async fn live_indexing_for_contract_event_dependencies( ); debug!( - "{}::{} - {} - Fetched {} event logs - blocks: {} - {}", + "{} - {} - Fetched {} event logs - blocks: {} - {}", &config.info_log_name(), - &config.network_contract().network, IndexingEventProgressStatus::Live.log(), logs.len(), from_block, @@ -516,12 +523,11 @@ async fn live_indexing_for_contract_event_dependencies( let complete = task.await; if let Err(e) = complete { error!( - "{}::{} - {} - Error indexing task: {} - will try again in 200ms", - &config.info_log_name(), - &config.network_contract().network, - IndexingEventProgressStatus::Live.log(), - e - ); + "{} - {} - Error indexing task: {} - will try again in 200ms", + &config.info_log_name(), + IndexingEventProgressStatus::Live.log(), + e + ); break; } ordering_live_indexing_details.last_seen_block_number = to_block; @@ -531,9 +537,8 @@ async fn live_indexing_for_contract_event_dependencies( .filter .set_from_block(to_block + U64::from(1)); debug!( - "{}::{} - {} - No events found between blocks {} - {}", + "{} - {} - No events found between blocks {} - {}", &config.info_log_name(), - &config.network_contract().network, IndexingEventProgressStatus::Live.log(), from_block, to_block @@ -557,9 +562,8 @@ async fn live_indexing_for_contract_event_dependencies( } Err(err) => { error!( - "{}::{} - {} - Error fetching logs: {} - will try again in 200ms", + "{} - {} - Error fetching logs: {} - will try again in 200ms", &config.info_log_name(), - &config.network_contract().network, IndexingEventProgressStatus::Live.log(), err ); @@ -569,9 +573,8 @@ async fn live_indexing_for_contract_event_dependencies( } Err(err) => { error!( - "{}::{} - {} - Error fetching logs: {} - will try again in 200ms", + "{} - {} - Error fetching logs: {} - will try again in 200ms", &config.info_log_name(), - &config.network_contract().network, IndexingEventProgressStatus::Live.log(), err ); @@ -621,7 +624,7 @@ async fn handle_logs_result( ) -> Result, Box> { match result { Ok(result) => { - debug!("Processing logs {} - length {}", config.event_name(), result.logs.len()); + debug!("{} - Processing {} logs", config.info_log_name(), result.logs.len()); let fn_data = result .logs diff --git a/core/src/indexer/reorg.rs b/core/src/indexer/reorg.rs index cfbeaea3..a08dca6d 100644 --- a/core/src/indexer/reorg.rs +++ b/core/src/indexer/reorg.rs @@ -4,11 +4,7 @@ use tracing::{debug, warn}; use crate::notifications::ChainStateNotification; /// Handles chain state notifications (reorgs, reverts, commits) -pub fn handle_chain_notification( - notification: ChainStateNotification, - info_log_name: &str, - network: &str, -) { +pub fn handle_chain_notification(notification: ChainStateNotification, info_log_name: &str) { match notification { ChainStateNotification::Reorged { revert_from_block, @@ -18,9 +14,8 @@ pub fn handle_chain_notification( new_tip_hash, } => { warn!( - "{}::{} - REORG DETECTED! Need to revert blocks {} to {} and re-index {} to {} (new tip: {})", + "{} - REORG DETECTED! Need to revert blocks {} to {} and re-index {} to {} (new tip: {})", info_log_name, - network, revert_from_block, revert_to_block, new_from_block, new_to_block, new_tip_hash @@ -29,15 +24,15 @@ pub fn handle_chain_notification( } ChainStateNotification::Reverted { from_block, to_block } => { warn!( - "{}::{} - CHAIN REVERTED! Blocks {} to {} have been reverted", - info_log_name, network, from_block, to_block + "{} - CHAIN REVERTED! Blocks {} to {} have been reverted", + info_log_name, from_block, to_block ); // TODO: In future PR, mark affected logs as removed in the database } ChainStateNotification::Committed { from_block, to_block, tip_hash } => { debug!( - "{}::{} - Chain committed: blocks {} to {} (tip: {})", - info_log_name, network, from_block, to_block, tip_hash + "{} - Chain committed: blocks {} to {} (tip: {})", + info_log_name, from_block, to_block, tip_hash ); } } diff --git a/core/src/indexer/start.rs b/core/src/indexer/start.rs index 90ca4bbb..3c037c7a 100644 --- a/core/src/indexer/start.rs +++ b/core/src/indexer/start.rs @@ -25,7 +25,7 @@ use crate::{ last_synced::{get_last_synced_block_number, SyncConfig}, native_transfer::{native_transfer_block_fetch, NATIVE_TRANSFER_CONTRACT_NAME}, process::{ - process_contracts_events_with_dependencies, process_event, + process_contracts_events_with_dependencies, process_non_blocking_event, ProcessContractsEventsWithDependenciesError, ProcessEventError, }, progress::IndexingEventsProgressState, @@ -451,7 +451,6 @@ pub async fn start_indexing_contract_events( project_path: project_path.clone(), indexer_name: event.indexer_name.clone(), contract_name: event.contract.name.clone(), - info_log_name: event.info_log_name(), topic_id: event.topic_id, event_name: event.event_name.clone(), network_contract: Arc::new(network_contract.clone()), @@ -505,7 +504,7 @@ pub async fn start_indexing_contract_events( &dependencies, ); } else { - let process_event = tokio::spawn(process_event(event_processing_config, false)); + let process_event = tokio::spawn(process_non_blocking_event(event_processing_config)); non_blocking_process_events.push(process_event); } } diff --git a/core/src/logger.rs b/core/src/logger.rs index 9d399760..5c4102c2 100644 --- a/core/src/logger.rs +++ b/core/src/logger.rs @@ -73,8 +73,12 @@ impl tracing_subscriber::fmt::time::FormatTime for CustomTimer { } } -pub fn setup_logger(log_level: LevelFilter) { - let filter = EnvFilter::from_default_env().add_directive(log_level.into()); +const LOG_LEVEL_ENV: &str = "RINDEXER_LOG"; + +pub fn setup_logger(default_log_level: LevelFilter) { + let filter = EnvFilter::try_from_env(LOG_LEVEL_ENV).unwrap_or( + EnvFilter::builder().with_default_directive(default_log_level.into()).parse_lossy(""), + ); let format = Format::default().with_timer(CustomTimer).with_level(true).with_target(false); diff --git a/documentation/docs/pages/docs/changelog.mdx b/documentation/docs/pages/docs/changelog.mdx index fa9f646d..545bcc10 100644 --- a/documentation/docs/pages/docs/changelog.mdx +++ b/documentation/docs/pages/docs/changelog.mdx @@ -6,6 +6,7 @@ ### Features ------------------------------------------------- - feat: check if the RPC chain id is matching the configured chain id in the yaml config on startup +- feat: add support for `RINDEXER_LOG` environment variable to control the log level of rindexer ### Bug fixes -------------------------------------------------