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(cli)!: make committee size configurable in iota start #5162

Merged
merged 12 commits into from
Feb 6, 2025
49 changes: 32 additions & 17 deletions crates/iota/src/iota_commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use std::{

use anyhow::{anyhow, bail, ensure};
use clap::*;
use colored::Colorize;
use fastcrypto::traits::KeyPair;
use iota_bridge::{
config::BridgeCommitteeConfig, iota_client::IotaBridgeClient,
Expand Down Expand Up @@ -170,7 +171,6 @@ pub enum IotaCommand {
/// dir that is generated by the `iota genesis`.
#[arg(long = "network.config")]
config_dir: Option<std::path::PathBuf>,

/// A new genesis is created each time this flag is set, and state is
/// not persisted between runs. Only use this flag when you want
/// to start the network from scratch every time you
Expand All @@ -181,7 +181,6 @@ pub enum IotaCommand {
/// start the network with.
#[arg(long)]
force_regenesis: bool,

/// Start a faucet with default host and port: 0.0.0.0:9123. This flag
/// accepts also a port, a host, or both (e.g., 0.0.0.0:9123).
/// When providing a specific value, please use the = sign between the
Expand All @@ -195,40 +194,39 @@ pub enum IotaCommand {
value_name = "FAUCET_HOST_PORT",
)]
with_faucet: Option<String>,

/// Set the amount of nanos that the faucet will put in an object.
/// Defaults to `200000000000`(200 IOTA).
#[arg(long)]
faucet_amount: Option<u64>,

#[cfg(feature = "indexer")]
#[command(flatten)]
indexer_feature_args: IndexerFeatureArgs,

/// Port to start the Fullnode RPC server on. Default port is 9000.
#[arg(long, default_value = "9000")]
fullnode_rpc_port: u16,

/// Set the epoch duration. Can only be used when `--force-regenesis`
/// flag is passed or if there's no genesis config and one will
/// be auto-generated. When this flag is not set but
/// `--force-regenesis` is set, the epoch duration will be set to 60
/// seconds.
#[arg(long)]
epoch_duration_ms: Option<u64>,

/// Make the fullnode dump executed checkpoints as files to this
/// directory. This is incompatible with --no-full-node.
///
/// If --with-indexer is set, this defaults to a temporary directory.
#[cfg(feature = "indexer")]
#[arg(long, value_name = "DATA_INGESTION_DIR")]
data_ingestion_dir: Option<PathBuf>,

/// Start the network without a fullnode
#[arg(long = "no-full-node")]
no_full_node: bool,

/// Set the number of validators in the network.
/// If a genesis was already generated with a specific number of
/// validators, this will not override it; the user should recreate the
/// genesis with the desired number of validators.
#[arg(long, help = "The number of validators in the network.")]
committee_size: Option<usize>,
/// The path to local migration snapshot files
#[arg(long, name = "path", num_args(0..))]
local_migration_snapshots: Vec<PathBuf>,
Expand Down Expand Up @@ -267,12 +265,13 @@ pub enum IotaCommand {
help = "Creates an extra faucet configuration for iota persisted runs."
)]
with_faucet: bool,
/// Set number of validators in the network.
#[arg(
long,
help = "The number of validators in the network.",
default_value_t = DEFAULT_NUMBER_OF_AUTHORITIES
)]
num_validators: usize,
committee_size: usize,
/// The path to local migration snapshot files
#[arg(long, name = "path", num_args(0..))]
local_migration_snapshots: Vec<PathBuf>,
Expand Down Expand Up @@ -391,6 +390,7 @@ impl IotaCommand {
#[cfg(feature = "indexer")]
data_ingestion_dir,
no_full_node,
committee_size,
epoch_duration_ms,
local_migration_snapshots,
remote_migration_snapshots,
Expand All @@ -408,6 +408,7 @@ impl IotaCommand {
#[cfg(feature = "indexer")]
data_ingestion_dir,
no_full_node,
committee_size,
local_migration_snapshots,
remote_migration_snapshots,
delegator,
Expand All @@ -424,7 +425,7 @@ impl IotaCommand {
epoch_duration_ms,
benchmark_ips,
with_faucet,
num_validators,
committee_size,
local_migration_snapshots: with_local_migration_snapshot,
remote_migration_snapshots: with_remote_migration_snapshot,
delegator,
Expand All @@ -437,7 +438,7 @@ impl IotaCommand {
epoch_duration_ms,
benchmark_ips,
with_faucet,
num_validators,
committee_size,
with_local_migration_snapshot,
with_remote_migration_snapshot,
delegator,
Expand Down Expand Up @@ -635,6 +636,7 @@ async fn start(
fullnode_rpc_port: u16,
#[cfg(feature = "indexer")] mut data_ingestion_dir: Option<PathBuf>,
no_full_node: bool,
committee_size: Option<usize>,
local_migration_snapshots: Vec<PathBuf>,
remote_migration_snapshots: Vec<SnapshotUrl>,
delegator: Option<IotaAddress>,
Expand Down Expand Up @@ -687,8 +689,11 @@ async fn start(
// If this is set, then no data will be persisted between runs, and a new
// genesis will be generated each run.
if force_regenesis {
swarm_builder =
swarm_builder.committee_size(NonZeroUsize::new(DEFAULT_NUMBER_OF_AUTHORITIES).unwrap());
let committee_size =
NonZeroUsize::new(committee_size.unwrap_or(DEFAULT_NUMBER_OF_AUTHORITIES))
.ok_or_else(|| anyhow!("Committee size must be at least 1."))?;

swarm_builder = swarm_builder.committee_size(committee_size);
let mut genesis_config = GenesisConfig::custom_genesis(1, 100);
let local_snapshots = local_migration_snapshots
.into_iter()
Expand Down Expand Up @@ -722,12 +727,22 @@ async fn start(
epoch_duration_ms,
None,
false,
DEFAULT_NUMBER_OF_AUTHORITIES,
committee_size.unwrap_or(DEFAULT_NUMBER_OF_AUTHORITIES),
local_migration_snapshots,
remote_migration_snapshots,
delegator,
)
.await?;
} else if committee_size.is_some() {
eprintln!(
"{}",
"[warning] The committee-size arg will be ignored as a network configuration \
already exists. To change the committee size, you'll have to adjust the \
network configuration file or regenerate a genesis with the desired \
committee size. See `iota genesis --help` for more information."
.yellow()
.bold()
);
}

let NetworkConfigLight {
Expand Down Expand Up @@ -928,7 +943,7 @@ async fn genesis(
epoch_duration_ms: Option<u64>,
benchmark_ips: Option<Vec<String>>,
with_faucet: bool,
num_validators: usize,
committee_size: usize,
local_migration_snapshots: Vec<PathBuf>,
remote_migration_snapshots: Vec<SnapshotUrl>,
delegator: Option<IotaAddress>,
Expand Down Expand Up @@ -1067,7 +1082,7 @@ async fn genesis(
builder = if let Some(validators) = validator_info {
builder.with_validators(validators)
} else {
builder.committee_size(NonZeroUsize::new(num_validators).unwrap())
builder.committee_size(NonZeroUsize::new(committee_size).unwrap())
};
let network_config = tokio::task::spawn_blocking(move || builder.build()).await?;
let mut keystore = FileBasedKeystore::new(&keystore_path)?;
Expand Down
5 changes: 3 additions & 2 deletions crates/iota/tests/cli_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ async fn test_genesis() -> Result<(), anyhow::Error> {
epoch_duration_ms: None,
benchmark_ips: None,
with_faucet: false,
num_validators: DEFAULT_NUMBER_OF_AUTHORITIES,
committee_size: DEFAULT_NUMBER_OF_AUTHORITIES,
local_migration_snapshots: vec![],
remote_migration_snapshots: vec![],
delegator: None,
Expand Down Expand Up @@ -131,7 +131,7 @@ async fn test_genesis() -> Result<(), anyhow::Error> {
epoch_duration_ms: None,
benchmark_ips: None,
with_faucet: false,
num_validators: DEFAULT_NUMBER_OF_AUTHORITIES,
committee_size: DEFAULT_NUMBER_OF_AUTHORITIES,
local_migration_snapshots: vec![],
remote_migration_snapshots: vec![],
delegator: None,
Expand Down Expand Up @@ -160,6 +160,7 @@ async fn test_start() -> Result<(), anyhow::Error> {
with_faucet: None,
faucet_amount: None,
fullnode_rpc_port: 9000,
committee_size: None,
epoch_duration_ms: None,
#[cfg(feature = "indexer")]
indexer_feature_args: IndexerFeatureArgs::for_testing(),
Expand Down
Loading