Skip to content

Commit

Permalink
feat: add Subnet type (#43)
Browse files Browse the repository at this point in the history
  • Loading branch information
Nuttymoon authored May 15, 2023
2 parents 2657c59 + 5577a58 commit dee11ee
Show file tree
Hide file tree
Showing 15 changed files with 275 additions and 201 deletions.
215 changes: 79 additions & 136 deletions Cargo.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions crates/ash_cli/src/avalanche/network.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ fn list(config: Option<&str>, json: bool) -> Result<(), CliError> {
for network in networks {
println!(" - '{}'", type_colorize(&network.name));
}

Ok(())
}

Expand Down
19 changes: 14 additions & 5 deletions crates/ash_cli/src/avalanche/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand All @@ -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<AvalancheNode, CliError> {
fn create_and_update_info(
http_host: &str,
http_port: u16,
https_enabled: bool,
) -> Result<AvalancheNode, CliError> {
let mut node = AvalancheNode {
http_host: http_host.to_string(),
http_port,
https_enabled,
..Default::default()
};

Expand All @@ -48,8 +55,8 @@ fn create_and_update_info(http_host: &str, http_port: u16) -> Result<AvalancheNo
Ok(node)
}

fn info(http_host: &str, http_port: u16, json: bool) -> 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());
Expand All @@ -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()
};

Expand All @@ -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)
}
}
}
2 changes: 2 additions & 0 deletions crates/ash_cli/src/avalanche/subnet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(())
}

Expand All @@ -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(())
}

Expand Down
15 changes: 11 additions & 4 deletions crates/ash_cli/src/avalanche/validator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(())
}

Expand All @@ -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(())
}

Expand Down
144 changes: 102 additions & 42 deletions crates/ash_cli/src/utils/templating.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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,
Expand All @@ -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:
Expand All @@ -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
)),
);

Expand All @@ -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!(
Expand All @@ -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));
}
}
}

Expand All @@ -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,
};

Expand All @@ -196,48 +242,62 @@ 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,
}
));
} else {
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,
}
));
Expand Down
1 change: 1 addition & 0 deletions crates/ash_sdk/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Loading

0 comments on commit dee11ee

Please sign in to comment.