diff --git a/lcli/src/main.rs b/lcli/src/main.rs index 8fbf5638b..38fec2ebb 100644 --- a/lcli/src/main.rs +++ b/lcli/src/main.rs @@ -968,7 +968,9 @@ fn run( .map_err(|e| format!("Failed to skip slots: {}", e)) } ("pretty-ssz", Some(matches)) => { - run_parse_ssz::(matches).map_err(|e| format!("Failed to pretty print hex: {}", e)) + let network_config = get_network_config()?; + run_parse_ssz::(network_config, matches) + .map_err(|e| format!("Failed to pretty print hex: {}", e)) } ("deploy-deposit-contract", Some(matches)) => { deploy_deposit_contract::run::(env, matches) diff --git a/lcli/src/parse_ssz.rs b/lcli/src/parse_ssz.rs index 5d988ee18..5c306f4fd 100644 --- a/lcli/src/parse_ssz.rs +++ b/lcli/src/parse_ssz.rs @@ -1,5 +1,6 @@ use clap::ArgMatches; use clap_utils::parse_required; +use eth2_network_config::Eth2NetworkConfig; use serde::Serialize; use snap::raw::Decoder; use ssz::Decode; @@ -26,7 +27,10 @@ impl FromStr for OutputFormat { } } -pub fn run_parse_ssz(matches: &ArgMatches) -> Result<(), String> { +pub fn run_parse_ssz( + network_config: Eth2NetworkConfig, + matches: &ArgMatches, +) -> Result<(), String> { let type_str = matches.value_of("type").ok_or("No type supplied")?; let filename = matches.value_of("ssz-file").ok_or("No file supplied")?; let format = parse_required(matches, "format")?; @@ -44,44 +48,79 @@ pub fn run_parse_ssz(matches: &ArgMatches) -> Result<(), String> { bytes }; - info!("Using {} spec", T::spec_name()); - info!("Type: {:?}", type_str); + let spec = &network_config.chain_spec::()?; + info!( + "Using {} network config ({} preset)", + spec.config_name.as_deref().unwrap_or("unknown"), + T::spec_name() + ); + info!("Type: {type_str}"); + // More fork-specific decoders may need to be added in future, but shouldn't be 100% necessary, + // as the fork-generic decoder will always be available (requires correct --network flag). match type_str { - "signed_block_base" => decode_and_print::>(&bytes, format)?, - "signed_block_altair" => decode_and_print::>(&bytes, format)?, - "signed_block_merge" => decode_and_print::>(&bytes, format)?, - "block_base" => decode_and_print::>(&bytes, format)?, - "block_altair" => decode_and_print::>(&bytes, format)?, - "block_merge" => decode_and_print::>(&bytes, format)?, - "state_base" => decode_and_print::>(&bytes, format)?, - "state_altair" => decode_and_print::>(&bytes, format)?, - "state_merge" => decode_and_print::>(&bytes, format)?, + "SignedBeaconBlock" => decode_and_print::>( + &bytes, + |bytes| SignedBeaconBlock::from_ssz_bytes(bytes, spec), + format, + )?, + "SignedBeaconBlockBase" | "SignedBeaconBlockPhase0" => { + decode_and_print(&bytes, SignedBeaconBlockBase::::from_ssz_bytes, format)? + } + "SignedBeaconBlockAltair" => { + decode_and_print(&bytes, SignedBeaconBlockAltair::::from_ssz_bytes, format)? + } + "SignedBeaconBlockMerge" | "SignedBeaconBlockBellatrix" => { + decode_and_print(&bytes, SignedBeaconBlockMerge::::from_ssz_bytes, format)? + } + "SignedBeaconBlockCapella" => decode_and_print( + &bytes, + SignedBeaconBlockCapella::::from_ssz_bytes, + format, + )?, + "BeaconState" => decode_and_print::>( + &bytes, + |bytes| BeaconState::from_ssz_bytes(bytes, spec), + format, + )?, + "BeaconStateBase" | "BeaconStatePhase0" => { + decode_and_print(&bytes, BeaconStateBase::::from_ssz_bytes, format)? + } + "BeaconStateAltair" => { + decode_and_print(&bytes, BeaconStateAltair::::from_ssz_bytes, format)? + } + "BeaconStateMerge" | "BeaconStateBellatrix" => { + decode_and_print(&bytes, BeaconStateMerge::::from_ssz_bytes, format)? + } + "BeaconStateCapella" => { + decode_and_print(&bytes, BeaconStateCapella::::from_ssz_bytes, format)? + } other => return Err(format!("Unknown type: {}", other)), }; Ok(()) } -fn decode_and_print( +fn decode_and_print( bytes: &[u8], + decoder: impl FnOnce(&[u8]) -> Result, output_format: OutputFormat, ) -> Result<(), String> { - let item = T::from_ssz_bytes(bytes).map_err(|e| format!("SSZ decode failed: {:?}", e))?; + let item = decoder(bytes).map_err(|e| format!("SSZ decode failed: {e:?}"))?; match output_format { OutputFormat::Json => { println!( "{}", serde_json::to_string(&item) - .map_err(|e| format!("Unable to write object to JSON: {:?}", e))? + .map_err(|e| format!("Unable to write object to JSON: {e:?}"))? ); } OutputFormat::Yaml => { println!( "{}", serde_yaml::to_string(&item) - .map_err(|e| format!("Unable to write object to YAML: {:?}", e))? + .map_err(|e| format!("Unable to write object to YAML: {e:?}"))? ); } } diff --git a/lcli/src/transition_blocks.rs b/lcli/src/transition_blocks.rs index 85705177d..23b0ae262 100644 --- a/lcli/src/transition_blocks.rs +++ b/lcli/src/transition_blocks.rs @@ -73,9 +73,10 @@ use eth2::{ }; use eth2_network_config::Eth2NetworkConfig; use ssz::Encode; +use state_processing::state_advance::complete_state_advance; use state_processing::{ - block_signature_verifier::BlockSignatureVerifier, per_block_processing, per_slot_processing, - BlockSignatureStrategy, ConsensusContext, StateProcessingStrategy, VerifyBlockRoot, + block_signature_verifier::BlockSignatureVerifier, per_block_processing, BlockSignatureStrategy, + ConsensusContext, StateProcessingStrategy, VerifyBlockRoot, }; use std::borrow::Cow; use std::fs::File; @@ -332,10 +333,8 @@ fn do_transition( // Transition the parent state to the block slot. let t = Instant::now(); - for i in pre_state.slot().as_u64()..block.slot().as_u64() { - per_slot_processing(&mut pre_state, Some(state_root), spec) - .map_err(|e| format!("Failed to advance slot on iteration {}: {:?}", i, e))?; - } + complete_state_advance(&mut pre_state, Some(state_root), block.slot(), spec) + .map_err(|e| format!("Unable to perform complete advance: {e:?}"))?; debug!("Slot processing: {:?}", t.elapsed()); let t = Instant::now(); diff --git a/scripts/local_testnet/start_local_testnet.sh b/scripts/local_testnet/start_local_testnet.sh index 64111d562..4b8357b99 100755 --- a/scripts/local_testnet/start_local_testnet.sh +++ b/scripts/local_testnet/start_local_testnet.sh @@ -103,7 +103,7 @@ echo "executing: ./setup.sh >> $LOG_DIR/setup.log" ./setup.sh >> $LOG_DIR/setup.log 2>&1 # Update future hardforks time in the EL genesis file based on the CL genesis time -GENESIS_TIME=$(lcli pretty-ssz state_merge $TESTNET_DIR/genesis.ssz | jq | grep -Po 'genesis_time": "\K.*\d') +GENESIS_TIME=$(lcli pretty-ssz --testnet-dir $TESTNET_DIR BeaconState $TESTNET_DIR/genesis.ssz | jq | grep -Po 'genesis_time": "\K.*\d') echo $GENESIS_TIME CAPELLA_TIME=$((GENESIS_TIME + (CAPELLA_FORK_EPOCH * 32 * SECONDS_PER_SLOT))) echo $CAPELLA_TIME