mirror of
https://github.com/sigp/lighthouse.git
synced 2026-05-07 16:55:46 +00:00
Merge branch 'unstable' into deneb-free-blobs
# Conflicts: # .github/workflows/docker.yml # .github/workflows/local-testnet.yml # .github/workflows/test-suite.yml # Cargo.lock # Cargo.toml # beacon_node/beacon_chain/src/beacon_chain.rs # beacon_node/beacon_chain/src/builder.rs # beacon_node/beacon_chain/src/test_utils.rs # beacon_node/execution_layer/src/engine_api/json_structures.rs # beacon_node/network/src/beacon_processor/mod.rs # beacon_node/network/src/beacon_processor/worker/gossip_methods.rs # beacon_node/network/src/sync/backfill_sync/mod.rs # beacon_node/store/src/config.rs # beacon_node/store/src/hot_cold_store.rs # common/eth2_network_config/Cargo.toml # consensus/ssz/src/decode/impls.rs # consensus/ssz_derive/src/lib.rs # consensus/ssz_derive/tests/tests.rs # consensus/ssz_types/src/serde_utils/mod.rs # consensus/tree_hash/src/impls.rs # consensus/tree_hash/src/lib.rs # consensus/types/Cargo.toml # consensus/types/src/beacon_state.rs # consensus/types/src/chain_spec.rs # consensus/types/src/eth_spec.rs # consensus/types/src/fork_name.rs # lcli/Cargo.toml # lcli/src/main.rs # lcli/src/new_testnet.rs # scripts/local_testnet/el_bootnode.sh # scripts/local_testnet/genesis.json # scripts/local_testnet/geth.sh # scripts/local_testnet/setup.sh # scripts/local_testnet/start_local_testnet.sh # scripts/local_testnet/vars.env # scripts/tests/doppelganger_protection.sh # scripts/tests/genesis.json # scripts/tests/vars.env # testing/ef_tests/Cargo.toml # validator_client/src/block_service.rs
This commit is contained in:
@@ -5,15 +5,15 @@ authors = ["Paul Hauner <paul@paulhauner.com>"]
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
eth2_ssz = "0.4.1"
|
||||
tree_hash = "0.4.1"
|
||||
ethereum_ssz = "0.5.0"
|
||||
tree_hash = "0.5.0"
|
||||
milagro_bls = { git = "https://github.com/sigp/milagro_bls", tag = "v1.4.2", optional = true }
|
||||
rand = "0.7.3"
|
||||
serde = "1.0.116"
|
||||
serde_derive = "1.0.116"
|
||||
eth2_serde_utils = "0.1.1"
|
||||
ethereum_serde_utils = "0.5.0"
|
||||
hex = "0.4.2"
|
||||
eth2_hashing = "0.3.0"
|
||||
ethereum_hashing = "1.0.0-beta.2"
|
||||
ethereum-types = "0.14.1"
|
||||
arbitrary = { version = "1.0", features = ["derive"], optional = true }
|
||||
zeroize = { version = "1.4.2", features = ["zeroize_derive"] }
|
||||
|
||||
@@ -4,9 +4,9 @@ use crate::{
|
||||
generic_signature::{GenericSignature, TSignature},
|
||||
Error, Hash256, INFINITY_SIGNATURE, SIGNATURE_BYTES_LEN,
|
||||
};
|
||||
use eth2_serde_utils::hex::encode as hex_encode;
|
||||
use serde::de::{Deserialize, Deserializer};
|
||||
use serde::ser::{Serialize, Serializer};
|
||||
use serde_utils::hex::encode as hex_encode;
|
||||
use ssz::{Decode, Encode};
|
||||
use std::fmt;
|
||||
use std::hash::{Hash, Hasher};
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use crate::generic_public_key_bytes::GenericPublicKeyBytes;
|
||||
use crate::Error;
|
||||
use eth2_serde_utils::hex::encode as hex_encode;
|
||||
use serde::de::{Deserialize, Deserializer};
|
||||
use serde::ser::{Serialize, Serializer};
|
||||
use serde_utils::hex::encode as hex_encode;
|
||||
use ssz::{Decode, Encode};
|
||||
use std::fmt;
|
||||
use std::hash::{Hash, Hasher};
|
||||
|
||||
@@ -2,9 +2,9 @@ use crate::{
|
||||
generic_public_key::{GenericPublicKey, TPublicKey},
|
||||
Error, PUBLIC_KEY_BYTES_LEN,
|
||||
};
|
||||
use eth2_serde_utils::hex::encode as hex_encode;
|
||||
use serde::de::{Deserialize, Deserializer};
|
||||
use serde::ser::{Serialize, Serializer};
|
||||
use serde_utils::hex::encode as hex_encode;
|
||||
use ssz::{Decode, Encode};
|
||||
use std::convert::TryInto;
|
||||
use std::fmt;
|
||||
|
||||
@@ -2,9 +2,9 @@ use crate::{
|
||||
generic_public_key::{GenericPublicKey, TPublicKey},
|
||||
Error, Hash256,
|
||||
};
|
||||
use eth2_serde_utils::hex::encode as hex_encode;
|
||||
use serde::de::{Deserialize, Deserializer};
|
||||
use serde::ser::{Serialize, Serializer};
|
||||
use serde_utils::hex::encode as hex_encode;
|
||||
use ssz::{Decode, Encode};
|
||||
use std::fmt;
|
||||
use std::hash::{Hash, Hasher};
|
||||
|
||||
@@ -3,9 +3,9 @@ use crate::{
|
||||
generic_signature::{GenericSignature, TSignature},
|
||||
Error, INFINITY_SIGNATURE, SIGNATURE_BYTES_LEN,
|
||||
};
|
||||
use eth2_serde_utils::hex::encode as hex_encode;
|
||||
use serde::de::{Deserialize, Deserializer};
|
||||
use serde::ser::{Serialize, Serializer};
|
||||
use serde_utils::hex::encode as hex_encode;
|
||||
use ssz::{Decode, Encode};
|
||||
use std::convert::TryInto;
|
||||
use std::fmt;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::PublicKey;
|
||||
use eth2_hashing::hash;
|
||||
use ethereum_hashing::hash;
|
||||
use ssz::Encode;
|
||||
|
||||
/// Returns the withdrawal credentials for a given public key.
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
[target.wasm32-unknown-unknown]
|
||||
runner = 'wasm-bindgen-test-runner'
|
||||
@@ -1,24 +0,0 @@
|
||||
[package]
|
||||
name = "eth2_hashing"
|
||||
version = "0.3.0"
|
||||
authors = ["Paul Hauner <paul@paulhauner.com>"]
|
||||
edition = "2021"
|
||||
license = "Apache-2.0"
|
||||
description = "Hashing primitives used in Ethereum 2.0"
|
||||
|
||||
[dependencies]
|
||||
lazy_static = { version = "1.4.0", optional = true }
|
||||
cpufeatures = { version = "0.2.5", optional = true }
|
||||
ring = "0.16.19"
|
||||
sha2 = "0.10"
|
||||
|
||||
[dev-dependencies]
|
||||
rustc-hex = "2.1.0"
|
||||
|
||||
[target.'cfg(target_arch = "wasm32")'.dev-dependencies]
|
||||
wasm-bindgen-test = "0.3.18"
|
||||
|
||||
[features]
|
||||
default = ["zero_hash_cache", "detect-cpufeatures"]
|
||||
zero_hash_cache = ["lazy_static"]
|
||||
detect-cpufeatures = ["cpufeatures"]
|
||||
@@ -1,251 +0,0 @@
|
||||
//! Optimized SHA256 for use in Ethereum 2.0.
|
||||
//!
|
||||
//! The initial purpose of this crate was to provide an abstraction over the hash function used in
|
||||
//! Ethereum 2.0. The hash function changed during the specification process, so defining it once in
|
||||
//! this crate made it easy to replace.
|
||||
//!
|
||||
//! Now this crate serves primarily as a wrapper over two SHA256 crates: `sha2` and `ring` –
|
||||
//! which it switches between at runtime based on the availability of SHA intrinsics.
|
||||
|
||||
pub use self::DynamicContext as Context;
|
||||
use sha2::Digest;
|
||||
|
||||
#[cfg(feature = "zero_hash_cache")]
|
||||
use lazy_static::lazy_static;
|
||||
|
||||
/// Length of a SHA256 hash in bytes.
|
||||
pub const HASH_LEN: usize = 32;
|
||||
|
||||
/// Returns the digest of `input` using the best available implementation.
|
||||
pub fn hash(input: &[u8]) -> Vec<u8> {
|
||||
DynamicImpl::best().hash(input)
|
||||
}
|
||||
|
||||
/// Hash function returning a fixed-size array (to save on allocations).
|
||||
///
|
||||
/// Uses the best available implementation based on CPU features.
|
||||
pub fn hash_fixed(input: &[u8]) -> [u8; HASH_LEN] {
|
||||
DynamicImpl::best().hash_fixed(input)
|
||||
}
|
||||
|
||||
/// Compute the hash of two slices concatenated.
|
||||
pub fn hash32_concat(h1: &[u8], h2: &[u8]) -> [u8; 32] {
|
||||
let mut ctxt = DynamicContext::new();
|
||||
ctxt.update(h1);
|
||||
ctxt.update(h2);
|
||||
ctxt.finalize()
|
||||
}
|
||||
|
||||
/// Context trait for abstracting over implementation contexts.
|
||||
pub trait Sha256Context {
|
||||
fn new() -> Self;
|
||||
|
||||
fn update(&mut self, bytes: &[u8]);
|
||||
|
||||
fn finalize(self) -> [u8; HASH_LEN];
|
||||
}
|
||||
|
||||
/// Top-level trait implemented by both `sha2` and `ring` implementations.
|
||||
pub trait Sha256 {
|
||||
type Context: Sha256Context;
|
||||
|
||||
fn hash(&self, input: &[u8]) -> Vec<u8>;
|
||||
|
||||
fn hash_fixed(&self, input: &[u8]) -> [u8; HASH_LEN];
|
||||
}
|
||||
|
||||
/// Implementation of SHA256 using the `sha2` crate (fastest on CPUs with SHA extensions).
|
||||
struct Sha2CrateImpl;
|
||||
|
||||
impl Sha256Context for sha2::Sha256 {
|
||||
fn new() -> Self {
|
||||
sha2::Digest::new()
|
||||
}
|
||||
|
||||
fn update(&mut self, bytes: &[u8]) {
|
||||
sha2::Digest::update(self, bytes)
|
||||
}
|
||||
|
||||
fn finalize(self) -> [u8; HASH_LEN] {
|
||||
sha2::Digest::finalize(self).into()
|
||||
}
|
||||
}
|
||||
|
||||
impl Sha256 for Sha2CrateImpl {
|
||||
type Context = sha2::Sha256;
|
||||
|
||||
fn hash(&self, input: &[u8]) -> Vec<u8> {
|
||||
Self::Context::digest(input).into_iter().collect()
|
||||
}
|
||||
|
||||
fn hash_fixed(&self, input: &[u8]) -> [u8; HASH_LEN] {
|
||||
Self::Context::digest(input).into()
|
||||
}
|
||||
}
|
||||
|
||||
/// Implementation of SHA256 using the `ring` crate (fastest on CPUs without SHA extensions).
|
||||
pub struct RingImpl;
|
||||
|
||||
impl Sha256Context for ring::digest::Context {
|
||||
fn new() -> Self {
|
||||
Self::new(&ring::digest::SHA256)
|
||||
}
|
||||
|
||||
fn update(&mut self, bytes: &[u8]) {
|
||||
self.update(bytes)
|
||||
}
|
||||
|
||||
fn finalize(self) -> [u8; HASH_LEN] {
|
||||
let mut output = [0; HASH_LEN];
|
||||
output.copy_from_slice(self.finish().as_ref());
|
||||
output
|
||||
}
|
||||
}
|
||||
|
||||
impl Sha256 for RingImpl {
|
||||
type Context = ring::digest::Context;
|
||||
|
||||
fn hash(&self, input: &[u8]) -> Vec<u8> {
|
||||
ring::digest::digest(&ring::digest::SHA256, input)
|
||||
.as_ref()
|
||||
.into()
|
||||
}
|
||||
|
||||
fn hash_fixed(&self, input: &[u8]) -> [u8; HASH_LEN] {
|
||||
let mut ctxt = Self::Context::new(&ring::digest::SHA256);
|
||||
ctxt.update(input);
|
||||
ctxt.finalize()
|
||||
}
|
||||
}
|
||||
|
||||
/// Default dynamic implementation that switches between available implementations.
|
||||
pub enum DynamicImpl {
|
||||
Sha2,
|
||||
Ring,
|
||||
}
|
||||
|
||||
// Runtime latch for detecting the availability of SHA extensions on x86_64.
|
||||
//
|
||||
// Inspired by the runtime switch within the `sha2` crate itself.
|
||||
#[cfg(all(feature = "detect-cpufeatures", target_arch = "x86_64"))]
|
||||
cpufeatures::new!(x86_sha_extensions, "sha", "sse2", "ssse3", "sse4.1");
|
||||
|
||||
#[inline(always)]
|
||||
pub fn have_sha_extensions() -> bool {
|
||||
#[cfg(all(feature = "detect-cpufeatures", target_arch = "x86_64"))]
|
||||
return x86_sha_extensions::get();
|
||||
|
||||
#[cfg(not(all(feature = "detect-cpufeatures", target_arch = "x86_64")))]
|
||||
return false;
|
||||
}
|
||||
|
||||
impl DynamicImpl {
|
||||
/// Choose the best available implementation based on the currently executing CPU.
|
||||
#[inline(always)]
|
||||
pub fn best() -> Self {
|
||||
if have_sha_extensions() {
|
||||
Self::Sha2
|
||||
} else {
|
||||
Self::Ring
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Sha256 for DynamicImpl {
|
||||
type Context = DynamicContext;
|
||||
|
||||
#[inline(always)]
|
||||
fn hash(&self, input: &[u8]) -> Vec<u8> {
|
||||
match self {
|
||||
Self::Sha2 => Sha2CrateImpl.hash(input),
|
||||
Self::Ring => RingImpl.hash(input),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn hash_fixed(&self, input: &[u8]) -> [u8; HASH_LEN] {
|
||||
match self {
|
||||
Self::Sha2 => Sha2CrateImpl.hash_fixed(input),
|
||||
Self::Ring => RingImpl.hash_fixed(input),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Context encapsulating all implemenation contexts.
|
||||
///
|
||||
/// This enum ends up being 8 bytes larger than the largest inner context.
|
||||
pub enum DynamicContext {
|
||||
Sha2(sha2::Sha256),
|
||||
Ring(ring::digest::Context),
|
||||
}
|
||||
|
||||
impl Sha256Context for DynamicContext {
|
||||
fn new() -> Self {
|
||||
match DynamicImpl::best() {
|
||||
DynamicImpl::Sha2 => Self::Sha2(Sha256Context::new()),
|
||||
DynamicImpl::Ring => Self::Ring(Sha256Context::new()),
|
||||
}
|
||||
}
|
||||
|
||||
fn update(&mut self, bytes: &[u8]) {
|
||||
match self {
|
||||
Self::Sha2(ctxt) => Sha256Context::update(ctxt, bytes),
|
||||
Self::Ring(ctxt) => Sha256Context::update(ctxt, bytes),
|
||||
}
|
||||
}
|
||||
|
||||
fn finalize(self) -> [u8; HASH_LEN] {
|
||||
match self {
|
||||
Self::Sha2(ctxt) => Sha256Context::finalize(ctxt),
|
||||
Self::Ring(ctxt) => Sha256Context::finalize(ctxt),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The max index that can be used with `ZERO_HASHES`.
|
||||
#[cfg(feature = "zero_hash_cache")]
|
||||
pub const ZERO_HASHES_MAX_INDEX: usize = 48;
|
||||
|
||||
#[cfg(feature = "zero_hash_cache")]
|
||||
lazy_static! {
|
||||
/// Cached zero hashes where `ZERO_HASHES[i]` is the hash of a Merkle tree with 2^i zero leaves.
|
||||
pub static ref ZERO_HASHES: Vec<Vec<u8>> = {
|
||||
let mut hashes = vec![vec![0; 32]; ZERO_HASHES_MAX_INDEX + 1];
|
||||
|
||||
for i in 0..ZERO_HASHES_MAX_INDEX {
|
||||
hashes[i + 1] = hash32_concat(&hashes[i], &hashes[i])[..].to_vec();
|
||||
}
|
||||
|
||||
hashes
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use rustc_hex::FromHex;
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
use wasm_bindgen_test::*;
|
||||
|
||||
#[cfg_attr(not(target_arch = "wasm32"), test)]
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
|
||||
fn test_hashing() {
|
||||
let input: Vec<u8> = b"hello world".as_ref().into();
|
||||
|
||||
let output = hash(input.as_ref());
|
||||
let expected_hex = "b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9";
|
||||
let expected: Vec<u8> = expected_hex.from_hex().unwrap();
|
||||
assert_eq!(expected, output);
|
||||
}
|
||||
|
||||
#[cfg(feature = "zero_hash_cache")]
|
||||
mod zero_hash {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn zero_hash_zero() {
|
||||
assert_eq!(ZERO_HASHES[0], vec![0; 32]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,15 +7,15 @@ edition = "2021"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
eth2_ssz = "0.4.1"
|
||||
eth2_ssz_derive = "0.3.1"
|
||||
tree_hash = "0.4.1"
|
||||
ethereum_ssz = "0.5.0"
|
||||
ethereum_ssz_derive = "0.5.0"
|
||||
tree_hash = "0.5.0"
|
||||
derivative = "2.1.1"
|
||||
serde = "1.0.116"
|
||||
serde_derive = "1.0.116"
|
||||
eth2_serde_utils = "0.1.1"
|
||||
ethereum_serde_utils = "0.5.0"
|
||||
hex = "0.4.2"
|
||||
eth2_hashing = "0.3.0"
|
||||
ethereum_hashing = "1.0.0-beta.2"
|
||||
c-kzg = {git = "https://github.com/ethereum/c-kzg-4844", rev = "fd24cf8e1e2f09a96b4e62a595b4e49f046ce6cf" }
|
||||
arbitrary = { version = "1.0", features = ["derive"], optional = true }
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use c_kzg::{Bytes48, BYTES_PER_COMMITMENT};
|
||||
use derivative::Derivative;
|
||||
use eth2_hashing::hash_fixed;
|
||||
use ethereum_hashing::hash_fixed;
|
||||
use serde::de::{Deserialize, Deserializer};
|
||||
use serde::ser::{Serialize, Serializer};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
@@ -32,7 +32,7 @@ impl From<KzgCommitment> for Bytes48 {
|
||||
|
||||
impl Display for KzgCommitment {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{}", eth2_serde_utils::hex::encode(self.0))
|
||||
write!(f, "{}", serde_utils::hex::encode(self.0))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,7 +121,7 @@ impl FromStr for KzgCommitment {
|
||||
|
||||
impl Debug for KzgCommitment {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}", eth2_serde_utils::hex::encode(self.0))
|
||||
write!(f, "{}", serde_utils::hex::encode(self.0))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ impl KzgProof {
|
||||
|
||||
impl fmt::Display for KzgProof {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{}", eth2_serde_utils::hex::encode(self.0))
|
||||
write!(f, "{}", serde_utils::hex::encode(self.0))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,7 +128,7 @@ impl FromStr for KzgProof {
|
||||
|
||||
impl Debug for KzgProof {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}", eth2_serde_utils::hex::encode(self.0))
|
||||
write!(f, "{}", serde_utils::hex::encode(self.0))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user