From d5dfea9b49d039fac862a0defbd254acde33e02c Mon Sep 17 00:00:00 2001 From: Jason Smythe Date: Tue, 22 Oct 2024 13:01:02 +0200 Subject: [PATCH] feat: prompt for start block on rpc url networks in contract import (#4) * feat: prompt for start_block on rpc contract import indexers * tests * feat: use custom type to allow recoverability for invalid startblock --------- Co-authored-by: denhampreen --- codegenerator/cli/CommandLineHelp.md | 1 + codegenerator/cli/npm/envio/evm.schema.json | 6 ++- codegenerator/cli/npm/envio/fuel.schema.json | 6 ++- .../cli/src/cli_args/clap_definitions.rs | 4 ++ codegenerator/cli/src/cli_args/init_config.rs | 8 ++-- .../cli_args/interactive_init/evm_prompts.rs | 39 ++++++++++++++++--- .../cli/src/config_parsing/chain_helpers.rs | 2 +- .../contract_import/converters.rs | 24 +++++++----- .../cli/src/config_parsing/human_config.rs | 8 ++-- .../cli/src/config_parsing/system_config.rs | 4 +- .../cli/src/config_parsing/validation.rs | 2 +- .../src/hbs_templating/codegen_templates.rs | 4 +- 12 files changed, 75 insertions(+), 33 deletions(-) diff --git a/codegenerator/cli/CommandLineHelp.md b/codegenerator/cli/CommandLineHelp.md index 003daefa6..11297816e 100644 --- a/codegenerator/cli/CommandLineHelp.md +++ b/codegenerator/cli/CommandLineHelp.md @@ -138,6 +138,7 @@ Initialize from a local json ABI file * `--contract-name ` β€” The name of the contract * `-b`, `--blockchain ` β€” Network from which contract address should be fetched for migration * `-r`, `--rpc-url ` β€” The rpc url to use if the network id used is unsupported by our hypersync +* `-s`, `--start-block ` β€” The start block to use on this network diff --git a/codegenerator/cli/npm/envio/evm.schema.json b/codegenerator/cli/npm/envio/evm.schema.json index a5e562546..115ece716 100644 --- a/codegenerator/cli/npm/envio/evm.schema.json +++ b/codegenerator/cli/npm/envio/evm.schema.json @@ -208,7 +208,8 @@ "start_block": { "description": "The block at which the indexer should start ingesting data", "type": "integer", - "format": "int32" + "format": "uint64", + "minimum": 0 }, "end_block": { "description": "The block at which the indexer should terminate.", @@ -216,7 +217,8 @@ "integer", "null" ], - "format": "int32" + "format": "uint64", + "minimum": 0 }, "contracts": { "description": "All the contracts that should be indexed on the given network", diff --git a/codegenerator/cli/npm/envio/fuel.schema.json b/codegenerator/cli/npm/envio/fuel.schema.json index f71a2db4a..074e19051 100644 --- a/codegenerator/cli/npm/envio/fuel.schema.json +++ b/codegenerator/cli/npm/envio/fuel.schema.json @@ -148,7 +148,8 @@ "start_block": { "description": "The block at which the indexer should start ingesting data", "type": "integer", - "format": "int32" + "format": "uint64", + "minimum": 0 }, "end_block": { "description": "The block at which the indexer should terminate.", @@ -156,7 +157,8 @@ "integer", "null" ], - "format": "int32" + "format": "uint64", + "minimum": 0 }, "hyperfuel_config": { "description": "Optional HyperFuel Config for additional fine-tuning", diff --git a/codegenerator/cli/src/cli_args/clap_definitions.rs b/codegenerator/cli/src/cli_args/clap_definitions.rs index c6c5848ab..9262ab170 100644 --- a/codegenerator/cli/src/cli_args/clap_definitions.rs +++ b/codegenerator/cli/src/cli_args/clap_definitions.rs @@ -278,6 +278,10 @@ pub mod evm { ///The rpc url to use if the network id used is unsupported by our hypersync #[arg(short, long)] pub rpc_url: Option, + + ///The start block to use on this network + #[arg(short, long)] + pub start_block: Option, } } diff --git a/codegenerator/cli/src/cli_args/init_config.rs b/codegenerator/cli/src/cli_args/init_config.rs index de1e422f4..1ab38e5ae 100644 --- a/codegenerator/cli/src/cli_args/init_config.rs +++ b/codegenerator/cli/src/cli_args/init_config.rs @@ -107,8 +107,8 @@ pub mod evm { .or_insert({ let rpc_config = match &selected_network.network { NetworkKind::Supported(_) => None, - NetworkKind::Unsupported(_, url) => Some(RpcConfig { - url: url.clone().into(), + NetworkKind::Unsupported { rpc_url, .. } => Some(RpcConfig { + url: rpc_url.clone().into(), sync_config: None, }), }; @@ -117,7 +117,7 @@ pub mod evm { NetworkKind::Supported(network) => { chain_helpers::Network::from(network).get_finite_end_block() } - NetworkKind::Unsupported(network_id, _) => { + NetworkKind::Unsupported { network_id, .. } => { chain_helpers::Network::from_network_id(network_id) .ok() .map(|network| network.get_finite_end_block()) @@ -129,7 +129,7 @@ pub mod evm { id: selected_network.network.get_network_id(), hypersync_config: None, rpc_config, - start_block: 0, + start_block: selected_network.network.get_start_block(), end_block, confirmed_block_threshold: None, contracts: Vec::new(), diff --git a/codegenerator/cli/src/cli_args/interactive_init/evm_prompts.rs b/codegenerator/cli/src/cli_args/interactive_init/evm_prompts.rs index 48a1e49ce..9922963ce 100644 --- a/codegenerator/cli/src/cli_args/interactive_init/evm_prompts.rs +++ b/codegenerator/cli/src/cli_args/interactive_init/evm_prompts.rs @@ -184,6 +184,7 @@ impl ContractImportArgs { ///To validate that a user is not double selecting a network id fn prompt_for_network_id( opt_rpc_url: &Option, + opt_start_block: &Option, already_selected_ids: Vec, ) -> Result { //The first option of the list, funnels the user to enter a u64 @@ -221,7 +222,7 @@ fn prompt_for_network_id( //Convert the id into a supported or unsupported network. //If unsupported, it will use the optional rpc url or prompt //for an rpc url - get_converter_network_u64(network_id, opt_rpc_url)? + get_converter_network_u64(network_id, opt_rpc_url, opt_start_block)? } //If a supported network choice was selected. We should be able to //parse it back to a supported network since it was serialized as a @@ -241,6 +242,7 @@ fn prompt_for_network_id( fn get_converter_network_u64( network_id: u64, rpc_url: &Option, + start_block: &Option, ) -> Result { let maybe_supported_network = Network::from_network_id(network_id).and_then(|n| Ok(HypersyncNetwork::try_from(n)?)); @@ -252,13 +254,36 @@ fn get_converter_network_u64( Some(r) => r.clone(), None => prompt_for_rpc_url()?, }; - converters::NetworkKind::Unsupported(network_id, rpc_url) + let start_block = match start_block { + Some(s) => s.clone(), + None => prompt_for_start_block()?, + }; + + converters::NetworkKind::Unsupported { + network_id, + rpc_url, + start_block, + } } }; Ok(network) } +///Prompt the user to enter a starting block +///only prompt when used when using rpc as it could +///be very slow to have the startblock at 0 with rpc πŸ¦ΆπŸ”« +fn prompt_for_start_block() -> Result { + let start_block = CustomType::::new( + "Please provide a start block for this network \ + (this can be edited later in config.yaml):", + ) + .with_error_message("Invalid start block input, please enter a number 0 or greater") + .prompt()?; + + Ok(start_block) +} + ///Prompt the user to enter an rpc url fn prompt_for_rpc_url() -> Result { Text::new( @@ -349,9 +374,9 @@ impl LocalImportArgs { match &self.blockchain { Some(b) => { let network_id: u64 = (b.clone()).into(); - get_converter_network_u64(network_id, &self.rpc_url) + get_converter_network_u64(network_id, &self.rpc_url, &self.start_block) } - None => prompt_for_network_id(&self.rpc_url, vec![]), + None => prompt_for_network_id(&self.rpc_url, &self.start_block, vec![]), } } @@ -385,10 +410,12 @@ impl Contract for SelectedContract { //In a new network case, no RPC url could be //derived from CLI flags const NO_RPC_URL: Option = None; + const NO_START_BLOCK: Option = None; //Select a new network (not from the list of existing network ids already added) - let selected_network = prompt_for_network_id(&NO_RPC_URL, self.get_network_ids()) - .context("Failed selecting network")?; + let selected_network = + prompt_for_network_id(&NO_RPC_URL, &NO_START_BLOCK, self.get_network_ids()) + .context("Failed selecting network")?; //Instantiate a network_selection without any contract addresses let network_selection = diff --git a/codegenerator/cli/src/config_parsing/chain_helpers.rs b/codegenerator/cli/src/config_parsing/chain_helpers.rs index 5090ed19f..c8a32723a 100644 --- a/codegenerator/cli/src/config_parsing/chain_helpers.rs +++ b/codegenerator/cli/src/config_parsing/chain_helpers.rs @@ -343,7 +343,7 @@ impl Network { } /// Returns the end block for this network if it is finite - pub fn get_finite_end_block(&self) -> Option { + pub fn get_finite_end_block(&self) -> Option { match self { Self::Goerli => Some(10_387_962), Self::Mumbai => Some(47_002_303), diff --git a/codegenerator/cli/src/config_parsing/contract_import/converters.rs b/codegenerator/cli/src/config_parsing/contract_import/converters.rs index a9f659152..a577735ed 100644 --- a/codegenerator/cli/src/config_parsing/contract_import/converters.rs +++ b/codegenerator/cli/src/config_parsing/contract_import/converters.rs @@ -59,27 +59,33 @@ impl SelectedContract { } } -type NetworkId = u64; -type RpcUrl = String; - #[derive(Clone, Debug)] pub enum NetworkKind { Supported(HypersyncNetwork), - Unsupported(NetworkId, RpcUrl), + Unsupported { + network_id: u64, + rpc_url: String, + start_block: u64, + }, } impl NetworkKind { - pub fn get_network_id(&self) -> NetworkId { + pub fn get_network_id(&self) -> u64 { match self { Self::Supported(n) => n.clone() as u64, - Self::Unsupported(n, _) => *n, + Self::Unsupported { network_id, .. } => *network_id, + } + } + pub fn get_start_block(&self) -> u64 { + match self { + Self::Supported(_) => 0, + Self::Unsupported { start_block, .. } => *start_block, } } - pub fn uses_hypersync(&self) -> bool { match self { Self::Supported(_) => true, - Self::Unsupported(_, _) => false, + Self::Unsupported { .. } => false, } } } @@ -88,7 +94,7 @@ impl Display for NetworkKind { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match &self { Self::Supported(n) => write!(f, "{}", n), - Self::Unsupported(n, _) => write!(f, "{}", n), + Self::Unsupported { network_id, .. } => write!(f, "{}", network_id), } } } diff --git a/codegenerator/cli/src/config_parsing/human_config.rs b/codegenerator/cli/src/config_parsing/human_config.rs index fe978ba46..cc883668b 100644 --- a/codegenerator/cli/src/config_parsing/human_config.rs +++ b/codegenerator/cli/src/config_parsing/human_config.rs @@ -374,10 +374,10 @@ pub mod evm { )] pub confirmed_block_threshold: Option, #[schemars(description = "The block at which the indexer should start ingesting data")] - pub start_block: i32, + pub start_block: u64, #[serde(skip_serializing_if = "Option::is_none")] #[schemars(description = "The block at which the indexer should terminate.")] - pub end_block: Option, + pub end_block: Option, #[schemars(description = "All the contracts that should be indexed on the given network")] pub contracts: Vec>, } @@ -498,10 +498,10 @@ pub mod fuel { #[schemars(description = "Public chain/network id")] pub id: NetworkId, #[schemars(description = "The block at which the indexer should start ingesting data")] - pub start_block: i32, + pub start_block: u64, #[serde(skip_serializing_if = "Option::is_none")] #[schemars(description = "The block at which the indexer should terminate.")] - pub end_block: Option, + pub end_block: Option, #[serde(skip_serializing_if = "Option::is_none")] #[schemars(description = "Optional HyperFuel Config for additional fine-tuning")] pub hyperfuel_config: Option, diff --git a/codegenerator/cli/src/config_parsing/system_config.rs b/codegenerator/cli/src/config_parsing/system_config.rs index 13f3a0d4e..ae94942ae 100644 --- a/codegenerator/cli/src/config_parsing/system_config.rs +++ b/codegenerator/cli/src/config_parsing/system_config.rs @@ -652,8 +652,8 @@ impl SyncSource { pub struct Network { pub id: u64, pub sync_source: SyncSource, - pub start_block: i32, - pub end_block: Option, + pub start_block: u64, + pub end_block: Option, pub confirmed_block_threshold: i32, pub contracts: Vec, } diff --git a/codegenerator/cli/src/config_parsing/validation.rs b/codegenerator/cli/src/config_parsing/validation.rs index d8f7abca7..f9fbee224 100644 --- a/codegenerator/cli/src/config_parsing/validation.rs +++ b/codegenerator/cli/src/config_parsing/validation.rs @@ -136,7 +136,7 @@ impl human_config::evm::Network { let is_unordered_multichain_mode = human_config.unordered_multichain_mode.unwrap_or(false); let is_multichain_indexer = human_config.networks.len() > 1; if !is_unordered_multichain_mode && is_multichain_indexer { - let make_err = |finite_end_block: i32| { + let make_err = |finite_end_block: u64| { Err(anyhow!( "Network {} has a finite end block of {}. Please set an end_block that is \ less than or equal to the finite end block in your config or set \ diff --git a/codegenerator/cli/src/hbs_templating/codegen_templates.rs b/codegenerator/cli/src/hbs_templating/codegen_templates.rs index 0f8597c9c..b040de78e 100644 --- a/codegenerator/cli/src/hbs_templating/codegen_templates.rs +++ b/codegenerator/cli/src/hbs_templating/codegen_templates.rs @@ -783,8 +783,8 @@ struct NetworkTemplate { hypersync_config: Option, hyperfuel_config: Option, confirmed_block_threshold: i32, - start_block: i32, - end_block: Option, + start_block: u64, + end_block: Option, } impl NetworkTemplate {