commit
						7ffed482b1
					
				
							
								
								
									
										24
									
								
								.travis.yml
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								.travis.yml
									
									
									
									
									
								
							| @ -1,4 +1,9 @@ | ||||
| language: rust | ||||
| cache: | ||||
|   directories: | ||||
|     - /home/travis/.cargo | ||||
| before_cache: | ||||
|   - rm -rf /home/travis/.cargo/registry | ||||
| before_install: | ||||
|   - curl -OL https://github.com/google/protobuf/releases/download/v3.4.0/protoc-3.4.0-linux-x86_64.zip | ||||
|   - unzip protoc-3.4.0-linux-x86_64.zip -d protoc3 | ||||
| @ -6,11 +11,13 @@ before_install: | ||||
|   - sudo mv protoc3/include/* /usr/local/include/ | ||||
|   - sudo chown $USER /usr/local/bin/protoc | ||||
|   - sudo chown -R $USER /usr/local/include/google | ||||
| env: | ||||
|   - BUILD=--all | ||||
|   - BUILD=--release --all | ||||
|   - BUILD= --manifest-path eth2/state_processing/Cargo.toml --release --features fake_crypto | ||||
| script: | ||||
|   - cargo build --verbose --all | ||||
|   - cargo build --verbose --release --all | ||||
|   - cargo test --verbose --all | ||||
|   - cargo test --verbose --release --all | ||||
|   - cargo build --verbose $BUILD | ||||
|   - cargo test --verbose $BUILD | ||||
|   - cargo fmt --all -- --check | ||||
|   # No clippy until later... | ||||
|   #- cargo clippy | ||||
| @ -22,6 +29,15 @@ matrix: | ||||
|   allow_failures: | ||||
|     - rust: nightly | ||||
|   fast_finish: true | ||||
|   exclude: | ||||
|       - rust: beta | ||||
|         env: BUILD=--release --all | ||||
|       - rust: beta | ||||
|         env: BUILD= --manifest-path eth2/state_processing/Cargo.toml --release --features fake_crypto | ||||
|       - rust: nightly | ||||
|         env: BUILD=--release --all | ||||
|       - rust: nightly | ||||
|         env: BUILD= --manifest-path eth2/state_processing/Cargo.toml --release --features fake_crypto | ||||
| install: | ||||
|   - rustup component add rustfmt | ||||
|   - rustup component add clippy | ||||
|  | ||||
| @ -18,6 +18,8 @@ members = [ | ||||
| 	"eth2/utils/ssz", | ||||
| 	"eth2/utils/ssz_derive", | ||||
| 	"eth2/utils/swap_or_not_shuffle", | ||||
| 	"eth2/utils/tree_hash", | ||||
| 	"eth2/utils/tree_hash_derive", | ||||
| 	"eth2/utils/fisher_yates_shuffle", | ||||
|     "eth2/utils/test_random_derive", | ||||
| 	"beacon_node", | ||||
|  | ||||
							
								
								
									
										5
									
								
								Jenkinsfile
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								Jenkinsfile
									
									
									
									
										vendored
									
									
								
							| @ -23,6 +23,11 @@ pipeline { | ||||
| 			steps { | ||||
| 				sh 'cargo test --verbose --all' | ||||
| 				sh 'cargo test --verbose --all --release' | ||||
|                 sh 'cargo test --manifest-path eth2/state_processing/Cargo.toml --verbose \ | ||||
|                                --release --features fake_crypto' | ||||
|                 sh 'cargo test --manifest-path eth2/state_processing/Cargo.toml --verbose \ | ||||
|                                --release --features fake_crypto -- --ignored' | ||||
| 
 | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| @ -23,4 +23,5 @@ serde_json = "1.0" | ||||
| slot_clock = { path = "../../eth2/utils/slot_clock" } | ||||
| ssz = { path = "../../eth2/utils/ssz" } | ||||
| state_processing = { path = "../../eth2/state_processing" } | ||||
| tree_hash = { path = "../../eth2/utils/tree_hash" } | ||||
| types = { path = "../../eth2/types" } | ||||
|  | ||||
| @ -303,8 +303,6 @@ where | ||||
|     /// then having it iteratively updated -- in such a case it's possible for another thread to
 | ||||
|     /// find the state at an old slot.
 | ||||
|     pub fn update_state(&self, mut state: BeaconState) -> Result<(), Error> { | ||||
|         let latest_block_header = self.head().beacon_block.block_header(); | ||||
| 
 | ||||
|         let present_slot = match self.slot_clock.present_slot() { | ||||
|             Ok(Some(slot)) => slot, | ||||
|             _ => return Err(Error::UnableToReadSlot), | ||||
| @ -312,7 +310,7 @@ where | ||||
| 
 | ||||
|         // If required, transition the new state to the present slot.
 | ||||
|         for _ in state.slot.as_u64()..present_slot.as_u64() { | ||||
|             per_slot_processing(&mut state, &latest_block_header, &self.spec)?; | ||||
|             per_slot_processing(&mut state, &self.spec)?; | ||||
|         } | ||||
| 
 | ||||
|         state.build_all_caches(&self.spec)?; | ||||
| @ -324,8 +322,6 @@ where | ||||
| 
 | ||||
|     /// Ensures the current canonical `BeaconState` has been transitioned to match the `slot_clock`.
 | ||||
|     pub fn catchup_state(&self) -> Result<(), Error> { | ||||
|         let latest_block_header = self.head().beacon_block.block_header(); | ||||
| 
 | ||||
|         let present_slot = match self.slot_clock.present_slot() { | ||||
|             Ok(Some(slot)) => slot, | ||||
|             _ => return Err(Error::UnableToReadSlot), | ||||
| @ -339,7 +335,7 @@ where | ||||
|             state.build_epoch_cache(RelativeEpoch::NextWithoutRegistryChange, &self.spec)?; | ||||
|             state.build_epoch_cache(RelativeEpoch::NextWithRegistryChange, &self.spec)?; | ||||
| 
 | ||||
|             per_slot_processing(&mut *state, &latest_block_header, &self.spec)?; | ||||
|             per_slot_processing(&mut *state, &self.spec)?; | ||||
|         } | ||||
| 
 | ||||
|         state.build_all_caches(&self.spec)?; | ||||
| @ -617,9 +613,8 @@ where | ||||
| 
 | ||||
|         // Transition the parent state to the block slot.
 | ||||
|         let mut state = parent_state; | ||||
|         let previous_block_header = parent_block.block_header(); | ||||
|         for _ in state.slot.as_u64()..block.slot.as_u64() { | ||||
|             if let Err(e) = per_slot_processing(&mut state, &previous_block_header, &self.spec) { | ||||
|             if let Err(e) = per_slot_processing(&mut state, &self.spec) { | ||||
|                 return Ok(BlockProcessingOutcome::InvalidBlock( | ||||
|                     InvalidBlock::SlotProcessingError(e), | ||||
|                 )); | ||||
|  | ||||
| @ -7,9 +7,9 @@ use db::stores::{BeaconBlockStore, BeaconStateStore}; | ||||
| use db::{DiskDB, MemoryDB}; | ||||
| use fork_choice::BitwiseLMDGhost; | ||||
| use slot_clock::SystemTimeSlotClock; | ||||
| use ssz::TreeHash; | ||||
| use std::path::PathBuf; | ||||
| use std::sync::Arc; | ||||
| use tree_hash::TreeHash; | ||||
| use types::test_utils::TestingBeaconStateBuilder; | ||||
| use types::{BeaconBlock, ChainSpec, Hash256}; | ||||
| 
 | ||||
| @ -32,7 +32,7 @@ pub fn initialise_beacon_chain( | ||||
|     let (genesis_state, _keypairs) = state_builder.build(); | ||||
| 
 | ||||
|     let mut genesis_block = BeaconBlock::empty(&spec); | ||||
|     genesis_block.state_root = Hash256::from_slice(&genesis_state.hash_tree_root()); | ||||
|     genesis_block.state_root = Hash256::from_slice(&genesis_state.tree_hash_root()); | ||||
| 
 | ||||
|     // Slot clock
 | ||||
|     let slot_clock = SystemTimeSlotClock::new( | ||||
| @ -73,7 +73,7 @@ pub fn initialise_test_beacon_chain( | ||||
|     let (genesis_state, _keypairs) = state_builder.build(); | ||||
| 
 | ||||
|     let mut genesis_block = BeaconBlock::empty(spec); | ||||
|     genesis_block.state_root = Hash256::from_slice(&genesis_state.hash_tree_root()); | ||||
|     genesis_block.state_root = Hash256::from_slice(&genesis_state.tree_hash_root()); | ||||
| 
 | ||||
|     // Slot clock
 | ||||
|     let slot_clock = SystemTimeSlotClock::new( | ||||
|  | ||||
| @ -5,8 +5,8 @@ use db::{ | ||||
| }; | ||||
| use fork_choice::BitwiseLMDGhost; | ||||
| use slot_clock::TestingSlotClock; | ||||
| use ssz::TreeHash; | ||||
| use std::sync::Arc; | ||||
| use tree_hash::TreeHash; | ||||
| use types::test_utils::TestingBeaconStateBuilder; | ||||
| use types::*; | ||||
| 
 | ||||
| @ -27,7 +27,7 @@ impl TestingBeaconChainBuilder { | ||||
|         let (genesis_state, _keypairs) = self.state_builder.build(); | ||||
| 
 | ||||
|         let mut genesis_block = BeaconBlock::empty(&spec); | ||||
|         genesis_block.state_root = Hash256::from_slice(&genesis_state.hash_tree_root()); | ||||
|         genesis_block.state_root = Hash256::from_slice(&genesis_state.tree_hash_root()); | ||||
| 
 | ||||
|         // Create the Beacon Chain
 | ||||
|         BeaconChain::from_genesis( | ||||
|  | ||||
| @ -38,5 +38,6 @@ serde_json = "1.0" | ||||
| serde_yaml = "0.8" | ||||
| slot_clock = { path = "../../../eth2/utils/slot_clock" } | ||||
| ssz = { path = "../../../eth2/utils/ssz" } | ||||
| tree_hash = { path = "../../../eth2/utils/tree_hash" } | ||||
| types = { path = "../../../eth2/types" } | ||||
| yaml-rust = "0.4.2" | ||||
|  | ||||
| @ -9,8 +9,8 @@ use fork_choice::BitwiseLMDGhost; | ||||
| use log::debug; | ||||
| use rayon::prelude::*; | ||||
| use slot_clock::TestingSlotClock; | ||||
| use ssz::TreeHash; | ||||
| use std::sync::Arc; | ||||
| use tree_hash::TreeHash; | ||||
| use types::{test_utils::TestingBeaconStateBuilder, *}; | ||||
| 
 | ||||
| type TestingBeaconChain = BeaconChain<MemoryDB, TestingSlotClock, BitwiseLMDGhost<MemoryDB>>; | ||||
| @ -54,7 +54,7 @@ impl BeaconChainHarness { | ||||
|         let (mut genesis_state, keypairs) = state_builder.build(); | ||||
| 
 | ||||
|         let mut genesis_block = BeaconBlock::empty(&spec); | ||||
|         genesis_block.state_root = Hash256::from_slice(&genesis_state.hash_tree_root()); | ||||
|         genesis_block.state_root = Hash256::from_slice(&genesis_state.tree_hash_root()); | ||||
| 
 | ||||
|         genesis_state | ||||
|             .build_epoch_cache(RelativeEpoch::Previous, &spec) | ||||
| @ -163,7 +163,7 @@ impl BeaconChainHarness { | ||||
|                         data: data.clone(), | ||||
|                         custody_bit: false, | ||||
|                     } | ||||
|                     .hash_tree_root(); | ||||
|                     .tree_hash_root(); | ||||
|                     let domain = self.spec.get_domain( | ||||
|                         state.slot.epoch(self.spec.slots_per_epoch), | ||||
|                         Domain::Attestation, | ||||
|  | ||||
| @ -8,7 +8,7 @@ | ||||
| //! producing blocks and attestations.
 | ||||
| //!
 | ||||
| //! Example:
 | ||||
| //! ```
 | ||||
| //! ```rust,no_run
 | ||||
| //! use test_harness::BeaconChainHarness;
 | ||||
| //! use types::ChainSpec;
 | ||||
| //!
 | ||||
|  | ||||
| @ -4,7 +4,7 @@ | ||||
| use crate::beacon_chain_harness::BeaconChainHarness; | ||||
| use beacon_chain::CheckPoint; | ||||
| use log::{info, warn}; | ||||
| use ssz::SignedRoot; | ||||
| use tree_hash::SignedRoot; | ||||
| use types::*; | ||||
| 
 | ||||
| use types::test_utils::*; | ||||
|  | ||||
| @ -15,6 +15,7 @@ version = { path = "../version" } | ||||
| types = { path = "../../eth2/types" } | ||||
| slog = { version = "^2.2.3" , features = ["max_level_trace", "release_max_level_debug"] } | ||||
| ssz = { path = "../../eth2/utils/ssz" } | ||||
| tree_hash = { path = "../../eth2/utils/tree_hash" } | ||||
| futures = "0.1.25" | ||||
| error-chain = "0.12.0" | ||||
| crossbeam-channel = "0.3.8" | ||||
|  | ||||
| @ -2,9 +2,9 @@ use crate::beacon_chain::BeaconChain; | ||||
| use eth2_libp2p::rpc::methods::*; | ||||
| use eth2_libp2p::PeerId; | ||||
| use slog::{debug, error}; | ||||
| use ssz::TreeHash; | ||||
| use std::sync::Arc; | ||||
| use std::time::{Duration, Instant}; | ||||
| use tree_hash::TreeHash; | ||||
| use types::{BeaconBlock, BeaconBlockBody, BeaconBlockHeader, Hash256, Slot}; | ||||
| 
 | ||||
| /// Provides a queue for fully and partially built `BeaconBlock`s.
 | ||||
| @ -15,7 +15,7 @@ use types::{BeaconBlock, BeaconBlockBody, BeaconBlockHeader, Hash256, Slot}; | ||||
| ///
 | ||||
| /// - When we receive a `BeaconBlockBody`, the only way we can find it's matching
 | ||||
| /// `BeaconBlockHeader` is to find a header such that `header.beacon_block_body ==
 | ||||
| /// hash_tree_root(body)`. Therefore, if we used a `HashMap` we would need to use the root of
 | ||||
| /// tree_hash_root(body)`. Therefore, if we used a `HashMap` we would need to use the root of
 | ||||
| /// `BeaconBlockBody` as the key.
 | ||||
| /// - It is possible for multiple distinct blocks to have identical `BeaconBlockBodies`. Therefore
 | ||||
| /// we cannot use a `HashMap` keyed by the root of `BeaconBlockBody`.
 | ||||
| @ -166,7 +166,7 @@ impl ImportQueue { | ||||
|         let mut required_bodies: Vec<Hash256> = vec![]; | ||||
| 
 | ||||
|         for header in headers { | ||||
|             let block_root = Hash256::from_slice(&header.hash_tree_root()[..]); | ||||
|             let block_root = Hash256::from_slice(&header.tree_hash_root()[..]); | ||||
| 
 | ||||
|             if self.chain_has_not_seen_block(&block_root) { | ||||
|                 self.insert_header(block_root, header, sender.clone()); | ||||
| @ -230,7 +230,7 @@ impl ImportQueue { | ||||
|     ///
 | ||||
|     /// If the body already existed, the `inserted` time is set to `now`.
 | ||||
|     fn insert_body(&mut self, body: BeaconBlockBody, sender: PeerId) { | ||||
|         let body_root = Hash256::from_slice(&body.hash_tree_root()[..]); | ||||
|         let body_root = Hash256::from_slice(&body.tree_hash_root()[..]); | ||||
| 
 | ||||
|         self.partials.iter_mut().for_each(|mut p| { | ||||
|             if let Some(header) = &mut p.header { | ||||
| @ -250,7 +250,7 @@ impl ImportQueue { | ||||
|     ///
 | ||||
|     /// If the partial already existed, the `inserted` time is set to `now`.
 | ||||
|     fn insert_full_block(&mut self, block: BeaconBlock, sender: PeerId) { | ||||
|         let block_root = Hash256::from_slice(&block.hash_tree_root()[..]); | ||||
|         let block_root = Hash256::from_slice(&block.tree_hash_root()[..]); | ||||
| 
 | ||||
|         let partial = PartialBeaconBlock { | ||||
|             slot: block.slot, | ||||
|  | ||||
| @ -5,10 +5,10 @@ use eth2_libp2p::rpc::methods::*; | ||||
| use eth2_libp2p::rpc::{RPCRequest, RPCResponse, RequestId}; | ||||
| use eth2_libp2p::PeerId; | ||||
| use slog::{debug, error, info, o, warn}; | ||||
| use ssz::TreeHash; | ||||
| use std::collections::HashMap; | ||||
| use std::sync::Arc; | ||||
| use std::time::Duration; | ||||
| use tree_hash::TreeHash; | ||||
| use types::{Attestation, BeaconBlock, Epoch, Hash256, Slot}; | ||||
| 
 | ||||
| /// The number of slots that we can import blocks ahead of us, before going into full Sync mode.
 | ||||
| @ -565,7 +565,7 @@ impl SimpleSync { | ||||
|             return false; | ||||
|         } | ||||
| 
 | ||||
|         let block_root = Hash256::from_slice(&block.hash_tree_root()); | ||||
|         let block_root = Hash256::from_slice(&block.tree_hash_root()); | ||||
| 
 | ||||
|         // Ignore any block that the chain already knows about.
 | ||||
|         if self.chain_has_seen_block(&block_root) { | ||||
|  | ||||
| @ -7,4 +7,5 @@ edition = "2018" | ||||
| [dependencies] | ||||
| slot_clock = { path = "../../eth2/utils/slot_clock" } | ||||
| ssz = { path = "../../eth2/utils/ssz" } | ||||
| tree_hash = { path = "../../eth2/utils/tree_hash" } | ||||
| types = { path = "../../eth2/types" } | ||||
|  | ||||
| @ -2,8 +2,8 @@ pub mod test_utils; | ||||
| mod traits; | ||||
| 
 | ||||
| use slot_clock::SlotClock; | ||||
| use ssz::TreeHash; | ||||
| use std::sync::Arc; | ||||
| use tree_hash::TreeHash; | ||||
| use types::{AttestationData, AttestationDataAndCustodyBit, FreeAttestation, Signature, Slot}; | ||||
| 
 | ||||
| pub use self::traits::{ | ||||
| @ -141,7 +141,7 @@ impl<T: SlotClock, U: BeaconNode, V: DutiesReader, W: Signer> Attester<T, U, V, | ||||
|             data: attestation_data.clone(), | ||||
|             custody_bit: PHASE_0_CUSTODY_BIT, | ||||
|         } | ||||
|         .hash_tree_root(); | ||||
|         .tree_hash_root(); | ||||
| 
 | ||||
|         self.signer | ||||
|             .sign_attestation_message(&message[..], DOMAIN_ATTESTATION) | ||||
|  | ||||
| @ -8,4 +8,5 @@ edition = "2018" | ||||
| int_to_bytes = { path = "../utils/int_to_bytes" } | ||||
| slot_clock = { path = "../utils/slot_clock" } | ||||
| ssz = { path = "../utils/ssz" } | ||||
| tree_hash = { path = "../../eth2/utils/tree_hash" } | ||||
| types = { path = "../types" } | ||||
|  | ||||
| @ -2,8 +2,8 @@ pub mod test_utils; | ||||
| mod traits; | ||||
| 
 | ||||
| use slot_clock::SlotClock; | ||||
| use ssz::{SignedRoot, TreeHash}; | ||||
| use std::sync::Arc; | ||||
| use tree_hash::{SignedRoot, TreeHash}; | ||||
| use types::{BeaconBlock, ChainSpec, Domain, Slot}; | ||||
| 
 | ||||
| pub use self::traits::{ | ||||
| @ -139,7 +139,7 @@ impl<T: SlotClock, U: BeaconNode, V: DutiesReader, W: Signer> BlockProducer<T, U | ||||
| 
 | ||||
|         let randao_reveal = { | ||||
|             // TODO: add domain, etc to this message. Also ensure result matches `into_to_bytes32`.
 | ||||
|             let message = slot.epoch(self.spec.slots_per_epoch).hash_tree_root(); | ||||
|             let message = slot.epoch(self.spec.slots_per_epoch).tree_hash_root(); | ||||
| 
 | ||||
|             match self.signer.sign_randao_reveal( | ||||
|                 &message, | ||||
|  | ||||
| @ -26,5 +26,10 @@ log = "0.4" | ||||
| merkle_proof = { path = "../utils/merkle_proof" } | ||||
| ssz = { path = "../utils/ssz" } | ||||
| ssz_derive = { path = "../utils/ssz_derive" } | ||||
| tree_hash = { path = "../utils/tree_hash" } | ||||
| tree_hash_derive = { path = "../utils/tree_hash_derive" } | ||||
| types = { path = "../types" } | ||||
| rayon = "1.0" | ||||
| 
 | ||||
| [features] | ||||
| fake_crypto = ["bls/fake_crypto"] | ||||
|  | ||||
| @ -1,6 +1,5 @@ | ||||
| use criterion::Criterion; | ||||
| use criterion::{black_box, Benchmark}; | ||||
| use ssz::TreeHash; | ||||
| use state_processing::{ | ||||
|     per_block_processing, | ||||
|     per_block_processing::{ | ||||
| @ -9,6 +8,7 @@ use state_processing::{ | ||||
|         verify_block_signature, | ||||
|     }, | ||||
| }; | ||||
| use tree_hash::TreeHash; | ||||
| use types::*; | ||||
| 
 | ||||
| /// Run the detailed benchmarking suite on the given `BeaconState`.
 | ||||
| @ -263,7 +263,7 @@ pub fn bench_block_processing( | ||||
|     c.bench( | ||||
|         &format!("{}/block_processing", desc), | ||||
|         Benchmark::new("tree_hash_block", move |b| { | ||||
|             b.iter(|| black_box(block.hash_tree_root())) | ||||
|             b.iter(|| black_box(block.tree_hash_root())) | ||||
|         }) | ||||
|         .sample_size(10), | ||||
|     ); | ||||
|  | ||||
| @ -1,6 +1,5 @@ | ||||
| use criterion::Criterion; | ||||
| use criterion::{black_box, Benchmark}; | ||||
| use ssz::TreeHash; | ||||
| use state_processing::{ | ||||
|     per_epoch_processing, | ||||
|     per_epoch_processing::{ | ||||
| @ -9,6 +8,7 @@ use state_processing::{ | ||||
|         update_active_tree_index_roots, update_latest_slashed_balances, | ||||
|     }, | ||||
| }; | ||||
| use tree_hash::TreeHash; | ||||
| use types::test_utils::TestingBeaconStateBuilder; | ||||
| use types::*; | ||||
| 
 | ||||
| @ -256,7 +256,7 @@ fn bench_epoch_processing(c: &mut Criterion, state: &BeaconState, spec: &ChainSp | ||||
|     c.bench( | ||||
|         &format!("{}/epoch_processing", desc), | ||||
|         Benchmark::new("tree_hash_state", move |b| { | ||||
|             b.iter(|| black_box(state_clone.hash_tree_root())) | ||||
|             b.iter(|| black_box(state_clone.tree_hash_root())) | ||||
|         }) | ||||
|         .sample_size(SMALL_BENCHING_SAMPLE_SIZE), | ||||
|     ); | ||||
|  | ||||
							
								
								
									
										1
									
								
								eth2/state_processing/build.rs
									
									
									
									
									
										Symbolic link
									
								
							
							
						
						
									
										1
									
								
								eth2/state_processing/build.rs
									
									
									
									
									
										Symbolic link
									
								
							| @ -0,0 +1 @@ | ||||
| ../utils/bls/build.rs | ||||
| @ -2,7 +2,7 @@ use types::{BeaconStateError as Error, *}; | ||||
| 
 | ||||
| /// Exit the validator of the given `index`.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| pub fn exit_validator( | ||||
|     state: &mut BeaconState, | ||||
|     validator_index: usize, | ||||
|  | ||||
| @ -3,7 +3,7 @@ use types::{BeaconStateError as Error, *}; | ||||
| 
 | ||||
| /// Slash the validator with index ``index``.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| pub fn slash_validator( | ||||
|     state: &mut BeaconState, | ||||
|     validator_index: usize, | ||||
|  | ||||
| @ -4,7 +4,7 @@ use types::*; | ||||
| ///
 | ||||
| /// Is title `verify_bitfield` in spec.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| pub fn verify_bitfield_length(bitfield: &Bitfield, committee_size: usize) -> bool { | ||||
|     if bitfield.num_bytes() != ((committee_size + 7) / 8) { | ||||
|         return false; | ||||
| @ -18,3 +18,62 @@ pub fn verify_bitfield_length(bitfield: &Bitfield, committee_size: usize) -> boo | ||||
| 
 | ||||
|     true | ||||
| } | ||||
| 
 | ||||
| #[cfg(test)] | ||||
| mod test { | ||||
|     use super::*; | ||||
| 
 | ||||
|     #[test] | ||||
|     fn bitfield_length() { | ||||
|         assert_eq!( | ||||
|             verify_bitfield_length(&Bitfield::from_bytes(&[0b0000_0001]), 4), | ||||
|             true | ||||
|         ); | ||||
| 
 | ||||
|         assert_eq!( | ||||
|             verify_bitfield_length(&Bitfield::from_bytes(&[0b0001_0001]), 4), | ||||
|             false | ||||
|         ); | ||||
| 
 | ||||
|         assert_eq!( | ||||
|             verify_bitfield_length(&Bitfield::from_bytes(&[0b0000_0000]), 4), | ||||
|             true | ||||
|         ); | ||||
| 
 | ||||
|         assert_eq!( | ||||
|             verify_bitfield_length(&Bitfield::from_bytes(&[0b1000_0000]), 8), | ||||
|             true | ||||
|         ); | ||||
| 
 | ||||
|         assert_eq!( | ||||
|             verify_bitfield_length(&Bitfield::from_bytes(&[0b1000_0000, 0b0000_0000]), 16), | ||||
|             true | ||||
|         ); | ||||
| 
 | ||||
|         assert_eq!( | ||||
|             verify_bitfield_length(&Bitfield::from_bytes(&[0b1000_0000, 0b0000_0000]), 15), | ||||
|             false | ||||
|         ); | ||||
| 
 | ||||
|         assert_eq!( | ||||
|             verify_bitfield_length(&Bitfield::from_bytes(&[0b0000_0000, 0b0000_0000]), 8), | ||||
|             false | ||||
|         ); | ||||
| 
 | ||||
|         assert_eq!( | ||||
|             verify_bitfield_length( | ||||
|                 &Bitfield::from_bytes(&[0b0000_0000, 0b0000_0000, 0b0000_0000]), | ||||
|                 8 | ||||
|             ), | ||||
|             false | ||||
|         ); | ||||
| 
 | ||||
|         assert_eq!( | ||||
|             verify_bitfield_length( | ||||
|                 &Bitfield::from_bytes(&[0b0000_0000, 0b0000_0000, 0b0000_0000]), | ||||
|                 24 | ||||
|             ), | ||||
|             true | ||||
|         ); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| use super::per_block_processing::{errors::BlockProcessingError, process_deposits}; | ||||
| use ssz::TreeHash; | ||||
| use tree_hash::TreeHash; | ||||
| use types::*; | ||||
| 
 | ||||
| pub enum GenesisError { | ||||
| @ -9,13 +9,13 @@ pub enum GenesisError { | ||||
| 
 | ||||
| /// Returns the genesis `BeaconState`
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| pub fn get_genesis_state( | ||||
|     genesis_validator_deposits: &[Deposit], | ||||
|     genesis_time: u64, | ||||
|     genesis_eth1_data: Eth1Data, | ||||
|     spec: &ChainSpec, | ||||
| ) -> Result<(), BlockProcessingError> { | ||||
| ) -> Result<BeaconState, BlockProcessingError> { | ||||
|     // Get the genesis `BeaconState`
 | ||||
|     let mut state = BeaconState::genesis(genesis_time, genesis_eth1_data, spec); | ||||
| 
 | ||||
| @ -36,13 +36,13 @@ pub fn get_genesis_state( | ||||
|     let active_validator_indices = state | ||||
|         .get_cached_active_validator_indices(RelativeEpoch::Current, spec)? | ||||
|         .to_vec(); | ||||
|     let genesis_active_index_root = Hash256::from_slice(&active_validator_indices.hash_tree_root()); | ||||
|     let genesis_active_index_root = Hash256::from_slice(&active_validator_indices.tree_hash_root()); | ||||
|     state.fill_active_index_roots_with(genesis_active_index_root, spec); | ||||
| 
 | ||||
|     // Generate the current shuffling seed.
 | ||||
|     state.current_shuffling_seed = state.generate_seed(spec.genesis_epoch, spec)?; | ||||
| 
 | ||||
|     Ok(()) | ||||
|     Ok(state) | ||||
| } | ||||
| 
 | ||||
| impl From<BlockProcessingError> for GenesisError { | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| use crate::common::slash_validator; | ||||
| use errors::{BlockInvalid as Invalid, BlockProcessingError as Error, IntoWithIndex}; | ||||
| use rayon::prelude::*; | ||||
| use ssz::{SignedRoot, TreeHash}; | ||||
| use tree_hash::{SignedRoot, TreeHash}; | ||||
| use types::*; | ||||
| 
 | ||||
| pub use self::verify_attester_slashing::{ | ||||
| @ -39,7 +39,7 @@ const VERIFY_DEPOSIT_MERKLE_PROOFS: bool = false; | ||||
| /// Returns `Ok(())` if the block is valid and the state was successfully updated. Otherwise
 | ||||
| /// returns an error describing why the block was invalid or how the function failed to execute.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| pub fn per_block_processing( | ||||
|     state: &mut BeaconState, | ||||
|     block: &BeaconBlock, | ||||
| @ -54,7 +54,7 @@ pub fn per_block_processing( | ||||
| /// Returns `Ok(())` if the block is valid and the state was successfully updated. Otherwise
 | ||||
| /// returns an error describing why the block was invalid or how the function failed to execute.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| pub fn per_block_processing_without_verifying_block_signature( | ||||
|     state: &mut BeaconState, | ||||
|     block: &BeaconBlock, | ||||
| @ -69,7 +69,7 @@ pub fn per_block_processing_without_verifying_block_signature( | ||||
| /// Returns `Ok(())` if the block is valid and the state was successfully updated. Otherwise
 | ||||
| /// returns an error describing why the block was invalid or how the function failed to execute.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| fn per_block_processing_signature_optional( | ||||
|     mut state: &mut BeaconState, | ||||
|     block: &BeaconBlock, | ||||
| @ -99,7 +99,7 @@ fn per_block_processing_signature_optional( | ||||
| 
 | ||||
| /// Processes the block header.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| pub fn process_block_header( | ||||
|     state: &mut BeaconState, | ||||
|     block: &BeaconBlock, | ||||
| @ -107,12 +107,14 @@ pub fn process_block_header( | ||||
| ) -> Result<(), Error> { | ||||
|     verify!(block.slot == state.slot, Invalid::StateSlotMismatch); | ||||
| 
 | ||||
|     // NOTE: this is not to spec. I think spec is broken. See:
 | ||||
|     //
 | ||||
|     // https://github.com/ethereum/eth2.0-specs/issues/797
 | ||||
|     let expected_previous_block_root = | ||||
|         Hash256::from_slice(&state.latest_block_header.signed_root()); | ||||
|     verify!( | ||||
|         block.previous_block_root == *state.get_block_root(state.slot - 1, spec)?, | ||||
|         Invalid::ParentBlockRootMismatch | ||||
|         block.previous_block_root == expected_previous_block_root, | ||||
|         Invalid::ParentBlockRootMismatch { | ||||
|             state: expected_previous_block_root, | ||||
|             block: block.previous_block_root, | ||||
|         } | ||||
|     ); | ||||
| 
 | ||||
|     state.latest_block_header = block.temporary_block_header(spec); | ||||
| @ -122,7 +124,7 @@ pub fn process_block_header( | ||||
| 
 | ||||
| /// Verifies the signature of a block.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| pub fn verify_block_signature( | ||||
|     state: &BeaconState, | ||||
|     block: &BeaconBlock, | ||||
| @ -150,7 +152,7 @@ pub fn verify_block_signature( | ||||
| /// Verifies the `randao_reveal` against the block's proposer pubkey and updates
 | ||||
| /// `state.latest_randao_mixes`.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| pub fn process_randao( | ||||
|     state: &mut BeaconState, | ||||
|     block: &BeaconBlock, | ||||
| @ -162,7 +164,7 @@ pub fn process_randao( | ||||
|     // Verify the RANDAO is a valid signature of the proposer.
 | ||||
|     verify!( | ||||
|         block.body.randao_reveal.verify( | ||||
|             &state.current_epoch(spec).hash_tree_root()[..], | ||||
|             &state.current_epoch(spec).tree_hash_root()[..], | ||||
|             spec.get_domain( | ||||
|                 block.slot.epoch(spec.slots_per_epoch), | ||||
|                 Domain::Randao, | ||||
| @ -181,7 +183,7 @@ pub fn process_randao( | ||||
| 
 | ||||
| /// Update the `state.eth1_data_votes` based upon the `eth1_data` provided.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| pub fn process_eth1_data(state: &mut BeaconState, eth1_data: &Eth1Data) -> Result<(), Error> { | ||||
|     // Attempt to find a `Eth1DataVote` with matching `Eth1Data`.
 | ||||
|     let matching_eth1_vote_index = state | ||||
| @ -207,7 +209,7 @@ pub fn process_eth1_data(state: &mut BeaconState, eth1_data: &Eth1Data) -> Resul | ||||
| /// Returns `Ok(())` if the validation and state updates completed successfully, otherwise returns
 | ||||
| /// an `Err` describing the invalid object or cause of failure.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| pub fn process_proposer_slashings( | ||||
|     state: &mut BeaconState, | ||||
|     proposer_slashings: &[ProposerSlashing], | ||||
| @ -240,7 +242,7 @@ pub fn process_proposer_slashings( | ||||
| /// Returns `Ok(())` if the validation and state updates completed successfully, otherwise returns
 | ||||
| /// an `Err` describing the invalid object or cause of failure.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| pub fn process_attester_slashings( | ||||
|     state: &mut BeaconState, | ||||
|     attester_slashings: &[AttesterSlashing], | ||||
| @ -298,7 +300,7 @@ pub fn process_attester_slashings( | ||||
| /// Returns `Ok(())` if the validation and state updates completed successfully, otherwise returns
 | ||||
| /// an `Err` describing the invalid object or cause of failure.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| pub fn process_attestations( | ||||
|     state: &mut BeaconState, | ||||
|     attestations: &[Attestation], | ||||
| @ -340,7 +342,7 @@ pub fn process_attestations( | ||||
| /// Returns `Ok(())` if the validation and state updates completed successfully, otherwise returns
 | ||||
| /// an `Err` describing the invalid object or cause of failure.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| pub fn process_deposits( | ||||
|     state: &mut BeaconState, | ||||
|     deposits: &[Deposit], | ||||
| @ -410,7 +412,7 @@ pub fn process_deposits( | ||||
| /// Returns `Ok(())` if the validation and state updates completed successfully, otherwise returns
 | ||||
| /// an `Err` describing the invalid object or cause of failure.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| pub fn process_exits( | ||||
|     state: &mut BeaconState, | ||||
|     voluntary_exits: &[VoluntaryExit], | ||||
| @ -442,7 +444,7 @@ pub fn process_exits( | ||||
| /// Returns `Ok(())` if the validation and state updates completed successfully, otherwise returns
 | ||||
| /// an `Err` describing the invalid object or cause of failure.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| pub fn process_transfers( | ||||
|     state: &mut BeaconState, | ||||
|     transfers: &[Transfer], | ||||
|  | ||||
| @ -67,7 +67,10 @@ impl_from_beacon_state_error!(BlockProcessingError); | ||||
| #[derive(Debug, PartialEq)] | ||||
| pub enum BlockInvalid { | ||||
|     StateSlotMismatch, | ||||
|     ParentBlockRootMismatch, | ||||
|     ParentBlockRootMismatch { | ||||
|         state: Hash256, | ||||
|         block: Hash256, | ||||
|     }, | ||||
|     BadSignature, | ||||
|     BadRandaoSignature, | ||||
|     MaxAttestationsExceeded, | ||||
| @ -271,10 +274,10 @@ pub enum ProposerSlashingValidationError { | ||||
| pub enum ProposerSlashingInvalid { | ||||
|     /// The proposer index is not a known validator.
 | ||||
|     ProposerUnknown(u64), | ||||
|     /// The two proposal have different slots.
 | ||||
|     /// The two proposal have different epochs.
 | ||||
|     ///
 | ||||
|     /// (proposal_1_slot, proposal_2_slot)
 | ||||
|     ProposalSlotMismatch(Slot, Slot), | ||||
|     ProposalEpochMismatch(Slot, Slot), | ||||
|     /// The proposals are identical and therefore not slashable.
 | ||||
|     ProposalsIdentical, | ||||
|     /// The specified proposer has already been slashed.
 | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| use super::errors::{AttestationInvalid as Invalid, AttestationValidationError as Error}; | ||||
| use crate::common::verify_bitfield_length; | ||||
| use ssz::TreeHash; | ||||
| use tree_hash::TreeHash; | ||||
| use types::*; | ||||
| 
 | ||||
| /// Indicates if an `Attestation` is valid to be included in a block in the current epoch of the
 | ||||
| @ -8,7 +8,7 @@ use types::*; | ||||
| ///
 | ||||
| /// Returns `Ok(())` if the `Attestation` is valid, otherwise indicates the reason for invalidity.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| pub fn validate_attestation( | ||||
|     state: &BeaconState, | ||||
|     attestation: &Attestation, | ||||
| @ -31,7 +31,7 @@ pub fn validate_attestation_time_independent_only( | ||||
| ///
 | ||||
| /// Returns `Ok(())` if the `Attestation` is valid, otherwise indicates the reason for invalidity.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| pub fn validate_attestation_without_signature( | ||||
|     state: &BeaconState, | ||||
|     attestation: &Attestation, | ||||
| @ -44,7 +44,7 @@ pub fn validate_attestation_without_signature( | ||||
| /// given state, optionally validating the aggregate signature.
 | ||||
| ///
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| fn validate_attestation_parametric( | ||||
|     state: &BeaconState, | ||||
|     attestation: &Attestation, | ||||
| @ -167,7 +167,7 @@ fn validate_attestation_parametric( | ||||
| /// Verify that the `source_epoch` and `source_root` of an `Attestation` correctly
 | ||||
| /// match the current (or previous) justified epoch and root from the state.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| fn verify_justified_epoch_and_root( | ||||
|     attestation: &Attestation, | ||||
|     state: &BeaconState, | ||||
| @ -222,7 +222,7 @@ fn verify_justified_epoch_and_root( | ||||
| ///  - `custody_bitfield` does not have a bit for each index of `committee`.
 | ||||
| ///  - A `validator_index` in `committee` is not in `state.validator_registry`.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| fn verify_attestation_signature( | ||||
|     state: &BeaconState, | ||||
|     committee: &[usize], | ||||
| @ -270,14 +270,14 @@ fn verify_attestation_signature( | ||||
|         data: a.data.clone(), | ||||
|         custody_bit: false, | ||||
|     } | ||||
|     .hash_tree_root(); | ||||
|     .tree_hash_root(); | ||||
| 
 | ||||
|     // Message when custody bitfield is `true`
 | ||||
|     let message_1 = AttestationDataAndCustodyBit { | ||||
|         data: a.data.clone(), | ||||
|         custody_bit: true, | ||||
|     } | ||||
|     .hash_tree_root(); | ||||
|     .tree_hash_root(); | ||||
| 
 | ||||
|     let mut messages = vec![]; | ||||
|     let mut keys = vec![]; | ||||
|  | ||||
| @ -7,7 +7,7 @@ use types::*; | ||||
| ///
 | ||||
| /// Returns `Ok(())` if the `AttesterSlashing` is valid, otherwise indicates the reason for invalidity.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| pub fn verify_attester_slashing( | ||||
|     state: &BeaconState, | ||||
|     attester_slashing: &AttesterSlashing, | ||||
| @ -41,7 +41,7 @@ pub fn verify_attester_slashing( | ||||
| ///
 | ||||
| /// Returns Ok(indices) if `indices.len() > 0`.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| pub fn gather_attester_slashing_indices( | ||||
|     state: &BeaconState, | ||||
|     attester_slashing: &AttesterSlashing, | ||||
|  | ||||
| @ -15,7 +15,7 @@ use types::*; | ||||
| ///
 | ||||
| /// Note: this function is incomplete.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| pub fn verify_deposit( | ||||
|     state: &BeaconState, | ||||
|     deposit: &Deposit, | ||||
| @ -46,7 +46,7 @@ pub fn verify_deposit( | ||||
| 
 | ||||
| /// Verify that the `Deposit` index is correct.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| pub fn verify_deposit_index(state: &BeaconState, deposit: &Deposit) -> Result<(), Error> { | ||||
|     verify!( | ||||
|         deposit.index == state.deposit_index, | ||||
| @ -88,7 +88,7 @@ pub fn get_existing_validator_index( | ||||
| 
 | ||||
| /// Verify that a deposit is included in the state's eth1 deposit root.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| fn verify_deposit_merkle_proof(state: &BeaconState, deposit: &Deposit, spec: &ChainSpec) -> bool { | ||||
|     let leaf = hash(&get_serialized_deposit_data(deposit)); | ||||
|     verify_merkle_proof( | ||||
| @ -102,7 +102,7 @@ fn verify_deposit_merkle_proof(state: &BeaconState, deposit: &Deposit, spec: &Ch | ||||
| 
 | ||||
| /// Helper struct for easily getting the serialized data generated by the deposit contract.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| #[derive(Encode)] | ||||
| struct SerializedDepositData { | ||||
|     amount: u64, | ||||
| @ -113,7 +113,7 @@ struct SerializedDepositData { | ||||
| /// Return the serialized data generated by the deposit contract that is used to generate the
 | ||||
| /// merkle proof.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| fn get_serialized_deposit_data(deposit: &Deposit) -> Vec<u8> { | ||||
|     let serialized_deposit_data = SerializedDepositData { | ||||
|         amount: deposit.deposit_data.amount, | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| use super::errors::{ExitInvalid as Invalid, ExitValidationError as Error}; | ||||
| use ssz::SignedRoot; | ||||
| use tree_hash::SignedRoot; | ||||
| use types::*; | ||||
| 
 | ||||
| /// Indicates if an `Exit` is valid to be included in a block in the current epoch of the given
 | ||||
| @ -7,7 +7,7 @@ use types::*; | ||||
| ///
 | ||||
| /// Returns `Ok(())` if the `Exit` is valid, otherwise indicates the reason for invalidity.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| pub fn verify_exit( | ||||
|     state: &BeaconState, | ||||
|     exit: &VoluntaryExit, | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| use super::errors::{ProposerSlashingInvalid as Invalid, ProposerSlashingValidationError as Error}; | ||||
| use ssz::SignedRoot; | ||||
| use tree_hash::SignedRoot; | ||||
| use types::*; | ||||
| 
 | ||||
| /// Indicates if a `ProposerSlashing` is valid to be included in a block in the current epoch of the given
 | ||||
| @ -7,7 +7,7 @@ use types::*; | ||||
| ///
 | ||||
| /// Returns `Ok(())` if the `ProposerSlashing` is valid, otherwise indicates the reason for invalidity.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| pub fn verify_proposer_slashing( | ||||
|     proposer_slashing: &ProposerSlashing, | ||||
|     state: &BeaconState, | ||||
| @ -21,8 +21,9 @@ pub fn verify_proposer_slashing( | ||||
|         })?; | ||||
| 
 | ||||
|     verify!( | ||||
|         proposer_slashing.header_1.slot == proposer_slashing.header_2.slot, | ||||
|         Invalid::ProposalSlotMismatch( | ||||
|         proposer_slashing.header_1.slot.epoch(spec.slots_per_epoch) | ||||
|             == proposer_slashing.header_2.slot.epoch(spec.slots_per_epoch), | ||||
|         Invalid::ProposalEpochMismatch( | ||||
|             proposer_slashing.header_1.slot, | ||||
|             proposer_slashing.header_2.slot | ||||
|         ) | ||||
| @ -66,7 +67,7 @@ pub fn verify_proposer_slashing( | ||||
| ///
 | ||||
| /// Returns `true` if the signature is valid.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| fn verify_header_signature( | ||||
|     header: &BeaconBlockHeader, | ||||
|     pubkey: &PublicKey, | ||||
|  | ||||
| @ -2,7 +2,7 @@ use super::errors::{ | ||||
|     SlashableAttestationInvalid as Invalid, SlashableAttestationValidationError as Error, | ||||
| }; | ||||
| use crate::common::verify_bitfield_length; | ||||
| use ssz::TreeHash; | ||||
| use tree_hash::TreeHash; | ||||
| use types::*; | ||||
| 
 | ||||
| /// Indicates if a `SlashableAttestation` is valid to be included in a block in the current epoch of the given
 | ||||
| @ -10,7 +10,7 @@ use types::*; | ||||
| ///
 | ||||
| /// Returns `Ok(())` if the `SlashableAttestation` is valid, otherwise indicates the reason for invalidity.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| pub fn verify_slashable_attestation( | ||||
|     state: &BeaconState, | ||||
|     slashable_attestation: &SlashableAttestation, | ||||
| @ -77,12 +77,12 @@ pub fn verify_slashable_attestation( | ||||
|         data: slashable_attestation.data.clone(), | ||||
|         custody_bit: false, | ||||
|     } | ||||
|     .hash_tree_root(); | ||||
|     .tree_hash_root(); | ||||
|     let message_1 = AttestationDataAndCustodyBit { | ||||
|         data: slashable_attestation.data.clone(), | ||||
|         custody_bit: true, | ||||
|     } | ||||
|     .hash_tree_root(); | ||||
|     .tree_hash_root(); | ||||
| 
 | ||||
|     let mut messages = vec![]; | ||||
|     let mut keys = vec![]; | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| use super::errors::{TransferInvalid as Invalid, TransferValidationError as Error}; | ||||
| use bls::get_withdrawal_credentials; | ||||
| use ssz::SignedRoot; | ||||
| use tree_hash::SignedRoot; | ||||
| use types::*; | ||||
| 
 | ||||
| /// Indicates if a `Transfer` is valid to be included in a block in the current epoch of the given
 | ||||
| @ -10,7 +10,7 @@ use types::*; | ||||
| ///
 | ||||
| /// Note: this function is incomplete.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| pub fn verify_transfer( | ||||
|     state: &BeaconState, | ||||
|     transfer: &Transfer, | ||||
| @ -122,7 +122,7 @@ fn verify_transfer_parametric( | ||||
| ///
 | ||||
| /// Does not check that the transfer is valid, however checks for overflow in all actions.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| pub fn execute_transfer( | ||||
|     state: &mut BeaconState, | ||||
|     transfer: &Transfer, | ||||
|  | ||||
| @ -3,8 +3,8 @@ use errors::EpochProcessingError as Error; | ||||
| use process_ejections::process_ejections; | ||||
| use process_exit_queue::process_exit_queue; | ||||
| use process_slashings::process_slashings; | ||||
| use ssz::TreeHash; | ||||
| use std::collections::HashMap; | ||||
| use tree_hash::TreeHash; | ||||
| use types::*; | ||||
| use update_registry_and_shuffling_data::update_registry_and_shuffling_data; | ||||
| use validator_statuses::{TotalBalances, ValidatorStatuses}; | ||||
| @ -32,7 +32,7 @@ pub type WinningRootHashSet = HashMap<u64, WinningRoot>; | ||||
| /// Mutates the given `BeaconState`, returning early if an error is encountered. If an error is
 | ||||
| /// returned, a state might be "half-processed" and therefore in an invalid state.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| pub fn per_epoch_processing(state: &mut BeaconState, spec: &ChainSpec) -> Result<(), Error> { | ||||
|     // Ensure the previous and next epoch caches are built.
 | ||||
|     state.build_epoch_cache(RelativeEpoch::Previous, spec)?; | ||||
| @ -86,7 +86,7 @@ pub fn per_epoch_processing(state: &mut BeaconState, spec: &ChainSpec) -> Result | ||||
| 
 | ||||
| /// Maybe resets the eth1 period.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| pub fn maybe_reset_eth1_period(state: &mut BeaconState, spec: &ChainSpec) { | ||||
|     let next_epoch = state.next_epoch(spec); | ||||
|     let voting_period = spec.epochs_per_eth1_voting_period; | ||||
| @ -108,7 +108,7 @@ pub fn maybe_reset_eth1_period(state: &mut BeaconState, spec: &ChainSpec) { | ||||
| /// - `justified_epoch`
 | ||||
| /// - `previous_justified_epoch`
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| pub fn update_justification_and_finalization( | ||||
|     state: &mut BeaconState, | ||||
|     total_balances: &TotalBalances, | ||||
| @ -178,7 +178,7 @@ pub fn update_justification_and_finalization( | ||||
| ///
 | ||||
| /// Also returns a `WinningRootHashSet` for later use during epoch processing.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| pub fn process_crosslinks( | ||||
|     state: &mut BeaconState, | ||||
|     spec: &ChainSpec, | ||||
| @ -221,7 +221,7 @@ pub fn process_crosslinks( | ||||
| 
 | ||||
| /// Finish up an epoch update.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| pub fn finish_epoch_update(state: &mut BeaconState, spec: &ChainSpec) -> Result<(), Error> { | ||||
|     let current_epoch = state.current_epoch(spec); | ||||
|     let next_epoch = state.next_epoch(spec); | ||||
| @ -236,7 +236,7 @@ pub fn finish_epoch_update(state: &mut BeaconState, spec: &ChainSpec) -> Result< | ||||
|         let active_index_root = Hash256::from_slice( | ||||
|             &state | ||||
|                 .get_active_validator_indices(next_epoch + spec.activation_exit_delay) | ||||
|                 .hash_tree_root()[..], | ||||
|                 .tree_hash_root()[..], | ||||
|         ); | ||||
|         state.set_active_index_root(next_epoch, active_index_root, spec)?; | ||||
| 
 | ||||
| @ -261,7 +261,7 @@ pub fn finish_epoch_update(state: &mut BeaconState, spec: &ChainSpec) -> Result< | ||||
|         let historical_batch: HistoricalBatch = state.historical_batch(); | ||||
|         state | ||||
|             .historical_roots | ||||
|             .push(Hash256::from_slice(&historical_batch.hash_tree_root()[..])); | ||||
|             .push(Hash256::from_slice(&historical_batch.tree_hash_root()[..])); | ||||
|     } | ||||
| 
 | ||||
|     state.previous_epoch_attestations = state.current_epoch_attestations.clone(); | ||||
|  | ||||
| @ -32,7 +32,7 @@ impl std::ops::AddAssign for Delta { | ||||
| 
 | ||||
| /// Apply attester and proposer rewards.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| pub fn apply_rewards( | ||||
|     state: &mut BeaconState, | ||||
|     validator_statuses: &mut ValidatorStatuses, | ||||
| @ -79,7 +79,7 @@ pub fn apply_rewards( | ||||
| /// Applies the attestation inclusion reward to each proposer for every validator who included an
 | ||||
| /// attestation in the previous epoch.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| fn get_proposer_deltas( | ||||
|     deltas: &mut Vec<Delta>, | ||||
|     state: &mut BeaconState, | ||||
| @ -120,7 +120,7 @@ fn get_proposer_deltas( | ||||
| 
 | ||||
| /// Apply rewards for participation in attestations during the previous epoch.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| fn get_justification_and_finalization_deltas( | ||||
|     deltas: &mut Vec<Delta>, | ||||
|     state: &BeaconState, | ||||
| @ -163,7 +163,7 @@ fn get_justification_and_finalization_deltas( | ||||
| 
 | ||||
| /// Determine the delta for a single validator, if the chain is finalizing normally.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| fn compute_normal_justification_and_finalization_delta( | ||||
|     validator: &ValidatorStatus, | ||||
|     total_balances: &TotalBalances, | ||||
| @ -215,7 +215,7 @@ fn compute_normal_justification_and_finalization_delta( | ||||
| 
 | ||||
| /// Determine the delta for a single delta, assuming the chain is _not_ finalizing normally.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| fn compute_inactivity_leak_delta( | ||||
|     validator: &ValidatorStatus, | ||||
|     base_reward: u64, | ||||
| @ -261,7 +261,7 @@ fn compute_inactivity_leak_delta( | ||||
| 
 | ||||
| /// Calculate the deltas based upon the winning roots for attestations during the previous epoch.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| fn get_crosslink_deltas( | ||||
|     deltas: &mut Vec<Delta>, | ||||
|     state: &BeaconState, | ||||
| @ -295,7 +295,7 @@ fn get_crosslink_deltas( | ||||
| 
 | ||||
| /// Returns the base reward for some validator.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| fn get_base_reward( | ||||
|     state: &BeaconState, | ||||
|     index: usize, | ||||
| @ -312,7 +312,7 @@ fn get_base_reward( | ||||
| 
 | ||||
| /// Returns the inactivity penalty for some validator.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| fn get_inactivity_penalty( | ||||
|     state: &BeaconState, | ||||
|     index: usize, | ||||
| @ -328,7 +328,7 @@ fn get_inactivity_penalty( | ||||
| 
 | ||||
| /// Returns the epochs since the last finalized epoch.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| fn epochs_since_finality(state: &BeaconState, spec: &ChainSpec) -> Epoch { | ||||
|     state.current_epoch(spec) + 1 - state.finalized_epoch | ||||
| } | ||||
|  | ||||
| @ -3,7 +3,7 @@ use types::*; | ||||
| 
 | ||||
| /// Returns validator indices which participated in the attestation.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| pub fn get_attestation_participants( | ||||
|     state: &BeaconState, | ||||
|     attestation_data: &AttestationData, | ||||
|  | ||||
| @ -5,7 +5,7 @@ use types::*; | ||||
| /// Returns the distance between the first included attestation for some validator and this
 | ||||
| /// slot.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| pub fn inclusion_distance( | ||||
|     state: &BeaconState, | ||||
|     attestations: &[&PendingAttestation], | ||||
| @ -18,7 +18,7 @@ pub fn inclusion_distance( | ||||
| 
 | ||||
| /// Returns the slot of the earliest included attestation for some validator.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| pub fn inclusion_slot( | ||||
|     state: &BeaconState, | ||||
|     attestations: &[&PendingAttestation], | ||||
| @ -31,7 +31,7 @@ pub fn inclusion_slot( | ||||
| 
 | ||||
| /// Finds the earliest included attestation for some validator.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| fn earliest_included_attestation( | ||||
|     state: &BeaconState, | ||||
|     attestations: &[&PendingAttestation], | ||||
|  | ||||
| @ -4,7 +4,7 @@ use types::{BeaconStateError as Error, *}; | ||||
| /// Iterate through the validator registry and eject active validators with balance below
 | ||||
| /// ``EJECTION_BALANCE``.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| pub fn process_ejections(state: &mut BeaconState, spec: &ChainSpec) -> Result<(), Error> { | ||||
|     // There is an awkward double (triple?) loop here because we can't loop across the borrowed
 | ||||
|     // active validator indices and mutate state in the one loop.
 | ||||
|  | ||||
| @ -2,7 +2,7 @@ use types::*; | ||||
| 
 | ||||
| /// Process the exit queue.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| pub fn process_exit_queue(state: &mut BeaconState, spec: &ChainSpec) { | ||||
|     let current_epoch = state.current_epoch(spec); | ||||
| 
 | ||||
| @ -31,7 +31,7 @@ pub fn process_exit_queue(state: &mut BeaconState, spec: &ChainSpec) { | ||||
| 
 | ||||
| /// Initiate an exit for the validator of the given `index`.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| fn prepare_validator_for_withdrawal( | ||||
|     state: &mut BeaconState, | ||||
|     validator_index: usize, | ||||
|  | ||||
| @ -2,7 +2,7 @@ use types::{BeaconStateError as Error, *}; | ||||
| 
 | ||||
| /// Process slashings.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| pub fn process_slashings( | ||||
|     state: &mut BeaconState, | ||||
|     current_total_balance: u64, | ||||
|  | ||||
| @ -4,7 +4,7 @@ use types::*; | ||||
| 
 | ||||
| /// Peforms a validator registry update, if required.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| pub fn update_registry_and_shuffling_data( | ||||
|     state: &mut BeaconState, | ||||
|     current_total_balance: u64, | ||||
| @ -49,7 +49,7 @@ pub fn update_registry_and_shuffling_data( | ||||
| 
 | ||||
| /// Returns `true` if the validator registry should be updated during an epoch processing.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| pub fn should_update_validator_registry( | ||||
|     state: &BeaconState, | ||||
|     spec: &ChainSpec, | ||||
| @ -78,7 +78,7 @@ pub fn should_update_validator_registry( | ||||
| ///
 | ||||
| /// Note: Utilizes the cache and will fail if the appropriate cache is not initialized.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| pub fn update_validator_registry( | ||||
|     state: &mut BeaconState, | ||||
|     current_total_balance: u64, | ||||
| @ -133,7 +133,7 @@ pub fn update_validator_registry( | ||||
| 
 | ||||
| /// Activate the validator of the given ``index``.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| pub fn activate_validator( | ||||
|     state: &mut BeaconState, | ||||
|     validator_index: usize, | ||||
|  | ||||
| @ -160,7 +160,7 @@ impl ValidatorStatuses { | ||||
|     /// - Active validators
 | ||||
|     /// - Total balances for the current and previous epochs.
 | ||||
|     ///
 | ||||
|     /// Spec v0.5.0
 | ||||
|     /// Spec v0.5.1
 | ||||
|     pub fn new(state: &BeaconState, spec: &ChainSpec) -> Result<Self, BeaconStateError> { | ||||
|         let mut statuses = Vec::with_capacity(state.validator_registry.len()); | ||||
|         let mut total_balances = TotalBalances::default(); | ||||
| @ -195,7 +195,7 @@ impl ValidatorStatuses { | ||||
|     /// Process some attestations from the given `state` updating the `statuses` and
 | ||||
|     /// `total_balances` fields.
 | ||||
|     ///
 | ||||
|     /// Spec v0.5.0
 | ||||
|     /// Spec v0.5.1
 | ||||
|     pub fn process_attestations( | ||||
|         &mut self, | ||||
|         state: &BeaconState, | ||||
| @ -261,7 +261,7 @@ impl ValidatorStatuses { | ||||
|     /// Update the `statuses` for each validator based upon whether or not they attested to the
 | ||||
|     /// "winning" shard block root for the previous epoch.
 | ||||
|     ///
 | ||||
|     /// Spec v0.5.0
 | ||||
|     /// Spec v0.5.1
 | ||||
|     pub fn process_winning_roots( | ||||
|         &mut self, | ||||
|         state: &BeaconState, | ||||
| @ -297,14 +297,14 @@ impl ValidatorStatuses { | ||||
| /// Returns the distance between when the attestation was created and when it was included in a
 | ||||
| /// block.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| fn inclusion_distance(a: &PendingAttestation) -> Slot { | ||||
|     a.inclusion_slot - a.data.slot | ||||
| } | ||||
| 
 | ||||
| /// Returns `true` if some `PendingAttestation` is from the supplied `epoch`.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| fn is_from_epoch(a: &PendingAttestation, epoch: Epoch, spec: &ChainSpec) -> bool { | ||||
|     a.data.slot.epoch(spec.slots_per_epoch) == epoch | ||||
| } | ||||
| @ -312,7 +312,7 @@ fn is_from_epoch(a: &PendingAttestation, epoch: Epoch, spec: &ChainSpec) -> bool | ||||
| /// Returns `true` if a `PendingAttestation` and `BeaconState` share the same beacon block hash for
 | ||||
| /// the first slot of the given epoch.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| fn has_common_epoch_boundary_root( | ||||
|     a: &PendingAttestation, | ||||
|     state: &BeaconState, | ||||
| @ -328,7 +328,7 @@ fn has_common_epoch_boundary_root( | ||||
| /// Returns `true` if a `PendingAttestation` and `BeaconState` share the same beacon block hash for
 | ||||
| /// the current slot of the `PendingAttestation`.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| fn has_common_beacon_block_root( | ||||
|     a: &PendingAttestation, | ||||
|     state: &BeaconState, | ||||
|  | ||||
| @ -16,7 +16,7 @@ impl WinningRoot { | ||||
|     /// A winning root is "better" than another if it has a higher `total_attesting_balance`. Ties
 | ||||
|     /// are broken by favouring the higher `crosslink_data_root` value.
 | ||||
|     ///
 | ||||
|     /// Spec v0.5.0
 | ||||
|     /// Spec v0.5.1
 | ||||
|     pub fn is_better_than(&self, other: &Self) -> bool { | ||||
|         if self.total_attesting_balance > other.total_attesting_balance { | ||||
|             true | ||||
| @ -34,7 +34,7 @@ impl WinningRoot { | ||||
| /// The `WinningRoot` object also contains additional fields that are useful in later stages of
 | ||||
| /// per-epoch processing.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| pub fn winning_root( | ||||
|     state: &BeaconState, | ||||
|     shard: u64, | ||||
| @ -89,7 +89,7 @@ pub fn winning_root( | ||||
| 
 | ||||
| /// Returns `true` if pending attestation `a` is eligible to become a winning root.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| fn is_eligible_for_winning_root(state: &BeaconState, a: &PendingAttestation, shard: Shard) -> bool { | ||||
|     if shard >= state.latest_crosslinks.len() as u64 { | ||||
|         return false; | ||||
| @ -100,7 +100,7 @@ fn is_eligible_for_winning_root(state: &BeaconState, a: &PendingAttestation, sha | ||||
| 
 | ||||
| /// Returns all indices which voted for a given crosslink. Does not contain duplicates.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| fn get_attesting_validator_indices( | ||||
|     state: &BeaconState, | ||||
|     shard: u64, | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| use crate::*; | ||||
| use ssz::TreeHash; | ||||
| use tree_hash::{SignedRoot, TreeHash}; | ||||
| use types::*; | ||||
| 
 | ||||
| #[derive(Debug, PartialEq)] | ||||
| @ -10,13 +10,9 @@ pub enum Error { | ||||
| 
 | ||||
| /// Advances a state forward by one slot, performing per-epoch processing if required.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| pub fn per_slot_processing( | ||||
|     state: &mut BeaconState, | ||||
|     latest_block_header: &BeaconBlockHeader, | ||||
|     spec: &ChainSpec, | ||||
| ) -> Result<(), Error> { | ||||
|     cache_state(state, latest_block_header, spec)?; | ||||
| /// Spec v0.5.1
 | ||||
| pub fn per_slot_processing(state: &mut BeaconState, spec: &ChainSpec) -> Result<(), Error> { | ||||
|     cache_state(state, spec)?; | ||||
| 
 | ||||
|     if (state.slot + 1) % spec.slots_per_epoch == 0 { | ||||
|         per_epoch_processing(state, spec)?; | ||||
| @ -27,12 +23,8 @@ pub fn per_slot_processing( | ||||
|     Ok(()) | ||||
| } | ||||
| 
 | ||||
| fn cache_state( | ||||
|     state: &mut BeaconState, | ||||
|     latest_block_header: &BeaconBlockHeader, | ||||
|     spec: &ChainSpec, | ||||
| ) -> Result<(), Error> { | ||||
|     let previous_slot_state_root = Hash256::from_slice(&state.hash_tree_root()[..]); | ||||
| fn cache_state(state: &mut BeaconState, spec: &ChainSpec) -> Result<(), Error> { | ||||
|     let previous_slot_state_root = Hash256::from_slice(&state.tree_hash_root()[..]); | ||||
| 
 | ||||
|     // Note: increment the state slot here to allow use of our `state_root` and `block_root`
 | ||||
|     // getter/setter functions.
 | ||||
| @ -46,7 +38,10 @@ fn cache_state( | ||||
|         state.latest_block_header.state_root = previous_slot_state_root | ||||
|     } | ||||
| 
 | ||||
|     let latest_block_root = Hash256::from_slice(&latest_block_header.hash_tree_root()[..]); | ||||
|     // Store the previous slot's post state transition root.
 | ||||
|     state.set_state_root(previous_slot, previous_slot_state_root, spec)?; | ||||
| 
 | ||||
|     let latest_block_root = Hash256::from_slice(&state.latest_block_header.signed_root()[..]); | ||||
|     state.set_block_root(previous_slot, latest_block_root, spec)?; | ||||
| 
 | ||||
|     // Set the state slot back to what it should be.
 | ||||
|  | ||||
| @ -2,14 +2,58 @@ | ||||
| 
 | ||||
| use serde_derive::Deserialize; | ||||
| use serde_yaml; | ||||
| use state_processing::{ | ||||
|     per_block_processing, per_block_processing_without_verifying_block_signature, | ||||
|     per_slot_processing, | ||||
| }; | ||||
| use state_processing::{per_block_processing, per_slot_processing}; | ||||
| use std::{fs::File, io::prelude::*, path::PathBuf}; | ||||
| use types::*; | ||||
| #[allow(unused_imports)] | ||||
| use yaml_utils; | ||||
| 
 | ||||
| #[derive(Debug, Deserialize)] | ||||
| pub struct ExpectedState { | ||||
|     pub slot: Option<Slot>, | ||||
|     pub genesis_time: Option<u64>, | ||||
|     pub fork: Option<Fork>, | ||||
|     pub validator_registry: Option<Vec<Validator>>, | ||||
|     pub validator_balances: Option<Vec<u64>>, | ||||
|     pub previous_epoch_attestations: Option<Vec<PendingAttestation>>, | ||||
|     pub current_epoch_attestations: Option<Vec<PendingAttestation>>, | ||||
|     pub historical_roots: Option<Vec<Hash256>>, | ||||
|     pub finalized_epoch: Option<Epoch>, | ||||
|     pub latest_block_roots: Option<TreeHashVector<Hash256>>, | ||||
| } | ||||
| 
 | ||||
| impl ExpectedState { | ||||
|     // Return a list of fields that differ, and a string representation of the beacon state's field.
 | ||||
|     fn check(&self, state: &BeaconState) -> Vec<(&str, String)> { | ||||
|         // Check field equality
 | ||||
|         macro_rules! cfe { | ||||
|             ($field_name:ident) => { | ||||
|                 if self.$field_name.as_ref().map_or(true, |$field_name| { | ||||
|                     println!("  > Checking {}", stringify!($field_name)); | ||||
|                     $field_name == &state.$field_name | ||||
|                 }) { | ||||
|                     vec![] | ||||
|                 } else { | ||||
|                     vec![(stringify!($field_name), format!("{:#?}", state.$field_name))] | ||||
|                 } | ||||
|             }; | ||||
|         } | ||||
| 
 | ||||
|         vec![ | ||||
|             cfe!(slot), | ||||
|             cfe!(genesis_time), | ||||
|             cfe!(fork), | ||||
|             cfe!(validator_registry), | ||||
|             cfe!(validator_balances), | ||||
|             cfe!(previous_epoch_attestations), | ||||
|             cfe!(current_epoch_attestations), | ||||
|             cfe!(historical_roots), | ||||
|             cfe!(finalized_epoch), | ||||
|             cfe!(latest_block_roots), | ||||
|         ] | ||||
|         .into_iter() | ||||
|         .flat_map(|x| x) | ||||
|         .collect() | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug, Deserialize)] | ||||
| pub struct TestCase { | ||||
| @ -18,6 +62,7 @@ pub struct TestCase { | ||||
|     pub verify_signatures: bool, | ||||
|     pub initial_state: BeaconState, | ||||
|     pub blocks: Vec<BeaconBlock>, | ||||
|     pub expected_state: ExpectedState, | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug, Deserialize)] | ||||
| @ -28,81 +73,81 @@ pub struct TestDoc { | ||||
|     pub test_cases: Vec<TestCase>, | ||||
| } | ||||
| 
 | ||||
| #[test] | ||||
| fn test_read_yaml() { | ||||
|     // Test sanity-check_small-config_32-vals.yaml
 | ||||
| fn load_test_case(test_name: &str) -> TestDoc { | ||||
|     let mut file = { | ||||
|         let mut file_path_buf = PathBuf::from(env!("CARGO_MANIFEST_DIR")); | ||||
|         file_path_buf.push("yaml_utils/specs/sanity-check_small-config_32-vals.yaml"); | ||||
|         file_path_buf.push(format!("yaml_utils/specs/{}", test_name)); | ||||
| 
 | ||||
|         File::open(file_path_buf).unwrap() | ||||
|     }; | ||||
| 
 | ||||
|     let mut yaml_str = String::new(); | ||||
| 
 | ||||
|     file.read_to_string(&mut yaml_str).unwrap(); | ||||
| 
 | ||||
|     yaml_str = yaml_str.to_lowercase(); | ||||
| 
 | ||||
|     let _doc: TestDoc = serde_yaml::from_str(&yaml_str.as_str()).unwrap(); | ||||
| 
 | ||||
|     // Test sanity-check_default-config_100-vals.yaml
 | ||||
|     file = { | ||||
|         let mut file_path_buf = PathBuf::from(env!("CARGO_MANIFEST_DIR")); | ||||
|         file_path_buf.push("yaml_utils/specs/sanity-check_default-config_100-vals.yaml"); | ||||
| 
 | ||||
|         File::open(file_path_buf).unwrap() | ||||
|     }; | ||||
| 
 | ||||
|     yaml_str = String::new(); | ||||
| 
 | ||||
|     file.read_to_string(&mut yaml_str).unwrap(); | ||||
| 
 | ||||
|     yaml_str = yaml_str.to_lowercase(); | ||||
| 
 | ||||
|     let _doc: TestDoc = serde_yaml::from_str(&yaml_str.as_str()).unwrap(); | ||||
|     serde_yaml::from_str(&yaml_str.as_str()).unwrap() | ||||
| } | ||||
| 
 | ||||
| #[test] | ||||
| fn run_state_transition_tests_small() { | ||||
|     // Test sanity-check_small-config_32-vals.yaml
 | ||||
|     let mut file = { | ||||
|         let mut file_path_buf = PathBuf::from(env!("CARGO_MANIFEST_DIR")); | ||||
|         file_path_buf.push("yaml_utils/specs/sanity-check_small-config_32-vals.yaml"); | ||||
| 
 | ||||
|         File::open(file_path_buf).unwrap() | ||||
|     }; | ||||
|     let mut yaml_str = String::new(); | ||||
|     file.read_to_string(&mut yaml_str).unwrap(); | ||||
|     yaml_str = yaml_str.to_lowercase(); | ||||
| 
 | ||||
|     let doc: TestDoc = serde_yaml::from_str(&yaml_str.as_str()).unwrap(); | ||||
| fn run_state_transition_test(test_name: &str) { | ||||
|     let doc = load_test_case(test_name); | ||||
| 
 | ||||
|     // Run Tests
 | ||||
|     let mut ok = true; | ||||
|     for (i, test_case) in doc.test_cases.iter().enumerate() { | ||||
|         let mut state = test_case.initial_state.clone(); | ||||
|         for block in test_case.blocks.iter() { | ||||
|             while block.slot > state.slot { | ||||
|                 let latest_block_header = state.latest_block_header.clone(); | ||||
|                 per_slot_processing(&mut state, &latest_block_header, &test_case.config).unwrap(); | ||||
|         let fake_crypto = cfg!(feature = "fake_crypto"); | ||||
|         if !test_case.verify_signatures == fake_crypto { | ||||
|             println!("Running {}", test_case.name); | ||||
|         } else { | ||||
|             println!( | ||||
|                 "Skipping {} (fake_crypto: {}, need fake: {})", | ||||
|                 test_case.name, fake_crypto, !test_case.verify_signatures | ||||
|             ); | ||||
|             continue; | ||||
|         } | ||||
|         let mut state = test_case.initial_state.clone(); | ||||
|         for (j, block) in test_case.blocks.iter().enumerate() { | ||||
|             while block.slot > state.slot { | ||||
|                 per_slot_processing(&mut state, &test_case.config).unwrap(); | ||||
|             } | ||||
|             if test_case.verify_signatures { | ||||
|             let res = per_block_processing(&mut state, &block, &test_case.config); | ||||
|             if res.is_err() { | ||||
|                     println!("{:?}", i); | ||||
|                 println!("Error in {} (#{}), on block {}", test_case.name, i, j); | ||||
|                 println!("{:?}", res); | ||||
|                 }; | ||||
|             } else { | ||||
|                 let res = per_block_processing_without_verifying_block_signature( | ||||
|                     &mut state, | ||||
|                     &block, | ||||
|                     &test_case.config, | ||||
|                 ok = false; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         let mismatched_fields = test_case.expected_state.check(&state); | ||||
|         if !mismatched_fields.is_empty() { | ||||
|             println!( | ||||
|                 "Error in expected state, these fields didn't match: {:?}", | ||||
|                 mismatched_fields.iter().map(|(f, _)| f).collect::<Vec<_>>() | ||||
|             ); | ||||
|                 if res.is_err() { | ||||
|                     println!("{:?}", i); | ||||
|                     println!("{:?}", res); | ||||
|             for (field_name, state_val) in mismatched_fields { | ||||
|                 println!("state.{} was: {}", field_name, state_val); | ||||
|             } | ||||
|             ok = false; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     assert!(ok, "one or more tests failed, see above"); | ||||
| } | ||||
| 
 | ||||
| #[test] | ||||
| #[cfg(not(debug_assertions))] | ||||
| fn test_read_yaml() { | ||||
|     load_test_case("sanity-check_small-config_32-vals.yaml"); | ||||
|     load_test_case("sanity-check_default-config_100-vals.yaml"); | ||||
| } | ||||
| 
 | ||||
| #[test] | ||||
| #[cfg(not(debug_assertions))] | ||||
| fn run_state_transition_tests_small() { | ||||
|     run_state_transition_test("sanity-check_small-config_32-vals.yaml"); | ||||
| } | ||||
| 
 | ||||
| // Run with --ignored to run this test
 | ||||
| #[test] | ||||
| #[ignore] | ||||
| fn run_state_transition_tests_large() { | ||||
|     run_state_transition_test("sanity-check_default-config_100-vals.yaml"); | ||||
| } | ||||
|  | ||||
| @ -6,7 +6,6 @@ edition = "2018" | ||||
| 
 | ||||
| [build-dependencies] | ||||
| reqwest = "0.9" | ||||
| tempdir = "0.3" | ||||
| 
 | ||||
| [dependencies] | ||||
| 
 | ||||
|  | ||||
| @ -1,5 +1,4 @@ | ||||
| extern crate reqwest; | ||||
| extern crate tempdir; | ||||
| 
 | ||||
| use std::fs::File; | ||||
| use std::io::copy; | ||||
|  | ||||
							
								
								
									
										15
									
								
								eth2/state_processing/yaml_utils/expected_state_fields.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										15
									
								
								eth2/state_processing/yaml_utils/expected_state_fields.py
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,15 @@ | ||||
| #!/usr/bin/env python3 | ||||
| 
 | ||||
| # Script to extract all the fields of the state mentioned in `expected_state` fields of tests | ||||
| # in the `spec` directory. These fields can then be added to the `ExpectedState` struct. | ||||
| # Might take a while to run. | ||||
| 
 | ||||
| import os, yaml | ||||
| 
 | ||||
| if __name__ == "__main__": | ||||
|     yaml_files = (filename for filename in os.listdir("specs") if filename.endswith(".yaml")) | ||||
|     parsed_yaml = (yaml.load(open("specs/" + filename, "r")) for filename in yaml_files) | ||||
|     all_fields = set() | ||||
|     for y in parsed_yaml: | ||||
|         all_fields.update(*({key for key in case["expected_state"]} for case in y["test_cases"])) | ||||
|     print(all_fields) | ||||
| @ -26,6 +26,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::{SignedRoot, TreeHash}; | ||||
| 
 | ||||
| /// Details an attestation that can be slashable.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| #[derive(
 | ||||
|     Debug, | ||||
|     Clone, | ||||
|  | ||||
| @ -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::{SignedRoot, TreeHash}; | ||||
| 
 | ||||
| /// The data upon which an attestation is based.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| #[derive(
 | ||||
|     Debug, | ||||
|     Clone, | ||||
|  | ||||
| @ -2,11 +2,12 @@ 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::TreeHash; | ||||
| 
 | ||||
| /// Used for pairing an attestation with a proof-of-custody.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| #[derive(Debug, Clone, PartialEq, Default, Serialize, Encode, Decode, TreeHash)] | ||||
| pub struct AttestationDataAndCustodyBit { | ||||
|     pub data: AttestationData, | ||||
|  | ||||
| @ -1,12 +1,13 @@ | ||||
| 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::TreeHash; | ||||
| 
 | ||||
| /// Two conflicting attestations.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| #[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Encode, Decode, TreeHash, TestRandom)] | ||||
| pub struct AttesterSlashing { | ||||
|     pub slashable_attestation_1: SlashableAttestation, | ||||
|  | ||||
| @ -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::{SignedRoot, TreeHash}; | ||||
| 
 | ||||
| /// A block of the `BeaconChain`.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| #[derive(
 | ||||
|     Debug, | ||||
|     PartialEq, | ||||
| @ -34,7 +35,7 @@ pub struct BeaconBlock { | ||||
| 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, | ||||
| @ -57,11 +58,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.
 | ||||
| @ -71,20 +72,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, | ||||
|  | ||||
| @ -2,12 +2,13 @@ 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::TreeHash; | ||||
| 
 | ||||
| /// The body of a `BeaconChain` block, containing operations.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| #[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Encode, Decode, TreeHash, TestRandom)] | ||||
| pub struct BeaconBlockBody { | ||||
|     pub randao_reveal: Signature, | ||||
|  | ||||
| @ -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::{SignedRoot, TreeHash}; | ||||
| 
 | ||||
| /// A header of a `BeaconBlock`.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| #[derive(
 | ||||
|     Debug, | ||||
|     PartialEq, | ||||
| @ -32,16 +33,16 @@ pub struct BeaconBlockHeader { | ||||
| } | ||||
| 
 | ||||
| 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, | ||||
|  | ||||
| @ -5,9 +5,11 @@ 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::TreeHash; | ||||
| 
 | ||||
| mod epoch_cache; | ||||
| mod pubkey_cache; | ||||
| @ -44,7 +46,7 @@ pub enum Error { | ||||
| 
 | ||||
| /// The state of the `BeaconChain` at some slot.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| #[derive(Debug, PartialEq, Clone, Serialize, Deserialize, TestRandom, Encode, Decode, TreeHash)] | ||||
| pub struct BeaconState { | ||||
|     // Misc
 | ||||
| @ -58,7 +60,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 +80,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>, | ||||
| 
 | ||||
| @ -118,7 +120,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 +139,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 +160,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![], | ||||
| 
 | ||||
| @ -186,11 +190,11 @@ impl BeaconState { | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /// 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 +221,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 +230,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 +250,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 +265,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 +274,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 +299,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 +325,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 +354,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 +370,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 +382,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 +396,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 +420,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 +438,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 +446,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 +460,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 +482,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 +490,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 +504,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 +528,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 +536,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 +550,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 +565,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 +573,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 +587,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 +603,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 +618,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 +637,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 +653,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], | ||||
|  | ||||
| @ -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(); | ||||
| 
 | ||||
|  | ||||
| @ -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::TreeHash; | ||||
| 
 | ||||
| /// Specifies the block hash for a shard at an epoch.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| #[derive(
 | ||||
|     Debug, | ||||
|     Clone, | ||||
|  | ||||
| @ -1,6 +1,7 @@ | ||||
| use crate::*; | ||||
| use serde_derive::{Deserialize, Serialize}; | ||||
| use ssz_derive::{Decode, Encode, TreeHash}; | ||||
| use ssz_derive::{Decode, Encode}; | ||||
| use tree_hash_derive::TreeHash; | ||||
| 
 | ||||
| #[derive(Default, Clone, Debug, PartialEq, Serialize, Deserialize, Decode, Encode, TreeHash)] | ||||
| pub struct CrosslinkCommittee { | ||||
|  | ||||
| @ -1,16 +1,17 @@ | ||||
| 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::TreeHash; | ||||
| 
 | ||||
| /// A deposit to potentially become a beacon chain validator.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| #[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Encode, Decode, TreeHash, TestRandom)] | ||||
| pub struct Deposit { | ||||
|     pub proof: Vec<Hash256>, | ||||
|     pub proof: TreeHashVector<Hash256>, | ||||
|     pub index: u64, | ||||
|     pub deposit_data: DepositData, | ||||
| } | ||||
|  | ||||
| @ -2,12 +2,13 @@ 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::TreeHash; | ||||
| 
 | ||||
| /// Data generated by the deposit contract.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| #[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Encode, Decode, TreeHash, TestRandom)] | ||||
| pub struct DepositData { | ||||
|     pub amount: u64, | ||||
|  | ||||
| @ -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::{SignedRoot, TreeHash}; | ||||
| 
 | ||||
| /// The data supplied by the user to the deposit contract.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| #[derive(
 | ||||
|     Debug, | ||||
|     PartialEq, | ||||
| @ -32,7 +33,7 @@ pub struct DepositInput { | ||||
| 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, | ||||
| @ -48,7 +49,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, | ||||
|  | ||||
| @ -2,12 +2,13 @@ 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::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, | ||||
| )] | ||||
|  | ||||
| @ -2,12 +2,13 @@ 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::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, | ||||
| )] | ||||
|  | ||||
| @ -5,12 +5,13 @@ 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::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, | ||||
| )] | ||||
| @ -25,7 +26,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 +40,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; | ||||
|  | ||||
| @ -1,17 +1,18 @@ | ||||
| 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::TreeHash; | ||||
| 
 | ||||
| /// Historical block and state roots.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Encode, Decode, TreeHash, 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)] | ||||
|  | ||||
| @ -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,12 +2,13 @@ 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::TreeHash; | ||||
| 
 | ||||
| /// An attestation that has been included in the state but not yet fully processed.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Encode, Decode, TreeHash, TestRandom)] | ||||
| pub struct PendingAttestation { | ||||
|     pub aggregation_bitfield: Bitfield, | ||||
|  | ||||
| @ -2,12 +2,13 @@ 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::TreeHash; | ||||
| 
 | ||||
| /// Two conflicting proposals from the same proposer (validator).
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| #[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Encode, Decode, TreeHash, TestRandom)] | ||||
| pub struct ProposerSlashing { | ||||
|     pub proposer_index: u64, | ||||
|  | ||||
| @ -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::{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, | ||||
| @ -34,14 +35,14 @@ pub struct SlashableAttestation { | ||||
| 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; | ||||
|  | ||||
| @ -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,21 @@ 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) | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|  | ||||
| @ -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
 | ||||
|  | ||||
| @ -17,7 +17,10 @@ mod testing_voluntary_exit_builder; | ||||
| 
 | ||||
| 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; | ||||
|  | ||||
| @ -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::{SignedRoot, TreeHash}; | ||||
| 
 | ||||
| /// The data submitted to the deposit contract.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| #[derive(
 | ||||
|     Debug, | ||||
|     Clone, | ||||
|  | ||||
							
								
								
									
										82
									
								
								eth2/types/src/tree_hash_vector.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								eth2/types/src/tree_hash_vector.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,82 @@ | ||||
| use crate::test_utils::{RngCore, TestRandom}; | ||||
| 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::standard_tree_hash::vec_tree_hash_root(self) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 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 { | ||||
|         Vec::random_for_test(rng).into() | ||||
|     } | ||||
| } | ||||
| @ -1,12 +1,13 @@ | ||||
| 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::TreeHash; | ||||
| 
 | ||||
| /// Information about a `BeaconChain` validator.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Encode, Decode, TestRandom, TreeHash)] | ||||
| pub struct Validator { | ||||
|     pub pubkey: PublicKey, | ||||
|  | ||||
| @ -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::{SignedRoot, TreeHash}; | ||||
| 
 | ||||
| /// An exit voluntarily submitted a validator who wishes to withdraw.
 | ||||
| ///
 | ||||
| /// Spec v0.5.0
 | ||||
| /// Spec v0.5.1
 | ||||
| #[derive(
 | ||||
|     Debug, | ||||
|     PartialEq, | ||||
|  | ||||
| @ -12,3 +12,7 @@ serde = "1.0" | ||||
| serde_derive = "1.0" | ||||
| serde_hex = { path = "../serde_hex" } | ||||
| ssz = { path = "../ssz" } | ||||
| tree_hash = { path = "../tree_hash" } | ||||
| 
 | ||||
| [features] | ||||
| fake_crypto = [] | ||||
|  | ||||
							
								
								
									
										19
									
								
								eth2/utils/bls/build.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								eth2/utils/bls/build.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,19 @@ | ||||
| // This build script is symlinked from each project that requires BLS's "fake crypto",
 | ||||
| // so that the `fake_crypto` feature of every sub-crate can be turned on by running
 | ||||
| // with FAKE_CRYPTO=1 from the top-level workspace.
 | ||||
| // At some point in the future it might be possible to do:
 | ||||
| // $ cargo test --all --release --features fake_crypto
 | ||||
| // but at the present time this doesn't work.
 | ||||
| // Related: https://github.com/rust-lang/cargo/issues/5364
 | ||||
| fn main() { | ||||
|     if let Ok(fake_crypto) = std::env::var("FAKE_CRYPTO") { | ||||
|         if fake_crypto == "1" { | ||||
|             println!("cargo:rustc-cfg=feature=\"fake_crypto\""); | ||||
|             println!("cargo:rerun-if-env-changed=FAKE_CRYPTO"); | ||||
|             println!( | ||||
|                 "cargo:warning=[{}]: Compiled with fake BLS cryptography. DO NOT USE, TESTING ONLY", | ||||
|                 std::env::var("CARGO_PKG_NAME").unwrap() | ||||
|             ); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -5,7 +5,8 @@ use bls_aggregates::{ | ||||
| use serde::de::{Deserialize, Deserializer}; | ||||
| use serde::ser::{Serialize, Serializer}; | ||||
| use serde_hex::{encode as hex_encode, HexVisitor}; | ||||
| use ssz::{decode, hash, Decodable, DecodeError, Encodable, SszStream, TreeHash}; | ||||
| use ssz::{decode, Decodable, DecodeError, Encodable, SszStream}; | ||||
| use tree_hash::tree_hash_ssz_encoding_as_vector; | ||||
| 
 | ||||
| /// A BLS aggregate signature.
 | ||||
| ///
 | ||||
| @ -165,11 +166,7 @@ impl<'de> Deserialize<'de> for AggregateSignature { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl TreeHash for AggregateSignature { | ||||
|     fn hash_tree_root(&self) -> Vec<u8> { | ||||
|         hash(&self.as_bytes()) | ||||
|     } | ||||
| } | ||||
| tree_hash_ssz_encoding_as_vector!(AggregateSignature); | ||||
| 
 | ||||
| #[cfg(test)] | ||||
| mod tests { | ||||
|  | ||||
| @ -2,7 +2,8 @@ use super::{fake_signature::FakeSignature, AggregatePublicKey, BLS_AGG_SIG_BYTE_ | ||||
| use serde::de::{Deserialize, Deserializer}; | ||||
| use serde::ser::{Serialize, Serializer}; | ||||
| use serde_hex::{encode as hex_encode, PrefixedHexVisitor}; | ||||
| use ssz::{hash, ssz_encode, Decodable, DecodeError, Encodable, SszStream, TreeHash}; | ||||
| use ssz::{ssz_encode, Decodable, DecodeError, Encodable, SszStream}; | ||||
| use tree_hash::tree_hash_ssz_encoding_as_vector; | ||||
| 
 | ||||
| /// A BLS aggregate signature.
 | ||||
| ///
 | ||||
| @ -98,11 +99,7 @@ impl<'de> Deserialize<'de> for FakeAggregateSignature { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl TreeHash for FakeAggregateSignature { | ||||
|     fn hash_tree_root(&self) -> Vec<u8> { | ||||
|         hash(&self.bytes) | ||||
|     } | ||||
| } | ||||
| tree_hash_ssz_encoding_as_vector!(FakeAggregateSignature); | ||||
| 
 | ||||
| #[cfg(test)] | ||||
| mod tests { | ||||
|  | ||||
| @ -3,7 +3,8 @@ use hex::encode as hex_encode; | ||||
| use serde::de::{Deserialize, Deserializer}; | ||||
| use serde::ser::{Serialize, Serializer}; | ||||
| use serde_hex::HexVisitor; | ||||
| use ssz::{hash, ssz_encode, Decodable, DecodeError, Encodable, SszStream, TreeHash}; | ||||
| use ssz::{ssz_encode, Decodable, DecodeError, Encodable, SszStream}; | ||||
| use tree_hash::tree_hash_ssz_encoding_as_vector; | ||||
| 
 | ||||
| /// A single BLS signature.
 | ||||
| ///
 | ||||
| @ -73,11 +74,7 @@ impl Decodable for FakeSignature { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl TreeHash for FakeSignature { | ||||
|     fn hash_tree_root(&self) -> Vec<u8> { | ||||
|         hash(&self.bytes) | ||||
|     } | ||||
| } | ||||
| tree_hash_ssz_encoding_as_vector!(FakeSignature); | ||||
| 
 | ||||
| impl Serialize for FakeSignature { | ||||
|     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> | ||||
|  | ||||
| @ -6,22 +6,22 @@ mod keypair; | ||||
| mod public_key; | ||||
| mod secret_key; | ||||
| 
 | ||||
| #[cfg(not(debug_assertions))] | ||||
| #[cfg(not(feature = "fake_crypto"))] | ||||
| mod aggregate_signature; | ||||
| #[cfg(not(debug_assertions))] | ||||
| #[cfg(not(feature = "fake_crypto"))] | ||||
| mod signature; | ||||
| #[cfg(not(debug_assertions))] | ||||
| #[cfg(not(feature = "fake_crypto"))] | ||||
| pub use crate::aggregate_signature::AggregateSignature; | ||||
| #[cfg(not(debug_assertions))] | ||||
| #[cfg(not(feature = "fake_crypto"))] | ||||
| pub use crate::signature::Signature; | ||||
| 
 | ||||
| #[cfg(debug_assertions)] | ||||
| #[cfg(feature = "fake_crypto")] | ||||
| mod fake_aggregate_signature; | ||||
| #[cfg(debug_assertions)] | ||||
| #[cfg(feature = "fake_crypto")] | ||||
| mod fake_signature; | ||||
| #[cfg(debug_assertions)] | ||||
| #[cfg(feature = "fake_crypto")] | ||||
| pub use crate::fake_aggregate_signature::FakeAggregateSignature as AggregateSignature; | ||||
| #[cfg(debug_assertions)] | ||||
| #[cfg(feature = "fake_crypto")] | ||||
| pub use crate::fake_signature::FakeSignature as Signature; | ||||
| 
 | ||||
| pub use crate::aggregate_public_key::AggregatePublicKey; | ||||
|  | ||||
| @ -3,10 +3,11 @@ use bls_aggregates::PublicKey as RawPublicKey; | ||||
| use serde::de::{Deserialize, Deserializer}; | ||||
| use serde::ser::{Serialize, Serializer}; | ||||
| use serde_hex::{encode as hex_encode, HexVisitor}; | ||||
| use ssz::{decode, hash, ssz_encode, Decodable, DecodeError, Encodable, SszStream, TreeHash}; | ||||
| use ssz::{decode, ssz_encode, Decodable, DecodeError, Encodable, SszStream}; | ||||
| use std::default; | ||||
| use std::fmt; | ||||
| use std::hash::{Hash, Hasher}; | ||||
| use tree_hash::tree_hash_ssz_encoding_as_vector; | ||||
| 
 | ||||
| /// A single BLS signature.
 | ||||
| ///
 | ||||
| @ -104,11 +105,7 @@ impl<'de> Deserialize<'de> for PublicKey { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl TreeHash for PublicKey { | ||||
|     fn hash_tree_root(&self) -> Vec<u8> { | ||||
|         hash(&self.0.as_bytes()) | ||||
|     } | ||||
| } | ||||
| tree_hash_ssz_encoding_as_vector!(PublicKey); | ||||
| 
 | ||||
| impl PartialEq for PublicKey { | ||||
|     fn eq(&self, other: &PublicKey) -> bool { | ||||
|  | ||||
Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
		Reference in New Issue
	
	Block a user