From 6f19d2aef1e94b70a5f3dee42f543f22ada09c57 Mon Sep 17 00:00:00 2001 From: Gauthier Leonard Date: Fri, 12 May 2023 15:22:11 +0200 Subject: [PATCH 1/4] feat(sdk): compute subnet_type from threshold --- Cargo.lock | 2 +- crates/ash_sdk/conf/default.yml | 6 ++++ .../src/avalanche/jsonrpc/platformvm.rs | 2 +- crates/ash_sdk/src/avalanche/subnets.rs | 28 +++++++++++++++++-- crates/ash_sdk/tests/conf/custom.yml | 1 + crates/ash_sdk/tests/conf/quicknode.yml | 1 + crates/ash_sdk/tests/conf/wrong.yml | 2 ++ 7 files changed, 38 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6471349..4a2b880 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -397,7 +397,7 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "avalanche-types" version = "0.0.379" -source = "git+https://github.com/AshAvalanche/avalanche-types-rs?branch=update-info-jsonrpc-responses#c0bae5724ad635de0dc4656deac915c581123a74" +source = "git+https://github.com/AshAvalanche/avalanche-types-rs?branch=update-info-jsonrpc-responses#b94fae0ddb0989672e9df797ff10c84230f0cc6d" dependencies = [ "async-trait", "bech32 0.9.1", diff --git a/crates/ash_sdk/conf/default.yml b/crates/ash_sdk/conf/default.yml index a14577b..25cdb79 100644 --- a/crates/ash_sdk/conf/default.yml +++ b/crates/ash_sdk/conf/default.yml @@ -6,6 +6,7 @@ avalancheNetworks: - name: mainnet subnets: - id: 11111111111111111111111111111111LpoYY + subnetType: PrimaryNetwork blockchains: - id: 11111111111111111111111111111111LpoYY name: P-Chain @@ -24,6 +25,7 @@ avalancheNetworks: - name: fuji subnets: - id: 11111111111111111111111111111111LpoYY + subnetType: PrimaryNetwork blockchains: - id: 11111111111111111111111111111111LpoYY name: P-Chain @@ -42,6 +44,7 @@ avalancheNetworks: - name: mainnet-ankr subnets: - id: 11111111111111111111111111111111LpoYY + subnetType: PrimaryNetwork blockchains: - id: 11111111111111111111111111111111LpoYY name: P-Chain @@ -60,6 +63,7 @@ avalancheNetworks: - name: fuji-ankr subnets: - id: 11111111111111111111111111111111LpoYY + subnetType: PrimaryNetwork blockchains: - id: 11111111111111111111111111111111LpoYY name: P-Chain @@ -78,6 +82,7 @@ avalancheNetworks: - name: mainnet-blast subnets: - id: 11111111111111111111111111111111LpoYY + subnetType: PrimaryNetwork blockchains: - id: 11111111111111111111111111111111LpoYY name: P-Chain @@ -96,6 +101,7 @@ avalancheNetworks: - name: fuji-blast subnets: - id: 11111111111111111111111111111111LpoYY + subnetType: PrimaryNetwork blockchains: - id: 11111111111111111111111111111111LpoYY name: P-Chain diff --git a/crates/ash_sdk/src/avalanche/jsonrpc/platformvm.rs b/crates/ash_sdk/src/avalanche/jsonrpc/platformvm.rs index 9bd0c19..7774834 100644 --- a/crates/ash_sdk/src/avalanche/jsonrpc/platformvm.rs +++ b/crates/ash_sdk/src/avalanche/jsonrpc/platformvm.rs @@ -177,7 +177,7 @@ mod tests { // Test that the node is connected assert!(ava_labs_node.connected); // Test that the node has a non-zero uptime - assert!(ava_labs_node.uptime > 0.0); + assert!(ava_labs_node.uptime > Some(0.0)); // Test that the node has a non-zero weight assert!(ava_labs_node.weight > Some(0)); // Test that the node has a non-zero potential reward diff --git a/crates/ash_sdk/src/avalanche/subnets.rs b/crates/ash_sdk/src/avalanche/subnets.rs index 3b7130c..cc5d82f 100644 --- a/crates/ash_sdk/src/avalanche/subnets.rs +++ b/crates/ash_sdk/src/avalanche/subnets.rs @@ -3,7 +3,9 @@ // Module that contains code to interact with Avalanche Subnets and validators -use crate::avalanche::{blockchains::AvalancheBlockchain, AvalancheOutputOwners}; +use crate::avalanche::{ + blockchains::AvalancheBlockchain, AvalancheOutputOwners, AVAX_PRIMARY_NETWORK_ID, +}; use crate::errors::*; use avalanche_types::{ ids::{node::Id as NodeId, Id}, @@ -11,11 +13,23 @@ use avalanche_types::{ }; use serde::{Deserialize, Serialize}; +/// Avalanche Subnet types +#[derive(Default, Debug, Clone, Serialize, Deserialize)] +pub enum AvalancheSubnetType { + PrimaryNetwork, + #[default] + Permissioned, + /// Also named "PoS" in the Avalanche documentation + Elastic, +} + /// Avalanche Subnet #[derive(Default, Debug, Clone, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct AvalancheSubnet { pub id: Id, + #[serde(default)] + pub subnet_type: AvalancheSubnetType, // TODO: store control keys as ShortIds #[serde(default)] pub control_keys: Vec, @@ -79,6 +93,16 @@ impl From for AvalancheSubnet { fn from(subnet: Subnet) -> Self { Self { id: subnet.id, + // Based on Avalanche documentation at https://docs.avax.network/apis/avalanchego/apis/p-chain#platformgetsubnets + // "If the Subnet is a PoS (= elastic) Subnet, then threshold will be 0 and controlKeys will be empty." + // The Primary Network is an elastic Subnet and its ID is hardcoded + subnet_type: match subnet.threshold { + 0 => match subnet.id.to_string().as_str() { + AVAX_PRIMARY_NETWORK_ID => AvalancheSubnetType::PrimaryNetwork, + _ => AvalancheSubnetType::Elastic, + }, + _ => AvalancheSubnetType::Permissioned, + }, control_keys: subnet .control_keys .map(|keys| { @@ -110,7 +134,7 @@ pub struct AvalancheSubnetValidator { pub potential_reward: Option, pub delegation_fee: Option, pub connected: bool, - pub uptime: f32, + pub uptime: Option, pub validation_reward_owner: Option, pub delegator_count: Option, pub delegator_weight: Option, diff --git a/crates/ash_sdk/tests/conf/custom.yml b/crates/ash_sdk/tests/conf/custom.yml index 50e0dc0..2bdedf5 100644 --- a/crates/ash_sdk/tests/conf/custom.yml +++ b/crates/ash_sdk/tests/conf/custom.yml @@ -6,6 +6,7 @@ avalancheNetworks: - name: custom subnets: - id: 11111111111111111111111111111111LpoYY + subnetType: PrimaryNetwork blockchains: - id: 11111111111111111111111111111111LpoYY name: P-Chain diff --git a/crates/ash_sdk/tests/conf/quicknode.yml b/crates/ash_sdk/tests/conf/quicknode.yml index 5048184..cb8cfde 100644 --- a/crates/ash_sdk/tests/conf/quicknode.yml +++ b/crates/ash_sdk/tests/conf/quicknode.yml @@ -6,6 +6,7 @@ avalancheNetworks: - name: fuji subnets: - id: 11111111111111111111111111111111LpoYY + subnetType: PrimaryNetwork blockchains: - id: 11111111111111111111111111111111LpoYY name: P-Chain diff --git a/crates/ash_sdk/tests/conf/wrong.yml b/crates/ash_sdk/tests/conf/wrong.yml index 0fe8c21..5c08e13 100644 --- a/crates/ash_sdk/tests/conf/wrong.yml +++ b/crates/ash_sdk/tests/conf/wrong.yml @@ -6,6 +6,7 @@ avalancheNetworks: - name: no-primary-network subnets: - id: yH8D7ThNJkxmtkuv2jgBa4P1Rn3Qpr4pPr7QYNfcdoS6k6HWp + subnetType: Permissioned blockchains: - id: 2JVSBoinj9C2J33VntvzYtVJNZdN2NKiwwKjcumHUWEb5DbBrm name: MyChain @@ -14,6 +15,7 @@ avalancheNetworks: - name: no-pchain subnets: - id: 11111111111111111111111111111111LpoYY + subnetType: PrimaryNetwork blockchains: - id: yH8D7ThNJkxmtkuv2jgBa4P1Rn3Qpr4pPr7QYNfcdoS6k6HWp name: C-Chain From 089a5fe4727b03bc09d4114226298887b920dac9 Mon Sep 17 00:00:00 2001 From: Gauthier Leonard Date: Fri, 12 May 2023 17:04:30 +0200 Subject: [PATCH 2/4] feat(cli): template validator info based on subnet --- Cargo.lock | 12 ++ crates/ash_cli/src/avalanche/network.rs | 1 + crates/ash_cli/src/avalanche/subnet.rs | 2 + crates/ash_cli/src/avalanche/validator.rs | 15 ++- crates/ash_cli/src/utils/templating.rs | 144 +++++++++++++++------- crates/ash_sdk/Cargo.toml | 1 + crates/ash_sdk/src/avalanche/subnets.rs | 3 +- crates/ash_sdk/src/lib.rs | 3 + 8 files changed, 134 insertions(+), 47 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4a2b880..fec5103 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -161,6 +161,7 @@ dependencies = [ "async-std", "avalanche-types", "config", + "enum-display-derive", "ethers", "hex", "regex", @@ -1485,6 +1486,17 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "enum-display-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f16ef37b2a9b242295d61a154ee91ae884afff6b8b933b486b12481cc58310ca" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "errno" version = "0.3.1" diff --git a/crates/ash_cli/src/avalanche/network.rs b/crates/ash_cli/src/avalanche/network.rs index f8343f6..3dcba0c 100644 --- a/crates/ash_cli/src/avalanche/network.rs +++ b/crates/ash_cli/src/avalanche/network.rs @@ -41,6 +41,7 @@ fn list(config: Option<&str>, json: bool) -> Result<(), CliError> { for network in networks { println!(" - '{}'", type_colorize(&network.name)); } + Ok(()) } diff --git a/crates/ash_cli/src/avalanche/subnet.rs b/crates/ash_cli/src/avalanche/subnet.rs index 96c84f3..da8322d 100644 --- a/crates/ash_cli/src/avalanche/subnet.rs +++ b/crates/ash_cli/src/avalanche/subnet.rs @@ -51,6 +51,7 @@ fn list(network_name: &str, config: Option<&str>, json: bool) -> Result<(), CliE for subnet in network.subnets.iter() { println!("{}", template_subnet_info(subnet, true, 0)); } + Ok(()) } @@ -69,6 +70,7 @@ fn info(network_name: &str, id: &str, config: Option<&str>, json: bool) -> Resul } println!("{}", template_subnet_info(subnet, false, 0)); + Ok(()) } diff --git a/crates/ash_cli/src/avalanche/validator.rs b/crates/ash_cli/src/avalanche/validator.rs index 9b2cd96..2b5a7e1 100644 --- a/crates/ash_cli/src/avalanche/validator.rs +++ b/crates/ash_cli/src/avalanche/validator.rs @@ -63,12 +63,16 @@ fn list( println!( "Found {} validator(s) on Subnet '{}':", - subnet.validators.len(), - subnet_id + type_colorize(&subnet.validators.len()), + type_colorize(&subnet_id) ); for validator in subnet.validators.iter() { - println!("{}", template_validator_info(validator, true, 2, true)); + println!( + "{}", + template_validator_info(validator, subnet, true, 2, true) + ); } + Ok(()) } @@ -95,8 +99,11 @@ fn info( println!("{}", serde_json::to_string(&validator).unwrap()); return Ok(()); } + println!( + "{}", + template_validator_info(validator, subnet, false, 0, true) + ); - println!("{}", template_validator_info(validator, false, 0, true)); Ok(()) } diff --git a/crates/ash_cli/src/utils/templating.rs b/crates/ash_cli/src/utils/templating.rs index fca8314..0edef92 100644 --- a/crates/ash_cli/src/utils/templating.rs +++ b/crates/ash_cli/src/utils/templating.rs @@ -4,8 +4,7 @@ use ash_sdk::avalanche::{ blockchains::AvalancheBlockchain, nodes::AvalancheNode, - subnets::{AvalancheSubnet, AvalancheSubnetValidator}, - AVAX_PRIMARY_NETWORK_ID, + subnets::{AvalancheSubnet, AvalancheSubnetType, AvalancheSubnetValidator}, }; use colored::{ColoredString, Colorize}; use indoc::formatdoc; @@ -76,6 +75,7 @@ pub(crate) fn template_blockchain_info( pub(crate) fn template_validator_info( validator: &AvalancheSubnetValidator, + subnet: &AvalancheSubnet, list: bool, indent: u8, extended: bool, @@ -87,20 +87,23 @@ pub(crate) fn template_validator_info( Tx ID: {} Start time: {} End time: {} - Connected: {} - Uptime: {} ", type_colorize(&validator.tx_id), type_colorize(&validator.start_time), type_colorize(&validator.end_time), - type_colorize(&validator.connected), - type_colorize(&validator.uptime), + ); + + let permissioned_subnet_info = &formatdoc!( + " + Weight: {}", + type_colorize(&validator.weight.unwrap_or_default()), ); let elastic_subnet_info = &formatdoc!( " + Connected: {} + Uptime: {} Stake amount: {} - Weight: {} Potential reward: {} Delegation fee: {} Validation reward owner: @@ -113,23 +116,56 @@ pub(crate) fn template_validator_info( Locktime: {} Threshold: {} Addresses: {}", - type_colorize(&validator.stake_amount.unwrap()), - type_colorize(&validator.weight.unwrap()), - type_colorize(&validator.potential_reward.unwrap()), - type_colorize(&validator.delegation_fee.unwrap()), - type_colorize(&validator.validation_reward_owner.clone().unwrap().locktime), - type_colorize(&validator.validation_reward_owner.clone().unwrap().threshold), + type_colorize(&validator.connected), + type_colorize(&validator.uptime.unwrap_or_default()), + type_colorize(&validator.stake_amount.unwrap_or_default()), + type_colorize(&validator.potential_reward.unwrap_or_default()), + type_colorize(&validator.delegation_fee.unwrap_or_default()), + type_colorize( + &validator + .validation_reward_owner + .clone() + .unwrap_or_default() + .locktime + ), + type_colorize( + &validator + .validation_reward_owner + .clone() + .unwrap_or_default() + .threshold + ), type_colorize(&format!( "{:?}", - validator.validation_reward_owner.clone().unwrap().addresses + validator + .validation_reward_owner + .clone() + .unwrap_or_default() + .addresses )), - type_colorize(&validator.delegator_count.unwrap()), - type_colorize(&validator.delegator_weight.unwrap()), - type_colorize(&validator.delegation_reward_owner.clone().unwrap().locktime), - type_colorize(&validator.delegation_reward_owner.clone().unwrap().threshold), + type_colorize(&validator.delegator_count.unwrap_or_default()), + type_colorize(&validator.delegator_weight.unwrap_or_default()), + type_colorize( + &validator + .delegation_reward_owner + .clone() + .unwrap_or_default() + .locktime + ), + type_colorize( + &validator + .delegation_reward_owner + .clone() + .unwrap_or_default() + .threshold + ), type_colorize(&format!( "{:?}", - validator.delegation_reward_owner.clone().unwrap().addresses + validator + .delegation_reward_owner + .clone() + .unwrap_or_default() + .addresses )), ); @@ -146,8 +182,13 @@ pub(crate) fn template_validator_info( info.push_str(&indent::indent_all_by(4, common_info)); // Display extra information if the validator is a primary validator - if validator.subnet_id.to_string() == AVAX_PRIMARY_NETWORK_ID { - info.push_str(&indent::indent_all_by(4, elastic_subnet_info)); + match subnet.subnet_type { + AvalancheSubnetType::Permissioned => { + info.push_str(&indent::indent_all_by(4, permissioned_subnet_info)); + } + AvalancheSubnetType::Elastic | AvalancheSubnetType::PrimaryNetwork => { + info.push_str(&indent::indent_all_by(4, elastic_subnet_info)); + } } } else { info.push_str(&formatdoc!( @@ -165,11 +206,16 @@ pub(crate) fn template_validator_info( type_colorize(&validator.subnet_id), )); - info.push_str(&indent::indent_all_by(4, common_info)); + info.push_str(&indent::indent_all_by(2, common_info)); // Display extra information if the validator is a primary validator - if validator.subnet_id.to_string() == AVAX_PRIMARY_NETWORK_ID { - info.push_str(&indent::indent_all_by(4, elastic_subnet_info)); + match subnet.subnet_type { + AvalancheSubnetType::Permissioned => { + info.push_str(&indent::indent_all_by(2, permissioned_subnet_info)); + } + AvalancheSubnetType::Elastic | AvalancheSubnetType::PrimaryNetwork => { + info.push_str(&indent::indent_all_by(2, elastic_subnet_info)); + } } } @@ -180,7 +226,7 @@ pub(crate) fn template_subnet_info(subnet: &AvalancheSubnet, list: bool, indent: let mut info = String::new(); let subindent = match list { - true => 3, + true => 2, false => 2, }; @@ -196,26 +242,37 @@ pub(crate) fn template_subnet_info(subnet: &AvalancheSubnet, list: bool, indent: for validator in subnet.validators.iter() { validators_info.push_str(&format!( "\n{}", - template_validator_info(validator, true, subindent, false) + template_validator_info(validator, subnet, true, subindent, false) )); } + let permissioned_subnet_info = &formatdoc!( + " + Control keys: {} + Threshold: {} + ", + type_colorize(&format!("{:?}", subnet.control_keys)), + type_colorize(&subnet.threshold), + ); + if list { info.push_str(&formatdoc!( " {} - {}: - Number of blockchains: {} - Control keys: {} - Threshold: {} - Blockchains: {}", + Type: {} + {} Blockchains list ({}): {}", template_horizontal_rule('-', format!("- '{}':", subnet.id).len()), type_colorize(&subnet.id), + type_colorize(&subnet.subnet_type.to_string()), + match subnet.subnet_type { + AvalancheSubnetType::Permissioned => + indent::indent_all_by(subindent.into(), permissioned_subnet_info), + _ => "".to_string(), + }, type_colorize(&subnet.blockchains.len()), - type_colorize(&format!("{:?}", subnet.control_keys)), - type_colorize(&subnet.threshold), match blockchains_info.is_empty() { - true => String::from("None"), + true => String::from("[]"), false => blockchains_info, } )); @@ -223,21 +280,24 @@ pub(crate) fn template_subnet_info(subnet: &AvalancheSubnet, list: bool, indent: info.push_str(&formatdoc!( " Subnet '{}': - Number of blockchains: {} - Control keys: {} - Threshold: {} - Blockchains: {} - Validators: {}", + Type: {} + {} Blockchains list ({}): {} + Validators list ({}): {}", type_colorize(&subnet.id), + type_colorize(&subnet.subnet_type.to_string()), + match subnet.subnet_type { + AvalancheSubnetType::Permissioned => + indent::indent_all_by(2, permissioned_subnet_info), + _ => "".to_string(), + }, type_colorize(&subnet.blockchains.len()), - type_colorize(&format!("{:?}", subnet.control_keys)), - type_colorize(&subnet.threshold), match blockchains_info.is_empty() { - true => String::from("None"), + true => String::from("[]"), false => blockchains_info, }, + type_colorize(&subnet.validators.len()), match validators_info.is_empty() { - true => String::from("None"), + true => String::from("[]"), false => validators_info, } )); diff --git a/crates/ash_sdk/Cargo.toml b/crates/ash_sdk/Cargo.toml index 7837075..0640615 100644 --- a/crates/ash_sdk/Cargo.toml +++ b/crates/ash_sdk/Cargo.toml @@ -29,6 +29,7 @@ async-std = { version = "1.10.0", features = ["attributes", "tokio1"] } # reqwest is used by ethers # We need to enable the rustls-tls-native-roots feature to support self-signed certificates reqwest = { version = "0.11.14", features = ["rustls-tls-native-roots"] } +enum-display-derive = "0.1.1" [dev-dependencies] tempfile = "3.3.0" diff --git a/crates/ash_sdk/src/avalanche/subnets.rs b/crates/ash_sdk/src/avalanche/subnets.rs index cc5d82f..09b3c18 100644 --- a/crates/ash_sdk/src/avalanche/subnets.rs +++ b/crates/ash_sdk/src/avalanche/subnets.rs @@ -12,9 +12,10 @@ use avalanche_types::{ jsonrpc::platformvm::{ApiPrimaryDelegator, ApiPrimaryValidator, Subnet}, }; use serde::{Deserialize, Serialize}; +use std::fmt::Display; /// Avalanche Subnet types -#[derive(Default, Debug, Clone, Serialize, Deserialize)] +#[derive(Default, Debug, Display, Clone, Serialize, Deserialize)] pub enum AvalancheSubnetType { PrimaryNetwork, #[default] diff --git a/crates/ash_sdk/src/lib.rs b/crates/ash_sdk/src/lib.rs index 1b930e5..09a4c66 100644 --- a/crates/ash_sdk/src/lib.rs +++ b/crates/ash_sdk/src/lib.rs @@ -4,3 +4,6 @@ pub mod avalanche; pub mod conf; pub mod errors; + +#[macro_use] +extern crate enum_display_derive; From 31871bf223bafbfe12841623fc413d894726315e Mon Sep 17 00:00:00 2001 From: Gauthier Leonard Date: Mon, 15 May 2023 11:50:53 +0200 Subject: [PATCH 3/4] chore: update dependencies --- Cargo.lock | 203 ++++++++++++++++++----------------------------------- 1 file changed, 67 insertions(+), 136 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fec5103..f476b68 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -334,7 +334,7 @@ checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.16", ] [[package]] @@ -398,7 +398,7 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "avalanche-types" version = "0.0.379" -source = "git+https://github.com/AshAvalanche/avalanche-types-rs?branch=update-info-jsonrpc-responses#b94fae0ddb0989672e9df797ff10c84230f0cc6d" +source = "git+https://github.com/AshAvalanche/avalanche-types-rs?branch=update-info-jsonrpc-responses#7fd5106b55e86e1046ff665b0b43ab5122f59cb9" dependencies = [ "async-trait", "bech32 0.9.1", @@ -408,7 +408,7 @@ dependencies = [ "cert-manager", "chrono", "cmp-manager", - "ecdsa 0.16.6", + "ecdsa 0.16.7", "ethers-core 2.0.4", "hex", "hmac", @@ -636,9 +636,9 @@ checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" [[package]] name = "bumpalo" -version = "3.12.1" +version = "3.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b1ce199063694f33ffb7dd4e0ee620741495c32833cde5aa08f02a0bf96f0c8" +checksum = "3c6ed94e98ecff0c12dd1b04c15ec0d7d9458ca8fe806cea6f12954efe74c63b" [[package]] name = "byte-slice-cast" @@ -849,7 +849,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.16", ] [[package]] @@ -873,16 +873,6 @@ version = "0.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32f5e2b424191b35b798b06e6c67fa5a5440a098925d931d7e91511d7d8fe275" -[[package]] -name = "codespan-reporting" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" -dependencies = [ - "termcolor", - "unicode-width", -] - [[package]] name = "coins-bip32" version = "0.7.0" @@ -1169,50 +1159,6 @@ dependencies = [ "cipher 0.4.4", ] -[[package]] -name = "cxx" -version = "1.0.94" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f61f1b6389c3fe1c316bf8a4dccc90a38208354b330925bce1f74a6c4756eb93" -dependencies = [ - "cc", - "cxxbridge-flags", - "cxxbridge-macro", - "link-cplusplus", -] - -[[package]] -name = "cxx-build" -version = "1.0.94" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12cee708e8962df2aeb38f594aae5d827c022b6460ac71a7a3e2c3c2aae5a07b" -dependencies = [ - "cc", - "codespan-reporting", - "once_cell", - "proc-macro2", - "quote", - "scratch", - "syn 2.0.15", -] - -[[package]] -name = "cxxbridge-flags" -version = "1.0.94" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7944172ae7e4068c533afbb984114a56c46e9ccddda550499caa222902c7f7bb" - -[[package]] -name = "cxxbridge-macro" -version = "1.0.94" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2345488264226bf682893e25de0769f3360aac9957980ec49361b083ddaa5bc5" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.15", -] - [[package]] name = "darling" version = "0.20.1" @@ -1234,7 +1180,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.15", + "syn 2.0.16", ] [[package]] @@ -1245,7 +1191,7 @@ checksum = "29a358ff9f12ec09c3e61fef9b5a9902623a695a46a917b07f269bff1445611a" dependencies = [ "darling_core", "quote", - "syn 2.0.15", + "syn 2.0.16", ] [[package]] @@ -1377,7 +1323,7 @@ checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.16", ] [[package]] @@ -1406,15 +1352,16 @@ dependencies = [ [[package]] name = "ecdsa" -version = "0.16.6" +version = "0.16.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a48e5d537b8a30c0b023116d981b16334be1485af7ca68db3a2b7024cbc957fd" +checksum = "0997c976637b606099b9985693efa3581e84e41f5c11ba5255f88711058ad428" dependencies = [ "der 0.7.5", "digest 0.10.6", "elliptic-curve 0.13.4", "rfc6979 0.4.0", "signature 2.1.0", + "spki 0.7.2", ] [[package]] @@ -2075,7 +2022,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.16", ] [[package]] @@ -2198,9 +2145,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.18" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17f8a914c2987b688368b5138aa05321db91f4090cf26118185672ad588bce21" +checksum = "d357c7ae988e7d2182f7d7871d0b963962420b0678b0997ce7de72001aeab782" dependencies = [ "bytes", "fnv", @@ -2387,12 +2334,11 @@ dependencies = [ [[package]] name = "iana-time-zone-haiku" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" dependencies = [ - "cxx", - "cxx-build", + "cc", ] [[package]] @@ -2566,9 +2512,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.61" +version = "0.3.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445dde2150c55e483f3d8416706b97ec8e8237c307e5b7b4b8dd15e6af2a0730" +checksum = "68c16e1bfd491478ab155fd8b4896b86f9ede344949b641e61501e07c2b8b4d5" dependencies = [ "wasm-bindgen", ] @@ -2604,7 +2550,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" dependencies = [ "cfg-if", - "ecdsa 0.16.6", + "ecdsa 0.16.7", "elliptic-curve 0.13.4", "once_cell", "sha2 0.10.6", @@ -2681,15 +2627,6 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "348108ab3fba42ec82ff6e9564fc4ca0247bdccdc68dd8af9764bbc79c3c8ffb" -[[package]] -name = "link-cplusplus" -version = "1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecd207c9c713c34f95a097a5b029ac2ce6010530c7b49d7fea24d977dede04f5" -dependencies = [ - "cc", -] - [[package]] name = "linked-hash-map" version = "0.5.6" @@ -2906,7 +2843,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.16", ] [[package]] @@ -2990,7 +2927,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.16", ] [[package]] @@ -3196,7 +3133,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.16", ] [[package]] @@ -3276,22 +3213,22 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.0.12" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad29a609b6bcd67fee905812e544992d216af9d755757c05ed2d0e15a74c6ecc" +checksum = "c95a7476719eab1e366eaf73d0260af3021184f18177925b07f54b30089ceead" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.0.12" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55" +checksum = "39407670928234ebc5e6e580247dd567ad73a3578460c5990f9503df207e8f07" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.16", ] [[package]] @@ -3443,9 +3380,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro2" -version = "1.0.56" +version = "1.0.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435" +checksum = "c4ec6d5fe0b140acb27c9a0444118cf55bfbb4e0b259739429abb4521dd67c16" dependencies = [ "unicode-ident", ] @@ -4034,12 +3971,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" -[[package]] -name = "scratch" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1792db035ce95be60c3f8853017b3999209281c24e2ba5bc8e59bf97a0c590c1" - [[package]] name = "scrypt" version = "0.10.0" @@ -4092,9 +4023,9 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.8.2" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a332be01508d814fed64bf28f798a146d73792121129962fdf335bb3c49a4254" +checksum = "ca2855b3715770894e67cbfa3df957790aa0c9edc3bf06efa1a84d77fa0839d1" dependencies = [ "bitflags", "core-foundation", @@ -4105,9 +4036,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.8.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31c9bb296072e961fcbd8853511dd39c2d8be2deb1e17c6860b1d30732b323b4" +checksum = "f51d0c0d83bec45f16480d0ce0058397a69e48fcdc52d1dc8855fb68acbd31a7" dependencies = [ "core-foundation-sys", "libc", @@ -4130,9 +4061,9 @@ checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" [[package]] name = "serde" -version = "1.0.162" +version = "1.0.163" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71b2f6e1ab5c2b98c05f0f35b236b22e8df7ead6ffbf51d7808da7f8817e7ab6" +checksum = "2113ab51b87a539ae008b5c6c02dc020ffa39afd2d83cffcb3f4eb2722cebec2" dependencies = [ "serde_derive", ] @@ -4150,13 +4081,13 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.162" +version = "1.0.163" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2a0814352fd64b58489904a44ea8d90cb1a91dcb6b4f5ebabc32c8318e93cb6" +checksum = "8c805777e3930c8883389c602315a24224bcc738b63905ef87cd1420353ea93e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.16", ] [[package]] @@ -4207,7 +4138,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.16", ] [[package]] @@ -4487,9 +4418,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.15" +version = "2.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a34fcf3e8b60f57e6a14301a2e916d323af98b0ea63c599441eec8558660c822" +checksum = "a6f671d4b5ffdb8eadec19c0ae67fe2639df8684bd7bc4b83d986b8db549cf01" dependencies = [ "proc-macro2", "quote", @@ -4580,7 +4511,7 @@ checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.16", ] [[package]] @@ -4656,9 +4587,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.28.0" +version = "1.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3c786bf8134e5a3a166db9b29ab8f48134739014a3eca7bc6bfa95d673b136f" +checksum = "0aa32867d44e6f2ce3385e89dceb990188b8bb0fb25b0cf576647a6f98ac5105" dependencies = [ "autocfg", "bytes", @@ -4681,7 +4612,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.16", ] [[package]] @@ -4800,14 +4731,14 @@ checksum = "0f57e3ca2a01450b1a921183a9c9cbfda207fd822cef4ccb00a65402cbba7a74" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.16", ] [[package]] name = "tracing-core" -version = "0.1.30" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" +checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" dependencies = [ "once_cell", ] @@ -5038,9 +4969,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.84" +version = "0.2.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b" +checksum = "5b6cb788c4e39112fbe1822277ef6fb3c55cd86b95cb3d3c4c1c9597e4ac74b4" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -5048,24 +4979,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.84" +version = "0.2.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95ce90fd5bcc06af55a641a86428ee4229e44e07033963a2290a8e241607ccb9" +checksum = "35e522ed4105a9d626d885b35d62501b30d9666283a5c8be12c14a8bdafe7822" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.16", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.34" +version = "0.4.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f219e0d211ba40266969f6dbdd90636da12f75bee4fc9d6c23d1260dadb51454" +checksum = "083abe15c5d88556b77bdf7aef403625be9e327ad37c62c4e4129af740168163" dependencies = [ "cfg-if", "js-sys", @@ -5075,9 +5006,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.84" +version = "0.2.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c21f77c0bedc37fd5dc21f897894a5ca01e7bb159884559461862ae90c0b4c5" +checksum = "358a79a0cb89d21db8120cbfb91392335913e4890665b1a7981d9e956903b434" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -5085,22 +5016,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.84" +version = "0.2.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6" +checksum = "4783ce29f09b9d93134d41297aded3a712b7b979e9c6f28c32cb88c973a94869" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.16", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.84" +version = "0.2.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d" +checksum = "a901d592cafaa4d711bc324edfaff879ac700b19c3dfd60058d2b445be2691eb" [[package]] name = "wasm-timer" @@ -5119,9 +5050,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.61" +version = "0.3.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e33b99f4b23ba3eec1a53ac264e35a755f00e966e0065077d6027c0f575b0b97" +checksum = "16b5f940c7edfdc6d12126d98c9ef4d1b3d470011c47c76a6581df47ad9ba721" dependencies = [ "js-sys", "wasm-bindgen", @@ -5488,7 +5419,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.16", ] [[package]] From 5577a5897e5afa70d95cc0d37a615d2925eb7963 Mon Sep 17 00:00:00 2001 From: Gauthier Leonard Date: Mon, 15 May 2023 16:02:19 +0200 Subject: [PATCH 4/4] feat: allow to query nodes info through HTTPS --- crates/ash_cli/src/avalanche/node.rs | 19 +++++++++++---- crates/ash_sdk/src/avalanche/nodes.rs | 35 ++++++++++++++++++--------- 2 files changed, 38 insertions(+), 16 deletions(-) diff --git a/crates/ash_cli/src/avalanche/node.rs b/crates/ash_cli/src/avalanche/node.rs index 6a10ddc..45e7d19 100644 --- a/crates/ash_cli/src/avalanche/node.rs +++ b/crates/ash_cli/src/avalanche/node.rs @@ -21,6 +21,8 @@ pub(crate) struct NodeCommand { http_host: String, #[arg(long, default_value = "9650", help = "Node's HTTP port", global = true)] http_port: u16, + #[arg(long, help = "Use HTTPS", global = true)] + https: bool, } #[derive(Subcommand)] @@ -35,10 +37,15 @@ enum NodeSubcommands { } // Create a new node and update its info -fn create_and_update_info(http_host: &str, http_port: u16) -> Result { +fn create_and_update_info( + http_host: &str, + http_port: u16, + https_enabled: bool, +) -> Result { let mut node = AvalancheNode { http_host: http_host.to_string(), http_port, + https_enabled, ..Default::default() }; @@ -48,8 +55,8 @@ fn create_and_update_info(http_host: &str, http_port: u16) -> Result Result<(), CliError> { - let node = create_and_update_info(http_host, http_port)?; +fn info(http_host: &str, http_port: u16, https_enabled: bool, json: bool) -> Result<(), CliError> { + let node = create_and_update_info(http_host, http_port, https_enabled)?; if json { println!("{}", serde_json::to_string(&node).unwrap()); @@ -64,12 +71,14 @@ fn info(http_host: &str, http_port: u16, json: bool) -> Result<(), CliError> { fn is_bootstrapped( http_host: &str, http_port: u16, + https_enabled: bool, chain: &str, json: bool, ) -> Result<(), CliError> { let node = AvalancheNode { http_host: http_host.to_string(), http_port, + https_enabled, ..Default::default() }; @@ -93,9 +102,9 @@ fn is_bootstrapped( // Parse node subcommand pub(crate) fn parse(node: NodeCommand, json: bool) -> Result<(), CliError> { match node.command { - NodeSubcommands::Info => info(&node.http_host, node.http_port, json), + NodeSubcommands::Info => info(&node.http_host, node.http_port, node.https, json), NodeSubcommands::IsBootstrapped { chain } => { - is_bootstrapped(&node.http_host, node.http_port, &chain, json) + is_bootstrapped(&node.http_host, node.http_port, node.https, &chain, json) } } } diff --git a/crates/ash_sdk/src/avalanche/nodes.rs b/crates/ash_sdk/src/avalanche/nodes.rs index e8a130c..1f2d88e 100644 --- a/crates/ash_sdk/src/avalanche/nodes.rs +++ b/crates/ash_sdk/src/avalanche/nodes.rs @@ -19,6 +19,7 @@ pub struct AvalancheNode { pub network: String, pub http_host: String, pub http_port: u16, + pub https_enabled: bool, pub public_ip: IpAddr, pub staking_port: u16, pub versions: AvalancheNodeVersions, @@ -31,6 +32,7 @@ impl Default for AvalancheNode { id: Id::default(), http_host: String::from("127.0.0.1"), http_port: 9650, + https_enabled: false, public_ip: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), staking_port: 9651, versions: AvalancheNodeVersions::default(), @@ -41,15 +43,26 @@ impl Default for AvalancheNode { } impl AvalancheNode { + /// Get the node HTTP endpoint URL + /// This endpoint is used to call the node's JSON RPC APIs + pub fn get_http_endpoint(&self) -> String { + format!( + "{api_scheme}://{http_host}:{http_port}", + api_scheme = if self.https_enabled { "https" } else { "http" }, + http_host = self.http_host, + http_port = self.http_port + ) + } + /// Update the node's information pub fn update_info(&mut self) -> Result<(), AshError> { - let node_host = format!("{}:{}", self.http_host, self.http_port); - let api_path = format!("http://{node_host}/{AVAX_INFO_API_ENDPOINT}",); + let http_endpoint = self.get_http_endpoint(); + let api_path = format!("{}/{}", http_endpoint, AVAX_INFO_API_ENDPOINT); self.id = get_node_id(&api_path).map_err(|e| RpcError::GetFailure { data_type: "ID".to_string(), target_type: "node".to_string(), - target_value: node_host.to_string(), + target_value: http_endpoint.clone(), msg: e.to_string(), })?; @@ -57,7 +70,7 @@ impl AvalancheNode { let node_ip = get_node_ip(&api_path).map_err(|e| RpcError::GetFailure { data_type: "node IP".to_string(), target_type: "node".to_string(), - target_value: node_host.to_string(), + target_value: http_endpoint.clone(), msg: e.to_string(), })?; self.public_ip = node_ip.ip(); @@ -66,14 +79,14 @@ impl AvalancheNode { self.versions = get_node_version(&api_path).map_err(|e| RpcError::GetFailure { data_type: "version".to_string(), target_type: "node".to_string(), - target_value: node_host.to_string(), + target_value: http_endpoint.clone(), msg: e.to_string(), })?; self.network = get_network_name(&api_path).map_err(|e| RpcError::GetFailure { data_type: "network".to_string(), target_type: "node".to_string(), - target_value: node_host.to_string(), + target_value: http_endpoint.clone(), msg: e.to_string(), })?; @@ -94,7 +107,7 @@ impl AvalancheNode { return Err(AshError::RpcError(RpcError::GetFailure { data_type: "uptime".to_string(), target_type: "node".to_string(), - target_value: node_host, + target_value: http_endpoint, msg: format!( "{:?}", RpcError::ResponseError { @@ -110,7 +123,7 @@ impl AvalancheNode { return Err(AshError::RpcError(RpcError::GetFailure { data_type: "uptime".to_string(), target_type: "node".to_string(), - target_value: node_host, + target_value: http_endpoint, msg: e.to_string(), })); } @@ -122,14 +135,14 @@ impl AvalancheNode { /// Check whether a given chain is done bootstrapping pub fn check_chain_bootstrapping(&self, chain: &str) -> Result { - let node_host = format!("{}:{}", self.http_host, self.http_port); - let api_path = format!("http://{node_host}/{AVAX_INFO_API_ENDPOINT}",); + let http_endpoint = self.get_http_endpoint(); + let api_path = format!("{}/{}", http_endpoint, AVAX_INFO_API_ENDPOINT); let is_bootstrapped = is_bootstrapped(&api_path, chain).map_err(|e| RpcError::GetFailure { data_type: format!("{} chain bootstrapping", chain), target_type: "node".to_string(), - target_value: node_host.to_string(), + target_value: http_endpoint.clone(), msg: e.to_string(), })?;