diff --git a/codegenerator/cli/Makefile b/codegenerator/cli/Makefile index 6dbae3d7a..89447d316 100644 --- a/codegenerator/cli/Makefile +++ b/codegenerator/cli/Makefile @@ -1,14 +1,19 @@ # Target to update schemas update-schemas: @echo "Updating schemas json schemas for evm human config..." - cargo run -- print-config-json-schema evm > ./npm/envio/evm.schema.json + cargo run -- script print-config-json-schema evm > ./npm/envio/evm.schema.json @echo "Updating schemas json schemas for fuel human config..." - cargo run -- print-config-json-schema fuel > ./npm/envio/fuel.schema.json + cargo run -- script print-config-json-schema fuel > ./npm/envio/fuel.schema.json # Target to update help update-help: @echo "Updating help doc..." - cargo run -- print-cli-help-md > ./CommandLineHelp.md + cargo run -- script print-cli-help-md > ./CommandLineHelp.md + +# Target to help find missing networks +print-missing-networks: + @echo "Printing missing networks..." + cargo run -- script print-missing-networks # Target to update generated docs, depends on update-schemas and update-help update-generated-docs: update-schemas update-help diff --git a/codegenerator/cli/src/cli_args/clap_definitions.rs b/codegenerator/cli/src/cli_args/clap_definitions.rs index cf1ba91d6..5e6cc3325 100644 --- a/codegenerator/cli/src/cli_args/clap_definitions.rs +++ b/codegenerator/cli/src/cli_args/clap_definitions.rs @@ -62,13 +62,18 @@ pub enum CommandType { ///Start the indexer without any automatic codegen Start(StartArgs), - ///Print help into a markdown file - ///Command to run: cargo run --bin envio -- print-all-help > CommandLineHelp.md #[clap(hide = true)] + #[command(subcommand)] + Script(Script), +} + +#[derive(Debug, Subcommand)] +pub enum Script { + ///Print missing networks from the API + PrintMissingNetworks, + ///Print help into a markdown file PrintCliHelpMd, ///Print help into a markdown file - ///Command to run: cargo run --bin envio -- print-all-help > CommandLineHelp.md - #[clap(hide = true)] #[command(subcommand)] PrintConfigJsonSchema(JsonSchema), } diff --git a/codegenerator/cli/src/config_parsing/chain_helpers.rs b/codegenerator/cli/src/config_parsing/chain_helpers.rs index 9340dc8f0..e33f44996 100644 --- a/codegenerator/cli/src/config_parsing/chain_helpers.rs +++ b/codegenerator/cli/src/config_parsing/chain_helpers.rs @@ -6,6 +6,7 @@ use clap::ValueEnum; use ethers::etherscan; use serde::{Deserialize, Serialize}; use strum::FromRepr; +use strum::IntoEnumIterator; use strum_macros::{Display, EnumIter, EnumString}; use subenum::subenum; @@ -248,6 +249,10 @@ pub enum Network { // Still syncing // #[subenum(HypersyncNetwork)] // Saakuru = 7225878, + // #[subenum(HypersyncNetwork)] + // CitreaDevnet = 62298, + // #[subenum(HypersyncNetwork)] + // MorphTestnet = 2810, } impl Network { @@ -343,6 +348,13 @@ impl Network { } } +impl HypersyncNetwork { + // This is a custom iterator that returns all the HypersyncNetwork enums that is made public accross crates (for convenience) + pub fn iter_hypersync_networks() -> impl Iterator { + HypersyncNetwork::iter() + } +} + pub enum BlockExplorerApi { DefaultEthers, Custom { @@ -558,9 +570,7 @@ mod test { .into_iter() .map(|s| { GraphNetwork::deserialize(serde_json::Value::String(s.clone())) - // serde_json::from_str::(&s) .expect(format!("Invalid graph network: {}", s).as_str()) - // GraphNetwork::from_str(&s).expect(format!("Invalid graph network: {}", s).as_str()) }) .collect::>(); diff --git a/codegenerator/cli/src/config_parsing/system_config.rs b/codegenerator/cli/src/config_parsing/system_config.rs index 199047d93..90e1c0d02 100644 --- a/codegenerator/cli/src/config_parsing/system_config.rs +++ b/codegenerator/cli/src/config_parsing/system_config.rs @@ -235,8 +235,7 @@ impl SystemConfig { Abi::Evm(evm_abi), ) .context(format!( - "Failed parsing locally defined network contract at network \ - id {}", + "Failed parsing locally defined network contract at network id {}", network.id ))?; @@ -953,9 +952,12 @@ impl Event { for event_config in events_config.iter() { let log = match &event_config.log_id { None => { - let logged_type = fuel_abi.get_type_by_struct_name(event_config.name.clone()).context( - "Failed to derive log ids from the event name. Use the lodId field to set it explicitely." - )?; + let logged_type = fuel_abi + .get_type_by_struct_name(event_config.name.clone()) + .context( + "Failed to derive log ids from the event name. Use the lodId field to \ + set it explicitely.", + )?; fuel_abi.get_log_by_type(logged_type.id)? } Some(log_id) => fuel_abi.get_log(&log_id)?, diff --git a/codegenerator/cli/src/executor/mod.rs b/codegenerator/cli/src/executor/mod.rs index 56b1f9ed3..8fbc13bb0 100644 --- a/codegenerator/cli/src/executor/mod.rs +++ b/codegenerator/cli/src/executor/mod.rs @@ -1,10 +1,11 @@ use crate::{ - clap_definitions::JsonSchema, + clap_definitions::{JsonSchema, Script}, cli_args::clap_definitions::{CommandLineArgs, CommandType}, commands, config_parsing::{human_config, system_config::SystemConfig}, persisted_state::{PersistedState, PersistedStateExists, CURRENT_CRATE_VERSION}, project_paths::ParsedProjectPaths, + scripts, }; mod codegen; @@ -90,10 +91,10 @@ pub async fn execute(command_line_args: CommandLineArgs) -> Result<()> { local::run_local(&local_commands, &parsed_project_paths).await?; } - CommandType::PrintCliHelpMd => { + CommandType::Script(Script::PrintCliHelpMd) => { println!("{}", CommandLineArgs::generate_markdown_help()); } - CommandType::PrintConfigJsonSchema(json_schema) => match json_schema { + CommandType::Script(Script::PrintConfigJsonSchema(json_schema)) => match json_schema { JsonSchema::Evm => { let schema = schema_for!(human_config::evm::HumanConfig); println!( @@ -111,6 +112,11 @@ pub async fn execute(command_line_args: CommandLineArgs) -> Result<()> { ); } }, + CommandType::Script(Script::PrintMissingNetworks) => { + scripts::print_missing_networks::run() + .await + .context("Failed print missing networks script")?; + } }; Ok(()) diff --git a/codegenerator/cli/src/lib.rs b/codegenerator/cli/src/lib.rs index a3fe34e0c..dad5dd399 100644 --- a/codegenerator/cli/src/lib.rs +++ b/codegenerator/cli/src/lib.rs @@ -11,6 +11,7 @@ mod hbs_templating; mod persisted_state; mod project_paths; mod rescript_types; +mod scripts; mod service_health; mod template_dirs; mod utils; diff --git a/codegenerator/cli/src/scripts/mod.rs b/codegenerator/cli/src/scripts/mod.rs new file mode 100644 index 000000000..1f0e62b1e --- /dev/null +++ b/codegenerator/cli/src/scripts/mod.rs @@ -0,0 +1 @@ +pub mod print_missing_networks; diff --git a/codegenerator/cli/src/scripts/print_missing_networks.rs b/codegenerator/cli/src/scripts/print_missing_networks.rs new file mode 100644 index 000000000..01562acb2 --- /dev/null +++ b/codegenerator/cli/src/scripts/print_missing_networks.rs @@ -0,0 +1,73 @@ +use crate::config_parsing::chain_helpers::{GraphNetwork, HypersyncNetwork}; +use anyhow::Result; +use convert_case::{Case, Casing}; +use reqwest; +use serde::Deserialize; +use std::collections::HashSet; + +#[derive(Deserialize, Debug)] +struct Chain { + name: String, + chain_id: u64, +} + +pub async fn run() -> Result<()> { + let url = "https://chains.hyperquery.xyz/active_chains"; + let response = reqwest::get(url).await?; + let chains: Vec = response.json().await?; + + let mut missing_chains = Vec::new(); + let mut api_chain_ids = HashSet::new(); + + for chain in &chains { + api_chain_ids.insert(chain.chain_id); + if HypersyncNetwork::from_repr(chain.chain_id).is_none() { + let is_graph = GraphNetwork::from_repr(chain.chain_id).is_some(); + + let subenums = match is_graph { + true => "HypersyncNetwork, GraphNetwork", + false => "HypersyncNetwork", + }; + missing_chains.push(format!( + " #[subenum({})]\n {} = {},", + subenums, + chain.name.to_case(Case::Pascal), + chain.chain_id + )); + } + } + + let mut extra_chains = Vec::new(); + for network in HypersyncNetwork::iter_hypersync_networks() { + let network_id = network as u64; + if !api_chain_ids.contains(&network_id) { + extra_chains.push(format!("{:?} (ID: {})", network, network_id)); + } + } + + if missing_chains.is_empty() && extra_chains.is_empty() { + println!( + "All chains from the API are present in the HypersyncNetwork enum, and vice versa. \ + Nothing to update." + ); + } else { + if !missing_chains.is_empty() { + println!("The following chains are missing from the Network enum:"); + for chain in missing_chains { + println!("{}", chain); + } + } + + if !extra_chains.is_empty() { + println!( + "\nThe following chains are in the HypersyncNetwork enum but not in the API \ + (remove the HypersyncNetwork enum from the chain_helpers.rs file):" + ); + for chain in extra_chains { + println!("- {}", chain); + } + } + } + + Ok(()) +}