mirror of
https://github.com/sigp/lighthouse.git
synced 2026-04-17 21:08:32 +00:00
Implement tree hash caching (#584)
* Implement basic tree hash caching * Use spaces to indent top-level Cargo.toml * Optimize BLS tree hash by hashing bytes directly * Implement tree hash caching for validator registry * Persist BeaconState tree hash cache to disk * Address Paul's review comments
This commit is contained in:
@@ -1,19 +0,0 @@
|
||||
// This build script is symlinked from each project that requires BLS's "fake crypto",
|
||||
// so that the `fake_crypto` feature of every sub-crate can be turned on by running
|
||||
// with FAKE_CRYPTO=1 from the top-level workspace.
|
||||
// At some point in the future it might be possible to do:
|
||||
// $ cargo test --all --release --features fake_crypto
|
||||
// but at the present time this doesn't work.
|
||||
// Related: https://github.com/rust-lang/cargo/issues/5364
|
||||
fn main() {
|
||||
if let Ok(fake_crypto) = std::env::var("FAKE_CRYPTO") {
|
||||
if fake_crypto == "1" {
|
||||
println!("cargo:rustc-cfg=feature=\"fake_crypto\"");
|
||||
println!("cargo:rerun-if-env-changed=FAKE_CRYPTO");
|
||||
println!(
|
||||
"cargo:warning=[{}]: Compiled with fake BLS cryptography. DO NOT USE, TESTING ONLY",
|
||||
std::env::var("CARGO_PKG_NAME").unwrap()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -155,7 +155,7 @@ impl_ssz!(
|
||||
"AggregateSignature"
|
||||
);
|
||||
|
||||
impl_tree_hash!(AggregateSignature, U96);
|
||||
impl_tree_hash!(AggregateSignature, BLS_AGG_SIG_BYTE_SIZE);
|
||||
|
||||
impl Serialize for AggregateSignature {
|
||||
/// Serde serialization is compliant the Ethereum YAML test format.
|
||||
|
||||
@@ -93,7 +93,7 @@ impl_ssz!(
|
||||
"FakeAggregateSignature"
|
||||
);
|
||||
|
||||
impl_tree_hash!(FakeAggregateSignature, U96);
|
||||
impl_tree_hash!(FakeAggregateSignature, BLS_AGG_SIG_BYTE_SIZE);
|
||||
|
||||
impl Serialize for FakeAggregateSignature {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
|
||||
@@ -102,7 +102,7 @@ impl default::Default for FakePublicKey {
|
||||
|
||||
impl_ssz!(FakePublicKey, BLS_PUBLIC_KEY_BYTE_SIZE, "FakePublicKey");
|
||||
|
||||
impl_tree_hash!(FakePublicKey, U48);
|
||||
impl_tree_hash!(FakePublicKey, BLS_PUBLIC_KEY_BYTE_SIZE);
|
||||
|
||||
impl Serialize for FakePublicKey {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
|
||||
@@ -91,7 +91,7 @@ impl FakeSignature {
|
||||
|
||||
impl_ssz!(FakeSignature, BLS_SIG_BYTE_SIZE, "FakeSignature");
|
||||
|
||||
impl_tree_hash!(FakeSignature, U96);
|
||||
impl_tree_hash!(FakeSignature, BLS_SIG_BYTE_SIZE);
|
||||
|
||||
impl Serialize for FakeSignature {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
|
||||
@@ -42,7 +42,7 @@ macro_rules! impl_ssz {
|
||||
}
|
||||
|
||||
macro_rules! impl_tree_hash {
|
||||
($type: ty, $byte_size: ident) => {
|
||||
($type: ty, $byte_size: expr) => {
|
||||
impl tree_hash::TreeHash for $type {
|
||||
fn tree_hash_type() -> tree_hash::TreeHashType {
|
||||
tree_hash::TreeHashType::Vector
|
||||
@@ -57,16 +57,19 @@ macro_rules! impl_tree_hash {
|
||||
}
|
||||
|
||||
fn tree_hash_root(&self) -> Vec<u8> {
|
||||
let vector: ssz_types::FixedVector<u8, ssz_types::typenum::$byte_size> =
|
||||
ssz_types::FixedVector::from(self.as_ssz_bytes());
|
||||
vector.tree_hash_root()
|
||||
// We could use the tree hash implementation for `FixedVec<u8, $byte_size>`,
|
||||
// but benchmarks have show that to be at least 15% slower because of the
|
||||
// unnecessary copying and allocation (one Vec per byte)
|
||||
let values_per_chunk = tree_hash::BYTES_PER_CHUNK;
|
||||
let minimum_chunk_count = ($byte_size + values_per_chunk - 1) / values_per_chunk;
|
||||
tree_hash::merkle_root(&self.as_ssz_bytes(), minimum_chunk_count)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! bytes_struct {
|
||||
($name: ident, $type: ty, $byte_size: expr, $small_name: expr, $ssz_type_size: ident,
|
||||
($name: ident, $type: ty, $byte_size: expr, $small_name: expr,
|
||||
$type_str: expr, $byte_size_str: expr) => {
|
||||
#[doc = "Stores `"]
|
||||
#[doc = $byte_size_str]
|
||||
@@ -82,9 +85,9 @@ macro_rules! bytes_struct {
|
||||
#[derive(Clone)]
|
||||
pub struct $name([u8; $byte_size]);
|
||||
};
|
||||
($name: ident, $type: ty, $byte_size: expr, $small_name: expr, $ssz_type_size: ident) => {
|
||||
bytes_struct!($name, $type, $byte_size, $small_name, $ssz_type_size, stringify!($type),
|
||||
stringify!($byte_size));
|
||||
($name: ident, $type: ty, $byte_size: expr, $small_name: expr) => {
|
||||
bytes_struct!($name, $type, $byte_size, $small_name, stringify!($type),
|
||||
stringify!($byte_size));
|
||||
|
||||
impl $name {
|
||||
pub fn from_bytes(bytes: &[u8]) -> Result<Self, ssz::DecodeError> {
|
||||
@@ -144,7 +147,7 @@ macro_rules! bytes_struct {
|
||||
|
||||
impl_ssz!($name, $byte_size, "$type");
|
||||
|
||||
impl_tree_hash!($name, $ssz_type_size);
|
||||
impl_tree_hash!($name, $byte_size);
|
||||
|
||||
impl serde::ser::Serialize for $name {
|
||||
/// Serde serialization is compliant the Ethereum YAML test format.
|
||||
|
||||
@@ -94,7 +94,7 @@ impl default::Default for PublicKey {
|
||||
|
||||
impl_ssz!(PublicKey, BLS_PUBLIC_KEY_BYTE_SIZE, "PublicKey");
|
||||
|
||||
impl_tree_hash!(PublicKey, U48);
|
||||
impl_tree_hash!(PublicKey, BLS_PUBLIC_KEY_BYTE_SIZE);
|
||||
|
||||
impl Serialize for PublicKey {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
|
||||
@@ -6,8 +6,7 @@ bytes_struct!(
|
||||
PublicKeyBytes,
|
||||
PublicKey,
|
||||
BLS_PUBLIC_KEY_BYTE_SIZE,
|
||||
"public key",
|
||||
U48
|
||||
"public key"
|
||||
);
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -49,7 +49,7 @@ impl SecretKey {
|
||||
|
||||
impl_ssz!(SecretKey, BLS_SECRET_KEY_BYTE_SIZE, "SecretKey");
|
||||
|
||||
impl_tree_hash!(SecretKey, U48);
|
||||
impl_tree_hash!(SecretKey, BLS_SECRET_KEY_BYTE_SIZE);
|
||||
|
||||
impl Serialize for SecretKey {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
|
||||
@@ -108,7 +108,7 @@ impl Signature {
|
||||
|
||||
impl_ssz!(Signature, BLS_SIG_BYTE_SIZE, "Signature");
|
||||
|
||||
impl_tree_hash!(Signature, U96);
|
||||
impl_tree_hash!(Signature, BLS_SIG_BYTE_SIZE);
|
||||
|
||||
impl Serialize for Signature {
|
||||
/// Serde serialization is compliant the Ethereum YAML test format.
|
||||
|
||||
@@ -2,13 +2,7 @@ use ssz::{Decode, DecodeError, Encode};
|
||||
|
||||
use super::{Signature, BLS_SIG_BYTE_SIZE};
|
||||
|
||||
bytes_struct!(
|
||||
SignatureBytes,
|
||||
Signature,
|
||||
BLS_SIG_BYTE_SIZE,
|
||||
"signature",
|
||||
U96
|
||||
);
|
||||
bytes_struct!(SignatureBytes, Signature, BLS_SIG_BYTE_SIZE, "signature");
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
Reference in New Issue
Block a user