From ad4e5adabc7b68a9e06ffc17a2df20575100e283 Mon Sep 17 00:00:00 2001 From: Paul Hauner Date: Tue, 26 May 2020 15:31:41 +1000 Subject: [PATCH] Integrate Witti testnet (#1193) * Update for latest master * Shift delay inside loop * Clean up genesis service * Tidy * Tidy logs * Address Michael's comments * Add pre-genesis logging * Remove est time till genesis * Fix time formatting * Tidy * Update docs for Witti * Update JS for Witti * Ensure deposit data is 0x-prefixed hex * Hard code witti testnet dir * Add --auto-register warning * Integrate local sigp testnet source * Reword warning --- Cargo.lock | 1 + book/src/become-a-validator.md | 20 +++++--------------- book/src/js/deposit.js | 2 +- common/eth2_testnet_config/.gitignore | 1 + common/eth2_testnet_config/build.rs | 4 ++-- common/eth2_testnet_config/src/lib.rs | 12 ++++++------ common/validator_dir/Cargo.toml | 1 + common/validator_dir/src/builder.rs | 3 ++- common/validator_dir/src/validator_dir.rs | 14 +++++++++++++- common/validator_dir/tests/tests.rs | 9 ++++++++- validator_client/src/lib.rs | 11 ++++++++++- 11 files changed, 50 insertions(+), 28 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 824bd84626..2494063d56 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5409,6 +5409,7 @@ dependencies = [ "deposit_contract", "eth2_keystore", "eth2_wallet", + "hex 0.4.2", "rand 0.7.3", "rayon", "tempfile", diff --git a/book/src/become-a-validator.md b/book/src/become-a-validator.md index 61fa9c280a..29b04da6e3 100644 --- a/book/src/become-a-validator.md +++ b/book/src/become-a-validator.md @@ -1,20 +1,10 @@ -# Become an Ethereum 2.0 Testnet Validator +# Become an Ethereum 2.0 Testnet Validator on Witti ---- +Running a Lighthouse validator on the [Witti](https://github.com/goerli/witti) +multi-client testnet is easy if you're familiar with the terminal. -**The Schlesi testnet is currently down.** - -Please do not submit any deposits. For updates, see: - -- The Lighthouse ["announcements"](https://discord.gg/cE3GEy) Discord channel. -- The Eth R&D ["Schlesi"](https://discord.gg/GQwzr7) Discord channel. -- [goerli/witti](https://github.com/goerli/witti) for technical information. - ---- - -Running a Lighthouse validator is easy if you're familiar with the terminal. - -Lighthouse runs on Linux, MacOS and Windows and has a Docker work-flow to make things as simple as possible. +Lighthouse runs on Linux, MacOS and Windows and has a Docker work-flow to make +things as simple as possible. ## 0. Acquire Goerli ETH diff --git a/book/src/js/deposit.js b/book/src/js/deposit.js index 5ad3f82150..55e4f6baa4 100644 --- a/book/src/js/deposit.js +++ b/book/src/js/deposit.js @@ -1,6 +1,6 @@ const NETWORK = "5"; const NETWORK_NAME = "Goerli Test Network"; -const DEPOSIT_CONTRACT = "0xA15554BF93a052669B511ae29EA21f3581677ac5"; +const DEPOSIT_CONTRACT = "0x42cc0FcEB02015F145105Cf6f19F90e9BEa76558"; const DEPOSIT_AMOUNT_ETH = "32"; const GAS_LIMIT = "4000000"; const DEPOSIT_DATA_BYTES = 420; diff --git a/common/eth2_testnet_config/.gitignore b/common/eth2_testnet_config/.gitignore index 0f72c8a612..9268a72298 100644 --- a/common/eth2_testnet_config/.gitignore +++ b/common/eth2_testnet_config/.gitignore @@ -1,2 +1,3 @@ testnet* schlesi-* +witti-* diff --git a/common/eth2_testnet_config/build.rs b/common/eth2_testnet_config/build.rs index 6a01b00057..7400d05a3e 100644 --- a/common/eth2_testnet_config/build.rs +++ b/common/eth2_testnet_config/build.rs @@ -6,7 +6,7 @@ use std::fs::File; use std::io::Write; use std::path::PathBuf; -const TESTNET_ID: &str = "schlesi-v0-11"; +const TESTNET_ID: &str = "witti-v0-11-3"; fn main() { if !base_dir().exists() { @@ -38,7 +38,7 @@ pub fn get_all_files() -> Result<(), String> { pub fn get_file(filename: &str) -> Result<(), String> { let url = format!( - "https://raw.githubusercontent.com/goerli/schlesi/839866fe29a1b4df3a87bfe2ff1257c8a58671c9/light/{}", + "https://raw.githubusercontent.com/sigp/witti/6d079b0f10f6bed75cd003e5f0ea5ecbe2044455/lighthouse/{}", filename ); diff --git a/common/eth2_testnet_config/src/lib.rs b/common/eth2_testnet_config/src/lib.rs index 0237295dbf..969dcab5fd 100644 --- a/common/eth2_testnet_config/src/lib.rs +++ b/common/eth2_testnet_config/src/lib.rs @@ -20,14 +20,14 @@ pub const BOOT_ENR_FILE: &str = "boot_enr.yaml"; pub const GENESIS_STATE_FILE: &str = "genesis.ssz"; pub const YAML_CONFIG_FILE: &str = "config.yaml"; -pub const HARDCODED_TESTNET: &str = "schlesi-v0-11"; +pub const HARDCODED_TESTNET: &str = "witti-v0-11-3"; -pub const HARDCODED_YAML_CONFIG: &[u8] = include_bytes!("../schlesi-v0-11/config.yaml"); -pub const HARDCODED_DEPLOY_BLOCK: &[u8] = include_bytes!("../schlesi-v0-11/deploy_block.txt"); +pub const HARDCODED_YAML_CONFIG: &[u8] = include_bytes!("../witti-v0-11-3/config.yaml"); +pub const HARDCODED_DEPLOY_BLOCK: &[u8] = include_bytes!("../witti-v0-11-3/deploy_block.txt"); pub const HARDCODED_DEPOSIT_CONTRACT: &[u8] = - include_bytes!("../schlesi-v0-11/deposit_contract.txt"); -pub const HARDCODED_GENESIS_STATE: &[u8] = include_bytes!("../schlesi-v0-11/genesis.ssz"); -pub const HARDCODED_BOOT_ENR: &[u8] = include_bytes!("../schlesi-v0-11/boot_enr.yaml"); + include_bytes!("../witti-v0-11-3/deposit_contract.txt"); +pub const HARDCODED_GENESIS_STATE: &[u8] = include_bytes!("../witti-v0-11-3/genesis.ssz"); +pub const HARDCODED_BOOT_ENR: &[u8] = include_bytes!("../witti-v0-11-3/boot_enr.yaml"); /// Specifies an Eth2 testnet. /// diff --git a/common/validator_dir/Cargo.toml b/common/validator_dir/Cargo.toml index 3ce0fea457..41d5982935 100644 --- a/common/validator_dir/Cargo.toml +++ b/common/validator_dir/Cargo.toml @@ -19,6 +19,7 @@ rand = "0.7.2" deposit_contract = { path = "../deposit_contract" } rayon = "1.3.0" tree_hash = { path = "../../consensus/tree_hash" } +hex = "0.4.2" [dev-dependencies] tempfile = "3.1.0" diff --git a/common/validator_dir/src/builder.rs b/common/validator_dir/src/builder.rs index 5189d4b446..d81d671158 100644 --- a/common/validator_dir/src/builder.rs +++ b/common/validator_dir/src/builder.rs @@ -175,13 +175,14 @@ impl<'a> Builder<'a> { if path.exists() { return Err(Error::DepositDataAlreadyExists(path)); } else { + let hex = format!("0x{}", hex::encode(&deposit_data)); OpenOptions::new() .write(true) .read(true) .create(true) .open(path.clone()) .map_err(Error::UnableToSaveDepositData)? - .write_all(&deposit_data) + .write_all(hex.as_bytes()) .map_err(Error::UnableToSaveDepositData)? } diff --git a/common/validator_dir/src/validator_dir.rs b/common/validator_dir/src/validator_dir.rs index d68ac6b600..fd37209167 100644 --- a/common/validator_dir/src/validator_dir.rs +++ b/common/validator_dir/src/validator_dir.rs @@ -27,6 +27,9 @@ pub enum Error { UnableToReadPassword(PathBuf), UnableToDecryptKeypair(KeystoreError), UnableToReadDepositData(io::Error), + DepositDataMissing0xPrefix, + DepositDataNotUtf8, + DepositDataInvalidHex(hex::FromHexError), DepositAmountDoesNotExist(PathBuf), UnableToReadDepositAmount(io::Error), UnableToParseDepositAmount(std::num::ParseIntError), @@ -160,7 +163,16 @@ impl ValidatorDir { if !path.exists() { return Ok(None); } - let deposit_data_rlp = read(path).map_err(Error::UnableToReadDepositData)?; + let deposit_data_rlp = read(path) + .map_err(Error::UnableToReadDepositData) + .and_then(|hex_bytes| { + let hex = std::str::from_utf8(&hex_bytes).map_err(|_| Error::DepositDataNotUtf8)?; + if hex.starts_with("0x") { + hex::decode(&hex[2..]).map_err(Error::DepositDataInvalidHex) + } else { + Err(Error::DepositDataMissing0xPrefix) + } + })?; // Read and parse `ETH1_DEPOSIT_AMOUNT_FILE`. let path = self.dir.join(ETH1_DEPOSIT_AMOUNT_FILE); diff --git a/common/validator_dir/tests/tests.rs b/common/validator_dir/tests/tests.rs index 1458fca1ca..cf73b6c2c2 100644 --- a/common/validator_dir/tests/tests.rs +++ b/common/validator_dir/tests/tests.rs @@ -6,7 +6,7 @@ use std::path::Path; use tempfile::{tempdir, TempDir}; use types::{test_utils::generate_deterministic_keypair, EthSpec, Keypair, MainnetEthSpec}; use validator_dir::{ - Builder, ValidatorDir, ETH1_DEPOSIT_TX_HASH_FILE, VOTING_KEYSTORE_FILE, + Builder, ValidatorDir, ETH1_DEPOSIT_DATA_FILE, ETH1_DEPOSIT_TX_HASH_FILE, VOTING_KEYSTORE_FILE, WITHDRAWAL_KEYSTORE_FILE, }; @@ -145,6 +145,13 @@ impl Harness { // Ensure the amount is consistent. assert_eq!(data.deposit_data.amount, amount); + + // Check that the eth1 deposit data file is a valid format. + let hex = + String::from_utf8(fs::read(validator.dir().join(ETH1_DEPOSIT_DATA_FILE)).unwrap()) + .unwrap(); + assert!(hex.starts_with("0x"), "deposit data should have 0x prefix"); + hex::decode(&hex[2..]).unwrap(); } else { // If there was no deposit then we should return `Ok(None)`. assert!(validator.eth1_deposit_data().unwrap().is_none()); diff --git a/validator_client/src/lib.rs b/validator_client/src/lib.rs index d396d40f9b..17d30df753 100644 --- a/validator_client/src/lib.rs +++ b/validator_client/src/lib.rs @@ -14,13 +14,14 @@ pub use config::Config; use attestation_service::{AttestationService, AttestationServiceBuilder}; use block_service::{BlockService, BlockServiceBuilder}; use clap::ArgMatches; +use config::SLASHING_PROTECTION_FILENAME; use duties_service::{DutiesService, DutiesServiceBuilder}; use environment::RuntimeContext; use exit_future::Signal; use fork_service::{ForkService, ForkServiceBuilder}; use notifier::spawn_notifier; use remote_beacon_node::RemoteBeaconNode; -use slog::{error, info, Logger}; +use slog::{error, info, warn, Logger}; use slot_clock::SlotClock; use slot_clock::SystemTimeSlotClock; use std::time::{SystemTime, UNIX_EPOCH}; @@ -71,6 +72,14 @@ impl ProductionValidatorClient { "datadir" => format!("{:?}", config.data_dir), ); + if !config.data_dir.join(SLASHING_PROTECTION_FILENAME).exists() && !config.auto_register { + warn!( + log_1, + "Will not register any validators"; + "msg" => "strongly consider using --auto-register on the first use", + ); + } + let beacon_node = RemoteBeaconNode::new_with_timeout(config.http_server.clone(), HTTP_TIMEOUT) .map_err(|e| format!("Unable to init beacon node http client: {}", e))?;