Embed interop validators into genesis
This commit is contained in:
parent
ff24773a5a
commit
df3615664e
@ -23,6 +23,7 @@ types = { path = "../consensus/types" }
|
|||||||
state_processing = { path = "../consensus/state_processing" }
|
state_processing = { path = "../consensus/state_processing" }
|
||||||
int_to_bytes = { path = "../consensus/int_to_bytes" }
|
int_to_bytes = { path = "../consensus/int_to_bytes" }
|
||||||
eth2_ssz = "0.4.1"
|
eth2_ssz = "0.4.1"
|
||||||
|
eth2_hashing = "0.3.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" }
|
||||||
genesis = { path = "../beacon_node/genesis" }
|
genesis = { path = "../beacon_node/genesis" }
|
||||||
|
@ -1,16 +1,23 @@
|
|||||||
use clap::ArgMatches;
|
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_hashing::hash;
|
||||||
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::Decode;
|
||||||
use ssz::Encode;
|
use ssz::Encode;
|
||||||
|
use state_processing::process_activations;
|
||||||
|
use state_processing::upgrade::{
|
||||||
|
upgrade_to_altair, upgrade_to_bellatrix, upgrade_to_capella, upgrade_to_eip4844,
|
||||||
|
};
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
use std::str::FromStr;
|
||||||
use std::time::{SystemTime, UNIX_EPOCH};
|
use std::time::{SystemTime, UNIX_EPOCH};
|
||||||
use types::{
|
use types::{
|
||||||
test_utils::generate_deterministic_keypairs, Address, Config, EthSpec, ExecutionPayloadHeader,
|
test_utils::generate_deterministic_keypairs, Address, BeaconState, ChainSpec, Config, Eth1Data,
|
||||||
ExecutionPayloadHeaderMerge,
|
EthSpec, ExecutionPayloadHeader, ExecutionPayloadHeaderMerge, Hash256, Keypair, PublicKey,
|
||||||
|
Validator,
|
||||||
};
|
};
|
||||||
|
|
||||||
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> {
|
||||||
@ -67,6 +74,14 @@ pub fn run<T: EthSpec>(testnet_dir_path: PathBuf, matches: &ArgMatches) -> Resul
|
|||||||
spec.bellatrix_fork_epoch = Some(fork_epoch);
|
spec.bellatrix_fork_epoch = Some(fork_epoch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(fork_epoch) = parse_optional(matches, "capella-fork-epoch")? {
|
||||||
|
spec.capella_fork_epoch = Some(fork_epoch);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(fork_epoch) = parse_optional(matches, "eip4844-fork-epoch")? {
|
||||||
|
spec.eip4844_fork_epoch = Some(fork_epoch);
|
||||||
|
}
|
||||||
|
|
||||||
let genesis_state_bytes = if matches.is_present("interop-genesis-state") {
|
let genesis_state_bytes = if matches.is_present("interop-genesis-state") {
|
||||||
let execution_payload_header: Option<ExecutionPayloadHeader<T>> =
|
let execution_payload_header: Option<ExecutionPayloadHeader<T>> =
|
||||||
parse_optional(matches, "execution-payload-header")?
|
parse_optional(matches, "execution-payload-header")?
|
||||||
@ -108,7 +123,7 @@ pub fn run<T: EthSpec>(testnet_dir_path: PathBuf, matches: &ArgMatches) -> Resul
|
|||||||
|
|
||||||
let keypairs = generate_deterministic_keypairs(validator_count);
|
let keypairs = generate_deterministic_keypairs(validator_count);
|
||||||
|
|
||||||
let genesis_state = interop_genesis_state::<T>(
|
let genesis_state = initialize_state_with_validators::<T>(
|
||||||
&keypairs,
|
&keypairs,
|
||||||
genesis_time,
|
genesis_time,
|
||||||
eth1_block_hash.into_root(),
|
eth1_block_hash.into_root(),
|
||||||
@ -130,3 +145,84 @@ pub fn run<T: EthSpec>(testnet_dir_path: PathBuf, matches: &ArgMatches) -> Resul
|
|||||||
|
|
||||||
testnet.write_to_file(testnet_dir_path, overwrite_files)
|
testnet.write_to_file(testnet_dir_path, overwrite_files)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn initialize_state_with_validators<T: EthSpec>(
|
||||||
|
keypairs: &[Keypair],
|
||||||
|
genesis_time: u64,
|
||||||
|
eth1_block_hash: Hash256,
|
||||||
|
execution_payload_header: Option<ExecutionPayloadHeader<T>>,
|
||||||
|
spec: &ChainSpec,
|
||||||
|
) -> Result<BeaconState<T>, String> {
|
||||||
|
// Empty eth1 data
|
||||||
|
let eth1_data = Eth1Data {
|
||||||
|
block_hash: eth1_block_hash,
|
||||||
|
deposit_count: 0,
|
||||||
|
deposit_root: Hash256::from_str(
|
||||||
|
"0xd70a234731285c6804c2a4f56711ddb8c82c99740f207854891028af34e27e5e",
|
||||||
|
)
|
||||||
|
.unwrap(), // empty deposit tree root
|
||||||
|
};
|
||||||
|
let mut state = BeaconState::new(genesis_time, eth1_data, spec);
|
||||||
|
|
||||||
|
// Seed RANDAO with Eth1 entropy
|
||||||
|
state.fill_randao_mixes_with(eth1_block_hash);
|
||||||
|
|
||||||
|
for keypair in keypairs.into_iter() {
|
||||||
|
let withdrawal_credentials = |pubkey: &PublicKey| {
|
||||||
|
let mut credentials = hash(&pubkey.as_ssz_bytes());
|
||||||
|
credentials[0] = spec.bls_withdrawal_prefix_byte;
|
||||||
|
Hash256::from_slice(&credentials)
|
||||||
|
};
|
||||||
|
let amount = spec.max_effective_balance;
|
||||||
|
// Create a new validator.
|
||||||
|
let validator = Validator {
|
||||||
|
pubkey: keypair.pk.clone().into(),
|
||||||
|
withdrawal_credentials: withdrawal_credentials(&keypair.pk),
|
||||||
|
activation_eligibility_epoch: spec.far_future_epoch,
|
||||||
|
activation_epoch: spec.far_future_epoch,
|
||||||
|
exit_epoch: spec.far_future_epoch,
|
||||||
|
withdrawable_epoch: spec.far_future_epoch,
|
||||||
|
effective_balance: std::cmp::min(
|
||||||
|
amount - amount % (spec.effective_balance_increment),
|
||||||
|
spec.max_effective_balance,
|
||||||
|
),
|
||||||
|
slashed: false,
|
||||||
|
};
|
||||||
|
state.validators_mut().push(validator).unwrap();
|
||||||
|
state.balances_mut().push(amount).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
process_activations(&mut state, spec).unwrap();
|
||||||
|
|
||||||
|
if spec
|
||||||
|
.altair_fork_epoch
|
||||||
|
.map_or(false, |fork_epoch| fork_epoch == T::genesis_epoch())
|
||||||
|
{
|
||||||
|
upgrade_to_altair(&mut state, spec).unwrap();
|
||||||
|
|
||||||
|
state.fork_mut().previous_version = spec.altair_fork_version;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Similarly, perform an upgrade to the merge if configured from genesis.
|
||||||
|
if spec
|
||||||
|
.bellatrix_fork_epoch
|
||||||
|
.map_or(false, |fork_epoch| fork_epoch == T::genesis_epoch())
|
||||||
|
{
|
||||||
|
upgrade_to_bellatrix(&mut state, spec).unwrap();
|
||||||
|
|
||||||
|
// Remove intermediate Altair fork from `state.fork`.
|
||||||
|
state.fork_mut().previous_version = spec.bellatrix_fork_version;
|
||||||
|
|
||||||
|
// Override latest execution payload header.
|
||||||
|
// See https://github.com/ethereum/consensus-specs/blob/v1.1.0/specs/merge/beacon-chain.md#testing
|
||||||
|
*state.latest_execution_payload_header_mut() = execution_payload_header.unwrap_or_default();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now that we have our validators, initialize the caches (including the committees)
|
||||||
|
state.build_all_caches(spec).unwrap();
|
||||||
|
|
||||||
|
// Set genesis validators root for domain separation and chain versioning
|
||||||
|
*state.genesis_validators_root_mut() = state.update_validators_tree_hash_cache().unwrap();
|
||||||
|
|
||||||
|
Ok(state)
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user