Skip to content

Commit

Permalink
feat: bootstrap cmd supports evm networks
Browse files Browse the repository at this point in the history
For a custom EVM network, this is very tedious, because the values from the previous network need to
be supplied as arguments, but it probably won't be used in practice for that case.
  • Loading branch information
jacderida committed Oct 31, 2024
1 parent 42d7a15 commit 08ee4b6
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 40 deletions.
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 @@ -1155,6 +1188,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 @@ -1163,6 +1201,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 @@ -1174,7 +1213,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 @@ -1237,13 +1309,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 @@ -1253,6 +1326,7 @@ async fn main() -> Result<()> {
.unwrap_or(environment_type.get_default_private_node_count()),
node_vm_count,
rewards_address,
chunk_size,
})
.await?;

Expand Down

0 comments on commit 08ee4b6

Please sign in to comment.