Skip to content
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
49 changes: 47 additions & 2 deletions src/dfx/src/commands/replica.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::commands::canister::create_waiter;
use crate::lib::environment::Environment;
use crate::lib::error::{DfxError, DfxResult};
use crate::lib::message::UserMessage;
use crate::lib::replica_config::ReplicaConfig;
use crate::lib::replica_config::{ReplicaConfig, SchedulerConfig};

use clap::{App, Arg, ArgMatches, SubCommand};
use crossbeam::channel::{Receiver, Sender};
Expand Down Expand Up @@ -32,6 +32,20 @@ pub fn construct() -> App<'static, 'static> {
.map(|_| ())
}),
)
.arg(
Arg::with_name("message-gas-max")
.help(UserMessage::ReplicaMessageGasMax.to_str())
.long("message-gas-max")
.takes_value(true)
.default_value("5368709120"),
)
.arg(
Arg::with_name("round-gas-max")
.help(UserMessage::ReplicaRoundGasMax.to_str())
.long("round-gas-max")
.takes_value(true)
.default_value("26843545600"),
)
}

fn ping_and_wait(frontend_url: &str) -> DfxResult {
Expand All @@ -47,6 +61,32 @@ fn ping_and_wait(frontend_url: &str) -> DfxResult {
.map_err(DfxError::from)
}

fn get_scheduler(args: &ArgMatches<'_>) -> DfxResult<SchedulerConfig> {
// Get mssage gas limit.
let message_gas_max = args
.value_of("message-gas-max")
.expect("default value")
.parse()
.map_err(|err| DfxError::InvalidArgument(format!("Invalid message gas limit: {}", err)))?;
// Get round gas limit.
let round_gas_max = args
.value_of("round-gas-max")
.expect("default value")
.parse()
.map_err(|err| DfxError::InvalidArgument(format!("Invalid round gas limit: {}", err)))?;
// Check message and round gas limits.
if message_gas_max >= round_gas_max {
let err = "Round gas limit must exceed message gas limit.".to_string();
Err(DfxError::InvalidArgument(err))
} else {
// Return scheduler configuration.
Ok(SchedulerConfig {
exec_gas: Some(message_gas_max),
round_gas_max: Some(round_gas_max),
})
}
}

// TODO(eftychis)/In progress: Rename to replica.
/// Start the Internet Computer locally. Spawns a proxy to forward and
/// manage browser requests. Responsible for running the network (one
Expand All @@ -63,6 +103,8 @@ pub fn exec(env: &dyn Environment, args: &ArgMatches<'_>) -> DfxResult {
.parse::<u16>()
.expect("Unreachable. Port should have been validated by clap.");

let scheduler = get_scheduler(args)?;

// We are doing this here to make sure we can write to the temp
// pid file.
std::fs::write(&pid_file_path, "")?;
Expand All @@ -79,7 +121,10 @@ pub fn exec(env: &dyn Environment, args: &ArgMatches<'_>) -> DfxResult {
let (_broadcast_stop, is_killed_replica) = unbounded();

b.set_message("Generating IC local replica configuration.");
let replica_config = ReplicaConfig::new(&state_root).with_port(port).to_toml()?;
let replica_config = ReplicaConfig::new(&state_root)
.with_port(port)
.with_scheduler(scheduler)
.to_toml()?;

// TODO(eftychis): we need a proper manager type when we start
// spawning multiple replica processes and registry.
Expand Down
2 changes: 2 additions & 0 deletions src/dfx/src/lib/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,9 @@ user_message!(

// dfx replica
Replica => "Start a local replica.",
ReplicaMessageGasMax => "Maximum amount of gas a single message can consume.",
ReplicaPort => "The port the local replica should listen to.",
ReplicaRoundGasMax => "Maximum amount of gas a single round can consume.",

// dfx start
CleanState => "Cleans state of current project.",
Expand Down
24 changes: 20 additions & 4 deletions src/dfx/src/lib/replica_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,27 +15,38 @@ pub struct HttpHandlerConfig {
pub write_port_to: Option<PathBuf>,
}

#[derive(Debug, Serialize)]
pub struct SchedulerConfig {
pub exec_gas: Option<u64>,
pub round_gas_max: Option<u64>,
}

#[derive(Debug, Serialize)]
pub struct StateManagerConfig {
pub state_root: PathBuf,
}

#[derive(Debug, Serialize)]
pub struct ReplicaConfig {
pub state_manager: StateManagerConfig,
pub http_handler: HttpHandlerConfig,
pub scheduler: SchedulerConfig,
pub state_manager: StateManagerConfig,
}

impl ReplicaConfig {
pub fn new(state_root: &Path) -> Self {
ReplicaConfig {
state_manager: StateManagerConfig {
state_root: state_root.to_path_buf(),
},
http_handler: HttpHandlerConfig {
write_port_to: None,
use_port: None,
},
scheduler: SchedulerConfig {
exec_gas: None,
round_gas_max: None,
},
state_manager: StateManagerConfig {
state_root: state_root.to_path_buf(),
},
}
}

Expand All @@ -51,6 +62,11 @@ impl ReplicaConfig {
self
}

pub fn with_scheduler(&mut self, scheduler: SchedulerConfig) -> &mut Self {
self.scheduler = scheduler;
self
}

pub fn to_toml(&self) -> DfxResult<String> {
toml::to_string(&self).map_err(DfxError::CouldNotSerializeClientConfiguration)
}
Expand Down