Skip to content

Commit

Permalink
Merge pull request #113 from movemntdev/0xmovses/system-deps
Browse files Browse the repository at this point in the history
0xmovses/system deps
  • Loading branch information
0xmovses authored Feb 20, 2024
2 parents 31a5d54 + cbc005b commit d8f6e0c
Show file tree
Hide file tree
Showing 5 changed files with 163 additions and 48 deletions.
23 changes: 3 additions & 20 deletions m1/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

44 changes: 44 additions & 0 deletions m1/simulator/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,49 @@ pub struct ReconnectCommand {
pub verbose: bool,
}

/// Add a node to the network
#[derive(Debug, Parser, Clone)]
pub struct AddNodeCommand {
/// Verbose output
#[clap(short, long, help = "Verbose output.")]
pub verbose: bool,

/// The name of the node to add
#[clap(long, help = "The name of the node to add.")]
pub name: Option<String>,
}

#[derive(Debug, Parser, Clone)]
pub struct RemoveNodeCommand {
/// Verbose output
#[clap(short, long, help = "Verbose output.")]
pub verbose: bool,

/// The name of the node to remove
#[clap(long, help = "The name of the node to remove.")]
pub name: String,
}

#[derive(Debug, Parser, Clone)]
pub struct AddValidatorCommand {
/// Verbose output
#[clap(short, long, help = "Verbose output.")]
pub verbose: bool,

/// The name of the validator to add
#[clap(long, help = "The name of the validator to add.")]
pub name: String,
}

#[derive(Debug, Parser, Clone)]
pub struct RemoveValidatorCommand {
/// Verbose output
#[clap(short, long, help = "Verbose output.")]
pub verbose: bool,

/// The name of the validator to remove
#[clap(long, help = "The name of the validator to remove.")]
pub name: String,
}

#[derive(Debug, Parser, Clone)]
Expand All @@ -94,6 +132,12 @@ pub enum SubCommands {
Start(StartCommand),
/// Adds a node to the network
AddNode(AddNodeCommand),
/// Removes a node from the network
RemoveNode(RemoveNodeCommand),
/// Adds a validator to the network
AddValidator(AddValidatorCommand),
/// Removes a validator from the network
RemoveValidator(RemoveValidatorCommand),
/// Simulates a network partition.
Partition(PartitionCommand),
/// Reconnects the validators after they have become partitioned
Expand Down
140 changes: 114 additions & 26 deletions m1/simulator/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use anyhow::{anyhow, Context, Result};
use core::time;
use serde::{Deserialize, Serialize};
use std::{
collections::HashMap,
env,
fs::{self, File},
io::{self, Write},
Expand All @@ -13,7 +14,11 @@ use std::{
};

use avalanche_network_runner_sdk::{
AddNodeRequest, BlockchainSpec, Client, GlobalConfig, StartRequest,
rpcpb::{
AddPermissionlessValidatorRequest, CustomChainInfo, PermissionlessStakerSpec,
RemoveSubnetValidatorRequest, VmidRequest, VmidResponse,
},
AddNodeRequest, BlockchainSpec, Client, GlobalConfig, RemoveNodeRequest, StartRequest,
};
use avalanche_types::{
ids::{self, Id as VmId},
Expand All @@ -25,15 +30,25 @@ use tonic::transport::Channel;

pub mod commands;

const AVALANCHEGO_VERSION: &str = "v1.10.9";
const AVALANCHEGO_VERSION: &str = "v1.10.12";
pub const LOCAL_GRPC_ENDPOINT: &str = "http://127.0.0.1:12342";
const VM_NAME: &str = "subnet";

/// The Simulator is used to run commands on the avalanche-go-network-runner.
/// It can be used across multiple threads and is thread safe.
pub struct Simulator {
/// The network runner client
pub cli: Arc<Client<Channel>>,
/// The command to run
pub command: SubCommands,
/// The path to the avalanchego binary, must be version no higher than 1.10.12
/// higher versions use a VM plugin version higher that `28`, which is used by `subnet`
pub avalanchego_path: String,
/// The path to the VM plugin
pub vm_plugin_path: String,
/// The subnet ID created by the network runner,
/// this is not the same value as the VM ID.
pub subnet_id: Option<String>,
}

impl Simulator {
Expand All @@ -44,16 +59,20 @@ impl Simulator {
command,
avalanchego_path: get_avalanchego_path()?,
vm_plugin_path: get_vm_plugin_path()?,
subnet_id: None,
})
}

pub async fn dispatch(&mut self) -> Result<()> {
match &self.command {
SubCommands::Start(cmd) => self.start_network(cmd.clone()).await?,
SubCommands::AddNode(cmd) => self.add_node(cmd.clone()).await?,
SubCommands::RemoveNode(cmd) => self.remove_node(cmd.clone()).await?,
SubCommands::AddValidator(cmd) => self.add_validator(cmd.clone()).await?,
SubCommands::RemoveValidator(cmd) => self.remove_validator(cmd.clone()).await?,
SubCommands::Partition(cmd) => self.partition_network(cmd.clone()).await?,
SubCommands::Reconnect(cmd) => self.reconnect_validators(cmd.clone()).await?,
SubCommands::Health(cmd) => self.network_health(cmd.clone()).await?,
SubCommands::AddNode(cmd) => self.add_node(cmd.clone()).await?,
}
Ok(())
}
Expand Down Expand Up @@ -149,17 +168,17 @@ impl Simulator {
blockchain_specs: vec![BlockchainSpec {
vm_name: String::from(VM_NAME),
genesis: genesis_file_path.to_string(),
// blockchain_alias : String::from("subnet"), // todo: this doesn't always work oddly enough, need to debug
//blockchain_alias : String::from("subnet"), // todo: this doesn't always work oddly enough, need to debug
..Default::default()
}],
..Default::default()
})
.await?;

log::info!(
"started avalanchego cluster with network-runner: {:?}",
resp
);


// enough time for network-runner to get ready
thread::sleep(Duration::from_secs(20));
Expand Down Expand Up @@ -242,31 +261,12 @@ impl Simulator {
}
}
log::info!("avalanchego RPC endpoints: {:?}", rpc_eps);

let resp = avalanche_sdk_info::get_network_id(&rpc_eps[0])
.await
.unwrap();
let network_id = resp.result.unwrap().network_id;
log::info!("network Id: {}", network_id);

// keep alive by sleeping for duration provided by SUBNET_TIMEOUT environment variable
// use sensible default

let val = std::env::var("SUBNET_TIMEOUT")
.unwrap_or_else(|_| "0".to_string())
.parse::<i64>()
.unwrap();

// log::info!("sleeping for {} seconds", timeout.as_secs());
// if val < 0 {
// // run forever
// loop {
// thread::sleep(Duration::from_secs(1000));
// }
// } else {
// let timeout = Duration::from_secs(val as u64);
// thread::sleep(timeout);
// }
Ok(())
}

Expand Down Expand Up @@ -302,11 +302,15 @@ impl Simulator {
}),
)
.init();
log::debug!("Running command: {:?}", cmd);
log::debug!("Running command: {:?}", cmd.clone());
let name = match cmd.name {
Some(n) => format!("node-{}", n),
None => format!("node-{}", random_manager::secure_string(5)),
};
let resp = self
.cli
.add_node(AddNodeRequest {
name: format!("node-simulator-{}", random_manager::secure_string(5)),
name,
exec_path: self.avalanchego_path.clone(),
node_config: None,
..Default::default()
Expand All @@ -315,6 +319,90 @@ impl Simulator {
log::info!("added node: {:?}", resp);
Ok(())
}

pub async fn remove_node(&self, cmd: RemoveNodeCommand) -> Result<()> {
env_logger::Builder::from_env(
env_logger::Env::default().default_filter_or(if cmd.verbose {
"debug"
} else {
"info"
}),
)
.init();
log::debug!("Running command: {:?}", cmd);
let resp = self
.cli
.remove_node(RemoveNodeRequest {
name: cmd.name,
..Default::default()
})
.await?;
log::info!("removed node: {:?}", resp);
Ok(())
}

pub async fn add_validator(&self, cmd: AddValidatorCommand) -> Result<()> {
env_logger::Builder::from_env(
env_logger::Env::default().default_filter_or(if cmd.verbose {
"debug"
} else {
"info"
}),
)
.init();

let resp = self.cli.health().await?;
let custom_chains: HashMap<String, CustomChainInfo> = resp
.cluster_info
.expect("no cluster info found")
.custom_chains
.clone();

let mut subnet_id = String::new();

// This is a bit brittle, but there is only one custom chain in the HashMap:
// the subnet. If more subets wanted to be tested on the simulator this wouldn't work.
// Create tracking issue for this. The problem is I can't get the blockchain ID as the key
// lookup for custom_chains.
for (i, chain) in custom_chains.into_iter().enumerate() {
if i == 0 {
subnet_id = chain.1.subnet_id;
}
}

let resp = self
.cli
.add_validator(AddPermissionlessValidatorRequest {
validator_spec: vec![PermissionlessStakerSpec {
subnet_id,
node_name: cmd.name,
..Default::default()
}],
})
.await?;
log::info!("added validator: {:?}", resp);
Ok(())
}

pub async fn remove_validator(&self, cmd: RemoveValidatorCommand) -> Result<()> {
env_logger::Builder::from_env(
env_logger::Env::default().default_filter_or(if cmd.verbose {
"debug"
} else {
"info"
}),
)
.init();
log::debug!("Running command: {:?}", cmd);
let resp = self
.cli
.remove_validator(RemoveSubnetValidatorRequest {
..Default::default()
})
.await?;
log::info!("removed validator: {:?}", resp);
Ok(())
}
}

#[must_use]
Expand Down
2 changes: 1 addition & 1 deletion m1/tests/e2e/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ simulator = { path = "../../simulator" }

[dev-dependencies]
avalanche-installer = "0.0.77"
avalanche-network-runner-sdk = "0.3.3" # https://crates.io/crates/avalanche-network-runner-sdk
avalanche-network-runner-sdk = { git = "https://github.com/0xmovses/avalanche-network-runner-sdk-rs", branch = "main" }
avalanche-types = { workspace = true } # https://crates.io/crates/avalanche-types
env_logger = "0.10.1"
log = "0.4.19"
Expand Down
2 changes: 1 addition & 1 deletion m1/tests/e2e/src/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use avalanche_types::{ids, jsonrpc::client::info as avalanche_sdk_info, subnet};
use simulator::{get_network_runner_grpc_endpoint, get_network_runner_enable_shutdown,
get_avalanchego_path, get_vm_plugin_path, init_m1_network};

const AVALANCHEGO_VERSION: &str = "v1.10.9";
const AVALANCHEGO_VERSION: &str = "v1.3.7";

#[tokio::test]
async fn e2e() {
Expand Down

0 comments on commit d8f6e0c

Please sign in to comment.