Skip to content

Commit

Permalink
feat: Avalanche Warp Navigator (#61)
Browse files Browse the repository at this point in the history
  • Loading branch information
Nuttymoon authored Sep 13, 2023
2 parents 5c3b143 + 8cc955b commit 3491ea5
Show file tree
Hide file tree
Showing 26 changed files with 2,051 additions and 1,415 deletions.
2,045 changes: 700 additions & 1,345 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
members = ["crates/ash_cli", "crates/ash_sdk"]

[workspace.package]
version = "0.2.4"
version = "0.3.0-alpha"
edition = "2021"
authors = ["E36 Knots"]
homepage = "https://ash.center"
Expand Down
2 changes: 1 addition & 1 deletion crates/ash_cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ categories.workspace = true
keywords.workspace = true

[dependencies]
ash_sdk = { path = "../ash_sdk", version = "0.2.4" }
ash_sdk = { path = "../ash_sdk", version = "0.3.0-alpha" }
clap = { version = "4.0.32", features = ["derive", "env", "cargo", "string"] }
colored = "2.0.0"
exitcode = "1.1.2"
Expand Down
5 changes: 4 additions & 1 deletion crates/ash_cli/src/avalanche.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ mod subnet;
mod validator;
mod vm;
mod wallet;
mod warp;
mod x;

// Module that contains the avalanche subcommand parser
Expand All @@ -33,6 +34,7 @@ enum AvalancheSubcommands {
Validator(validator::ValidatorCommand),
Vm(vm::VmCommand),
Wallet(wallet::WalletCommand),
Warp(warp::WarpCommand),
X(x::XCommand),
}

Expand Down Expand Up @@ -89,7 +91,8 @@ pub(crate) fn parse(
AvalancheSubcommands::Subnet(subnet) => subnet::parse(subnet, config, json),
AvalancheSubcommands::Validator(validator) => validator::parse(validator, config, json),
AvalancheSubcommands::Vm(vm) => vm::parse(vm, json),
AvalancheSubcommands::X(x) => x::parse(x, config, json),
AvalancheSubcommands::Wallet(wallet) => wallet::parse(wallet, config, json),
AvalancheSubcommands::Warp(warp) => warp::parse(warp, config, json),
AvalancheSubcommands::X(x) => x::parse(x, config, json),
}
}
2 changes: 1 addition & 1 deletion crates/ash_cli/src/avalanche/subnet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ fn list(network_name: &str, config: Option<&str>, json: bool) -> Result<(), CliE
}

println!(
"Found {} Subnet(s) on network '{}':",
"Found {} Subnets on network '{}':",
type_colorize(&network.subnets.len()),
type_colorize(&network.name)
);
Expand Down
4 changes: 2 additions & 2 deletions crates/ash_cli/src/avalanche/validator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ fn list(
.map_err(|e| CliError::dataerr(format!("Error listing validators: {e}")))?;
validators = subnet.pending_validators.clone();
format!(
"Found {} pending validator(s) on Subnet '{}':",
"Found {} pending validators on Subnet '{}':",
type_colorize(&subnet.pending_validators.len()),
type_colorize(&subnet_id)
)
Expand All @@ -117,7 +117,7 @@ fn list(
.map_err(|e| CliError::dataerr(format!("Error listing validators: {e}")))?;
validators = subnet.validators.clone();
format!(
"Found {} validator(s) on Subnet '{}':",
"Found {} validators on Subnet '{}':",
type_colorize(&subnet.validators.len()),
type_colorize(&subnet_id)
)
Expand Down
7 changes: 6 additions & 1 deletion crates/ash_cli/src/avalanche/wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,12 @@ enum WalletSubcommands {
#[arg(env = "AVALANCHE_PRIVATE_KEY")]
private_key: String,
/// Private key format
#[arg(long, short = 'e', default_value = "cb58")]
#[arg(
long,
short = 'e',
default_value = "cb58",
env = "AVALANCHE_KEY_ENCODING"
)]
key_encoding: PrivateKeyEncoding,
},
/// Randomly generate a private key (giving access to a wallet)
Expand Down
138 changes: 138 additions & 0 deletions crates/ash_cli/src/avalanche/warp.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
// SPDX-License-Identifier: BSD-3-Clause
// Copyright (c) 2023, E36 Knots

// Module that contains the vm subcommand parser

use crate::{
avalanche::*,
utils::{error::CliError, parsing::*, templating::*},
};
use async_std::task;
use clap::{Parser, Subcommand};
use colored::Colorize;

/// Interact with Avalanche Warp Messaging
#[derive(Parser)]
#[command()]
pub(crate) struct WarpCommand {
#[command(subcommand)]
command: WarpSubcommands,
/// Avalanche network
#[arg(
long,
short = 'n',
default_value = "fuji",
global = true,
env = "AVALANCHE_NETWORK"
)]
network: String,
}

#[derive(Subcommand)]
enum WarpSubcommands {
/// Navigate the Warp: monitor Avalanche Warp Messages sent between chains
#[command()]
Navigate {
/// Source chain ID or name
source_chain: String,
/// Block from which to start monitoring
#[arg(long, short = 'f', default_value = "earliest")]
from_block: String,
/// Block at which to stop monitoring
#[arg(long, short = 't', default_value = "latest")]
to_block: String,
/// Show extended information (notably signatures)
/// This option is only available in non-JSON mode
#[arg(long, short = 'e')]
extended: bool,
},
}

fn navigate(
network_name: &str,
source_chain: &str,
from_block: &str,
to_block: &str,
extended: bool,
config: Option<&str>,
json: bool,
) -> Result<(), CliError> {
// Display warning about the experimental nature of this feature
eprintln!(
"{}",
"Warning: this feature is experimental and may break at any time."
.yellow()
.bold()
);

let mut network = load_network(network_name, config)?;
update_network_subnets(&mut network)?;

// Try loading the blockchain by its ID or by its name depending on whether source_chain is an ID
let blockchain_id = parse_id(source_chain);
let blockchain = match blockchain_id {
Ok(id) => network
.get_blockchain(id)
.map_err(|e| CliError::dataerr(format!("Error loading blockchain info: {e}")))?,
Err(_) => network
.get_blockchain_by_name(source_chain)
.map_err(|e| CliError::dataerr(format!("Error loading blockchain info: {e}")))?,
}
.clone();
update_subnet_validators(&mut network, &blockchain.subnet_id.to_string())?;

let subnet = network
.get_subnet(blockchain.subnet_id)
.map_err(|e| CliError::dataerr(format!("Error loading subnet info: {e}")))?;

let warp_messages =
task::block_on(async { blockchain.get_warp_messages(from_block, to_block).await })
.map_err(|e| CliError::dataerr(format!("Error reading warp messages: {e}")))?
.iter()
.map(|warp_message| {
let mut signed_warp_message = warp_message.clone();
let signatures = subnet
.get_warp_message_node_signatures(warp_message, None)
.unwrap_or(vec![]);
for sig in signatures {
signed_warp_message.add_node_signature(sig);
}
signed_warp_message
})
.collect::<Vec<_>>();

if json {
println!("{}", serde_json::to_string(&warp_messages).unwrap());
return Ok(());
}

println!("Found {} Warp messages:", warp_messages.len());
for warp_message in warp_messages {
println!(
"{}",
template_warp_message(&warp_message, &blockchain, extended, true, 0)
);
}

Ok(())
}

// Parse warp subcommand
pub(crate) fn parse(warp: WarpCommand, config: Option<&str>, json: bool) -> Result<(), CliError> {
match warp.command {
WarpSubcommands::Navigate {
source_chain,
from_block,
to_block,
extended,
} => navigate(
&warp.network,
&source_chain,
&from_block,
&to_block,
extended,
config,
json,
),
}
}
Loading

0 comments on commit 3491ea5

Please sign in to comment.