diff --git a/chain/ethereum/src/network.rs b/chain/ethereum/src/network.rs index bb95dcb1b0f..0c236df33b0 100644 --- a/chain/ethereum/src/network.rs +++ b/chain/ethereum/src/network.rs @@ -98,7 +98,7 @@ impl EthereumNetworkAdapters { use graph::slog::{o, Discard, Logger}; - use graph::components::adapter::MockIdentValidator; + use graph::components::adapter::NoopIdentValidator; let chain_id: ChainId = "testing".into(); adapters.sort_by(|a, b| { a.capabilities @@ -109,7 +109,7 @@ impl EthereumNetworkAdapters { let provider = ProviderManager::new( Logger::root(Discard, o!()), vec![(chain_id.clone(), adapters)].into_iter(), - Arc::new(MockIdentValidator), + Arc::new(NoopIdentValidator), ); provider.mark_all_valid().await; @@ -299,7 +299,7 @@ impl EthereumNetworkAdapters { #[cfg(test)] mod tests { use graph::cheap_clone::CheapClone; - use graph::components::adapter::{MockIdentValidator, ProviderManager, ProviderName}; + use graph::components::adapter::{NoopIdentValidator, ProviderManager, ProviderName}; use graph::data::value::Word; use graph::http::HeaderMap; use graph::{ @@ -746,7 +746,7 @@ mod tests { .collect(), )] .into_iter(), - Arc::new(MockIdentValidator), + Arc::new(NoopIdentValidator), ); manager.mark_all_valid().await; @@ -842,7 +842,7 @@ mod tests { .iter() .cloned() .map(|a| (chain_id.clone(), vec![a])), - Arc::new(MockIdentValidator), + Arc::new(NoopIdentValidator), ); manager.mark_all_valid().await; @@ -870,7 +870,7 @@ mod tests { .iter() .cloned() .map(|a| (chain_id.clone(), vec![a])), - Arc::new(MockIdentValidator), + Arc::new(NoopIdentValidator), ); manager.mark_all_valid().await; @@ -912,7 +912,7 @@ mod tests { no_available_adapter.iter().cloned().collect(), )] .into_iter(), - Arc::new(MockIdentValidator), + Arc::new(NoopIdentValidator), ); manager.mark_all_valid().await; diff --git a/graph/src/components/adapter.rs b/graph/src/components/adapter.rs index 1c5ed2e6ad9..260624c141e 100644 --- a/graph/src/components/adapter.rs +++ b/graph/src/components/adapter.rs @@ -183,9 +183,10 @@ impl> IdentValidator for } } -pub struct MockIdentValidator; +/// This is mostly used for testing or for running with disabled genesis validation. +pub struct NoopIdentValidator; -impl IdentValidator for MockIdentValidator { +impl IdentValidator for NoopIdentValidator { fn check_ident( &self, _chain_id: &ChainId, @@ -227,7 +228,7 @@ impl Default for ProviderManager { logger: Logger::root(Discard, o!()), adapters: HashMap::default(), status: vec![], - validator: Arc::new(MockIdentValidator {}), + validator: Arc::new(NoopIdentValidator {}), }), } } @@ -589,7 +590,7 @@ mod test { use crate::{ bail, blockchain::BlockHash, - components::adapter::{ChainId, GenesisCheckStatus, MockIdentValidator}, + components::adapter::{ChainId, GenesisCheckStatus, NoopIdentValidator}, data::value::Word, prelude::lazy_static, }; @@ -782,7 +783,7 @@ mod test { let chain_id = chain_id.into(); let validator: Arc = match validator { - None => Arc::new(MockIdentValidator {}), + None => Arc::new(NoopIdentValidator {}), Some(validator) => Arc::new(validator), }; diff --git a/graph/src/env/mod.rs b/graph/src/env/mod.rs index 43703a31df0..af53562528a 100644 --- a/graph/src/env/mod.rs +++ b/graph/src/env/mod.rs @@ -212,6 +212,15 @@ pub struct EnvVars { /// Set the maximum grpc decode size(in MB) for firehose BlockIngestor connections. /// Defaults to 25MB pub firehose_grpc_max_decode_size_mb: usize, + /// Defined whether or not graph-node should refuse to perform genesis validation + /// before using an adapter. Disabled by default for the moment, will be enabled + /// on the next release. Disabling validation means the recorded genesis will be 0x00 + /// if no genesis hash can be retrieved from an adapter. If enabled, the adapter is + /// ignored if unable to produce a genesis hash or produces a different an unexpected hash. + pub genesis_validation_enabled: bool, + /// How long do we wait for a response from the provider before considering that it is unavailable. + /// Default is 30s. + pub genesis_validation_timeout: Duration, } impl EnvVars { @@ -294,6 +303,8 @@ impl EnvVars { dips_metrics_object_store_url: inner.dips_metrics_object_store_url, section_map: inner.section_map, firehose_grpc_max_decode_size_mb: inner.firehose_grpc_max_decode_size_mb, + genesis_validation_enabled: inner.genesis_validation_enabled.0, + genesis_validation_timeout: Duration::from_secs(inner.genesis_validation_timeout), }) } @@ -439,6 +450,10 @@ struct Inner { section_map: Option, #[envconfig(from = "GRAPH_NODE_FIREHOSE_MAX_DECODE_SIZE", default = "25")] firehose_grpc_max_decode_size_mb: usize, + #[envconfig(from = "GRAPH_NODE_GENESIS_VALIDATION_ENABLED", default = "false")] + genesis_validation_enabled: EnvVarBoolean, + #[envconfig(from = "GRAPH_NODE_GENESIS_VALIDATION_TIMEOUT_SECONDS", default = "30")] + genesis_validation_timeout: u64, } #[derive(Clone, Debug)] diff --git a/graph/src/firehose/endpoints.rs b/graph/src/firehose/endpoints.rs index cd8b7806401..6cb5a1a9467 100644 --- a/graph/src/firehose/endpoints.rs +++ b/graph/src/firehose/endpoints.rs @@ -638,7 +638,7 @@ impl FirehoseEndpoints { pub fn for_testing(adapters: Vec>) -> Self { use slog::{o, Discard}; - use crate::components::adapter::MockIdentValidator; + use crate::components::adapter::NoopIdentValidator; let chain_id: Word = "testing".into(); Self( @@ -646,7 +646,7 @@ impl FirehoseEndpoints { ProviderManager::new( Logger::root(Discard, o!()), vec![(chain_id, adapters)].into_iter(), - Arc::new(MockIdentValidator), + Arc::new(NoopIdentValidator), ), ) } diff --git a/node/src/chain.rs b/node/src/chain.rs index dfc48607ef8..23696dc48ea 100644 --- a/node/src/chain.rs +++ b/node/src/chain.rs @@ -31,7 +31,7 @@ use graph::itertools::Itertools; use graph::log::factory::LoggerFactory; use graph::prelude::anyhow; use graph::prelude::MetricsRegistry; -use graph::slog::{debug, error, info, o, Logger}; +use graph::slog::{debug, error, info, o, warn, Logger}; use graph::url::Url; use graph::util::security::SafeDisplay; use graph_chain_ethereum::{self as ethereum, Transport}; @@ -432,10 +432,14 @@ pub async fn networks_as_chains( let chain_store = match store.chain_store(chain_id) { Some(c) => c, None => { - let ident = networks - .chain_identifier(&logger, chain_id) - .await - .expect("must be able to get chain identity to create a store"); + let ident = match networks.chain_identifier(&logger, chain_id).await { + Ok(ident) => ident, + Err(err) if !config.genesis_validation_enabled => { + warn!(&logger, "unable to fetch genesis for {}. Err: {}.falling back to the default value because validation is disabled", chain_id, err); + ChainIdentifier::default() + } + err => err.expect("must be able to get chain identity to create a store"), + }; store .create_chain_store(chain_id, ident) .expect("must be able to create store if one is not yet setup for the chain") @@ -669,7 +673,7 @@ pub async fn networks_as_chains( mod test { use crate::config::{Config, Opt}; use crate::network_setup::{AdapterConfiguration, Networks}; - use graph::components::adapter::{ChainId, MockIdentValidator}; + use graph::components::adapter::{ChainId, NoopIdentValidator}; use graph::endpoint::EndpointMetrics; use graph::log::logger; use graph::prelude::{tokio, MetricsRegistry}; @@ -702,7 +706,7 @@ mod test { let metrics = Arc::new(EndpointMetrics::mock()); let config = Config::load(&logger, &opt).expect("can create config"); let metrics_registry = Arc::new(MetricsRegistry::mock()); - let ident_validator = Arc::new(MockIdentValidator); + let ident_validator = Arc::new(NoopIdentValidator); let networks = Networks::from_config(logger, &config, metrics_registry, metrics, ident_validator) diff --git a/node/src/main.rs b/node/src/main.rs index 0572f1997b1..f3682ed8a37 100644 --- a/node/src/main.rs +++ b/node/src/main.rs @@ -1,6 +1,6 @@ use clap::Parser as _; use git_testament::{git_testament, render_testament}; -use graph::components::adapter::IdentValidator; +use graph::components::adapter::{IdentValidator, NoopIdentValidator}; use graph::futures01::Future as _; use graph::futures03::compat::Future01CompatExt; use graph::futures03::future::TryFutureExt; @@ -258,7 +258,13 @@ async fn main() { let network_store = store_builder.network_store(config.chain_ids()); let block_store = network_store.block_store(); - let validator: Arc = network_store.block_store(); + + let validator: Arc = if env_vars.genesis_validation_enabled { + network_store.block_store() + } else { + Arc::new(NoopIdentValidator {}) + }; + let network_adapters = Networks::from_config( logger.cheap_clone(), &config, diff --git a/node/src/manager/commands/config.rs b/node/src/manager/commands/config.rs index 2198fc5d71d..9f300a1c63e 100644 --- a/node/src/manager/commands/config.rs +++ b/node/src/manager/commands/config.rs @@ -3,7 +3,7 @@ use std::{collections::BTreeMap, sync::Arc}; use graph::{ anyhow::{bail, Context}, components::{ - adapter::{ChainId, IdentValidator, IdentValidatorError, MockIdentValidator, ProviderName}, + adapter::{ChainId, IdentValidator, IdentValidatorError, NoopIdentValidator, ProviderName}, subgraph::{Setting, Settings}, }, endpoint::EndpointMetrics, @@ -176,7 +176,7 @@ pub async fn provider( &config, registry, metrics, - Arc::new(MockIdentValidator), + Arc::new(NoopIdentValidator), ) .await?; let network: ChainId = network.into(); diff --git a/node/src/network_setup.rs b/node/src/network_setup.rs index 24903154f99..6cc41395346 100644 --- a/node/src/network_setup.rs +++ b/node/src/network_setup.rs @@ -8,13 +8,13 @@ use graph::{ cheap_clone::CheapClone, components::{ adapter::{ - ChainId, IdentValidator, MockIdentValidator, NetIdentifiable, ProviderManager, + ChainId, IdentValidator, NetIdentifiable, NoopIdentValidator, ProviderManager, ProviderName, }, metrics::MetricsRegistry, }, endpoint::EndpointMetrics, - env::EnvVars, + env::{EnvVars, ENV_VARS}, firehose::{FirehoseEndpoint, FirehoseEndpoints}, futures03::future::TryFutureExt, itertools::Itertools, @@ -119,17 +119,17 @@ impl Networks { rpc_provider_manager: ProviderManager::new( Logger::root(Discard, o!()), vec![].into_iter(), - Arc::new(MockIdentValidator), + Arc::new(NoopIdentValidator), ), firehose_provider_manager: ProviderManager::new( Logger::root(Discard, o!()), vec![].into_iter(), - Arc::new(MockIdentValidator), + Arc::new(NoopIdentValidator), ), substreams_provider_manager: ProviderManager::new( Logger::root(Discard, o!()), vec![].into_iter(), - Arc::new(MockIdentValidator), + Arc::new(NoopIdentValidator), ), } } @@ -146,7 +146,7 @@ impl Networks { &ChainId, Vec<(ProviderName, Result)>, )> { - let timeout = Duration::from_secs(20); + let timeout = ENV_VARS.genesis_validation_timeout; let mut out = vec![]; for chain_id in self.adapters.iter().map(|a| a.chain_id()).sorted().dedup() { let mut inner = vec![];