Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v1.1.1 spec updates #2684

Merged
merged 8 commits into from
Oct 8, 2021
Merged
Show file tree
Hide file tree
Changes from 4 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
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions beacon_node/beacon_chain/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -928,6 +928,7 @@ mod test {
&generate_deterministic_keypairs(validator_count),
genesis_time,
Hash256::from_slice(DEFAULT_ETH1_BLOCK_HASH),
None,
&spec,
)
.expect("should create interop genesis state");
Expand Down Expand Up @@ -997,6 +998,7 @@ mod test {
&keypairs,
genesis_time,
Hash256::from_slice(DEFAULT_ETH1_BLOCK_HASH),
None,
spec,
)
.expect("should build state");
Expand Down
2 changes: 2 additions & 0 deletions beacon_node/beacon_chain/src/test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ impl<E: EthSpec> Builder<EphemeralHarnessType<E>> {
&validator_keypairs,
HARNESS_GENESIS_TIME,
Hash256::from_slice(DEFAULT_ETH1_BLOCK_HASH),
None,
builder.get_spec(),
)
.expect("should generate interop state");
Expand All @@ -229,6 +230,7 @@ impl<E: EthSpec> Builder<DiskHarnessType<E>> {
&validator_keypairs,
HARNESS_GENESIS_TIME,
Hash256::from_slice(DEFAULT_ETH1_BLOCK_HASH),
None,
builder.get_spec(),
)
.expect("should generate interop state");
Expand Down
1 change: 1 addition & 0 deletions beacon_node/client/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ where
&keypairs,
genesis_time,
Hash256::from_slice(DEFAULT_ETH1_BLOCK_HASH),
None,
&spec,
)?;
builder.genesis_state(genesis_state).map(|v| (v, None))?
Expand Down
1 change: 1 addition & 0 deletions beacon_node/genesis/src/eth1_genesis_service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,7 @@ impl Eth1GenesisService {
eth1_block.hash,
eth1_block.timestamp,
genesis_deposits(deposit_logs, spec)?,
None,
spec,
)
.map_err(|e| format!("Unable to initialize genesis state: {:?}", e))?;
Expand Down
9 changes: 7 additions & 2 deletions beacon_node/genesis/src/interop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ use eth2_hashing::hash;
use rayon::prelude::*;
use ssz::Encode;
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];

Expand All @@ -15,9 +18,9 @@ pub fn interop_genesis_state<T: EthSpec>(
keypairs: &[Keypair],
genesis_time: u64,
eth1_block_hash: Hash256,
execution_payload_hearder: Option<ExecutionPayloadHeader<T>>,
paulhauner marked this conversation as resolved.
Show resolved Hide resolved
spec: &ChainSpec,
) -> Result<BeaconState<T>, String> {
let eth1_block_hash = eth1_block_hash;
let eth1_timestamp = 2_u64.pow(40);
let amount = spec.max_effective_balance;

Expand Down Expand Up @@ -47,6 +50,7 @@ pub fn interop_genesis_state<T: EthSpec>(
eth1_block_hash,
eth1_timestamp,
genesis_deposits(datas, spec)?,
execution_payload_hearder,
paulhauner marked this conversation as resolved.
Show resolved Hide resolved
spec,
)
.map_err(|e| format!("Unable to initialize genesis state: {:?}", e))?;
Expand Down Expand Up @@ -80,6 +84,7 @@ mod test {
&keypairs,
genesis_time,
Hash256::from_slice(DEFAULT_ETH1_BLOCK_HASH),
None,
spec,
)
.expect("should build state");
Expand Down
1 change: 1 addition & 0 deletions beacon_node/network/src/subnet_service/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ impl TestBeaconChain {
&keypairs,
0,
Hash256::from_slice(DEFAULT_ETH1_BLOCK_HASH),
None,
&spec,
)
.expect("should generate interop state"),
Expand Down
16 changes: 6 additions & 10 deletions consensus/state_processing/src/genesis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ use crate::common::DepositDataTree;
use crate::upgrade::{upgrade_to_altair, upgrade_to_merge};
use safe_arith::{ArithError, SafeArith};
use tree_hash::TreeHash;
use types::consts::merge_testing::{GENESIS_BASE_FEE_PER_GAS, GENESIS_GAS_LIMIT};
use types::DEPOSIT_TREE_DEPTH;
use types::*;

Expand All @@ -14,6 +13,7 @@ pub fn initialize_beacon_state_from_eth1<T: EthSpec>(
eth1_block_hash: Hash256,
eth1_timestamp: u64,
deposits: Vec<Deposit>,
execution_payload_header: Option<ExecutionPayloadHeader<T>>,
spec: &ChainSpec,
) -> Result<BeaconState<T>, BlockProcessingError> {
let genesis_time = eth2_genesis_time(eth1_timestamp, spec)?;
Expand Down Expand Up @@ -52,6 +52,8 @@ pub fn initialize_beacon_state_from_eth1<T: EthSpec>(
.map_or(false, |fork_epoch| fork_epoch == T::genesis_epoch())
{
upgrade_to_altair(&mut state, spec)?;

state.fork_mut().previous_version = spec.altair_fork_version;
}

// Similarly, perform an upgrade to the merge if configured from genesis.
Expand All @@ -62,18 +64,12 @@ pub fn initialize_beacon_state_from_eth1<T: EthSpec>(
upgrade_to_merge(&mut state, spec)?;

// 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.
// See https://github.com/ethereum/consensus-specs/blob/v1.1.0/specs/merge/beacon-chain.md#testing
*state.latest_execution_payload_header_mut()? = ExecutionPayloadHeader {
block_hash: eth1_block_hash,
timestamp: eth1_timestamp,
random: eth1_block_hash,
gas_limit: GENESIS_GAS_LIMIT,
base_fee_per_gas: GENESIS_BASE_FEE_PER_GAS,
..ExecutionPayloadHeader::default()
};
*state.latest_execution_payload_header_mut()? =
execution_payload_header.unwrap_or_default();
}

// Now that we have our validators, initialize the caches (including the committees)
Expand Down
1 change: 1 addition & 0 deletions consensus/types/src/beacon_state/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -562,6 +562,7 @@ fn tree_hash_cache_linear_history_long_skip() {
&keypairs,
0,
Hash256::from_slice(DEFAULT_ETH1_BLOCK_HASH),
None,
spec,
)
.unwrap();
Expand Down
10 changes: 0 additions & 10 deletions consensus/types/src/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,3 @@ pub mod altair {

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,
]);
}
1 change: 1 addition & 0 deletions lcli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ serde_json = "1.0.66"
env_logger = "0.9.0"
types = { path = "../consensus/types" }
state_processing = { path = "../consensus/state_processing" }
int_to_bytes = { path = "../consensus/int_to_bytes" }
eth2_ssz = "0.4.0"
environment = { path = "../lighthouse/environment" }
eth2_network_config = { path = "../common/eth2_network_config" }
Expand Down
39 changes: 39 additions & 0 deletions lcli/src/create_payload_header.rs
Original file line number Diff line number Diff line change
@@ -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(())
}
1 change: 1 addition & 0 deletions lcli/src/interop_genesis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ pub fn run<T: EthSpec>(testnet_dir: PathBuf, matches: &ArgMatches) -> Result<(),
&keypairs,
genesis_time,
Hash256::from_slice(DEFAULT_ETH1_BLOCK_HASH),
None,
&spec,
)?;

Expand Down
63 changes: 63 additions & 0 deletions lcli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
extern crate log;
mod change_genesis_time;
mod check_deposit_data;
mod create_payload_header;
mod deploy_deposit_contract;
mod eth1_genesis;
mod etl;
Expand Down Expand Up @@ -271,6 +272,57 @@ fn main() {
.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::with_name("new-testnet")
.about(
Expand Down Expand Up @@ -426,6 +478,15 @@ fn main() {
.takes_value(true)
.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::with_name("validator-count")
.long("validator-count")
Expand Down Expand Up @@ -653,6 +714,8 @@ fn run<T: EthSpec>(
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)) => {
replace_state_pubkeys::run::<T>(testnet_dir, matches)
.map_err(|e| format!("Failed to run replace-state-pubkeys command: {}", e))
Expand Down
58 changes: 47 additions & 11 deletions lcli/src/new_testnet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,15 @@ use clap::ArgMatches;
use clap_utils::{parse_optional, parse_required, parse_ssz_optional};
use eth2_network_config::Eth2NetworkConfig;
use genesis::interop_genesis_state;
use ssz::Decode;
use ssz::Encode;
use std::fs::File;
use std::io::Read;
use std::path::PathBuf;
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> {
let deposit_contract_address: Address = parse_required(matches, "deposit-contract-address")?;
Expand Down Expand Up @@ -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 eth1_block_hash = parse_required(matches, "eth1-block-hash")?;
let validator_count = parse_required(matches, "validator-count")?;
let genesis_time = if let Some(time) = parse_optional(matches, "genesis-time")? {
time
let execution_payload_header: Option<ExecutionPayloadHeader<T>> =
parse_optional(matches, "execution-payload-header")?
.map(|filename: String| {
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 {
SystemTime::now()
.duration_since(UNIX_EPOCH)
.map_err(|e| format!("Unable to get time: {:?}", e))?
.as_secs()
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()
.duration_since(UNIX_EPOCH)
.map_err(|e| format!("Unable to get time: {:?}", e))?
.as_secs(),
);
(eth1_block_hash, genesis_time)
};

let validator_count = parse_required(matches, "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())
} else {
Expand Down
Loading