v1.1.1 spec updates (#2684)
* update initializing from eth1 for merge genesis * read execution payload header from file lcli * add `create-payload-header` command to `lcli` * fix base fee parsing * Apply suggestions from code review * default `execution_payload_header` bool to false when deserializing `meta.yml` in EF tests Co-authored-by: Paul Hauner <paul@paulhauner.com>
This commit is contained in:
parent
6dde12f311
commit
d8eec16c5e
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -2709,6 +2709,7 @@ dependencies = [
|
|||||||
"eth2_ssz 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"eth2_ssz 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"eth2_wallet",
|
"eth2_wallet",
|
||||||
"genesis",
|
"genesis",
|
||||||
|
"int_to_bytes",
|
||||||
"lighthouse_network",
|
"lighthouse_network",
|
||||||
"lighthouse_version",
|
"lighthouse_version",
|
||||||
"log",
|
"log",
|
||||||
|
@ -954,6 +954,7 @@ mod test {
|
|||||||
&generate_deterministic_keypairs(validator_count),
|
&generate_deterministic_keypairs(validator_count),
|
||||||
genesis_time,
|
genesis_time,
|
||||||
Hash256::from_slice(DEFAULT_ETH1_BLOCK_HASH),
|
Hash256::from_slice(DEFAULT_ETH1_BLOCK_HASH),
|
||||||
|
None,
|
||||||
&spec,
|
&spec,
|
||||||
)
|
)
|
||||||
.expect("should create interop genesis state");
|
.expect("should create interop genesis state");
|
||||||
@ -1023,6 +1024,7 @@ mod test {
|
|||||||
&keypairs,
|
&keypairs,
|
||||||
genesis_time,
|
genesis_time,
|
||||||
Hash256::from_slice(DEFAULT_ETH1_BLOCK_HASH),
|
Hash256::from_slice(DEFAULT_ETH1_BLOCK_HASH),
|
||||||
|
None,
|
||||||
spec,
|
spec,
|
||||||
)
|
)
|
||||||
.expect("should build state");
|
.expect("should build state");
|
||||||
|
@ -182,6 +182,7 @@ impl<E: EthSpec> Builder<EphemeralHarnessType<E>> {
|
|||||||
&validator_keypairs,
|
&validator_keypairs,
|
||||||
HARNESS_GENESIS_TIME,
|
HARNESS_GENESIS_TIME,
|
||||||
Hash256::from_slice(DEFAULT_ETH1_BLOCK_HASH),
|
Hash256::from_slice(DEFAULT_ETH1_BLOCK_HASH),
|
||||||
|
None,
|
||||||
builder.get_spec(),
|
builder.get_spec(),
|
||||||
)
|
)
|
||||||
.expect("should generate interop state");
|
.expect("should generate interop state");
|
||||||
@ -228,6 +229,7 @@ impl<E: EthSpec> Builder<DiskHarnessType<E>> {
|
|||||||
&validator_keypairs,
|
&validator_keypairs,
|
||||||
HARNESS_GENESIS_TIME,
|
HARNESS_GENESIS_TIME,
|
||||||
Hash256::from_slice(DEFAULT_ETH1_BLOCK_HASH),
|
Hash256::from_slice(DEFAULT_ETH1_BLOCK_HASH),
|
||||||
|
None,
|
||||||
builder.get_spec(),
|
builder.get_spec(),
|
||||||
)
|
)
|
||||||
.expect("should generate interop state");
|
.expect("should generate interop state");
|
||||||
|
@ -234,6 +234,7 @@ where
|
|||||||
&keypairs,
|
&keypairs,
|
||||||
genesis_time,
|
genesis_time,
|
||||||
Hash256::from_slice(DEFAULT_ETH1_BLOCK_HASH),
|
Hash256::from_slice(DEFAULT_ETH1_BLOCK_HASH),
|
||||||
|
None,
|
||||||
&spec,
|
&spec,
|
||||||
)?;
|
)?;
|
||||||
builder.genesis_state(genesis_state).map(|v| (v, None))?
|
builder.genesis_state(genesis_state).map(|v| (v, None))?
|
||||||
|
@ -373,6 +373,7 @@ impl Eth1GenesisService {
|
|||||||
eth1_block.hash,
|
eth1_block.hash,
|
||||||
eth1_block.timestamp,
|
eth1_block.timestamp,
|
||||||
genesis_deposits(deposit_logs, spec)?,
|
genesis_deposits(deposit_logs, spec)?,
|
||||||
|
None,
|
||||||
spec,
|
spec,
|
||||||
)
|
)
|
||||||
.map_err(|e| format!("Unable to initialize genesis state: {:?}", e))?;
|
.map_err(|e| format!("Unable to initialize genesis state: {:?}", e))?;
|
||||||
|
@ -3,7 +3,10 @@ use eth2_hashing::hash;
|
|||||||
use rayon::prelude::*;
|
use rayon::prelude::*;
|
||||||
use ssz::Encode;
|
use ssz::Encode;
|
||||||
use state_processing::initialize_beacon_state_from_eth1;
|
use state_processing::initialize_beacon_state_from_eth1;
|
||||||
use types::{BeaconState, ChainSpec, DepositData, EthSpec, Hash256, Keypair, PublicKey, Signature};
|
use types::{
|
||||||
|
BeaconState, ChainSpec, DepositData, EthSpec, ExecutionPayloadHeader, Hash256, Keypair,
|
||||||
|
PublicKey, Signature,
|
||||||
|
};
|
||||||
|
|
||||||
pub const DEFAULT_ETH1_BLOCK_HASH: &[u8] = &[0x42; 32];
|
pub const DEFAULT_ETH1_BLOCK_HASH: &[u8] = &[0x42; 32];
|
||||||
|
|
||||||
@ -15,9 +18,9 @@ pub fn interop_genesis_state<T: EthSpec>(
|
|||||||
keypairs: &[Keypair],
|
keypairs: &[Keypair],
|
||||||
genesis_time: u64,
|
genesis_time: u64,
|
||||||
eth1_block_hash: Hash256,
|
eth1_block_hash: Hash256,
|
||||||
|
execution_payload_header: Option<ExecutionPayloadHeader<T>>,
|
||||||
spec: &ChainSpec,
|
spec: &ChainSpec,
|
||||||
) -> Result<BeaconState<T>, String> {
|
) -> Result<BeaconState<T>, String> {
|
||||||
let eth1_block_hash = eth1_block_hash;
|
|
||||||
let eth1_timestamp = 2_u64.pow(40);
|
let eth1_timestamp = 2_u64.pow(40);
|
||||||
let amount = spec.max_effective_balance;
|
let amount = spec.max_effective_balance;
|
||||||
|
|
||||||
@ -47,6 +50,7 @@ pub fn interop_genesis_state<T: EthSpec>(
|
|||||||
eth1_block_hash,
|
eth1_block_hash,
|
||||||
eth1_timestamp,
|
eth1_timestamp,
|
||||||
genesis_deposits(datas, spec)?,
|
genesis_deposits(datas, spec)?,
|
||||||
|
execution_payload_header,
|
||||||
spec,
|
spec,
|
||||||
)
|
)
|
||||||
.map_err(|e| format!("Unable to initialize genesis state: {:?}", e))?;
|
.map_err(|e| format!("Unable to initialize genesis state: {:?}", e))?;
|
||||||
@ -80,6 +84,7 @@ mod test {
|
|||||||
&keypairs,
|
&keypairs,
|
||||||
genesis_time,
|
genesis_time,
|
||||||
Hash256::from_slice(DEFAULT_ETH1_BLOCK_HASH),
|
Hash256::from_slice(DEFAULT_ETH1_BLOCK_HASH),
|
||||||
|
None,
|
||||||
spec,
|
spec,
|
||||||
)
|
)
|
||||||
.expect("should build state");
|
.expect("should build state");
|
||||||
|
@ -56,6 +56,7 @@ impl TestBeaconChain {
|
|||||||
&keypairs,
|
&keypairs,
|
||||||
0,
|
0,
|
||||||
Hash256::from_slice(DEFAULT_ETH1_BLOCK_HASH),
|
Hash256::from_slice(DEFAULT_ETH1_BLOCK_HASH),
|
||||||
|
None,
|
||||||
&spec,
|
&spec,
|
||||||
)
|
)
|
||||||
.expect("should generate interop state"),
|
.expect("should generate interop state"),
|
||||||
|
@ -5,7 +5,6 @@ use crate::common::DepositDataTree;
|
|||||||
use crate::upgrade::{upgrade_to_altair, upgrade_to_merge};
|
use crate::upgrade::{upgrade_to_altair, upgrade_to_merge};
|
||||||
use safe_arith::{ArithError, SafeArith};
|
use safe_arith::{ArithError, SafeArith};
|
||||||
use tree_hash::TreeHash;
|
use tree_hash::TreeHash;
|
||||||
use types::consts::merge_testing::{GENESIS_BASE_FEE_PER_GAS, GENESIS_GAS_LIMIT};
|
|
||||||
use types::DEPOSIT_TREE_DEPTH;
|
use types::DEPOSIT_TREE_DEPTH;
|
||||||
use types::*;
|
use types::*;
|
||||||
|
|
||||||
@ -14,6 +13,7 @@ pub fn initialize_beacon_state_from_eth1<T: EthSpec>(
|
|||||||
eth1_block_hash: Hash256,
|
eth1_block_hash: Hash256,
|
||||||
eth1_timestamp: u64,
|
eth1_timestamp: u64,
|
||||||
deposits: Vec<Deposit>,
|
deposits: Vec<Deposit>,
|
||||||
|
execution_payload_header: Option<ExecutionPayloadHeader<T>>,
|
||||||
spec: &ChainSpec,
|
spec: &ChainSpec,
|
||||||
) -> Result<BeaconState<T>, BlockProcessingError> {
|
) -> Result<BeaconState<T>, BlockProcessingError> {
|
||||||
let genesis_time = eth2_genesis_time(eth1_timestamp, spec)?;
|
let genesis_time = eth2_genesis_time(eth1_timestamp, spec)?;
|
||||||
@ -64,18 +64,12 @@ pub fn initialize_beacon_state_from_eth1<T: EthSpec>(
|
|||||||
upgrade_to_merge(&mut state, spec)?;
|
upgrade_to_merge(&mut state, spec)?;
|
||||||
|
|
||||||
// Remove intermediate Altair fork from `state.fork`.
|
// Remove intermediate Altair fork from `state.fork`.
|
||||||
state.fork_mut().previous_version = spec.genesis_fork_version;
|
state.fork_mut().previous_version = spec.merge_fork_version;
|
||||||
|
|
||||||
// Override latest execution payload header.
|
// Override latest execution payload header.
|
||||||
// See https://github.com/ethereum/consensus-specs/blob/v1.1.0/specs/merge/beacon-chain.md#testing
|
// See https://github.com/ethereum/consensus-specs/blob/v1.1.0/specs/merge/beacon-chain.md#testing
|
||||||
*state.latest_execution_payload_header_mut()? = ExecutionPayloadHeader {
|
*state.latest_execution_payload_header_mut()? =
|
||||||
block_hash: eth1_block_hash,
|
execution_payload_header.unwrap_or_default();
|
||||||
timestamp: eth1_timestamp,
|
|
||||||
random: eth1_block_hash,
|
|
||||||
gas_limit: GENESIS_GAS_LIMIT,
|
|
||||||
base_fee_per_gas: GENESIS_BASE_FEE_PER_GAS,
|
|
||||||
..ExecutionPayloadHeader::default()
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now that we have our validators, initialize the caches (including the committees)
|
// Now that we have our validators, initialize the caches (including the committees)
|
||||||
|
@ -562,6 +562,7 @@ fn tree_hash_cache_linear_history_long_skip() {
|
|||||||
&keypairs,
|
&keypairs,
|
||||||
0,
|
0,
|
||||||
Hash256::from_slice(DEFAULT_ETH1_BLOCK_HASH),
|
Hash256::from_slice(DEFAULT_ETH1_BLOCK_HASH),
|
||||||
|
None,
|
||||||
spec,
|
spec,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -19,13 +19,3 @@ pub mod altair {
|
|||||||
|
|
||||||
pub const NUM_FLAG_INDICES: usize = 3;
|
pub const NUM_FLAG_INDICES: usize = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod merge_testing {
|
|
||||||
use ethereum_types::H256;
|
|
||||||
pub const GENESIS_GAS_LIMIT: u64 = 30_000_000;
|
|
||||||
pub const GENESIS_BASE_FEE_PER_GAS: H256 = H256([
|
|
||||||
0x00, 0xca, 0x9a, 0x3b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
@ -19,6 +19,7 @@ serde_json = "1.0.66"
|
|||||||
env_logger = "0.9.0"
|
env_logger = "0.9.0"
|
||||||
types = { path = "../consensus/types" }
|
types = { path = "../consensus/types" }
|
||||||
state_processing = { path = "../consensus/state_processing" }
|
state_processing = { path = "../consensus/state_processing" }
|
||||||
|
int_to_bytes = { path = "../consensus/int_to_bytes" }
|
||||||
eth2_ssz = "0.4.0"
|
eth2_ssz = "0.4.0"
|
||||||
environment = { path = "../lighthouse/environment" }
|
environment = { path = "../lighthouse/environment" }
|
||||||
eth2_network_config = { path = "../common/eth2_network_config" }
|
eth2_network_config = { path = "../common/eth2_network_config" }
|
||||||
|
39
lcli/src/create_payload_header.rs
Normal file
39
lcli/src/create_payload_header.rs
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
use bls::Hash256;
|
||||||
|
use clap::ArgMatches;
|
||||||
|
use clap_utils::{parse_optional, parse_required};
|
||||||
|
use int_to_bytes::int_to_bytes32;
|
||||||
|
use ssz::Encode;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::Write;
|
||||||
|
use std::time::{SystemTime, UNIX_EPOCH};
|
||||||
|
use types::{EthSpec, ExecutionPayloadHeader};
|
||||||
|
|
||||||
|
pub fn run<T: EthSpec>(matches: &ArgMatches) -> Result<(), String> {
|
||||||
|
let eth1_block_hash = parse_required(matches, "execution-block-hash")?;
|
||||||
|
let genesis_time = parse_optional(matches, "genesis-time")?.unwrap_or(
|
||||||
|
SystemTime::now()
|
||||||
|
.duration_since(UNIX_EPOCH)
|
||||||
|
.map_err(|e| format!("Unable to get time: {:?}", e))?
|
||||||
|
.as_secs(),
|
||||||
|
);
|
||||||
|
let base_fee_per_gas = Hash256::from_slice(&int_to_bytes32(parse_required(
|
||||||
|
matches,
|
||||||
|
"base-fee-per-gas",
|
||||||
|
)?));
|
||||||
|
let gas_limit = parse_required(matches, "gas-limit")?;
|
||||||
|
let file_name = matches.value_of("file").ok_or("No file supplied")?;
|
||||||
|
|
||||||
|
let execution_payload_header: ExecutionPayloadHeader<T> = ExecutionPayloadHeader {
|
||||||
|
gas_limit,
|
||||||
|
base_fee_per_gas,
|
||||||
|
timestamp: genesis_time,
|
||||||
|
block_hash: eth1_block_hash,
|
||||||
|
random: eth1_block_hash,
|
||||||
|
..ExecutionPayloadHeader::default()
|
||||||
|
};
|
||||||
|
let mut file = File::create(file_name).map_err(|_| "Unable to create file".to_string())?;
|
||||||
|
let bytes = execution_payload_header.as_ssz_bytes();
|
||||||
|
file.write_all(bytes.as_slice())
|
||||||
|
.map_err(|_| "Unable to write to file".to_string())?;
|
||||||
|
Ok(())
|
||||||
|
}
|
@ -38,6 +38,7 @@ pub fn run<T: EthSpec>(testnet_dir: PathBuf, matches: &ArgMatches) -> Result<(),
|
|||||||
&keypairs,
|
&keypairs,
|
||||||
genesis_time,
|
genesis_time,
|
||||||
Hash256::from_slice(DEFAULT_ETH1_BLOCK_HASH),
|
Hash256::from_slice(DEFAULT_ETH1_BLOCK_HASH),
|
||||||
|
None,
|
||||||
&spec,
|
&spec,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
extern crate log;
|
extern crate log;
|
||||||
mod change_genesis_time;
|
mod change_genesis_time;
|
||||||
mod check_deposit_data;
|
mod check_deposit_data;
|
||||||
|
mod create_payload_header;
|
||||||
mod deploy_deposit_contract;
|
mod deploy_deposit_contract;
|
||||||
mod eth1_genesis;
|
mod eth1_genesis;
|
||||||
mod etl;
|
mod etl;
|
||||||
@ -271,6 +272,57 @@ fn main() {
|
|||||||
.help("The mnemonic for key derivation."),
|
.help("The mnemonic for key derivation."),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
.subcommand(
|
||||||
|
SubCommand::with_name("create-payload-header")
|
||||||
|
.about("Generates an SSZ file containing bytes for an `ExecutionPayloadHeader`. \
|
||||||
|
Useful as input for `lcli new-testnet --execution-payload-header FILE`. ")
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("execution-block-hash")
|
||||||
|
.long("execution-block-hash")
|
||||||
|
.value_name("BLOCK_HASH")
|
||||||
|
.takes_value(true)
|
||||||
|
.help("The block hash used when generating an execution payload. This \
|
||||||
|
value is used for `execution_payload_header.block_hash` as well as \
|
||||||
|
`execution_payload_header.random`")
|
||||||
|
.required(true)
|
||||||
|
.default_value(
|
||||||
|
"0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("genesis-time")
|
||||||
|
.long("genesis-time")
|
||||||
|
.value_name("INTEGER")
|
||||||
|
.takes_value(true)
|
||||||
|
.help("The genesis time when generating an execution payload.")
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("base-fee-per-gas")
|
||||||
|
.long("base-fee-per-gas")
|
||||||
|
.value_name("INTEGER")
|
||||||
|
.takes_value(true)
|
||||||
|
.help("The base fee per gas field in the execution payload generated.")
|
||||||
|
.required(true)
|
||||||
|
.default_value("1000000000"),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("gas-limit")
|
||||||
|
.long("gas-limit")
|
||||||
|
.value_name("INTEGER")
|
||||||
|
.takes_value(true)
|
||||||
|
.help("The gas limit field in the execution payload generated.")
|
||||||
|
.required(true)
|
||||||
|
.default_value("30000000"),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("file")
|
||||||
|
.long("file")
|
||||||
|
.value_name("FILE")
|
||||||
|
.takes_value(true)
|
||||||
|
.required(true)
|
||||||
|
.help("Output file"),
|
||||||
|
)
|
||||||
|
)
|
||||||
.subcommand(
|
.subcommand(
|
||||||
SubCommand::with_name("new-testnet")
|
SubCommand::with_name("new-testnet")
|
||||||
.about(
|
.about(
|
||||||
@ -426,6 +478,15 @@ fn main() {
|
|||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.help("The eth1 block hash used when generating a genesis state."),
|
.help("The eth1 block hash used when generating a genesis state."),
|
||||||
)
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("execution-payload-header")
|
||||||
|
.long("execution-payload-header")
|
||||||
|
.value_name("FILE")
|
||||||
|
.takes_value(true)
|
||||||
|
.required(false)
|
||||||
|
.help("Path to file containing `ExecutionPayloadHeader` SSZ bytes to be \
|
||||||
|
used in the genesis state."),
|
||||||
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("validator-count")
|
Arg::with_name("validator-count")
|
||||||
.long("validator-count")
|
.long("validator-count")
|
||||||
@ -661,6 +722,8 @@ fn run<T: EthSpec>(
|
|||||||
change_genesis_time::run::<T>(testnet_dir, matches)
|
change_genesis_time::run::<T>(testnet_dir, matches)
|
||||||
.map_err(|e| format!("Failed to run change-genesis-time command: {}", e))
|
.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)) => {
|
("replace-state-pubkeys", Some(matches)) => {
|
||||||
replace_state_pubkeys::run::<T>(testnet_dir, matches)
|
replace_state_pubkeys::run::<T>(testnet_dir, matches)
|
||||||
.map_err(|e| format!("Failed to run replace-state-pubkeys command: {}", e))
|
.map_err(|e| format!("Failed to run replace-state-pubkeys command: {}", e))
|
||||||
|
@ -2,10 +2,15 @@ use clap::ArgMatches;
|
|||||||
use clap_utils::{parse_optional, parse_required, parse_ssz_optional};
|
use clap_utils::{parse_optional, parse_required, parse_ssz_optional};
|
||||||
use eth2_network_config::Eth2NetworkConfig;
|
use eth2_network_config::Eth2NetworkConfig;
|
||||||
use genesis::interop_genesis_state;
|
use genesis::interop_genesis_state;
|
||||||
|
use ssz::Decode;
|
||||||
use ssz::Encode;
|
use ssz::Encode;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::Read;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::time::{SystemTime, UNIX_EPOCH};
|
use std::time::{SystemTime, UNIX_EPOCH};
|
||||||
use types::{test_utils::generate_deterministic_keypairs, Address, Config, EthSpec};
|
use types::{
|
||||||
|
test_utils::generate_deterministic_keypairs, Address, Config, EthSpec, ExecutionPayloadHeader,
|
||||||
|
};
|
||||||
|
|
||||||
pub fn run<T: EthSpec>(testnet_dir_path: PathBuf, matches: &ArgMatches) -> Result<(), String> {
|
pub fn run<T: EthSpec>(testnet_dir_path: PathBuf, matches: &ArgMatches) -> Result<(), String> {
|
||||||
let deposit_contract_address: Address = parse_required(matches, "deposit-contract-address")?;
|
let deposit_contract_address: Address = parse_required(matches, "deposit-contract-address")?;
|
||||||
@ -62,20 +67,51 @@ pub fn run<T: EthSpec>(testnet_dir_path: PathBuf, matches: &ArgMatches) -> Resul
|
|||||||
}
|
}
|
||||||
|
|
||||||
let genesis_state_bytes = if matches.is_present("interop-genesis-state") {
|
let genesis_state_bytes = if matches.is_present("interop-genesis-state") {
|
||||||
let eth1_block_hash = parse_required(matches, "eth1-block-hash")?;
|
let execution_payload_header: Option<ExecutionPayloadHeader<T>> =
|
||||||
let validator_count = parse_required(matches, "validator-count")?;
|
parse_optional(matches, "execution-payload-header")?
|
||||||
let genesis_time = if let Some(time) = parse_optional(matches, "genesis-time")? {
|
.map(|filename: String| {
|
||||||
time
|
let mut bytes = vec![];
|
||||||
|
let mut file = File::open(filename.as_str())
|
||||||
|
.map_err(|e| format!("Unable to open {}: {}", filename, e))?;
|
||||||
|
file.read_to_end(&mut bytes)
|
||||||
|
.map_err(|e| format!("Unable to read {}: {}", filename, e))?;
|
||||||
|
ExecutionPayloadHeader::<T>::from_ssz_bytes(bytes.as_slice())
|
||||||
|
.map_err(|e| format!("SSZ decode failed: {:?}", e))
|
||||||
|
})
|
||||||
|
.transpose()?;
|
||||||
|
|
||||||
|
let (eth1_block_hash, genesis_time) = if let Some(payload) =
|
||||||
|
execution_payload_header.as_ref()
|
||||||
|
{
|
||||||
|
let eth1_block_hash =
|
||||||
|
parse_optional(matches, "eth1-block-hash")?.unwrap_or(payload.block_hash);
|
||||||
|
let genesis_time =
|
||||||
|
parse_optional(matches, "genesis-time")?.unwrap_or(payload.timestamp);
|
||||||
|
(eth1_block_hash, genesis_time)
|
||||||
} else {
|
} else {
|
||||||
|
let eth1_block_hash = parse_required(matches, "eth1-block-hash").map_err(|_| {
|
||||||
|
"One of `--execution-payload-header` or `--eth1-block-hash` must be set".to_string()
|
||||||
|
})?;
|
||||||
|
let genesis_time = parse_optional(matches, "genesis-time")?.unwrap_or(
|
||||||
SystemTime::now()
|
SystemTime::now()
|
||||||
.duration_since(UNIX_EPOCH)
|
.duration_since(UNIX_EPOCH)
|
||||||
.map_err(|e| format!("Unable to get time: {:?}", e))?
|
.map_err(|e| format!("Unable to get time: {:?}", e))?
|
||||||
.as_secs()
|
.as_secs(),
|
||||||
|
);
|
||||||
|
(eth1_block_hash, genesis_time)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let validator_count = parse_required(matches, "validator-count")?;
|
||||||
|
|
||||||
let keypairs = generate_deterministic_keypairs(validator_count);
|
let keypairs = generate_deterministic_keypairs(validator_count);
|
||||||
let genesis_state =
|
|
||||||
interop_genesis_state::<T>(&keypairs, genesis_time, eth1_block_hash, &spec)?;
|
let genesis_state = interop_genesis_state::<T>(
|
||||||
|
&keypairs,
|
||||||
|
genesis_time,
|
||||||
|
eth1_block_hash,
|
||||||
|
execution_payload_header,
|
||||||
|
&spec,
|
||||||
|
)?;
|
||||||
|
|
||||||
Some(genesis_state.as_ssz_bytes())
|
Some(genesis_state.as_ssz_bytes())
|
||||||
} else {
|
} else {
|
||||||
|
@ -4,11 +4,12 @@ use crate::decode::{ssz_decode_file, ssz_decode_state, yaml_decode_file};
|
|||||||
use serde_derive::Deserialize;
|
use serde_derive::Deserialize;
|
||||||
use state_processing::initialize_beacon_state_from_eth1;
|
use state_processing::initialize_beacon_state_from_eth1;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use types::{BeaconState, Deposit, EthSpec, ForkName, Hash256};
|
use types::{BeaconState, Deposit, EthSpec, ExecutionPayloadHeader, ForkName, Hash256};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize)]
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
struct Metadata {
|
struct Metadata {
|
||||||
deposits_count: usize,
|
deposits_count: usize,
|
||||||
|
execution_payload_header: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize)]
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
@ -24,6 +25,7 @@ pub struct GenesisInitialization<E: EthSpec> {
|
|||||||
pub eth1_block_hash: Hash256,
|
pub eth1_block_hash: Hash256,
|
||||||
pub eth1_timestamp: u64,
|
pub eth1_timestamp: u64,
|
||||||
pub deposits: Vec<Deposit>,
|
pub deposits: Vec<Deposit>,
|
||||||
|
pub execution_payload_header: Option<ExecutionPayloadHeader<E>>,
|
||||||
pub state: Option<BeaconState<E>>,
|
pub state: Option<BeaconState<E>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,6 +36,14 @@ impl<E: EthSpec> LoadCase for GenesisInitialization<E> {
|
|||||||
eth1_timestamp,
|
eth1_timestamp,
|
||||||
} = yaml_decode_file(&path.join("eth1.yaml"))?;
|
} = yaml_decode_file(&path.join("eth1.yaml"))?;
|
||||||
let meta: Metadata = yaml_decode_file(&path.join("meta.yaml"))?;
|
let meta: Metadata = yaml_decode_file(&path.join("meta.yaml"))?;
|
||||||
|
let execution_payload_header: Option<ExecutionPayloadHeader<E>> =
|
||||||
|
if meta.execution_payload_header.unwrap_or(false) {
|
||||||
|
Some(ssz_decode_file(
|
||||||
|
&path.join("execution_payload_header.ssz_snappy"),
|
||||||
|
)?)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
let deposits: Vec<Deposit> = (0..meta.deposits_count)
|
let deposits: Vec<Deposit> = (0..meta.deposits_count)
|
||||||
.map(|i| {
|
.map(|i| {
|
||||||
let filename = format!("deposits_{}.ssz_snappy", i);
|
let filename = format!("deposits_{}.ssz_snappy", i);
|
||||||
@ -48,6 +58,7 @@ impl<E: EthSpec> LoadCase for GenesisInitialization<E> {
|
|||||||
eth1_block_hash,
|
eth1_block_hash,
|
||||||
eth1_timestamp,
|
eth1_timestamp,
|
||||||
deposits,
|
deposits,
|
||||||
|
execution_payload_header,
|
||||||
state: Some(state),
|
state: Some(state),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -66,6 +77,7 @@ impl<E: EthSpec> Case for GenesisInitialization<E> {
|
|||||||
self.eth1_block_hash,
|
self.eth1_block_hash,
|
||||||
self.eth1_timestamp,
|
self.eth1_timestamp,
|
||||||
self.deposits.clone(),
|
self.deposits.clone(),
|
||||||
|
self.execution_payload_header.clone(),
|
||||||
spec,
|
spec,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user