lighthouse/common/eth2_network_config/build.rs
Paul Hauner d61f507184 Add Holesky (#4653)
## Issue Addressed

NA

## Proposed Changes

Add the Holesky network config as per 36e4ff2d51/custom_config_data.

Since the genesis state is ~190MB, I've opted to *not* include it in the binary and instead download it at runtime (see #4564 for context). To download this file we have:

- A hard-coded URL for a SigP-hosted S3 bucket with the Holesky genesis state. Assuming this download works correctly, users will be none the wiser that the state wasn't included in the binary (apart from some additional logs)
- If the user provides a `--checkpoint-sync-url` flag, then LH will download the genesis state from that server rather than our S3 bucket.
- If the user provides a `--genesis-state-url` flag, then LH will download the genesis state from that server regardless of the S3 bucket or `--checkpoint-sync-url` flag.
- Whenever a genesis state is downloaded it is checked against a checksum baked into the binary.
- A genesis state will never be downloaded if it's already included in the binary.
- There is a `--genesis-state-url-timeout` flag to tweak the timeout for downloading the genesis state file.

## Log Output

Example of log output when a state is downloaded:

```bash
Aug 23 05:40:13.424 INFO Logging to file                         path: "/Users/paul/.lighthouse/holesky/beacon/logs/beacon.log"
Aug 23 05:40:13.425 INFO Lighthouse started                      version: Lighthouse/v4.3.0-bd9931f+
Aug 23 05:40:13.425 INFO Configured for network                  name: holesky
Aug 23 05:40:13.426 INFO Data directory initialised              datadir: /Users/paul/.lighthouse/holesky
Aug 23 05:40:13.427 INFO Deposit contract                        address: 0x4242424242424242424242424242424242424242, deploy_block: 0
Aug 23 05:40:13.427 INFO Downloading genesis state               info: this may take some time on testnets with large validator counts, timeout: 60s, server: https://sigp-public-genesis-states.s3.ap-southeast-2.amazonaws.com/
Aug 23 05:40:29.895 INFO Starting from known genesis state       service: beacon
```

Example of log output when there are no URLs specified:

```
Aug 23 06:29:51.645 INFO Logging to file                         path: "/Users/paul/.lighthouse/goerli/beacon/logs/beacon.log"
Aug 23 06:29:51.646 INFO Lighthouse started                      version: Lighthouse/v4.3.0-666a39c+
Aug 23 06:29:51.646 INFO Configured for network                  name: goerli
Aug 23 06:29:51.647 INFO Data directory initialised              datadir: /Users/paul/.lighthouse/goerli
Aug 23 06:29:51.647 INFO Deposit contract                        address: 0xff50ed3d0ec03ac01d4c79aad74928bff48a7b2b, deploy_block: 4367322
The genesis state is not present in the binary and there are no known download URLs. Please use --checkpoint-sync-url or --genesis-state-url.
```

## Additional Info

I tested the `--genesis-state-url` flag with all 9 Goerli checkpoint sync servers on https://eth-clients.github.io/checkpoint-sync-endpoints/ and they all worked 🎉 

My IDE eagerly formatted some `Cargo.toml`. I've disabled it but I don't see the value in spending time reverting the changes that are already there.

I also added the `GenesisStateBytes` enum to avoid an unnecessary clone on the genesis state bytes baked into the binary. This is not a huge deal on Mainnet, but will become more relevant when testing with big genesis states.

When we do a fresh checkpoint sync we're downloading the genesis state to check the `genesis_validators_root` against the finalised state we receive. This is not *entirely* pointless, since we verify the checksum when we download the genesis state so we are actually guaranteeing that the finalised state is on the same network. There might be a smarter/less-download-y way to go about this, but I've run out of cycles to figure that out. Perhaps we can grab it in the next release?
2023-08-28 05:34:27 +00:00

59 lines
2.1 KiB
Rust

//! Extracts zipped genesis states on first run.
use eth2_config::{
Eth2NetArchiveAndDirectory, GenesisStateSource, ETH2_NET_DIRS, GENESIS_FILE_NAME,
};
use std::fs::File;
use std::io;
use zip::ZipArchive;
fn main() {
for network in ETH2_NET_DIRS {
match uncompress_state(network) {
Ok(()) => (),
Err(e) => panic!(
"Failed to uncompress {} genesis state zip file: {}",
network.name, e
),
}
}
}
/// Uncompress the network configs archive into a network configs folder.
fn uncompress_state(network: &Eth2NetArchiveAndDirectory<'static>) -> Result<(), String> {
let genesis_ssz_path = network.dir().join(GENESIS_FILE_NAME);
// Take care to not overwrite the genesis.ssz if it already exists, as that causes
// spurious rebuilds.
if genesis_ssz_path.exists() {
return Ok(());
}
if network.genesis_state_source == GenesisStateSource::IncludedBytes {
// Extract genesis state from genesis.ssz.zip
let archive_path = network.genesis_state_archive();
let archive_file = File::open(&archive_path)
.map_err(|e| format!("Failed to open archive file {:?}: {:?}", archive_path, e))?;
let mut archive =
ZipArchive::new(archive_file).map_err(|e| format!("Error with zip file: {}", e))?;
let mut file = archive.by_name(GENESIS_FILE_NAME).map_err(|e| {
format!(
"Error retrieving file {} inside zip: {}",
GENESIS_FILE_NAME, e
)
})?;
let mut outfile = File::create(&genesis_ssz_path)
.map_err(|e| format!("Error while creating file {:?}: {}", genesis_ssz_path, e))?;
io::copy(&mut file, &mut outfile)
.map_err(|e| format!("Error writing file {:?}: {}", genesis_ssz_path, e))?;
} else {
// Create empty genesis.ssz if genesis is unknown or to be downloaded via URL.
// This is a bit of a hack to make `include_bytes!` easier to deal with.
File::create(genesis_ssz_path)
.map_err(|e| format!("Failed to create {}: {}", GENESIS_FILE_NAME, e))?;
}
Ok(())
}