Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: bootstrap cmd supports evm networks #212

Merged
merged 1 commit into from
Oct 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/ansible/provisioning.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,25 +62,25 @@ impl From<BootstrapOptions> for ProvisionOptions {
ProvisionOptions {
binary_option: bootstrap_options.binary_option,
bootstrap_node_count: 0,
chunk_size: None,
chunk_size: bootstrap_options.chunk_size,
downloaders_count: 0,
env_variables: bootstrap_options.env_variables,
evm_network: bootstrap_options.evm_network,
funding_wallet_secret_key: None,
log_format: bootstrap_options.log_format,
logstash_details: None,
name: bootstrap_options.name,
nat_gateway: None,
max_archived_log_files: bootstrap_options.max_archived_log_files,
max_log_files: bootstrap_options.max_log_files,
name: bootstrap_options.name,
nat_gateway: None,
node_count: bootstrap_options.node_count,
output_inventory_dir_path: bootstrap_options.output_inventory_dir_path,
private_node_count: bootstrap_options.private_node_count,
private_node_vms: Vec::new(),
public_rpc: false,
rewards_address: bootstrap_options.rewards_address,
safe_version: None,
uploaders_count: None,
rewards_address: String::new(),
}
}
}
Expand Down
21 changes: 12 additions & 9 deletions src/bootstrap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,19 @@ use crate::{
ansible::{inventory::AnsibleInventoryType, provisioning::ProvisionOptions},
error::Result,
write_environment_details, BinaryOption, DeploymentType, EnvironmentDetails, EnvironmentType,
EvmNetwork, InfraRunOptions, LogFormat, NodeType, TestnetDeployer,
EvmCustomTestnetData, EvmNetwork, InfraRunOptions, LogFormat, NodeType, TestnetDeployer,
};
use colored::Colorize;

#[derive(Clone)]
pub struct BootstrapOptions {
pub binary_option: BinaryOption,
pub bootstrap_peer: String,
pub chunk_size: Option<u64>,
pub environment_type: EnvironmentType,
pub env_variables: Option<Vec<(String, String)>>,
pub evm_network: EvmNetwork,
pub evm_custom_testnet_data: Option<EvmCustomTestnetData>,
pub log_format: Option<LogFormat>,
pub max_archived_log_files: u16,
pub max_log_files: u16,
Expand All @@ -31,6 +33,7 @@ pub struct BootstrapOptions {
pub private_node_count: u16,
pub private_node_vm_count: Option<u16>,
pub rewards_address: String,
pub node_vm_size: Option<String>,
}

impl TestnetDeployer {
Expand All @@ -55,26 +58,26 @@ impl TestnetDeployer {
deployment_type: DeploymentType::Bootstrap,
environment_type: options.environment_type.clone(),
evm_network: options.evm_network.clone(),
evm_testnet_data: None,
evm_testnet_data: options.evm_custom_testnet_data.clone(),
funding_wallet_address: None,
rewards_address: options.rewards_address.clone(),
},
)
.await?;

self.create_or_update_infra(&InfraRunOptions {
bootstrap_node_vm_count: None,
bootstrap_node_vm_count: Some(0),
bootstrap_node_vm_size: None,
enable_build_vm: build_custom_binaries,
evm_node_count: None,
evm_node_count: Some(0),
evm_node_vm_size: None,
genesis_vm_count: None,
genesis_vm_count: Some(0),
name: options.name.clone(),
node_vm_count: options.node_vm_count,
node_vm_size: None,
node_vm_size: options.node_vm_size.clone(),
private_node_vm_count: options.private_node_vm_count,
tfvars_filename: options.environment_type.get_tfvars_filename().to_string(),
uploader_vm_count: None,
uploader_vm_count: Some(0),
uploader_vm_size: None,
})
.map_err(|err| {
Expand Down Expand Up @@ -109,7 +112,7 @@ impl TestnetDeployer {
&provision_options,
&options.bootstrap_peer,
NodeType::Normal,
None,
options.evm_custom_testnet_data.clone(),
) {
Ok(()) => {
println!("Provisioned normal nodes");
Expand Down Expand Up @@ -147,7 +150,7 @@ impl TestnetDeployer {
match self.ansible_provisioner.provision_private_nodes(
&mut provision_options,
&options.bootstrap_peer,
None,
options.evm_custom_testnet_data.clone(),
) {
Ok(()) => {
println!("Provisioned private nodes");
Expand Down
42 changes: 25 additions & 17 deletions src/inventory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,18 +185,22 @@ impl DeploymentInventoryService {
.ansible_runner
.get_inventory(AnsibleInventoryType::BootstrapNodes, false)?;

let uploader_and_sks = self.ansible_provisioner.get_uploader_secret_keys()?;
let uploader_vms = uploader_and_sks
.iter()
.map(|(vm, sks)| UploaderVirtualMachine {
vm: vm.clone(),
wallet_public_key: sks
.iter()
.enumerate()
.map(|(user, sk)| (format!("safe{}", user + 1), sk.address().encode_hex()))
.collect(),
})
.collect::<Vec<_>>();
let uploader_vms = if environment_details.deployment_type != DeploymentType::Bootstrap {
let uploader_and_sks = self.ansible_provisioner.get_uploader_secret_keys()?;
uploader_and_sks
.iter()
.map(|(vm, sks)| UploaderVirtualMachine {
vm: vm.clone(),
wallet_public_key: sks
.iter()
.enumerate()
.map(|(user, sk)| (format!("safe{}", user + 1), sk.address().encode_hex()))
.collect(),
})
.collect()
} else {
Vec::new()
};

println!("Retrieving node registries from all VMs...");
let mut failed_node_registry_vms = Vec::new();
Expand Down Expand Up @@ -273,24 +277,28 @@ impl DeploymentInventoryService {
)?
};

let safe_version = {
let safe_version = if environment_details.deployment_type != DeploymentType::Bootstrap {
let random_uploader_vm = uploader_vms
.choose(&mut rand::thread_rng())
.ok_or_else(|| eyre!("No uploader VMs available to retrieve safe version"))?;
self.get_bin_version(
Some(self.get_bin_version(
&random_uploader_vm.vm,
"autonomi --version",
"autonomi-cli ",
)?
)?)
} else {
None
};

println!("Retrieved binary versions from previous deployment:");
println!(" safenode: {}", safenode_version);
println!(" safenode-manager: {}", safenode_manager_version);
println!(" autonomi: {}", safe_version);
if let Some(version) = &safe_version {
println!(" autonomi: {}", version);
}

BinaryOption::Versioned {
safe_version: Some(safe_version),
safe_version,
safenode_version,
safenode_manager_version,
}
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -804,6 +804,7 @@ impl TestnetDeployer {
uploader_vm_count.to_string(),
));
}

args.push((
"use_custom_bin".to_string(),
options.enable_build_vm.to_string(),
Expand Down
94 changes: 84 additions & 10 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ use sn_testnet_deploy::{
network_commands, notify_slack,
setup::setup_dotenv_file,
upscale::UpscaleOptions,
BinaryOption, CloudProvider, EnvironmentType, EvmNetwork, LogFormat, TestnetDeployBuilder,
UpgradeOptions,
BinaryOption, CloudProvider, EnvironmentType, EvmCustomTestnetData, EvmNetwork, LogFormat,
TestnetDeployBuilder, UpgradeOptions,
};
use std::{env, net::IpAddr};
use std::{str::FromStr, time::Duration};
Expand Down Expand Up @@ -62,6 +62,11 @@ enum Commands {
/// The peer from an existing network that we can bootstrap from.
#[arg(long)]
bootstrap_peer: String,
/// Specify the chunk size for the custom binaries using a 64-bit integer.
///
/// This option only applies if the --branch and --repo-owner arguments are used.
#[clap(long, value_parser = parse_chunk_size)]
chunk_size: Option<u64>,
/// The type of deployment.
///
/// Possible values are 'development', 'production' or 'staging'. The value used will
Expand All @@ -80,6 +85,31 @@ enum Commands {
/// Example: --env SN_LOG=all,RUST_LOG=libp2p=debug
#[clap(name = "env", long, use_value_delimiter = true, value_parser = parse_environment_variables, verbatim_doc_comment)]
env_variables: Option<Vec<(String, String)>>,
/// The address of the data payments contract.
///
/// This argument only applies if the EVM network type is 'custom'.
#[arg(long)]
evm_data_payments_address: Option<String>,
/// The private key of the wallet that deployed the contracts.
///
/// This argument only applies if the EVM network type is 'custom'.
#[arg(long)]
evm_deployer_wallet_private_key: Option<String>,
/// The EVM network to use.
///
/// Valid values are "arbitrum-one", "arbitrum-sepolia", or "custom".
#[clap(long, default_value_t = EvmNetwork::ArbitrumOne, value_parser = parse_evm_network)]
evm_network_type: EvmNetwork,
/// The address of the payment token contract.
///
/// This argument only applies if the EVM network type is 'custom'.
#[arg(long)]
evm_payment_token_address: Option<String>,
/// The RPC URL for the EVM network.
///
/// This argument only applies if the EVM network type is 'custom'.
#[arg(long)]
evm_rpc_url: Option<String>,
/// Override the maximum number of forks Ansible will use to execute tasks on target hosts.
///
/// The default value from ansible.cfg is 50.
Expand All @@ -106,6 +136,12 @@ enum Commands {
/// If the argument is not used, the default format will be applied.
#[clap(long, value_parser = LogFormat::parse_from_str, verbatim_doc_comment)]
log_format: Option<LogFormat>,
/// The maximum of archived log files to keep. After reaching this limit, the older files are deleted.
#[clap(long, default_value = "5")]
max_archived_log_files: u16,
/// The maximum number of log files to keep. After reaching this limit, the older files are archived.
#[clap(long, default_value = "10")]
max_log_files: u16,
/// The name of the environment
#[arg(short = 'n', long)]
name: String,
Expand All @@ -130,12 +166,9 @@ enum Commands {
/// argument.
#[clap(long)]
node_vm_count: Option<u16>,
/// The maximum of archived log files to keep. After reaching this limit, the older files are deleted.
#[clap(long, default_value = "5")]
max_archived_log_files: u16,
/// The maximum number of log files to keep. After reaching this limit, the older files are archived.
#[clap(long, default_value = "10")]
max_log_files: u16,
/// Override the size of the node VMs.
#[clap(long)]
node_vm_size: Option<String>,
/// Optionally set the payment forward public key for a custom safenode binary.
///
/// This argument only applies if the '--branch' and '--repo-owner' arguments are used.
Expand Down Expand Up @@ -1151,6 +1184,11 @@ async fn main() -> Result<()> {
branch,
environment_type,
env_variables,
evm_data_payments_address,
evm_deployer_wallet_private_key,
evm_network_type,
evm_payment_token_address,
evm_rpc_url,
forks,
foundation_pk,
genesis_pk,
Expand All @@ -1159,6 +1197,7 @@ async fn main() -> Result<()> {
network_royalties_pk,
node_count,
node_vm_count,
node_vm_size,
max_archived_log_files,
max_log_files,
payment_forward_pk,
Expand All @@ -1170,7 +1209,40 @@ async fn main() -> Result<()> {
safenode_features,
safenode_version,
safenode_manager_version,
chunk_size,
} => {
let evm_custom_testnet_data = match evm_network_type {
EvmNetwork::Custom => {
if evm_data_payments_address.is_none()
|| evm_payment_token_address.is_none()
|| evm_rpc_url.is_none()
{
return Err(eyre!(
"When using a custom EVM network, you must supply evm-data-payments-address, evm-payment-token-address, and evm-rpc-url"
));
}
Some(EvmCustomTestnetData {
data_payments_address: evm_data_payments_address.unwrap(),
deployer_wallet_private_key: evm_deployer_wallet_private_key
.unwrap_or_default(),
payment_token_address: evm_payment_token_address.unwrap(),
rpc_url: evm_rpc_url.unwrap(),
})
}
_ => {
if evm_data_payments_address.is_some()
|| evm_payment_token_address.is_some()
|| evm_rpc_url.is_some()
|| evm_deployer_wallet_private_key.is_some()
{
return Err(eyre!(
"EVM custom network parameters can only be used with evm-network-type=custom"
));
}
None
}
};

let network_keys = validate_and_get_pks(
foundation_pk,
genesis_pk,
Expand Down Expand Up @@ -1233,13 +1305,14 @@ async fn main() -> Result<()> {
bootstrap_peer,
environment_type: environment_type.clone(),
env_variables,
// TODO: Should come from the previous deployment.
evm_network: EvmNetwork::ArbitrumOne,
evm_network: evm_network_type,
evm_custom_testnet_data,
log_format,
name: name.clone(),
node_count: node_count.unwrap_or(environment_type.get_default_node_count()),
max_archived_log_files,
max_log_files,
node_vm_size,
output_inventory_dir_path: inventory_service
.working_directory_path
.join("ansible")
Expand All @@ -1249,6 +1322,7 @@ async fn main() -> Result<()> {
.unwrap_or(environment_type.get_default_private_node_count()),
node_vm_count,
rewards_address,
chunk_size,
})
.await?;

Expand Down
Loading