mirror of
https://github.com/sigp/lighthouse.git
synced 2026-04-18 13:28:33 +00:00
Merge branch 'master' into sos
This commit is contained in:
@@ -34,7 +34,7 @@ fn power_of_2_below(x: u64) -> u64 {
|
||||
}
|
||||
|
||||
/// Stores the necessary data structures to run the optimised bitwise lmd ghost algorithm.
|
||||
pub struct BitwiseLMDGhost<T: ClientDB + Sized, B> {
|
||||
pub struct BitwiseLMDGhost<T: ClientDB + Sized, E> {
|
||||
/// A cache of known ancestors at given heights for a specific block.
|
||||
//TODO: Consider FnvHashMap
|
||||
cache: HashMap<CacheKey<u64>, Hash256>,
|
||||
@@ -51,10 +51,10 @@ pub struct BitwiseLMDGhost<T: ClientDB + Sized, B> {
|
||||
/// State storage access.
|
||||
state_store: Arc<BeaconStateStore<T>>,
|
||||
max_known_height: SlotHeight,
|
||||
_phantom: PhantomData<B>,
|
||||
_phantom: PhantomData<E>,
|
||||
}
|
||||
|
||||
impl<T, B: EthSpec> BitwiseLMDGhost<T, B>
|
||||
impl<T, E: EthSpec> BitwiseLMDGhost<T, E>
|
||||
where
|
||||
T: ClientDB + Sized,
|
||||
{
|
||||
@@ -88,7 +88,7 @@ where
|
||||
// build a hashmap of block_hash to weighted votes
|
||||
let mut latest_votes: HashMap<Hash256, u64> = HashMap::new();
|
||||
// gets the current weighted votes
|
||||
let current_state: BeaconState<B> = self
|
||||
let current_state: BeaconState<E> = self
|
||||
.state_store
|
||||
.get_deserialized(&state_root)?
|
||||
.ok_or_else(|| ForkChoiceError::MissingBeaconState(*state_root))?;
|
||||
@@ -243,7 +243,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ClientDB + Sized, B: EthSpec> ForkChoice for BitwiseLMDGhost<T, B> {
|
||||
impl<T: ClientDB + Sized, E: EthSpec> ForkChoice for BitwiseLMDGhost<T, E> {
|
||||
fn add_block(
|
||||
&mut self,
|
||||
block: &BeaconBlock,
|
||||
|
||||
@@ -34,7 +34,7 @@ fn power_of_2_below(x: u64) -> u64 {
|
||||
}
|
||||
|
||||
/// Stores the necessary data structures to run the optimised lmd ghost algorithm.
|
||||
pub struct OptimizedLMDGhost<T: ClientDB + Sized, B> {
|
||||
pub struct OptimizedLMDGhost<T: ClientDB + Sized, E> {
|
||||
/// A cache of known ancestors at given heights for a specific block.
|
||||
//TODO: Consider FnvHashMap
|
||||
cache: HashMap<CacheKey<u64>, Hash256>,
|
||||
@@ -51,10 +51,10 @@ pub struct OptimizedLMDGhost<T: ClientDB + Sized, B> {
|
||||
/// State storage access.
|
||||
state_store: Arc<BeaconStateStore<T>>,
|
||||
max_known_height: SlotHeight,
|
||||
_phantom: PhantomData<B>,
|
||||
_phantom: PhantomData<E>,
|
||||
}
|
||||
|
||||
impl<T, B: EthSpec> OptimizedLMDGhost<T, B>
|
||||
impl<T, E: EthSpec> OptimizedLMDGhost<T, E>
|
||||
where
|
||||
T: ClientDB + Sized,
|
||||
{
|
||||
@@ -88,7 +88,7 @@ where
|
||||
// build a hashmap of block_hash to weighted votes
|
||||
let mut latest_votes: HashMap<Hash256, u64> = HashMap::new();
|
||||
// gets the current weighted votes
|
||||
let current_state: BeaconState<B> = self
|
||||
let current_state: BeaconState<E> = self
|
||||
.state_store
|
||||
.get_deserialized(&state_root)?
|
||||
.ok_or_else(|| ForkChoiceError::MissingBeaconState(*state_root))?;
|
||||
@@ -214,7 +214,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ClientDB + Sized, B: EthSpec> ForkChoice for OptimizedLMDGhost<T, B> {
|
||||
impl<T: ClientDB + Sized, E: EthSpec> ForkChoice for OptimizedLMDGhost<T, E> {
|
||||
fn add_block(
|
||||
&mut self,
|
||||
block: &BeaconBlock,
|
||||
|
||||
@@ -13,7 +13,7 @@ use types::{BeaconBlock, BeaconState, ChainSpec, EthSpec, Hash256, Slot};
|
||||
|
||||
//TODO: Pruning and syncing
|
||||
|
||||
pub struct SlowLMDGhost<T: ClientDB + Sized, B> {
|
||||
pub struct SlowLMDGhost<T: ClientDB + Sized, E> {
|
||||
/// The latest attestation targets as a map of validator index to block hash.
|
||||
//TODO: Could this be a fixed size vec
|
||||
latest_attestation_targets: HashMap<u64, Hash256>,
|
||||
@@ -23,10 +23,10 @@ pub struct SlowLMDGhost<T: ClientDB + Sized, B> {
|
||||
block_store: Arc<BeaconBlockStore<T>>,
|
||||
/// State storage access.
|
||||
state_store: Arc<BeaconStateStore<T>>,
|
||||
_phantom: PhantomData<B>,
|
||||
_phantom: PhantomData<E>,
|
||||
}
|
||||
|
||||
impl<T, B: EthSpec> SlowLMDGhost<T, B>
|
||||
impl<T, E: EthSpec> SlowLMDGhost<T, E>
|
||||
where
|
||||
T: ClientDB + Sized,
|
||||
{
|
||||
@@ -57,7 +57,7 @@ where
|
||||
// build a hashmap of block_hash to weighted votes
|
||||
let mut latest_votes: HashMap<Hash256, u64> = HashMap::new();
|
||||
// gets the current weighted votes
|
||||
let current_state: BeaconState<B> = self
|
||||
let current_state: BeaconState<E> = self
|
||||
.state_store
|
||||
.get_deserialized(&state_root)?
|
||||
.ok_or_else(|| ForkChoiceError::MissingBeaconState(*state_root))?;
|
||||
@@ -108,7 +108,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ClientDB + Sized, B: EthSpec> ForkChoice for SlowLMDGhost<T, B> {
|
||||
impl<T: ClientDB + Sized, E: EthSpec> ForkChoice for SlowLMDGhost<T, E> {
|
||||
/// Process when a block is added
|
||||
fn add_block(
|
||||
&mut self,
|
||||
|
||||
@@ -539,10 +539,10 @@ where
|
||||
/// The keys in the map should be validator indices, which will be looked up
|
||||
/// in the state's validator registry and then passed to `prune_if`.
|
||||
/// Entries for unknown validators will be kept.
|
||||
fn prune_validator_hash_map<T, F, B: EthSpec>(
|
||||
fn prune_validator_hash_map<T, F, E: EthSpec>(
|
||||
map: &mut HashMap<u64, T>,
|
||||
prune_if: F,
|
||||
finalized_state: &BeaconState<B>,
|
||||
finalized_state: &BeaconState<E>,
|
||||
) where
|
||||
F: Fn(&Validator) -> bool,
|
||||
{
|
||||
@@ -722,12 +722,12 @@ mod tests {
|
||||
|
||||
/// Create a signed attestation for use in tests.
|
||||
/// Signed by all validators in `committee[signing_range]` and `committee[extra_signer]`.
|
||||
fn signed_attestation<R: std::slice::SliceIndex<[usize], Output = [usize]>, B: EthSpec>(
|
||||
fn signed_attestation<R: std::slice::SliceIndex<[usize], Output = [usize]>, E: EthSpec>(
|
||||
committee: &CrosslinkCommittee,
|
||||
keypairs: &[Keypair],
|
||||
signing_range: R,
|
||||
slot: Slot,
|
||||
state: &BeaconState<B>,
|
||||
state: &BeaconState<E>,
|
||||
spec: &ChainSpec,
|
||||
extra_signer: Option<usize>,
|
||||
) -> Attestation {
|
||||
@@ -754,10 +754,10 @@ mod tests {
|
||||
}
|
||||
|
||||
/// Test state for attestation-related tests.
|
||||
fn attestation_test_state<B: EthSpec>(
|
||||
fn attestation_test_state<E: EthSpec>(
|
||||
num_committees: usize,
|
||||
) -> (BeaconState<B>, Vec<Keypair>, ChainSpec) {
|
||||
let spec = B::spec();
|
||||
) -> (BeaconState<E>, Vec<Keypair>, ChainSpec) {
|
||||
let spec = E::spec();
|
||||
|
||||
let num_validators =
|
||||
num_committees * (spec.slots_per_epoch * spec.target_committee_size) as usize;
|
||||
@@ -775,9 +775,9 @@ mod tests {
|
||||
}
|
||||
|
||||
/// Set the latest crosslink in the state to match the attestation.
|
||||
fn fake_latest_crosslink<B: EthSpec>(
|
||||
fn fake_latest_crosslink<E: EthSpec>(
|
||||
att: &Attestation,
|
||||
state: &mut BeaconState<B>,
|
||||
state: &mut BeaconState<E>,
|
||||
spec: &ChainSpec,
|
||||
) {
|
||||
state.latest_crosslinks[att.data.shard as usize] = Crosslink {
|
||||
|
||||
@@ -27,7 +27,6 @@ pub mod pending_attestation;
|
||||
pub mod proposer_slashing;
|
||||
pub mod slashable_attestation;
|
||||
pub mod transfer;
|
||||
// pub mod tree_hash_vector;
|
||||
pub mod voluntary_exit;
|
||||
#[macro_use]
|
||||
pub mod slot_epoch_macros;
|
||||
@@ -66,7 +65,6 @@ pub use crate::slashable_attestation::SlashableAttestation;
|
||||
pub use crate::slot_epoch::{Epoch, Slot};
|
||||
pub use crate::slot_height::SlotHeight;
|
||||
pub use crate::transfer::Transfer;
|
||||
// pub use crate::tree_hash_vector::TreeHashVector;
|
||||
pub use crate::validator::Validator;
|
||||
pub use crate::voluntary_exit::VoluntaryExit;
|
||||
|
||||
|
||||
@@ -1,142 +0,0 @@
|
||||
use crate::test_utils::{RngCore, TestRandom};
|
||||
use cached_tree_hash::CachedTreeHash;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use ssz::{Decode, DecodeError, Encode};
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use tree_hash::TreeHash;
|
||||
|
||||
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
|
||||
pub struct TreeHashVector<T>(Vec<T>);
|
||||
|
||||
impl<T> From<Vec<T>> for TreeHashVector<T> {
|
||||
fn from(vec: Vec<T>) -> TreeHashVector<T> {
|
||||
TreeHashVector(vec)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Into<Vec<T>> for TreeHashVector<T> {
|
||||
fn into(self) -> Vec<T> {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Deref for TreeHashVector<T> {
|
||||
type Target = Vec<T>;
|
||||
|
||||
fn deref(&self) -> &Vec<T> {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> DerefMut for TreeHashVector<T> {
|
||||
fn deref_mut(&mut self) -> &mut Vec<T> {
|
||||
&mut self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> tree_hash::TreeHash for TreeHashVector<T>
|
||||
where
|
||||
T: TreeHash,
|
||||
{
|
||||
fn tree_hash_type() -> tree_hash::TreeHashType {
|
||||
tree_hash::TreeHashType::Vector
|
||||
}
|
||||
|
||||
fn tree_hash_packed_encoding(&self) -> Vec<u8> {
|
||||
unreachable!("Vector should never be packed.")
|
||||
}
|
||||
|
||||
fn tree_hash_packing_factor() -> usize {
|
||||
unreachable!("Vector should never be packed.")
|
||||
}
|
||||
|
||||
fn tree_hash_root(&self) -> Vec<u8> {
|
||||
tree_hash::impls::vec_tree_hash_root(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> CachedTreeHash for TreeHashVector<T>
|
||||
where
|
||||
T: CachedTreeHash + TreeHash,
|
||||
{
|
||||
fn new_tree_hash_cache(
|
||||
&self,
|
||||
depth: usize,
|
||||
) -> Result<cached_tree_hash::TreeHashCache, cached_tree_hash::Error> {
|
||||
let (cache, _overlay) = cached_tree_hash::vec::new_tree_hash_cache(self, depth)?;
|
||||
|
||||
Ok(cache)
|
||||
}
|
||||
|
||||
fn tree_hash_cache_schema(&self, depth: usize) -> cached_tree_hash::BTreeSchema {
|
||||
cached_tree_hash::vec::produce_schema(self, depth)
|
||||
}
|
||||
|
||||
fn update_tree_hash_cache(
|
||||
&self,
|
||||
cache: &mut cached_tree_hash::TreeHashCache,
|
||||
) -> Result<(), cached_tree_hash::Error> {
|
||||
cached_tree_hash::vec::update_tree_hash_cache(self, cache)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Encode for TreeHashVector<T>
|
||||
where
|
||||
T: Encode,
|
||||
{
|
||||
fn ssz_append(&self, s: &mut SszStream) {
|
||||
s.append_vec(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Decode for TreeHashVector<T>
|
||||
where
|
||||
T: Decode,
|
||||
{
|
||||
fn ssz_decode(bytes: &[u8], index: usize) -> Result<(Self, usize), DecodeError> {
|
||||
ssz::decode_ssz_list(bytes, index).and_then(|(vec, i)| Ok((vec.into(), i)))
|
||||
}
|
||||
}
|
||||
|
||||
impl<U> TestRandom for TreeHashVector<U>
|
||||
where
|
||||
U: TestRandom,
|
||||
{
|
||||
fn random_for_test(rng: &mut impl RngCore) -> Self {
|
||||
TreeHashVector::from(vec![
|
||||
U::random_for_test(rng),
|
||||
U::random_for_test(rng),
|
||||
U::random_for_test(rng),
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
use tree_hash::TreeHash;
|
||||
|
||||
#[test]
|
||||
pub fn test_cached_tree_hash() {
|
||||
let original = TreeHashVector::from(vec![1_u64, 2, 3, 4]);
|
||||
|
||||
let mut cache = cached_tree_hash::TreeHashCache::new(&original).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
cache.tree_hash_root().unwrap().to_vec(),
|
||||
original.tree_hash_root()
|
||||
);
|
||||
|
||||
let modified = TreeHashVector::from(vec![1_u64, 1, 1, 1]);
|
||||
|
||||
cache.update(&modified).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
cache.tree_hash_root().unwrap().to_vec(),
|
||||
modified.tree_hash_root()
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,8 +2,8 @@ use super::*;
|
||||
|
||||
/// A schema defining a binary tree over a `TreeHashCache`.
|
||||
///
|
||||
/// This structure is used for succinct storage, run-time functionality is gained by converting the
|
||||
/// schema into a `BTreeOverlay`.
|
||||
/// This structure is used for succinct storage; run-time functionality is gained by converting a
|
||||
/// `BTreeSchema` into a `BTreeOverlay`.
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub struct BTreeSchema {
|
||||
/// The depth of a schema defines how far it is nested within other fixed-length items.
|
||||
@@ -48,8 +48,8 @@ pub enum LeafNode {
|
||||
Padding,
|
||||
}
|
||||
|
||||
/// Instantiated from a `BTreeSchema`, allows for interpreting some chunks of a `TreeHashCache` as
|
||||
/// a perfect binary tree.
|
||||
/// Instantiated from a `BTreeSchema`, a `BTreeOverlay` allows for interpreting some
|
||||
/// non-consecutive chunks of a `TreeHashCache` as a perfect binary tree.
|
||||
///
|
||||
/// The primary purpose of this struct is to map from binary tree "nodes" to `TreeHashCache`
|
||||
/// "chunks". Each tree has nodes `0..n` where `n` is the number of nodes and `0` is the root node.
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
//! Performs cached merkle-hashing adhering to the Ethereum 2.0 specification defined
|
||||
//! [here](https://github.com/ethereum/eth2.0-specs/blob/v0.5.1/specs/simple-serialize.md#merkleization).
|
||||
//!
|
||||
//! Caching allows for reduced hashing when some object has only been partially modified. This
|
||||
//! allows for significant CPU-time savings (at the cost of additional storage). For example,
|
||||
//! Caching allows for reduced hashing when some object has only been partially modified, which
|
||||
//! consumes less CPU-time at the cost of additional storage. For example,
|
||||
//! determining the root of a list of 1024 items with a single modification has been observed to
|
||||
//! run in 1/25th of the time of a full merkle hash.
|
||||
//!
|
||||
@@ -61,8 +61,8 @@ pub trait CachedTreeHash: TreeHash {
|
||||
fn update_tree_hash_cache(&self, cache: &mut TreeHashCache) -> Result<(), Error>;
|
||||
}
|
||||
|
||||
/// Implements `CachedTreeHash` on `$type` as a fixed-length tree-hash vector of the ssz encoding
|
||||
/// of `$type`.
|
||||
/// Implements `CachedTreeHash` on `$type`, where `$type` is a fixed-length vector and each item in
|
||||
/// the `$type` is encoded as bytes using `ssz_encode`.
|
||||
#[macro_export]
|
||||
macro_rules! cached_tree_hash_ssz_encoding_as_vector {
|
||||
($type: ident, $num_bytes: expr) => {
|
||||
@@ -95,8 +95,8 @@ macro_rules! cached_tree_hash_ssz_encoding_as_vector {
|
||||
};
|
||||
}
|
||||
|
||||
/// Implements `CachedTreeHash` on `$type` as a variable-length tree-hash list of the result of
|
||||
/// calling `.as_bytes()` on `$type`.
|
||||
/// Implements `CachedTreeHash` on `$type`, where `$type` is a variable-length list and each item
|
||||
/// in `$type` is encoded as bytes by calling `item.to_bytes()`.
|
||||
#[macro_export]
|
||||
macro_rules! cached_tree_hash_bytes_as_list {
|
||||
($type: ident) => {
|
||||
|
||||
Reference in New Issue
Block a user