Skip to content
Closed
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
9 changes: 7 additions & 2 deletions lcli/src/block_root.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,19 @@ use clap::ArgMatches;
use clap_utils::{parse_optional, parse_required};
use environment::Environment;
use eth2::{types::BlockId, BeaconNodeHttpClient, SensitiveUrl, Timeouts};
use eth2_network_config::Eth2NetworkConfig;
use std::path::PathBuf;
use std::time::{Duration, Instant};
use types::{EthSpec, FullPayload, SignedBeaconBlock};

const HTTP_TIMEOUT: Duration = Duration::from_secs(5);

pub fn run<T: EthSpec>(env: Environment<T>, matches: &ArgMatches) -> Result<(), String> {
let spec = &T::default_spec();
pub fn run<T: EthSpec>(
env: Environment<T>,
network_config: Eth2NetworkConfig,
matches: &ArgMatches,
) -> Result<(), String> {
let spec = &network_config.chain_spec::<T>()?;
let executor = env.core_context().executor;

/*
Expand Down
136 changes: 114 additions & 22 deletions lcli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@ mod new_testnet;
mod parse_ssz;
mod replace_state_pubkeys;
mod skip_slots;
mod state_root;
mod transition_blocks;

use clap::{App, Arg, ArgMatches, SubCommand};
use clap_utils::parse_path_with_default_in_home_dir;
use clap_utils::parse_optional;
use environment::{EnvironmentBuilder, LoggerConfig};
use eth2_network_config::Eth2NetworkConfig;
use parse_ssz::run_parse_ssz;
use std::path::PathBuf;
use std::process;
Expand Down Expand Up @@ -50,7 +52,16 @@ fn main() {
.value_name("PATH")
.takes_value(true)
.global(true)
.help("The testnet dir. Defaults to ~/.lighthouse/testnet"),
.help("The testnet dir."),
)
.arg(
Arg::with_name("network")
.long("network")
.value_name("NAME")
.takes_value(true)
.global(true)
.help("The network to use. Defaults to mainnet.")
.conflicts_with("testnet-dir")
)
.subcommand(
SubCommand::with_name("skip-slots")
Expand Down Expand Up @@ -126,7 +137,7 @@ fn main() {
.takes_value(true)
.conflicts_with("beacon-url")
.requires("block-path")
.help("Path to load a BeaconState from file as SSZ."),
.help("Path to load a BeaconState from as SSZ."),
)
.arg(
Arg::with_name("block-path")
Expand All @@ -135,7 +146,7 @@ fn main() {
.takes_value(true)
.conflicts_with("beacon-url")
.requires("pre-state-path")
.help("Path to load a SignedBeaconBlock from file as SSZ."),
.help("Path to load a SignedBeaconBlock from as SSZ."),
)
.arg(
Arg::with_name("post-state-output-path")
Expand Down Expand Up @@ -808,14 +819,14 @@ fn main() {
)
.subcommand(
SubCommand::with_name("block-root")
.about("Computes the block root of some block")
.about("Computes the block root of some block.")
.arg(
Arg::with_name("block-path")
.long("block-path")
.value_name("PATH")
.takes_value(true)
.conflicts_with("beacon-url")
.help("Path to load a SignedBeaconBlock from file as SSZ."),
.help("Path to load a SignedBeaconBlock from as SSZ."),
)
.arg(
Arg::with_name("beacon-url")
Expand All @@ -841,6 +852,41 @@ fn main() {
.help("Number of repeat runs, useful for benchmarking."),
)
)
.subcommand(
SubCommand::with_name("state-root")
.about("Computes the state root of some state.")
.arg(
Arg::with_name("state-path")
.long("state-path")
.value_name("PATH")
.takes_value(true)
.conflicts_with("beacon-url")
.help("Path to load a BeaconState from as SSZ."),
)
.arg(
Arg::with_name("beacon-url")
.long("beacon-url")
.value_name("URL")
.takes_value(true)
.help("URL to a beacon-API provider."),
)
.arg(
Arg::with_name("state-id")
.long("state-id")
.value_name("BLOCK_ID")
.takes_value(true)
.requires("beacon-url")
.help("Identifier for a state as per beacon-API standards (slot, root, etc.)"),
)
.arg(
Arg::with_name("runs")
.long("runs")
.value_name("INTEGER")
.takes_value(true)
.default_value("1")
.help("Number of repeat runs, useful for benchmarking."),
)
)
.get_matches();

let result = matches
Expand Down Expand Up @@ -887,17 +933,44 @@ fn run<T: EthSpec>(
.build()
.map_err(|e| format!("should build env: {:?}", e))?;

let testnet_dir = parse_path_with_default_in_home_dir(
matches,
"testnet-dir",
PathBuf::from(directory::DEFAULT_ROOT_DIR).join("testnet"),
)?;
// Determine testnet-dir path or network name depending on CLI flags.
let (testnet_dir, network_name) =
if let Some(testnet_dir) = parse_optional::<PathBuf>(matches, "testnet-dir")? {
(Some(testnet_dir), None)
} else {
let network_name =
parse_optional(matches, "network")?.unwrap_or_else(|| "mainnet".to_string());
(None, Some(network_name))
};

// Lazily load either the testnet dir or the network config, as required.
// Some subcommands like new-testnet need the testnet dir but not the network config.
let get_testnet_dir = || testnet_dir.clone().ok_or("testnet-dir is required");
let get_network_config = || {
if let Some(testnet_dir) = &testnet_dir {
Eth2NetworkConfig::load(testnet_dir.clone()).map_err(|e| {
format!(
"Unable to open testnet dir at {}: {}",
testnet_dir.display(),
e
)
})
} else {
let network_name = network_name.ok_or("no network name or testnet-dir provided")?;
Eth2NetworkConfig::constant(&network_name)?.ok_or("invalid network name".into())
}
};

match matches.subcommand() {
("transition-blocks", Some(matches)) => transition_blocks::run::<T>(env, matches)
.map_err(|e| format!("Failed to transition blocks: {}", e)),
("transition-blocks", Some(matches)) => {
let network_config = get_network_config()?;
transition_blocks::run::<T>(env, network_config, matches)
.map_err(|e| format!("Failed to transition blocks: {}", e))
}
("skip-slots", Some(matches)) => {
skip_slots::run::<T>(env, matches).map_err(|e| format!("Failed to skip slots: {}", e))
let network_config = get_network_config()?;
skip_slots::run::<T>(env, network_config, matches)
.map_err(|e| format!("Failed to skip slots: {}", e))
}
("pretty-ssz", Some(matches)) => {
run_parse_ssz::<T>(matches).map_err(|e| format!("Failed to pretty print hex: {}", e))
Expand All @@ -906,22 +979,33 @@ fn run<T: EthSpec>(
deploy_deposit_contract::run::<T>(env, matches)
.map_err(|e| format!("Failed to run deploy-deposit-contract command: {}", e))
}
("eth1-genesis", Some(matches)) => eth1_genesis::run::<T>(env, testnet_dir, matches)
.map_err(|e| format!("Failed to run eth1-genesis command: {}", e)),
("interop-genesis", Some(matches)) => interop_genesis::run::<T>(testnet_dir, matches)
.map_err(|e| format!("Failed to run interop-genesis command: {}", e)),
("eth1-genesis", Some(matches)) => {
let testnet_dir = get_testnet_dir()?;
eth1_genesis::run::<T>(env, testnet_dir, matches)
.map_err(|e| format!("Failed to run eth1-genesis command: {}", e))
}
("interop-genesis", Some(matches)) => {
let testnet_dir = get_testnet_dir()?;
interop_genesis::run::<T>(testnet_dir, matches)
.map_err(|e| format!("Failed to run interop-genesis command: {}", e))
}
("change-genesis-time", Some(matches)) => {
let testnet_dir = get_testnet_dir()?;
change_genesis_time::run::<T>(testnet_dir, matches)
.map_err(|e| format!("Failed to run change-genesis-time command: {}", e))
}
("create-payload-header", Some(matches)) => create_payload_header::run::<T>(matches)
.map_err(|e| format!("Failed to run create-payload-header command: {}", e)),
("replace-state-pubkeys", Some(matches)) => {
let testnet_dir = get_testnet_dir()?;
replace_state_pubkeys::run::<T>(testnet_dir, matches)
.map_err(|e| format!("Failed to run replace-state-pubkeys command: {}", e))
}
("new-testnet", Some(matches)) => new_testnet::run::<T>(testnet_dir, matches)
.map_err(|e| format!("Failed to run new_testnet command: {}", e)),
("new-testnet", Some(matches)) => {
let testnet_dir = get_testnet_dir()?;
new_testnet::run::<T>(testnet_dir, matches)
.map_err(|e| format!("Failed to run new_testnet command: {}", e))
}
("check-deposit-data", Some(matches)) => check_deposit_data::run(matches)
.map_err(|e| format!("Failed to run check-deposit-data command: {}", e)),
("generate-bootnode-enr", Some(matches)) => generate_bootnode_enr::run::<T>(matches)
Expand All @@ -932,8 +1016,16 @@ fn run<T: EthSpec>(
.map_err(|e| format!("Failed to run mnemonic-validators command: {}", e)),
("indexed-attestations", Some(matches)) => indexed_attestations::run::<T>(matches)
.map_err(|e| format!("Failed to run indexed-attestations command: {}", e)),
("block-root", Some(matches)) => block_root::run::<T>(env, matches)
.map_err(|e| format!("Failed to run block-root command: {}", e)),
("block-root", Some(matches)) => {
let network_config = get_network_config()?;
block_root::run::<T>(env, network_config, matches)
.map_err(|e| format!("Failed to run block-root command: {}", e))
}
("state-root", Some(matches)) => {
let network_config = get_network_config()?;
state_root::run::<T>(env, network_config, matches)
.map_err(|e| format!("Failed to run state-root command: {}", e))
}
(other, _) => Err(format!("Unknown subcommand {}. See --help.", other)),
}
}
9 changes: 7 additions & 2 deletions lcli/src/skip_slots.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ use clap::ArgMatches;
use clap_utils::{parse_optional, parse_required};
use environment::Environment;
use eth2::{types::StateId, BeaconNodeHttpClient, SensitiveUrl, Timeouts};
use eth2_network_config::Eth2NetworkConfig;
use ssz::Encode;
use state_processing::state_advance::{complete_state_advance, partial_state_advance};
use std::fs::File;
Expand All @@ -59,8 +60,12 @@ use types::{BeaconState, CloneConfig, EthSpec, Hash256};

const HTTP_TIMEOUT: Duration = Duration::from_secs(10);

pub fn run<T: EthSpec>(env: Environment<T>, matches: &ArgMatches) -> Result<(), String> {
let spec = &T::default_spec();
pub fn run<T: EthSpec>(
env: Environment<T>,
network_config: Eth2NetworkConfig,
matches: &ArgMatches,
) -> Result<(), String> {
let spec = &network_config.chain_spec::<T>()?;
let executor = env.core_context().executor;

let output_path: Option<PathBuf> = parse_optional(matches, "output-path")?;
Expand Down
76 changes: 76 additions & 0 deletions lcli/src/state_root.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
use crate::transition_blocks::load_from_ssz_with;
use clap::ArgMatches;
use clap_utils::{parse_optional, parse_required};
use environment::Environment;
use eth2::{types::StateId, BeaconNodeHttpClient, SensitiveUrl, Timeouts};
use eth2_network_config::Eth2NetworkConfig;
use std::path::PathBuf;
use std::time::{Duration, Instant};
use types::{BeaconState, EthSpec};

const HTTP_TIMEOUT: Duration = Duration::from_secs(10);

pub fn run<T: EthSpec>(
env: Environment<T>,
network_config: Eth2NetworkConfig,
matches: &ArgMatches,
) -> Result<(), String> {
let executor = env.core_context().executor;

let spec = &network_config.chain_spec::<T>()?;

let state_path: Option<PathBuf> = parse_optional(matches, "state-path")?;
let beacon_url: Option<SensitiveUrl> = parse_optional(matches, "beacon-url")?;
let runs: usize = parse_required(matches, "runs")?;

info!(
"Using {} network ({} spec)",
spec.config_name.as_deref().unwrap_or("unknown"),
T::spec_name()
);
info!("Doing {} runs", runs);

let state = match (state_path, beacon_url) {
(Some(state_path), None) => {
info!("State path: {:?}", state_path);
load_from_ssz_with(&state_path, spec, BeaconState::from_ssz_bytes)?
}
(None, Some(beacon_url)) => {
let state_id: StateId = parse_required(matches, "state-id")?;
let client = BeaconNodeHttpClient::new(beacon_url, Timeouts::set_all(HTTP_TIMEOUT));
executor
.handle()
.ok_or("shutdown in progress")?
.block_on(async move {
client
.get_debug_beacon_states::<T>(state_id)
.await
.map_err(|e| format!("Failed to download state: {:?}", e))
})
.map_err(|e| format!("Failed to complete task: {:?}", e))?
.ok_or_else(|| format!("Unable to locate state at {:?}", state_id))?
.data
}
_ => return Err("must supply either --state-path or --beacon-url".into()),
};

/*
* Perform the core "runs".
*/
let mut state_root = None;
for i in 0..runs {
let mut state = state.clone();
let timer = Instant::now();
state_root = Some(
state
.update_tree_hash_cache()
.map_err(|e| format!("error computing state root: {e:?}"))?,
);
info!("Run {}: {:?}", i, timer.elapsed());
}

if let Some(state_root) = state_root {
info!("State root is {:?}", state_root);
}
Ok(())
}
9 changes: 7 additions & 2 deletions lcli/src/transition_blocks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ use eth2::{
types::{BlockId, StateId},
BeaconNodeHttpClient, SensitiveUrl, Timeouts,
};
use eth2_network_config::Eth2NetworkConfig;
use ssz::Encode;
use state_processing::{
block_signature_verifier::BlockSignatureVerifier, per_block_processing, per_slot_processing,
Expand All @@ -94,8 +95,12 @@ struct Config {
exclude_post_block_thc: bool,
}

pub fn run<T: EthSpec>(env: Environment<T>, matches: &ArgMatches) -> Result<(), String> {
let spec = &T::default_spec();
pub fn run<T: EthSpec>(
env: Environment<T>,
network_config: Eth2NetworkConfig,
matches: &ArgMatches,
) -> Result<(), String> {
let spec = &network_config.chain_spec::<T>()?;
let executor = env.core_context().executor;

/*
Expand Down