Files
lighthouse/testing/ef_tests/src/decode.rs
Eitan Seri-Levi 3913ea44c6 Persist light client updates (#5545)
* persist light client updates

* update beacon chain to serve light client updates

* resolve todos

* cache best update

* extend cache parts

* is better light client update

* resolve merge conflict

* initial api changes

* add lc update db column

* fmt

* added tests

* add sim

* Merge branch 'unstable' of https://github.com/sigp/lighthouse into persist-light-client-updates

* fix some weird issues with the simulator

* tests

* Merge branch 'unstable' of https://github.com/sigp/lighthouse into persist-light-client-updates

* test changes

* merge conflict

* testing

* started work on ef tests and some code clean up

* update tests

* linting

* noop pre altair, were still failing on electra though

* allow for zeroed light client header

* Merge branch 'unstable' of https://github.com/sigp/lighthouse into persist-light-client-updates

* merge unstable

* remove unwraps

* remove unwraps

* Update light_client_update.rs

* merge unstable

* move functionality to helper methods

* refactor is best update fn

* refactor is best update fn

* improve organization of light client server cache logic

* fork diget calc, and only spawn as many blcoks as we need for the lc update test

* fetch lc update from the cache if it exists

* fmt

* Fix beacon_chain tests

* Add debug code to update ranking_order ef test

* Fix compare code

* merge conflicts

* fix test

* Merge branch 'persist-light-client-updates' of https://github.com/eserilev/lighthouse into persist-light-client-updates

* Use blinded blocks for light client proofs

* fix ef test

* merge conflicts

* fix lc update check

* Lint

* resolve merge conflict

* Merge branch 'persist-light-client-updates' of https://github.com/eserilev/lighthouse into persist-light-client-updates

* revert basic sim

* small fix

* revert sim

* Review PR

* resolve merge conflicts

* Merge branch 'unstable' into persist-light-client-updates
2024-08-09 07:36:20 +00:00

108 lines
3.4 KiB
Rust

use super::*;
use fs2::FileExt;
use snap::raw::Decoder;
use std::fs::{self};
use std::io::Write;
use std::path::Path;
use std::path::PathBuf;
use types::{BeaconState, LightClientUpdate};
/// See `log_file_access` for details.
const ACCESSED_FILE_LOG_FILENAME: &str = ".accessed_file_log.txt";
/// Writes `path` to a file that contains a log of all files accessed during testing.
///
/// That log file might later be used to ensure that all spec tests were accessed and none were
/// accidentally missed.
pub fn log_file_access<P: AsRef<Path>>(file_accessed: P) {
let passed_test_list_path =
PathBuf::from(env!("CARGO_MANIFEST_DIR")).join(ACCESSED_FILE_LOG_FILENAME);
let mut file = fs::File::options()
.append(true)
.create(true)
.open(passed_test_list_path)
.expect("should open file");
file.lock_exclusive().expect("unable to lock file");
writeln!(&mut file, "{:?}", file_accessed.as_ref()).expect("should write to file");
file.unlock().expect("unable to unlock file");
}
pub fn yaml_decode<T: serde::de::DeserializeOwned>(string: &str) -> Result<T, Error> {
serde_yaml::from_str(string).map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))
}
pub fn yaml_decode_file<T: serde::de::DeserializeOwned>(path: &Path) -> Result<T, Error> {
log_file_access(path);
fs::read_to_string(path)
.map_err(|e| {
Error::FailedToParseTest(format!("Unable to load {}: {:?}", path.display(), e))
})
.and_then(|s| yaml_decode(&s))
}
/// Decode a Snappy encoded file.
///
/// Files in the EF tests are unframed, so we need to use `snap::raw::Decoder`.
pub fn snappy_decode_file(path: &Path) -> Result<Vec<u8>, Error> {
log_file_access(path);
let bytes = fs::read(path).map_err(|e| {
Error::FailedToParseTest(format!("Unable to load {}: {:?}", path.display(), e))
})?;
let mut decoder = Decoder::new();
decoder.decompress_vec(&bytes).map_err(|e| {
Error::FailedToParseTest(format!(
"Error decoding snappy encoding for {}: {:?}",
path.display(),
e
))
})
}
pub fn ssz_decode_file_with<T, F>(path: &Path, f: F) -> Result<T, Error>
where
F: FnOnce(&[u8]) -> Result<T, ssz::DecodeError>,
{
log_file_access(path);
let bytes = snappy_decode_file(path)?;
f(&bytes).map_err(|e| {
match e {
// NOTE: this is a bit hacky, but seemingly better than the alternatives
ssz::DecodeError::BytesInvalid(message) if message.contains("Blst") => {
Error::InvalidBLSInput(message)
}
e => Error::FailedToParseTest(format!(
"Unable to parse SSZ at {}: {:?}",
path.display(),
e
)),
}
})
}
pub fn ssz_decode_file<T: ssz::Decode>(path: &Path) -> Result<T, Error> {
log_file_access(path);
ssz_decode_file_with(path, T::from_ssz_bytes)
}
pub fn ssz_decode_state<E: EthSpec>(
path: &Path,
spec: &ChainSpec,
) -> Result<BeaconState<E>, Error> {
log_file_access(path);
ssz_decode_file_with(path, |bytes| BeaconState::from_ssz_bytes(bytes, spec))
}
pub fn ssz_decode_light_client_update<E: EthSpec>(
path: &Path,
fork_name: &ForkName,
) -> Result<LightClientUpdate<E>, Error> {
log_file_access(path);
ssz_decode_file_with(path, |bytes| {
LightClientUpdate::from_ssz_bytes(bytes, fork_name)
})
}