mirror of
https://github.com/sigp/lighthouse.git
synced 2026-04-18 13:28:33 +00:00
Merge branch 'master' into testnet-key-load
This commit is contained in:
@@ -7,6 +7,7 @@ edition = "2018"
|
||||
[dependencies]
|
||||
bls = { path = "../utils/bls" }
|
||||
boolean-bitfield = { path = "../utils/boolean-bitfield" }
|
||||
cached_tree_hash = { path = "../utils/cached_tree_hash" }
|
||||
dirs = "1.0"
|
||||
derivative = "1.0"
|
||||
ethereum-types = "0.5"
|
||||
@@ -26,6 +27,8 @@ ssz = { path = "../utils/ssz" }
|
||||
ssz_derive = { path = "../utils/ssz_derive" }
|
||||
swap_or_not_shuffle = { path = "../utils/swap_or_not_shuffle" }
|
||||
test_random_derive = { path = "../utils/test_random_derive" }
|
||||
tree_hash = { path = "../utils/tree_hash" }
|
||||
tree_hash_derive = { path = "../utils/tree_hash_derive" }
|
||||
libp2p = { git = "https://github.com/SigP/rust-libp2p", rev = "b3c32d9a821ae6cc89079499cc6e8a6bab0bffc3" }
|
||||
|
||||
[dev-dependencies]
|
||||
|
||||
@@ -2,13 +2,14 @@ use super::{AggregateSignature, AttestationData, Bitfield};
|
||||
use crate::test_utils::TestRandom;
|
||||
use rand::RngCore;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use ssz::TreeHash;
|
||||
use ssz_derive::{Decode, Encode, SignedRoot, TreeHash};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash::TreeHash;
|
||||
use tree_hash_derive::{CachedTreeHash, SignedRoot, TreeHash};
|
||||
|
||||
/// Details an attestation that can be slashable.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
/// Spec v0.5.1
|
||||
#[derive(
|
||||
Debug,
|
||||
Clone,
|
||||
@@ -18,6 +19,7 @@ use test_random_derive::TestRandom;
|
||||
Encode,
|
||||
Decode,
|
||||
TreeHash,
|
||||
CachedTreeHash,
|
||||
TestRandom,
|
||||
SignedRoot,
|
||||
)]
|
||||
@@ -25,6 +27,7 @@ pub struct Attestation {
|
||||
pub aggregation_bitfield: Bitfield,
|
||||
pub data: AttestationData,
|
||||
pub custody_bitfield: Bitfield,
|
||||
#[signed_root(skip_hashing)]
|
||||
pub aggregate_signature: AggregateSignature,
|
||||
}
|
||||
|
||||
@@ -56,4 +59,5 @@ mod tests {
|
||||
use super::*;
|
||||
|
||||
ssz_tests!(Attestation);
|
||||
cached_tree_hash_tests!(Attestation);
|
||||
}
|
||||
|
||||
@@ -2,13 +2,14 @@ use crate::test_utils::TestRandom;
|
||||
use crate::{Crosslink, Epoch, Hash256, Slot};
|
||||
use rand::RngCore;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use ssz::TreeHash;
|
||||
use ssz_derive::{Decode, Encode, SignedRoot, TreeHash};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash::TreeHash;
|
||||
use tree_hash_derive::{CachedTreeHash, SignedRoot, TreeHash};
|
||||
|
||||
/// The data upon which an attestation is based.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
/// Spec v0.5.1
|
||||
#[derive(
|
||||
Debug,
|
||||
Clone,
|
||||
@@ -20,6 +21,7 @@ use test_random_derive::TestRandom;
|
||||
Encode,
|
||||
Decode,
|
||||
TreeHash,
|
||||
CachedTreeHash,
|
||||
TestRandom,
|
||||
SignedRoot,
|
||||
)]
|
||||
@@ -46,4 +48,5 @@ mod tests {
|
||||
use super::*;
|
||||
|
||||
ssz_tests!(AttestationData);
|
||||
cached_tree_hash_tests!(AttestationData);
|
||||
}
|
||||
|
||||
@@ -2,12 +2,13 @@ use super::AttestationData;
|
||||
use crate::test_utils::TestRandom;
|
||||
use rand::RngCore;
|
||||
use serde_derive::Serialize;
|
||||
use ssz_derive::{Decode, Encode, TreeHash};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use tree_hash_derive::{CachedTreeHash, TreeHash};
|
||||
|
||||
/// Used for pairing an attestation with a proof-of-custody.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
#[derive(Debug, Clone, PartialEq, Default, Serialize, Encode, Decode, TreeHash)]
|
||||
/// Spec v0.5.1
|
||||
#[derive(Debug, Clone, PartialEq, Default, Serialize, Encode, Decode, TreeHash, CachedTreeHash)]
|
||||
pub struct AttestationDataAndCustodyBit {
|
||||
pub data: AttestationData,
|
||||
pub custody_bit: bool,
|
||||
@@ -27,4 +28,5 @@ mod test {
|
||||
use super::*;
|
||||
|
||||
ssz_tests!(AttestationDataAndCustodyBit);
|
||||
cached_tree_hash_tests!(AttestationDataAndCustodyBit);
|
||||
}
|
||||
|
||||
@@ -1,13 +1,25 @@
|
||||
use crate::{test_utils::TestRandom, SlashableAttestation};
|
||||
use rand::RngCore;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use ssz_derive::{Decode, Encode, TreeHash};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash_derive::{CachedTreeHash, TreeHash};
|
||||
|
||||
/// Two conflicting attestations.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Encode, Decode, TreeHash, TestRandom)]
|
||||
/// Spec v0.5.1
|
||||
#[derive(
|
||||
Debug,
|
||||
PartialEq,
|
||||
Clone,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
Encode,
|
||||
Decode,
|
||||
TreeHash,
|
||||
CachedTreeHash,
|
||||
TestRandom,
|
||||
)]
|
||||
pub struct AttesterSlashing {
|
||||
pub slashable_attestation_1: SlashableAttestation,
|
||||
pub slashable_attestation_2: SlashableAttestation,
|
||||
@@ -18,4 +30,5 @@ mod tests {
|
||||
use super::*;
|
||||
|
||||
ssz_tests!(AttesterSlashing);
|
||||
cached_tree_hash_tests!(AttesterSlashing);
|
||||
}
|
||||
|
||||
@@ -3,13 +3,14 @@ use crate::*;
|
||||
use bls::Signature;
|
||||
use rand::RngCore;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use ssz::TreeHash;
|
||||
use ssz_derive::{Decode, Encode, SignedRoot, TreeHash};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash::TreeHash;
|
||||
use tree_hash_derive::{CachedTreeHash, SignedRoot, TreeHash};
|
||||
|
||||
/// A block of the `BeaconChain`.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
/// Spec v0.5.1
|
||||
#[derive(
|
||||
Debug,
|
||||
PartialEq,
|
||||
@@ -19,6 +20,7 @@ use test_random_derive::TestRandom;
|
||||
Encode,
|
||||
Decode,
|
||||
TreeHash,
|
||||
CachedTreeHash,
|
||||
TestRandom,
|
||||
SignedRoot,
|
||||
)]
|
||||
@@ -27,13 +29,14 @@ pub struct BeaconBlock {
|
||||
pub previous_block_root: Hash256,
|
||||
pub state_root: Hash256,
|
||||
pub body: BeaconBlockBody,
|
||||
#[signed_root(skip_hashing)]
|
||||
pub signature: Signature,
|
||||
}
|
||||
|
||||
impl BeaconBlock {
|
||||
/// Returns an empty block to be used during genesis.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
/// Spec v0.5.1
|
||||
pub fn empty(spec: &ChainSpec) -> BeaconBlock {
|
||||
BeaconBlock {
|
||||
slot: spec.genesis_slot,
|
||||
@@ -56,11 +59,11 @@ impl BeaconBlock {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the `hash_tree_root` of the block.
|
||||
/// Returns the `tree_hash_root | update` of the block.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
/// Spec v0.5.1
|
||||
pub fn canonical_root(&self) -> Hash256 {
|
||||
Hash256::from_slice(&self.hash_tree_root()[..])
|
||||
Hash256::from_slice(&self.tree_hash_root()[..])
|
||||
}
|
||||
|
||||
/// Returns a full `BeaconBlockHeader` of this block.
|
||||
@@ -70,20 +73,20 @@ impl BeaconBlock {
|
||||
///
|
||||
/// Note: performs a full tree-hash of `self.body`.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
/// Spec v0.5.1
|
||||
pub fn block_header(&self) -> BeaconBlockHeader {
|
||||
BeaconBlockHeader {
|
||||
slot: self.slot,
|
||||
previous_block_root: self.previous_block_root,
|
||||
state_root: self.state_root,
|
||||
block_body_root: Hash256::from_slice(&self.body.hash_tree_root()[..]),
|
||||
block_body_root: Hash256::from_slice(&self.body.tree_hash_root()[..]),
|
||||
signature: self.signature.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a "temporary" header, where the `state_root` is `spec.zero_hash`.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
/// Spec v0.5.1
|
||||
pub fn temporary_block_header(&self, spec: &ChainSpec) -> BeaconBlockHeader {
|
||||
BeaconBlockHeader {
|
||||
state_root: spec.zero_hash,
|
||||
@@ -98,4 +101,5 @@ mod tests {
|
||||
use super::*;
|
||||
|
||||
ssz_tests!(BeaconBlock);
|
||||
cached_tree_hash_tests!(BeaconBlock);
|
||||
}
|
||||
|
||||
@@ -2,13 +2,25 @@ use crate::test_utils::TestRandom;
|
||||
use crate::*;
|
||||
use rand::RngCore;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use ssz_derive::{Decode, Encode, TreeHash};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash_derive::{CachedTreeHash, TreeHash};
|
||||
|
||||
/// The body of a `BeaconChain` block, containing operations.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Encode, Decode, TreeHash, TestRandom)]
|
||||
/// Spec v0.5.1
|
||||
#[derive(
|
||||
Debug,
|
||||
PartialEq,
|
||||
Clone,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
Encode,
|
||||
Decode,
|
||||
TreeHash,
|
||||
CachedTreeHash,
|
||||
TestRandom,
|
||||
)]
|
||||
pub struct BeaconBlockBody {
|
||||
pub randao_reveal: Signature,
|
||||
pub eth1_data: Eth1Data,
|
||||
@@ -25,4 +37,5 @@ mod tests {
|
||||
use super::*;
|
||||
|
||||
ssz_tests!(BeaconBlockBody);
|
||||
cached_tree_hash_tests!(BeaconBlockBody);
|
||||
}
|
||||
|
||||
@@ -3,13 +3,14 @@ use crate::*;
|
||||
use bls::Signature;
|
||||
use rand::RngCore;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use ssz::TreeHash;
|
||||
use ssz_derive::{Decode, Encode, SignedRoot, TreeHash};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash::{SignedRoot, TreeHash};
|
||||
use tree_hash_derive::{CachedTreeHash, SignedRoot, TreeHash};
|
||||
|
||||
/// A header of a `BeaconBlock`.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
/// Spec v0.5.1
|
||||
#[derive(
|
||||
Debug,
|
||||
PartialEq,
|
||||
@@ -19,6 +20,7 @@ use test_random_derive::TestRandom;
|
||||
Encode,
|
||||
Decode,
|
||||
TreeHash,
|
||||
CachedTreeHash,
|
||||
TestRandom,
|
||||
SignedRoot,
|
||||
)]
|
||||
@@ -27,20 +29,21 @@ pub struct BeaconBlockHeader {
|
||||
pub previous_block_root: Hash256,
|
||||
pub state_root: Hash256,
|
||||
pub block_body_root: Hash256,
|
||||
#[signed_root(skip_hashing)]
|
||||
pub signature: Signature,
|
||||
}
|
||||
|
||||
impl BeaconBlockHeader {
|
||||
/// Returns the `hash_tree_root` of the header.
|
||||
/// Returns the `tree_hash_root` of the header.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
/// Spec v0.5.1
|
||||
pub fn canonical_root(&self) -> Hash256 {
|
||||
Hash256::from_slice(&self.hash_tree_root()[..])
|
||||
Hash256::from_slice(&self.signed_root()[..])
|
||||
}
|
||||
|
||||
/// Given a `body`, consumes `self` and returns a complete `BeaconBlock`.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
/// Spec v0.5.1
|
||||
pub fn into_block(self, body: BeaconBlockBody) -> BeaconBlock {
|
||||
BeaconBlock {
|
||||
slot: self.slot,
|
||||
@@ -57,4 +60,5 @@ mod tests {
|
||||
use super::*;
|
||||
|
||||
ssz_tests!(BeaconBlockHeader);
|
||||
cached_tree_hash_tests!(BeaconBlockHeader);
|
||||
}
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
use self::epoch_cache::{get_active_validator_indices, EpochCache, Error as EpochCacheError};
|
||||
use crate::test_utils::TestRandom;
|
||||
use crate::*;
|
||||
use cached_tree_hash::{Error as TreeHashCacheError, TreeHashCache};
|
||||
use int_to_bytes::int_to_bytes32;
|
||||
use pubkey_cache::PubkeyCache;
|
||||
use rand::RngCore;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use ssz::{hash, ssz_encode, TreeHash};
|
||||
use ssz_derive::{Decode, Encode, TreeHash};
|
||||
use ssz::{hash, ssz_encode};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash::TreeHash;
|
||||
use tree_hash_derive::{CachedTreeHash, TreeHash};
|
||||
|
||||
mod epoch_cache;
|
||||
mod pubkey_cache;
|
||||
@@ -40,12 +43,24 @@ pub enum Error {
|
||||
EpochCacheUninitialized(RelativeEpoch),
|
||||
RelativeEpochError(RelativeEpochError),
|
||||
EpochCacheError(EpochCacheError),
|
||||
TreeHashCacheError(TreeHashCacheError),
|
||||
}
|
||||
|
||||
/// The state of the `BeaconChain` at some slot.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, TestRandom, Encode, Decode, TreeHash)]
|
||||
/// Spec v0.5.1
|
||||
#[derive(
|
||||
Debug,
|
||||
PartialEq,
|
||||
Clone,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
TestRandom,
|
||||
Encode,
|
||||
Decode,
|
||||
TreeHash,
|
||||
CachedTreeHash,
|
||||
)]
|
||||
pub struct BeaconState {
|
||||
// Misc
|
||||
pub slot: Slot,
|
||||
@@ -58,7 +73,7 @@ pub struct BeaconState {
|
||||
pub validator_registry_update_epoch: Epoch,
|
||||
|
||||
// Randomness and committees
|
||||
pub latest_randao_mixes: Vec<Hash256>,
|
||||
pub latest_randao_mixes: TreeHashVector<Hash256>,
|
||||
pub previous_shuffling_start_shard: u64,
|
||||
pub current_shuffling_start_shard: u64,
|
||||
pub previous_shuffling_epoch: Epoch,
|
||||
@@ -78,11 +93,11 @@ pub struct BeaconState {
|
||||
pub finalized_root: Hash256,
|
||||
|
||||
// Recent state
|
||||
pub latest_crosslinks: Vec<Crosslink>,
|
||||
latest_block_roots: Vec<Hash256>,
|
||||
latest_state_roots: Vec<Hash256>,
|
||||
latest_active_index_roots: Vec<Hash256>,
|
||||
latest_slashed_balances: Vec<u64>,
|
||||
pub latest_crosslinks: TreeHashVector<Crosslink>,
|
||||
pub latest_block_roots: TreeHashVector<Hash256>,
|
||||
latest_state_roots: TreeHashVector<Hash256>,
|
||||
latest_active_index_roots: TreeHashVector<Hash256>,
|
||||
latest_slashed_balances: TreeHashVector<u64>,
|
||||
pub latest_block_header: BeaconBlockHeader,
|
||||
pub historical_roots: Vec<Hash256>,
|
||||
|
||||
@@ -110,6 +125,12 @@ pub struct BeaconState {
|
||||
#[tree_hash(skip_hashing)]
|
||||
#[test_random(default)]
|
||||
pub pubkey_cache: PubkeyCache,
|
||||
#[serde(skip_serializing, skip_deserializing)]
|
||||
#[ssz(skip_serializing)]
|
||||
#[ssz(skip_deserializing)]
|
||||
#[tree_hash(skip_hashing)]
|
||||
#[test_random(default)]
|
||||
pub tree_hash_cache: TreeHashCache,
|
||||
}
|
||||
|
||||
impl BeaconState {
|
||||
@@ -118,7 +139,7 @@ impl BeaconState {
|
||||
/// This does not fully build a genesis beacon state, it omits processing of initial validator
|
||||
/// deposits. To obtain a full genesis beacon state, use the `BeaconStateBuilder`.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
/// Spec v0.5.1
|
||||
pub fn genesis(genesis_time: u64, latest_eth1_data: Eth1Data, spec: &ChainSpec) -> BeaconState {
|
||||
let initial_crosslink = Crosslink {
|
||||
epoch: spec.genesis_epoch,
|
||||
@@ -137,7 +158,8 @@ impl BeaconState {
|
||||
validator_registry_update_epoch: spec.genesis_epoch,
|
||||
|
||||
// Randomness and committees
|
||||
latest_randao_mixes: vec![spec.zero_hash; spec.latest_randao_mixes_length as usize],
|
||||
latest_randao_mixes: vec![spec.zero_hash; spec.latest_randao_mixes_length as usize]
|
||||
.into(),
|
||||
previous_shuffling_start_shard: spec.genesis_start_shard,
|
||||
current_shuffling_start_shard: spec.genesis_start_shard,
|
||||
previous_shuffling_epoch: spec.genesis_epoch,
|
||||
@@ -157,11 +179,12 @@ impl BeaconState {
|
||||
finalized_root: spec.zero_hash,
|
||||
|
||||
// Recent state
|
||||
latest_crosslinks: vec![initial_crosslink; spec.shard_count as usize],
|
||||
latest_block_roots: vec![spec.zero_hash; spec.slots_per_historical_root],
|
||||
latest_state_roots: vec![spec.zero_hash; spec.slots_per_historical_root],
|
||||
latest_active_index_roots: vec![spec.zero_hash; spec.latest_active_index_roots_length],
|
||||
latest_slashed_balances: vec![0; spec.latest_slashed_exit_length],
|
||||
latest_crosslinks: vec![initial_crosslink; spec.shard_count as usize].into(),
|
||||
latest_block_roots: vec![spec.zero_hash; spec.slots_per_historical_root].into(),
|
||||
latest_state_roots: vec![spec.zero_hash; spec.slots_per_historical_root].into(),
|
||||
latest_active_index_roots: vec![spec.zero_hash; spec.latest_active_index_roots_length]
|
||||
.into(),
|
||||
latest_slashed_balances: vec![0; spec.latest_slashed_exit_length].into(),
|
||||
latest_block_header: BeaconBlock::empty(spec).temporary_block_header(spec),
|
||||
historical_roots: vec![],
|
||||
|
||||
@@ -183,14 +206,15 @@ impl BeaconState {
|
||||
EpochCache::default(),
|
||||
],
|
||||
pubkey_cache: PubkeyCache::default(),
|
||||
tree_hash_cache: TreeHashCache::default(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the `hash_tree_root` of the state.
|
||||
/// Returns the `tree_hash_root` of the state.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
/// Spec v0.5.1
|
||||
pub fn canonical_root(&self) -> Hash256 {
|
||||
Hash256::from_slice(&self.hash_tree_root()[..])
|
||||
Hash256::from_slice(&self.tree_hash_root()[..])
|
||||
}
|
||||
|
||||
pub fn historical_batch(&self) -> HistoricalBatch {
|
||||
@@ -217,7 +241,7 @@ impl BeaconState {
|
||||
|
||||
/// The epoch corresponding to `self.slot`.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
/// Spec v0.5.1
|
||||
pub fn current_epoch(&self, spec: &ChainSpec) -> Epoch {
|
||||
self.slot.epoch(spec.slots_per_epoch)
|
||||
}
|
||||
@@ -226,14 +250,14 @@ impl BeaconState {
|
||||
///
|
||||
/// If the current epoch is the genesis epoch, the genesis_epoch is returned.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
/// Spec v0.5.1
|
||||
pub fn previous_epoch(&self, spec: &ChainSpec) -> Epoch {
|
||||
self.current_epoch(&spec) - 1
|
||||
}
|
||||
|
||||
/// The epoch following `self.current_epoch()`.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
/// Spec v0.5.1
|
||||
pub fn next_epoch(&self, spec: &ChainSpec) -> Epoch {
|
||||
self.current_epoch(spec) + 1
|
||||
}
|
||||
@@ -246,7 +270,7 @@ impl BeaconState {
|
||||
///
|
||||
/// Note: Utilizes the cache and will fail if the appropriate cache is not initialized.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
/// Spec v0.5.1
|
||||
pub fn get_cached_active_validator_indices(
|
||||
&self,
|
||||
relative_epoch: RelativeEpoch,
|
||||
@@ -261,7 +285,7 @@ impl BeaconState {
|
||||
///
|
||||
/// Does not utilize the cache, performs a full iteration over the validator registry.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
/// Spec v0.5.1
|
||||
pub fn get_active_validator_indices(&self, epoch: Epoch) -> Vec<usize> {
|
||||
get_active_validator_indices(&self.validator_registry, epoch)
|
||||
}
|
||||
@@ -270,7 +294,7 @@ impl BeaconState {
|
||||
///
|
||||
/// Note: Utilizes the cache and will fail if the appropriate cache is not initialized.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
/// Spec v0.5.1
|
||||
pub fn get_crosslink_committees_at_slot(
|
||||
&self,
|
||||
slot: Slot,
|
||||
@@ -295,7 +319,7 @@ impl BeaconState {
|
||||
///
|
||||
/// Note: Utilizes the cache and will fail if the appropriate cache is not initialized.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
/// Spec v0.5.1
|
||||
pub fn get_crosslink_committee_for_shard(
|
||||
&self,
|
||||
epoch: Epoch,
|
||||
@@ -321,7 +345,7 @@ impl BeaconState {
|
||||
///
|
||||
/// If the state does not contain an index for a beacon proposer at the requested `slot`, then `None` is returned.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
/// Spec v0.5.1
|
||||
pub fn get_beacon_proposer_index(
|
||||
&self,
|
||||
slot: Slot,
|
||||
@@ -350,7 +374,7 @@ impl BeaconState {
|
||||
|
||||
/// Safely obtains the index for latest block roots, given some `slot`.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
/// Spec v0.5.1
|
||||
fn get_latest_block_roots_index(&self, slot: Slot, spec: &ChainSpec) -> Result<usize, Error> {
|
||||
if (slot < self.slot) && (self.slot <= slot + spec.slots_per_historical_root as u64) {
|
||||
let i = slot.as_usize() % spec.slots_per_historical_root;
|
||||
@@ -366,7 +390,7 @@ impl BeaconState {
|
||||
|
||||
/// Return the block root at a recent `slot`.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
/// Spec v0.5.1
|
||||
pub fn get_block_root(
|
||||
&self,
|
||||
slot: Slot,
|
||||
@@ -378,7 +402,7 @@ impl BeaconState {
|
||||
|
||||
/// Sets the block root for some given slot.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
/// Spec v0.5.1
|
||||
pub fn set_block_root(
|
||||
&mut self,
|
||||
slot: Slot,
|
||||
@@ -392,7 +416,7 @@ impl BeaconState {
|
||||
|
||||
/// Safely obtains the index for `latest_randao_mixes`
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
/// Spec v0.5.1
|
||||
fn get_randao_mix_index(&self, epoch: Epoch, spec: &ChainSpec) -> Result<usize, Error> {
|
||||
let current_epoch = self.current_epoch(spec);
|
||||
|
||||
@@ -416,7 +440,7 @@ impl BeaconState {
|
||||
///
|
||||
/// See `Self::get_randao_mix`.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
/// Spec v0.5.1
|
||||
pub fn update_randao_mix(
|
||||
&mut self,
|
||||
epoch: Epoch,
|
||||
@@ -434,7 +458,7 @@ impl BeaconState {
|
||||
|
||||
/// Return the randao mix at a recent ``epoch``.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
/// Spec v0.5.1
|
||||
pub fn get_randao_mix(&self, epoch: Epoch, spec: &ChainSpec) -> Result<&Hash256, Error> {
|
||||
let i = self.get_randao_mix_index(epoch, spec)?;
|
||||
Ok(&self.latest_randao_mixes[i])
|
||||
@@ -442,7 +466,7 @@ impl BeaconState {
|
||||
|
||||
/// Set the randao mix at a recent ``epoch``.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
/// Spec v0.5.1
|
||||
pub fn set_randao_mix(
|
||||
&mut self,
|
||||
epoch: Epoch,
|
||||
@@ -456,7 +480,7 @@ impl BeaconState {
|
||||
|
||||
/// Safely obtains the index for `latest_active_index_roots`, given some `epoch`.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
/// Spec v0.5.1
|
||||
fn get_active_index_root_index(&self, epoch: Epoch, spec: &ChainSpec) -> Result<usize, Error> {
|
||||
let current_epoch = self.current_epoch(spec);
|
||||
|
||||
@@ -478,7 +502,7 @@ impl BeaconState {
|
||||
|
||||
/// Return the `active_index_root` at a recent `epoch`.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
/// Spec v0.5.1
|
||||
pub fn get_active_index_root(&self, epoch: Epoch, spec: &ChainSpec) -> Result<Hash256, Error> {
|
||||
let i = self.get_active_index_root_index(epoch, spec)?;
|
||||
Ok(self.latest_active_index_roots[i])
|
||||
@@ -486,7 +510,7 @@ impl BeaconState {
|
||||
|
||||
/// Set the `active_index_root` at a recent `epoch`.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
/// Spec v0.5.1
|
||||
pub fn set_active_index_root(
|
||||
&mut self,
|
||||
epoch: Epoch,
|
||||
@@ -500,15 +524,15 @@ impl BeaconState {
|
||||
|
||||
/// Replace `active_index_roots` with clones of `index_root`.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
/// Spec v0.5.1
|
||||
pub fn fill_active_index_roots_with(&mut self, index_root: Hash256, spec: &ChainSpec) {
|
||||
self.latest_active_index_roots =
|
||||
vec![index_root; spec.latest_active_index_roots_length as usize]
|
||||
vec![index_root; spec.latest_active_index_roots_length as usize].into()
|
||||
}
|
||||
|
||||
/// Safely obtains the index for latest state roots, given some `slot`.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
/// Spec v0.5.1
|
||||
fn get_latest_state_roots_index(&self, slot: Slot, spec: &ChainSpec) -> Result<usize, Error> {
|
||||
if (slot < self.slot) && (self.slot <= slot + spec.slots_per_historical_root as u64) {
|
||||
let i = slot.as_usize() % spec.slots_per_historical_root;
|
||||
@@ -524,7 +548,7 @@ impl BeaconState {
|
||||
|
||||
/// Gets the state root for some slot.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
/// Spec v0.5.1
|
||||
pub fn get_state_root(&mut self, slot: Slot, spec: &ChainSpec) -> Result<&Hash256, Error> {
|
||||
let i = self.get_latest_state_roots_index(slot, spec)?;
|
||||
Ok(&self.latest_state_roots[i])
|
||||
@@ -532,7 +556,7 @@ impl BeaconState {
|
||||
|
||||
/// Sets the latest state root for slot.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
/// Spec v0.5.1
|
||||
pub fn set_state_root(
|
||||
&mut self,
|
||||
slot: Slot,
|
||||
@@ -546,7 +570,7 @@ impl BeaconState {
|
||||
|
||||
/// Safely obtains the index for `latest_slashed_balances`, given some `epoch`.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
/// Spec v0.5.1
|
||||
fn get_slashed_balance_index(&self, epoch: Epoch, spec: &ChainSpec) -> Result<usize, Error> {
|
||||
let i = epoch.as_usize() % spec.latest_slashed_exit_length;
|
||||
|
||||
@@ -561,7 +585,7 @@ impl BeaconState {
|
||||
|
||||
/// Gets the total slashed balances for some epoch.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
/// Spec v0.5.1
|
||||
pub fn get_slashed_balance(&self, epoch: Epoch, spec: &ChainSpec) -> Result<u64, Error> {
|
||||
let i = self.get_slashed_balance_index(epoch, spec)?;
|
||||
Ok(self.latest_slashed_balances[i])
|
||||
@@ -569,7 +593,7 @@ impl BeaconState {
|
||||
|
||||
/// Sets the total slashed balances for some epoch.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
/// Spec v0.5.1
|
||||
pub fn set_slashed_balance(
|
||||
&mut self,
|
||||
epoch: Epoch,
|
||||
@@ -583,7 +607,7 @@ impl BeaconState {
|
||||
|
||||
/// Generate a seed for the given `epoch`.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
/// Spec v0.5.1
|
||||
pub fn generate_seed(&self, epoch: Epoch, spec: &ChainSpec) -> Result<Hash256, Error> {
|
||||
let mut input = self
|
||||
.get_randao_mix(epoch - spec.min_seed_lookahead, spec)?
|
||||
@@ -599,7 +623,7 @@ impl BeaconState {
|
||||
|
||||
/// Return the effective balance (also known as "balance at stake") for a validator with the given ``index``.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
/// Spec v0.5.1
|
||||
pub fn get_effective_balance(
|
||||
&self,
|
||||
validator_index: usize,
|
||||
@@ -614,14 +638,14 @@ impl BeaconState {
|
||||
|
||||
/// Return the epoch at which an activation or exit triggered in ``epoch`` takes effect.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
/// Spec v0.5.1
|
||||
pub fn get_delayed_activation_exit_epoch(&self, epoch: Epoch, spec: &ChainSpec) -> Epoch {
|
||||
epoch + 1 + spec.activation_exit_delay
|
||||
}
|
||||
|
||||
/// Initiate an exit for the validator of the given `index`.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
/// Spec v0.5.1
|
||||
pub fn initiate_validator_exit(&mut self, validator_index: usize) {
|
||||
self.validator_registry[validator_index].initiated_exit = true;
|
||||
}
|
||||
@@ -633,7 +657,7 @@ impl BeaconState {
|
||||
///
|
||||
/// Note: Utilizes the cache and will fail if the appropriate cache is not initialized.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
/// Spec v0.5.1
|
||||
pub fn get_attestation_duties(
|
||||
&self,
|
||||
validator_index: usize,
|
||||
@@ -649,7 +673,7 @@ impl BeaconState {
|
||||
|
||||
/// Return the combined effective balance of an array of validators.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
/// Spec v0.5.1
|
||||
pub fn get_total_balance(
|
||||
&self,
|
||||
validator_indices: &[usize],
|
||||
@@ -668,6 +692,7 @@ impl BeaconState {
|
||||
self.build_epoch_cache(RelativeEpoch::NextWithoutRegistryChange, spec)?;
|
||||
self.build_epoch_cache(RelativeEpoch::NextWithRegistryChange, spec)?;
|
||||
self.update_pubkey_cache()?;
|
||||
self.update_tree_hash_cache()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -774,6 +799,39 @@ impl BeaconState {
|
||||
pub fn drop_pubkey_cache(&mut self) {
|
||||
self.pubkey_cache = PubkeyCache::default()
|
||||
}
|
||||
|
||||
/// Update the tree hash cache, building it for the first time if it is empty.
|
||||
///
|
||||
/// Returns the `tree_hash_root` resulting from the update. This root can be considered the
|
||||
/// canonical root of `self`.
|
||||
pub fn update_tree_hash_cache(&mut self) -> Result<Hash256, Error> {
|
||||
if self.tree_hash_cache.is_empty() {
|
||||
self.tree_hash_cache = TreeHashCache::new(self)?;
|
||||
} else {
|
||||
// Move the cache outside of `self` to satisfy the borrow checker.
|
||||
let mut cache = std::mem::replace(&mut self.tree_hash_cache, TreeHashCache::default());
|
||||
|
||||
cache.update(self)?;
|
||||
|
||||
// Move the updated cache back into `self`.
|
||||
self.tree_hash_cache = cache
|
||||
}
|
||||
|
||||
self.cached_tree_hash_root()
|
||||
}
|
||||
|
||||
/// Returns the tree hash root determined by the last execution of `self.update_tree_hash_cache(..)`.
|
||||
///
|
||||
/// Note: does _not_ update the cache and may return an outdated root.
|
||||
///
|
||||
/// Returns an error if the cache is not initialized or if an error is encountered during the
|
||||
/// cache update.
|
||||
pub fn cached_tree_hash_root(&self) -> Result<Hash256, Error> {
|
||||
self.tree_hash_cache
|
||||
.tree_hash_root()
|
||||
.and_then(|b| Ok(Hash256::from_slice(b)))
|
||||
.map_err(|e| e.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<RelativeEpochError> for Error {
|
||||
@@ -787,3 +845,9 @@ impl From<EpochCacheError> for Error {
|
||||
Error::EpochCacheError(e)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<TreeHashCacheError> for Error {
|
||||
fn from(e: TreeHashCacheError) -> Error {
|
||||
Error::TreeHashCacheError(e)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,7 +138,7 @@ impl EpochCache {
|
||||
/// Returns a list of all `validator_registry` indices where the validator is active at the given
|
||||
/// `epoch`.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
/// Spec v0.5.1
|
||||
pub fn get_active_validator_indices(validators: &[Validator], epoch: Epoch) -> Vec<usize> {
|
||||
let mut active = Vec::with_capacity(validators.len());
|
||||
|
||||
@@ -288,7 +288,7 @@ impl EpochCrosslinkCommitteesBuilder {
|
||||
self.active_validator_indices,
|
||||
spec.shuffle_round_count,
|
||||
&self.shuffling_seed[..],
|
||||
true,
|
||||
false,
|
||||
)
|
||||
.ok_or_else(|| Error::UnableToShuffle)?
|
||||
};
|
||||
|
||||
@@ -27,7 +27,7 @@ fn do_sane_cache_test(
|
||||
active_indices,
|
||||
spec.shuffle_round_count,
|
||||
&expected_seed[..],
|
||||
true,
|
||||
false,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ use super::*;
|
||||
use crate::test_utils::*;
|
||||
|
||||
ssz_tests!(BeaconState);
|
||||
cached_tree_hash_tests!(BeaconState);
|
||||
|
||||
/// Test that
|
||||
///
|
||||
@@ -55,3 +56,22 @@ fn cache_initialization() {
|
||||
test_cache_initialization(&mut state, RelativeEpoch::NextWithRegistryChange, &spec);
|
||||
test_cache_initialization(&mut state, RelativeEpoch::NextWithoutRegistryChange, &spec);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tree_hash_cache() {
|
||||
use crate::test_utils::{SeedableRng, TestRandom, XorShiftRng};
|
||||
use tree_hash::TreeHash;
|
||||
|
||||
let mut rng = XorShiftRng::from_seed([42; 16]);
|
||||
|
||||
let mut state = BeaconState::random_for_test(&mut rng);
|
||||
|
||||
let root = state.update_tree_hash_cache().unwrap();
|
||||
|
||||
assert_eq!(root.as_bytes(), &state.tree_hash_root()[..]);
|
||||
|
||||
state.slot = state.slot + 1;
|
||||
|
||||
let root = state.update_tree_hash_cache().unwrap();
|
||||
assert_eq!(root.as_bytes(), &state.tree_hash_root()[..]);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ const GWEI: u64 = 1_000_000_000;
|
||||
|
||||
/// Each of the BLS signature domains.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
/// Spec v0.5.1
|
||||
pub enum Domain {
|
||||
BeaconBlock,
|
||||
Randao,
|
||||
@@ -20,7 +20,7 @@ pub enum Domain {
|
||||
|
||||
/// Holds all the "constants" for a BeaconChain.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
/// Spec v0.5.1
|
||||
#[derive(PartialEq, Debug, Clone, Deserialize)]
|
||||
#[serde(default)]
|
||||
pub struct ChainSpec {
|
||||
@@ -126,7 +126,7 @@ pub struct ChainSpec {
|
||||
impl ChainSpec {
|
||||
/// Return the number of committees in one epoch.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
/// Spec v0.5.1
|
||||
pub fn get_epoch_committee_count(&self, active_validator_count: usize) -> u64 {
|
||||
std::cmp::max(
|
||||
1,
|
||||
@@ -139,7 +139,7 @@ impl ChainSpec {
|
||||
|
||||
/// Get the domain number that represents the fork meta and signature domain.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
/// Spec v0.5.1
|
||||
pub fn get_domain(&self, epoch: Epoch, domain: Domain, fork: &Fork) -> u64 {
|
||||
let domain_constant = match domain {
|
||||
Domain::BeaconBlock => self.domain_beacon_block,
|
||||
@@ -161,7 +161,7 @@ impl ChainSpec {
|
||||
|
||||
/// Returns a `ChainSpec` compatible with the Ethereum Foundation specification.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
/// Spec v0.5.1
|
||||
pub fn foundation() -> Self {
|
||||
let genesis_slot = Slot::new(2_u64.pow(32));
|
||||
let slots_per_epoch = 64;
|
||||
|
||||
@@ -2,12 +2,13 @@ use crate::test_utils::TestRandom;
|
||||
use crate::{Epoch, Hash256};
|
||||
use rand::RngCore;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use ssz_derive::{Decode, Encode, TreeHash};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash_derive::{CachedTreeHash, TreeHash};
|
||||
|
||||
/// Specifies the block hash for a shard at an epoch.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
/// Spec v0.5.1
|
||||
#[derive(
|
||||
Debug,
|
||||
Clone,
|
||||
@@ -19,6 +20,7 @@ use test_random_derive::TestRandom;
|
||||
Encode,
|
||||
Decode,
|
||||
TreeHash,
|
||||
CachedTreeHash,
|
||||
TestRandom,
|
||||
)]
|
||||
pub struct Crosslink {
|
||||
@@ -31,4 +33,5 @@ mod tests {
|
||||
use super::*;
|
||||
|
||||
ssz_tests!(Crosslink);
|
||||
cached_tree_hash_tests!(Crosslink);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,20 @@
|
||||
use crate::*;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use ssz_derive::{Decode, Encode, TreeHash};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use tree_hash_derive::{CachedTreeHash, TreeHash};
|
||||
|
||||
#[derive(Default, Clone, Debug, PartialEq, Serialize, Deserialize, Decode, Encode, TreeHash)]
|
||||
#[derive(
|
||||
Default,
|
||||
Clone,
|
||||
Debug,
|
||||
PartialEq,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
Decode,
|
||||
Encode,
|
||||
TreeHash,
|
||||
CachedTreeHash,
|
||||
)]
|
||||
pub struct CrosslinkCommittee {
|
||||
pub slot: Slot,
|
||||
pub shard: Shard,
|
||||
|
||||
@@ -1,16 +1,28 @@
|
||||
use super::{DepositData, Hash256};
|
||||
use super::{DepositData, Hash256, TreeHashVector};
|
||||
use crate::test_utils::TestRandom;
|
||||
use rand::RngCore;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use ssz_derive::{Decode, Encode, TreeHash};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash_derive::{CachedTreeHash, TreeHash};
|
||||
|
||||
/// A deposit to potentially become a beacon chain validator.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Encode, Decode, TreeHash, TestRandom)]
|
||||
/// Spec v0.5.1
|
||||
#[derive(
|
||||
Debug,
|
||||
PartialEq,
|
||||
Clone,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
Encode,
|
||||
Decode,
|
||||
TreeHash,
|
||||
CachedTreeHash,
|
||||
TestRandom,
|
||||
)]
|
||||
pub struct Deposit {
|
||||
pub proof: Vec<Hash256>,
|
||||
pub proof: TreeHashVector<Hash256>,
|
||||
pub index: u64,
|
||||
pub deposit_data: DepositData,
|
||||
}
|
||||
@@ -20,4 +32,5 @@ mod tests {
|
||||
use super::*;
|
||||
|
||||
ssz_tests!(Deposit);
|
||||
cached_tree_hash_tests!(Deposit);
|
||||
}
|
||||
|
||||
@@ -2,13 +2,25 @@ use super::DepositInput;
|
||||
use crate::test_utils::TestRandom;
|
||||
use rand::RngCore;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use ssz_derive::{Decode, Encode, TreeHash};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash_derive::{CachedTreeHash, TreeHash};
|
||||
|
||||
/// Data generated by the deposit contract.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Encode, Decode, TreeHash, TestRandom)]
|
||||
/// Spec v0.5.1
|
||||
#[derive(
|
||||
Debug,
|
||||
PartialEq,
|
||||
Clone,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
Encode,
|
||||
Decode,
|
||||
TreeHash,
|
||||
CachedTreeHash,
|
||||
TestRandom,
|
||||
)]
|
||||
pub struct DepositData {
|
||||
pub amount: u64,
|
||||
pub timestamp: u64,
|
||||
@@ -20,4 +32,5 @@ mod tests {
|
||||
use super::*;
|
||||
|
||||
ssz_tests!(DepositData);
|
||||
cached_tree_hash_tests!(DepositData);
|
||||
}
|
||||
|
||||
@@ -3,13 +3,14 @@ use crate::*;
|
||||
use bls::{PublicKey, Signature};
|
||||
use rand::RngCore;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use ssz::{SignedRoot, TreeHash};
|
||||
use ssz_derive::{Decode, Encode, SignedRoot, TreeHash};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash::{SignedRoot, TreeHash};
|
||||
use tree_hash_derive::{CachedTreeHash, SignedRoot, TreeHash};
|
||||
|
||||
/// The data supplied by the user to the deposit contract.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
/// Spec v0.5.1
|
||||
#[derive(
|
||||
Debug,
|
||||
PartialEq,
|
||||
@@ -20,18 +21,20 @@ use test_random_derive::TestRandom;
|
||||
Decode,
|
||||
SignedRoot,
|
||||
TreeHash,
|
||||
CachedTreeHash,
|
||||
TestRandom,
|
||||
)]
|
||||
pub struct DepositInput {
|
||||
pub pubkey: PublicKey,
|
||||
pub withdrawal_credentials: Hash256,
|
||||
#[signed_root(skip_hashing)]
|
||||
pub proof_of_possession: Signature,
|
||||
}
|
||||
|
||||
impl DepositInput {
|
||||
/// Generate the 'proof_of_posession' signature for a given DepositInput details.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
/// Spec v0.5.1
|
||||
pub fn create_proof_of_possession(
|
||||
&self,
|
||||
secret_key: &SecretKey,
|
||||
@@ -47,7 +50,7 @@ impl DepositInput {
|
||||
|
||||
/// Verify that proof-of-possession is valid.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
/// Spec v0.5.1
|
||||
pub fn validate_proof_of_possession(
|
||||
&self,
|
||||
epoch: Epoch,
|
||||
@@ -66,6 +69,7 @@ mod tests {
|
||||
use super::*;
|
||||
|
||||
ssz_tests!(DepositInput);
|
||||
cached_tree_hash_tests!(DepositInput);
|
||||
|
||||
#[test]
|
||||
fn can_create_and_validate() {
|
||||
|
||||
@@ -2,14 +2,25 @@ use super::Hash256;
|
||||
use crate::test_utils::TestRandom;
|
||||
use rand::RngCore;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use ssz_derive::{Decode, Encode, TreeHash};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash_derive::{CachedTreeHash, TreeHash};
|
||||
|
||||
/// Contains data obtained from the Eth1 chain.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
/// Spec v0.5.1
|
||||
#[derive(
|
||||
Debug, PartialEq, Clone, Default, Serialize, Deserialize, Encode, Decode, TreeHash, TestRandom,
|
||||
Debug,
|
||||
PartialEq,
|
||||
Clone,
|
||||
Default,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
Encode,
|
||||
Decode,
|
||||
TreeHash,
|
||||
CachedTreeHash,
|
||||
TestRandom,
|
||||
)]
|
||||
pub struct Eth1Data {
|
||||
pub deposit_root: Hash256,
|
||||
@@ -21,4 +32,5 @@ mod tests {
|
||||
use super::*;
|
||||
|
||||
ssz_tests!(Eth1Data);
|
||||
cached_tree_hash_tests!(Eth1Data);
|
||||
}
|
||||
|
||||
@@ -2,14 +2,25 @@ use super::Eth1Data;
|
||||
use crate::test_utils::TestRandom;
|
||||
use rand::RngCore;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use ssz_derive::{Decode, Encode, TreeHash};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash_derive::{CachedTreeHash, TreeHash};
|
||||
|
||||
/// A summation of votes for some `Eth1Data`.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
/// Spec v0.5.1
|
||||
#[derive(
|
||||
Debug, PartialEq, Clone, Default, Serialize, Deserialize, Encode, Decode, TreeHash, TestRandom,
|
||||
Debug,
|
||||
PartialEq,
|
||||
Clone,
|
||||
Default,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
Encode,
|
||||
Decode,
|
||||
TreeHash,
|
||||
CachedTreeHash,
|
||||
TestRandom,
|
||||
)]
|
||||
pub struct Eth1DataVote {
|
||||
pub eth1_data: Eth1Data,
|
||||
@@ -21,4 +32,5 @@ mod tests {
|
||||
use super::*;
|
||||
|
||||
ssz_tests!(Eth1DataVote);
|
||||
cached_tree_hash_tests!(Eth1DataVote);
|
||||
}
|
||||
|
||||
@@ -5,14 +5,25 @@ use crate::{
|
||||
use int_to_bytes::int_to_bytes4;
|
||||
use rand::RngCore;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use ssz_derive::{Decode, Encode, TreeHash};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash_derive::{CachedTreeHash, TreeHash};
|
||||
|
||||
/// Specifies a fork of the `BeaconChain`, to prevent replay attacks.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
/// Spec v0.5.1
|
||||
#[derive(
|
||||
Debug, Clone, PartialEq, Default, Serialize, Deserialize, Encode, Decode, TreeHash, TestRandom,
|
||||
Debug,
|
||||
Clone,
|
||||
PartialEq,
|
||||
Default,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
Encode,
|
||||
Decode,
|
||||
TreeHash,
|
||||
CachedTreeHash,
|
||||
TestRandom,
|
||||
)]
|
||||
pub struct Fork {
|
||||
#[serde(deserialize_with = "fork_from_hex_str")]
|
||||
@@ -25,7 +36,7 @@ pub struct Fork {
|
||||
impl Fork {
|
||||
/// Initialize the `Fork` from the genesis parameters in the `spec`.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
/// Spec v0.5.1
|
||||
pub fn genesis(spec: &ChainSpec) -> Self {
|
||||
let mut current_version: [u8; 4] = [0; 4];
|
||||
current_version.copy_from_slice(&int_to_bytes4(spec.genesis_fork_version));
|
||||
@@ -39,7 +50,7 @@ impl Fork {
|
||||
|
||||
/// Return the fork version of the given ``epoch``.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
/// Spec v0.5.1
|
||||
pub fn get_fork_version(&self, epoch: Epoch) -> [u8; 4] {
|
||||
if epoch < self.epoch {
|
||||
return self.previous_version;
|
||||
@@ -53,6 +64,7 @@ mod tests {
|
||||
use super::*;
|
||||
|
||||
ssz_tests!(Fork);
|
||||
cached_tree_hash_tests!(Fork);
|
||||
|
||||
fn test_genesis(version: u32, epoch: Epoch) {
|
||||
let mut spec = ChainSpec::foundation();
|
||||
|
||||
@@ -1,17 +1,29 @@
|
||||
use crate::test_utils::TestRandom;
|
||||
use crate::Hash256;
|
||||
use crate::{Hash256, TreeHashVector};
|
||||
use rand::RngCore;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use ssz_derive::{Decode, Encode, TreeHash};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash_derive::{CachedTreeHash, TreeHash};
|
||||
|
||||
/// Historical block and state roots.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Encode, Decode, TreeHash, TestRandom)]
|
||||
/// Spec v0.5.1
|
||||
#[derive(
|
||||
Debug,
|
||||
Clone,
|
||||
PartialEq,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
Encode,
|
||||
Decode,
|
||||
TreeHash,
|
||||
CachedTreeHash,
|
||||
TestRandom,
|
||||
)]
|
||||
pub struct HistoricalBatch {
|
||||
pub block_roots: Vec<Hash256>,
|
||||
pub state_roots: Vec<Hash256>,
|
||||
pub block_roots: TreeHashVector<Hash256>,
|
||||
pub state_roots: TreeHashVector<Hash256>,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -19,4 +31,5 @@ mod tests {
|
||||
use super::*;
|
||||
|
||||
ssz_tests!(HistoricalBatch);
|
||||
cached_tree_hash_tests!(HistoricalBatch);
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ 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;
|
||||
@@ -65,6 +66,7 @@ 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;
|
||||
|
||||
|
||||
@@ -2,13 +2,25 @@ use crate::test_utils::TestRandom;
|
||||
use crate::{Attestation, AttestationData, Bitfield, Slot};
|
||||
use rand::RngCore;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use ssz_derive::{Decode, Encode, TreeHash};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash_derive::{CachedTreeHash, TreeHash};
|
||||
|
||||
/// An attestation that has been included in the state but not yet fully processed.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Encode, Decode, TreeHash, TestRandom)]
|
||||
/// Spec v0.5.1
|
||||
#[derive(
|
||||
Debug,
|
||||
Clone,
|
||||
PartialEq,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
Encode,
|
||||
Decode,
|
||||
TreeHash,
|
||||
CachedTreeHash,
|
||||
TestRandom,
|
||||
)]
|
||||
pub struct PendingAttestation {
|
||||
pub aggregation_bitfield: Bitfield,
|
||||
pub data: AttestationData,
|
||||
@@ -33,4 +45,5 @@ mod tests {
|
||||
use super::*;
|
||||
|
||||
ssz_tests!(PendingAttestation);
|
||||
cached_tree_hash_tests!(PendingAttestation);
|
||||
}
|
||||
|
||||
@@ -2,13 +2,25 @@ use super::BeaconBlockHeader;
|
||||
use crate::test_utils::TestRandom;
|
||||
use rand::RngCore;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use ssz_derive::{Decode, Encode, TreeHash};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash_derive::{CachedTreeHash, TreeHash};
|
||||
|
||||
/// Two conflicting proposals from the same proposer (validator).
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Encode, Decode, TreeHash, TestRandom)]
|
||||
/// Spec v0.5.1
|
||||
#[derive(
|
||||
Debug,
|
||||
PartialEq,
|
||||
Clone,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
Encode,
|
||||
Decode,
|
||||
TreeHash,
|
||||
CachedTreeHash,
|
||||
TestRandom,
|
||||
)]
|
||||
pub struct ProposerSlashing {
|
||||
pub proposer_index: u64,
|
||||
pub header_1: BeaconBlockHeader,
|
||||
@@ -20,4 +32,5 @@ mod tests {
|
||||
use super::*;
|
||||
|
||||
ssz_tests!(ProposerSlashing);
|
||||
cached_tree_hash_tests!(ProposerSlashing);
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ pub enum Error {
|
||||
/// Defines the epochs relative to some epoch. Most useful when referring to the committees prior
|
||||
/// to and following some epoch.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
/// Spec v0.5.1
|
||||
#[derive(Debug, PartialEq, Clone, Copy)]
|
||||
pub enum RelativeEpoch {
|
||||
/// The prior epoch.
|
||||
@@ -32,7 +32,7 @@ pub enum RelativeEpoch {
|
||||
impl RelativeEpoch {
|
||||
/// Returns the `epoch` that `self` refers to, with respect to the `base` epoch.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
/// Spec v0.5.1
|
||||
pub fn into_epoch(self, base: Epoch) -> Epoch {
|
||||
match self {
|
||||
RelativeEpoch::Previous => base - 1,
|
||||
@@ -51,7 +51,7 @@ impl RelativeEpoch {
|
||||
/// - `AmbiguiousNextEpoch` whenever `other` is one after `base`, because it's unknowable if
|
||||
/// there will be a registry change.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
/// Spec v0.5.1
|
||||
pub fn from_epoch(base: Epoch, other: Epoch) -> Result<Self, Error> {
|
||||
if other == base - 1 {
|
||||
Ok(RelativeEpoch::Previous)
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
use crate::{test_utils::TestRandom, AggregateSignature, AttestationData, Bitfield, ChainSpec};
|
||||
use rand::RngCore;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use ssz::TreeHash;
|
||||
use ssz_derive::{Decode, Encode, SignedRoot, TreeHash};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash::TreeHash;
|
||||
use tree_hash_derive::{CachedTreeHash, SignedRoot, TreeHash};
|
||||
|
||||
/// Details an attestation that can be slashable.
|
||||
///
|
||||
/// To be included in an `AttesterSlashing`.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
/// Spec v0.5.1
|
||||
#[derive(
|
||||
Debug,
|
||||
PartialEq,
|
||||
@@ -19,6 +20,7 @@ use test_random_derive::TestRandom;
|
||||
Encode,
|
||||
Decode,
|
||||
TreeHash,
|
||||
CachedTreeHash,
|
||||
TestRandom,
|
||||
SignedRoot,
|
||||
)]
|
||||
@@ -27,20 +29,21 @@ pub struct SlashableAttestation {
|
||||
pub validator_indices: Vec<u64>,
|
||||
pub data: AttestationData,
|
||||
pub custody_bitfield: Bitfield,
|
||||
#[signed_root(skip_hashing)]
|
||||
pub aggregate_signature: AggregateSignature,
|
||||
}
|
||||
|
||||
impl SlashableAttestation {
|
||||
/// Check if ``attestation_data_1`` and ``attestation_data_2`` have the same target.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
/// Spec v0.5.1
|
||||
pub fn is_double_vote(&self, other: &SlashableAttestation, spec: &ChainSpec) -> bool {
|
||||
self.data.slot.epoch(spec.slots_per_epoch) == other.data.slot.epoch(spec.slots_per_epoch)
|
||||
}
|
||||
|
||||
/// Check if ``attestation_data_1`` surrounds ``attestation_data_2``.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
/// Spec v0.5.1
|
||||
pub fn is_surround_vote(&self, other: &SlashableAttestation, spec: &ChainSpec) -> bool {
|
||||
let source_epoch_1 = self.data.source_epoch;
|
||||
let source_epoch_2 = other.data.source_epoch;
|
||||
@@ -131,6 +134,7 @@ mod tests {
|
||||
}
|
||||
|
||||
ssz_tests!(SlashableAttestation);
|
||||
cached_tree_hash_tests!(SlashableAttestation);
|
||||
|
||||
fn create_slashable_attestation(
|
||||
slot_factor: u64,
|
||||
|
||||
@@ -14,7 +14,7 @@ use crate::test_utils::TestRandom;
|
||||
use rand::RngCore;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use slog;
|
||||
use ssz::{hash, ssz_encode, Decodable, DecodeError, Encodable, SszStream, TreeHash};
|
||||
use ssz::{ssz_encode, Decodable, DecodeError, Encodable, SszStream};
|
||||
use std::cmp::{Ord, Ordering};
|
||||
use std::fmt;
|
||||
use std::hash::{Hash, Hasher};
|
||||
|
||||
@@ -206,11 +206,41 @@ macro_rules! impl_ssz {
|
||||
}
|
||||
}
|
||||
|
||||
impl TreeHash for $type {
|
||||
fn hash_tree_root(&self) -> Vec<u8> {
|
||||
let mut result: Vec<u8> = vec![];
|
||||
result.append(&mut self.0.hash_tree_root());
|
||||
hash(&result)
|
||||
impl tree_hash::TreeHash for $type {
|
||||
fn tree_hash_type() -> tree_hash::TreeHashType {
|
||||
tree_hash::TreeHashType::Basic
|
||||
}
|
||||
|
||||
fn tree_hash_packed_encoding(&self) -> Vec<u8> {
|
||||
ssz_encode(self)
|
||||
}
|
||||
|
||||
fn tree_hash_packing_factor() -> usize {
|
||||
32 / 8
|
||||
}
|
||||
|
||||
fn tree_hash_root(&self) -> Vec<u8> {
|
||||
int_to_bytes::int_to_bytes32(self.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl cached_tree_hash::CachedTreeHash for $type {
|
||||
fn new_tree_hash_cache(
|
||||
&self,
|
||||
depth: usize,
|
||||
) -> Result<cached_tree_hash::TreeHashCache, cached_tree_hash::Error> {
|
||||
self.0.new_tree_hash_cache(depth)
|
||||
}
|
||||
|
||||
fn tree_hash_cache_schema(&self, depth: usize) -> cached_tree_hash::BTreeSchema {
|
||||
self.0.tree_hash_cache_schema(depth)
|
||||
}
|
||||
|
||||
fn update_tree_hash_cache(
|
||||
&self,
|
||||
cache: &mut cached_tree_hash::TreeHashCache,
|
||||
) -> Result<(), cached_tree_hash::Error> {
|
||||
self.0.update_tree_hash_cache(cache)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -535,6 +565,7 @@ macro_rules! all_tests {
|
||||
math_between_tests!($type, $type);
|
||||
math_tests!($type);
|
||||
ssz_tests!($type);
|
||||
cached_tree_hash_tests!($type);
|
||||
|
||||
mod u64_tests {
|
||||
use super::*;
|
||||
|
||||
@@ -2,7 +2,7 @@ use crate::slot_epoch::{Epoch, Slot};
|
||||
use crate::test_utils::TestRandom;
|
||||
use rand::RngCore;
|
||||
use serde_derive::Serialize;
|
||||
use ssz::{hash, ssz_encode, Decodable, DecodeError, Encodable, SszStream, TreeHash};
|
||||
use ssz::{ssz_encode, Decodable, DecodeError, Encodable, SszStream};
|
||||
use std::cmp::{Ord, Ordering};
|
||||
use std::fmt;
|
||||
use std::hash::{Hash, Hasher};
|
||||
|
||||
@@ -17,14 +17,14 @@ macro_rules! ssz_tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_hash_tree_root() {
|
||||
pub fn test_tree_hash_root() {
|
||||
use crate::test_utils::{SeedableRng, TestRandom, XorShiftRng};
|
||||
use ssz::TreeHash;
|
||||
use tree_hash::TreeHash;
|
||||
|
||||
let mut rng = XorShiftRng::from_seed([42; 16]);
|
||||
let original = $type::random_for_test(&mut rng);
|
||||
|
||||
let result = original.hash_tree_root();
|
||||
let result = original.tree_hash_root();
|
||||
|
||||
assert_eq!(result.len(), 32);
|
||||
// TODO: Add further tests
|
||||
@@ -32,3 +32,51 @@ macro_rules! ssz_tests {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[macro_export]
|
||||
macro_rules! cached_tree_hash_tests {
|
||||
($type: ident) => {
|
||||
#[test]
|
||||
pub fn test_cached_tree_hash() {
|
||||
use crate::test_utils::{SeedableRng, TestRandom, XorShiftRng};
|
||||
use tree_hash::TreeHash;
|
||||
|
||||
let mut rng = XorShiftRng::from_seed([42; 16]);
|
||||
|
||||
// Test the original hash
|
||||
let original = $type::random_for_test(&mut rng);
|
||||
let mut cache = cached_tree_hash::TreeHashCache::new(&original).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
cache.tree_hash_root().unwrap().to_vec(),
|
||||
original.tree_hash_root(),
|
||||
"Original hash failed."
|
||||
);
|
||||
|
||||
// Test the updated hash
|
||||
let modified = $type::random_for_test(&mut rng);
|
||||
cache.update(&modified).unwrap();
|
||||
assert_eq!(
|
||||
cache.tree_hash_root().unwrap().to_vec(),
|
||||
modified.tree_hash_root(),
|
||||
"Modification hash failed"
|
||||
);
|
||||
|
||||
// Produce a new cache for the modified object and compare it to the updated cache.
|
||||
let mut modified_cache = cached_tree_hash::TreeHashCache::new(&modified).unwrap();
|
||||
|
||||
// Reset the caches.
|
||||
cache.reset_modifications();
|
||||
modified_cache.reset_modifications();
|
||||
|
||||
// Ensure the modified cache is the same as a newly created cache. This is a sanity
|
||||
// check to make sure there are no artifacts of the original cache remaining after an
|
||||
// update.
|
||||
assert_eq!(
|
||||
modified_cache, cache,
|
||||
"The modified cache does not match a new cache."
|
||||
)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -18,7 +18,10 @@ mod testing_voluntary_exit_builder;
|
||||
pub use generate_deterministic_keypairs::generate_deterministic_keypair;
|
||||
pub use generate_deterministic_keypairs::generate_deterministic_keypairs;
|
||||
pub use keypairs_file::KeypairsFile;
|
||||
pub use rand::{prng::XorShiftRng, SeedableRng};
|
||||
pub use rand::{
|
||||
RngCore,
|
||||
{prng::XorShiftRng, SeedableRng},
|
||||
};
|
||||
pub use serde_utils::{fork_from_hex_str, u8_from_hex_str};
|
||||
pub use test_random::TestRandom;
|
||||
pub use testing_attestation_builder::TestingAttestationBuilder;
|
||||
|
||||
@@ -44,11 +44,13 @@ where
|
||||
U: TestRandom<T>,
|
||||
{
|
||||
fn random_for_test(rng: &mut T) -> Self {
|
||||
vec![
|
||||
<U>::random_for_test(rng),
|
||||
<U>::random_for_test(rng),
|
||||
<U>::random_for_test(rng),
|
||||
]
|
||||
let mut output = vec![];
|
||||
|
||||
for _ in 0..(usize::random_for_test(rng) % 4) {
|
||||
output.push(<U>::random_for_test(rng));
|
||||
}
|
||||
|
||||
output
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use crate::test_utils::TestingAttestationDataBuilder;
|
||||
use crate::*;
|
||||
use ssz::TreeHash;
|
||||
use tree_hash::TreeHash;
|
||||
|
||||
/// Builds an attestation to be used for testing purposes.
|
||||
///
|
||||
@@ -74,7 +74,7 @@ impl TestingAttestationBuilder {
|
||||
data: self.attestation.data.clone(),
|
||||
custody_bit: false,
|
||||
}
|
||||
.hash_tree_root();
|
||||
.tree_hash_root();
|
||||
|
||||
let domain = spec.get_domain(
|
||||
self.attestation.data.slot.epoch(spec.slots_per_epoch),
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::*;
|
||||
use ssz::TreeHash;
|
||||
use tree_hash::TreeHash;
|
||||
|
||||
/// Builds an `AttesterSlashing`.
|
||||
///
|
||||
@@ -66,7 +66,7 @@ impl TestingAttesterSlashingBuilder {
|
||||
data: attestation.data.clone(),
|
||||
custody_bit: false,
|
||||
};
|
||||
let message = attestation_data_and_custody_bit.hash_tree_root();
|
||||
let message = attestation_data_and_custody_bit.tree_hash_root();
|
||||
|
||||
for (i, validator_index) in validator_indices.iter().enumerate() {
|
||||
attestation.custody_bitfield.set(i, false);
|
||||
|
||||
@@ -6,7 +6,7 @@ use crate::{
|
||||
*,
|
||||
};
|
||||
use rayon::prelude::*;
|
||||
use ssz::{SignedRoot, TreeHash};
|
||||
use tree_hash::{SignedRoot, TreeHash};
|
||||
|
||||
/// Builds a beacon block to be used for testing purposes.
|
||||
///
|
||||
@@ -43,7 +43,7 @@ impl TestingBeaconBlockBuilder {
|
||||
/// Modifying the block's slot after signing may invalidate the signature.
|
||||
pub fn set_randao_reveal(&mut self, sk: &SecretKey, fork: &Fork, spec: &ChainSpec) {
|
||||
let epoch = self.block.slot.epoch(spec.slots_per_epoch);
|
||||
let message = epoch.hash_tree_root();
|
||||
let message = epoch.tree_hash_root();
|
||||
let domain = spec.get_domain(epoch, Domain::Randao, fork);
|
||||
self.block.body.randao_reveal = Signature::new(&message, domain, sk);
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ impl TestingDepositBuilder {
|
||||
/// Instantiates a new builder.
|
||||
pub fn new(pubkey: PublicKey, amount: u64) -> Self {
|
||||
let deposit = Deposit {
|
||||
proof: vec![],
|
||||
proof: vec![].into(),
|
||||
index: 0,
|
||||
deposit_data: DepositData {
|
||||
amount,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::*;
|
||||
use ssz::SignedRoot;
|
||||
use tree_hash::SignedRoot;
|
||||
|
||||
/// Builds a `ProposerSlashing`.
|
||||
///
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::*;
|
||||
use ssz::SignedRoot;
|
||||
use tree_hash::SignedRoot;
|
||||
|
||||
/// Builds a transfer to be used for testing purposes.
|
||||
///
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::*;
|
||||
use ssz::SignedRoot;
|
||||
use tree_hash::SignedRoot;
|
||||
|
||||
/// Builds an exit to be used for testing purposes.
|
||||
///
|
||||
|
||||
@@ -4,13 +4,14 @@ use bls::{PublicKey, Signature};
|
||||
use derivative::Derivative;
|
||||
use rand::RngCore;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use ssz::TreeHash;
|
||||
use ssz_derive::{Decode, Encode, SignedRoot, TreeHash};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash::TreeHash;
|
||||
use tree_hash_derive::{CachedTreeHash, SignedRoot, TreeHash};
|
||||
|
||||
/// The data submitted to the deposit contract.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
/// Spec v0.5.1
|
||||
#[derive(
|
||||
Debug,
|
||||
Clone,
|
||||
@@ -19,6 +20,7 @@ use test_random_derive::TestRandom;
|
||||
Encode,
|
||||
Decode,
|
||||
TreeHash,
|
||||
CachedTreeHash,
|
||||
TestRandom,
|
||||
SignedRoot,
|
||||
Derivative,
|
||||
@@ -32,6 +34,7 @@ pub struct Transfer {
|
||||
pub slot: Slot,
|
||||
pub pubkey: PublicKey,
|
||||
#[derivative(Hash = "ignore")]
|
||||
#[signed_root(skip_hashing)]
|
||||
pub signature: Signature,
|
||||
}
|
||||
|
||||
@@ -40,4 +43,5 @@ mod tests {
|
||||
use super::*;
|
||||
|
||||
ssz_tests!(Transfer);
|
||||
cached_tree_hash_tests!(Transfer);
|
||||
}
|
||||
|
||||
142
eth2/types/src/tree_hash_vector.rs
Normal file
142
eth2/types/src/tree_hash_vector.rs
Normal file
@@ -0,0 +1,142 @@
|
||||
use crate::test_utils::{RngCore, TestRandom};
|
||||
use cached_tree_hash::CachedTreeHash;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use ssz::{Decodable, DecodeError, Encodable, SszStream};
|
||||
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> Encodable for TreeHashVector<T>
|
||||
where
|
||||
T: Encodable,
|
||||
{
|
||||
fn ssz_append(&self, s: &mut SszStream) {
|
||||
s.append_vec(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Decodable for TreeHashVector<T>
|
||||
where
|
||||
T: Decodable,
|
||||
{
|
||||
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<T: RngCore, U> TestRandom<T> for TreeHashVector<U>
|
||||
where
|
||||
U: TestRandom<T>,
|
||||
{
|
||||
fn random_for_test(rng: &mut T) -> 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()
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,13 +1,25 @@
|
||||
use crate::{test_utils::TestRandom, Epoch, Hash256, PublicKey};
|
||||
use rand::RngCore;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use ssz_derive::{Decode, Encode, TreeHash};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash_derive::{CachedTreeHash, TreeHash};
|
||||
|
||||
/// Information about a `BeaconChain` validator.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Encode, Decode, TestRandom, TreeHash)]
|
||||
/// Spec v0.5.1
|
||||
#[derive(
|
||||
Debug,
|
||||
Clone,
|
||||
PartialEq,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
Encode,
|
||||
Decode,
|
||||
TestRandom,
|
||||
TreeHash,
|
||||
CachedTreeHash,
|
||||
)]
|
||||
pub struct Validator {
|
||||
pub pubkey: PublicKey,
|
||||
pub withdrawal_credentials: Hash256,
|
||||
@@ -110,4 +122,5 @@ mod tests {
|
||||
}
|
||||
|
||||
ssz_tests!(Validator);
|
||||
cached_tree_hash_tests!(Validator);
|
||||
}
|
||||
|
||||
@@ -2,13 +2,14 @@ use crate::{test_utils::TestRandom, Epoch};
|
||||
use bls::Signature;
|
||||
use rand::RngCore;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use ssz::TreeHash;
|
||||
use ssz_derive::{Decode, Encode, SignedRoot, TreeHash};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash::TreeHash;
|
||||
use tree_hash_derive::{CachedTreeHash, SignedRoot, TreeHash};
|
||||
|
||||
/// An exit voluntarily submitted a validator who wishes to withdraw.
|
||||
///
|
||||
/// Spec v0.5.0
|
||||
/// Spec v0.5.1
|
||||
#[derive(
|
||||
Debug,
|
||||
PartialEq,
|
||||
@@ -18,12 +19,14 @@ use test_random_derive::TestRandom;
|
||||
Encode,
|
||||
Decode,
|
||||
TreeHash,
|
||||
CachedTreeHash,
|
||||
TestRandom,
|
||||
SignedRoot,
|
||||
)]
|
||||
pub struct VoluntaryExit {
|
||||
pub epoch: Epoch,
|
||||
pub validator_index: u64,
|
||||
#[signed_root(skip_hashing)]
|
||||
pub signature: Signature,
|
||||
}
|
||||
|
||||
@@ -32,4 +35,5 @@ mod tests {
|
||||
use super::*;
|
||||
|
||||
ssz_tests!(VoluntaryExit);
|
||||
cached_tree_hash_tests!(VoluntaryExit);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user