mirror of
https://github.com/sigp/lighthouse.git
synced 2026-05-08 17:26:04 +00:00
Merge branch 'master' into ssz-derive
This commit is contained in:
@@ -35,12 +35,12 @@ impl Attestation {
|
||||
}
|
||||
|
||||
impl TreeHash for Attestation {
|
||||
fn hash_tree_root(&self) -> Vec<u8> {
|
||||
fn hash_tree_root_internal(&self) -> Vec<u8> {
|
||||
let mut result: Vec<u8> = vec![];
|
||||
result.append(&mut self.aggregation_bitfield.hash_tree_root());
|
||||
result.append(&mut self.data.hash_tree_root());
|
||||
result.append(&mut self.custody_bitfield.hash_tree_root());
|
||||
result.append(&mut self.aggregate_signature.hash_tree_root());
|
||||
result.append(&mut self.aggregation_bitfield.hash_tree_root_internal());
|
||||
result.append(&mut self.data.hash_tree_root_internal());
|
||||
result.append(&mut self.custody_bitfield.hash_tree_root_internal());
|
||||
result.append(&mut self.aggregate_signature.hash_tree_root_internal());
|
||||
hash(&result)
|
||||
}
|
||||
}
|
||||
@@ -74,11 +74,11 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_hash_tree_root() {
|
||||
pub fn test_hash_tree_root_internal() {
|
||||
let mut rng = XorShiftRng::from_seed([42; 16]);
|
||||
let original = Attestation::random_for_test(&mut rng);
|
||||
|
||||
let result = original.hash_tree_root();
|
||||
let result = original.hash_tree_root_internal();
|
||||
|
||||
assert_eq!(result.len(), 32);
|
||||
// TODO: Add further tests
|
||||
|
||||
@@ -45,16 +45,16 @@ impl AttestationData {
|
||||
}
|
||||
|
||||
impl TreeHash for AttestationData {
|
||||
fn hash_tree_root(&self) -> Vec<u8> {
|
||||
fn hash_tree_root_internal(&self) -> Vec<u8> {
|
||||
let mut result: Vec<u8> = vec![];
|
||||
result.append(&mut self.slot.hash_tree_root());
|
||||
result.append(&mut self.shard.hash_tree_root());
|
||||
result.append(&mut self.beacon_block_root.hash_tree_root());
|
||||
result.append(&mut self.epoch_boundary_root.hash_tree_root());
|
||||
result.append(&mut self.shard_block_root.hash_tree_root());
|
||||
result.append(&mut self.latest_crosslink.hash_tree_root());
|
||||
result.append(&mut self.justified_epoch.hash_tree_root());
|
||||
result.append(&mut self.justified_block_root.hash_tree_root());
|
||||
result.append(&mut self.slot.hash_tree_root_internal());
|
||||
result.append(&mut self.shard.hash_tree_root_internal());
|
||||
result.append(&mut self.beacon_block_root.hash_tree_root_internal());
|
||||
result.append(&mut self.epoch_boundary_root.hash_tree_root_internal());
|
||||
result.append(&mut self.shard_block_root.hash_tree_root_internal());
|
||||
result.append(&mut self.latest_crosslink.hash_tree_root_internal());
|
||||
result.append(&mut self.justified_epoch.hash_tree_root_internal());
|
||||
result.append(&mut self.justified_block_root.hash_tree_root_internal());
|
||||
hash(&result)
|
||||
}
|
||||
}
|
||||
@@ -92,11 +92,11 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_hash_tree_root() {
|
||||
pub fn test_hash_tree_root_internal() {
|
||||
let mut rng = XorShiftRng::from_seed([42; 16]);
|
||||
let original = AttestationData::random_for_test(&mut rng);
|
||||
|
||||
let result = original.hash_tree_root();
|
||||
let result = original.hash_tree_root_internal();
|
||||
|
||||
assert_eq!(result.len(), 32);
|
||||
// TODO: Add further tests
|
||||
|
||||
@@ -12,11 +12,11 @@ pub struct AttestationDataAndCustodyBit {
|
||||
}
|
||||
|
||||
impl TreeHash for AttestationDataAndCustodyBit {
|
||||
fn hash_tree_root(&self) -> Vec<u8> {
|
||||
fn hash_tree_root_internal(&self) -> Vec<u8> {
|
||||
let mut result: Vec<u8> = vec![];
|
||||
result.append(&mut self.data.hash_tree_root());
|
||||
result.append(&mut self.data.hash_tree_root_internal());
|
||||
// TODO: add bool ssz
|
||||
// result.append(custody_bit.hash_tree_root());
|
||||
// result.append(custody_bit.hash_tree_root_internal());
|
||||
ssz::hash(&result)
|
||||
}
|
||||
}
|
||||
@@ -51,11 +51,11 @@ mod test {
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_hash_tree_root() {
|
||||
pub fn test_hash_tree_root_internal() {
|
||||
let mut rng = XorShiftRng::from_seed([42; 16]);
|
||||
let original = AttestationDataAndCustodyBit::random_for_test(&mut rng);
|
||||
|
||||
let result = original.hash_tree_root();
|
||||
let result = original.hash_tree_root_internal();
|
||||
|
||||
assert_eq!(result.len(), 32);
|
||||
// TODO: Add further tests
|
||||
|
||||
@@ -11,10 +11,10 @@ pub struct AttesterSlashing {
|
||||
}
|
||||
|
||||
impl TreeHash for AttesterSlashing {
|
||||
fn hash_tree_root(&self) -> Vec<u8> {
|
||||
fn hash_tree_root_internal(&self) -> Vec<u8> {
|
||||
let mut result: Vec<u8> = vec![];
|
||||
result.append(&mut self.slashable_attestation_1.hash_tree_root());
|
||||
result.append(&mut self.slashable_attestation_2.hash_tree_root());
|
||||
result.append(&mut self.slashable_attestation_1.hash_tree_root_internal());
|
||||
result.append(&mut self.slashable_attestation_2.hash_tree_root_internal());
|
||||
hash(&result)
|
||||
}
|
||||
}
|
||||
@@ -46,11 +46,11 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_hash_tree_root() {
|
||||
pub fn test_hash_tree_root_internal() {
|
||||
let mut rng = XorShiftRng::from_seed([42; 16]);
|
||||
let original = AttesterSlashing::random_for_test(&mut rng);
|
||||
|
||||
let result = original.hash_tree_root();
|
||||
let result = original.hash_tree_root_internal();
|
||||
|
||||
assert_eq!(result.len(), 32);
|
||||
// TODO: Add further tests
|
||||
|
||||
@@ -61,15 +61,15 @@ impl BeaconBlock {
|
||||
}
|
||||
|
||||
impl TreeHash for BeaconBlock {
|
||||
fn hash_tree_root(&self) -> Vec<u8> {
|
||||
fn hash_tree_root_internal(&self) -> Vec<u8> {
|
||||
let mut result: Vec<u8> = vec![];
|
||||
result.append(&mut self.slot.hash_tree_root());
|
||||
result.append(&mut self.parent_root.hash_tree_root());
|
||||
result.append(&mut self.state_root.hash_tree_root());
|
||||
result.append(&mut self.randao_reveal.hash_tree_root());
|
||||
result.append(&mut self.eth1_data.hash_tree_root());
|
||||
result.append(&mut self.signature.hash_tree_root());
|
||||
result.append(&mut self.body.hash_tree_root());
|
||||
result.append(&mut self.slot.hash_tree_root_internal());
|
||||
result.append(&mut self.parent_root.hash_tree_root_internal());
|
||||
result.append(&mut self.state_root.hash_tree_root_internal());
|
||||
result.append(&mut self.randao_reveal.hash_tree_root_internal());
|
||||
result.append(&mut self.eth1_data.hash_tree_root_internal());
|
||||
result.append(&mut self.signature.hash_tree_root_internal());
|
||||
result.append(&mut self.body.hash_tree_root_internal());
|
||||
hash(&result)
|
||||
}
|
||||
}
|
||||
@@ -106,11 +106,11 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_hash_tree_root() {
|
||||
pub fn test_hash_tree_root_internal() {
|
||||
let mut rng = XorShiftRng::from_seed([42; 16]);
|
||||
let original = BeaconBlock::random_for_test(&mut rng);
|
||||
|
||||
let result = original.hash_tree_root();
|
||||
let result = original.hash_tree_root_internal();
|
||||
|
||||
assert_eq!(result.len(), 32);
|
||||
// TODO: Add further tests
|
||||
|
||||
@@ -15,13 +15,13 @@ pub struct BeaconBlockBody {
|
||||
}
|
||||
|
||||
impl TreeHash for BeaconBlockBody {
|
||||
fn hash_tree_root(&self) -> Vec<u8> {
|
||||
fn hash_tree_root_internal(&self) -> Vec<u8> {
|
||||
let mut result: Vec<u8> = vec![];
|
||||
result.append(&mut self.proposer_slashings.hash_tree_root());
|
||||
result.append(&mut self.attester_slashings.hash_tree_root());
|
||||
result.append(&mut self.attestations.hash_tree_root());
|
||||
result.append(&mut self.deposits.hash_tree_root());
|
||||
result.append(&mut self.exits.hash_tree_root());
|
||||
result.append(&mut self.proposer_slashings.hash_tree_root_internal());
|
||||
result.append(&mut self.attester_slashings.hash_tree_root_internal());
|
||||
result.append(&mut self.attestations.hash_tree_root_internal());
|
||||
result.append(&mut self.deposits.hash_tree_root_internal());
|
||||
result.append(&mut self.exits.hash_tree_root_internal());
|
||||
hash(&result)
|
||||
}
|
||||
}
|
||||
@@ -56,11 +56,11 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_hash_tree_root() {
|
||||
pub fn test_hash_tree_root_internal() {
|
||||
let mut rng = XorShiftRng::from_seed([42; 16]);
|
||||
let original = BeaconBlockBody::random_for_test(&mut rng);
|
||||
|
||||
let result = original.hash_tree_root();
|
||||
let result = original.hash_tree_root_internal();
|
||||
|
||||
assert_eq!(result.len(), 32);
|
||||
// TODO: Add further tests
|
||||
|
||||
@@ -6,6 +6,7 @@ use crate::{
|
||||
};
|
||||
use bls::verify_proof_of_possession;
|
||||
use honey_badger_split::SplitExt;
|
||||
use log::trace;
|
||||
use rand::RngCore;
|
||||
use serde_derive::Serialize;
|
||||
use ssz::{hash, Decodable, DecodeError, Encodable, SszStream, TreeHash};
|
||||
@@ -205,7 +206,12 @@ impl BeaconState {
|
||||
///
|
||||
/// Spec v0.2.0
|
||||
pub fn previous_epoch(&self, spec: &ChainSpec) -> Epoch {
|
||||
self.current_epoch(spec).saturating_sub(1_u64)
|
||||
let current_epoch = self.current_epoch(&spec);
|
||||
if current_epoch == spec.genesis_epoch {
|
||||
current_epoch
|
||||
} else {
|
||||
current_epoch - 1
|
||||
}
|
||||
}
|
||||
|
||||
/// The epoch following `self.current_epoch()`.
|
||||
@@ -262,11 +268,25 @@ impl BeaconState {
|
||||
let active_validator_indices =
|
||||
get_active_validator_indices(&self.validator_registry, epoch);
|
||||
|
||||
if active_validator_indices.is_empty() {
|
||||
return None;
|
||||
}
|
||||
|
||||
trace!(
|
||||
"get_shuffling: active_validator_indices.len() == {}",
|
||||
active_validator_indices.len()
|
||||
);
|
||||
|
||||
let committees_per_epoch =
|
||||
self.get_epoch_committee_count(active_validator_indices.len(), spec);
|
||||
|
||||
let mut shuffled_active_validator_indices =
|
||||
Vec::with_capacity(active_validator_indices.len());
|
||||
trace!(
|
||||
"get_shuffling: active_validator_indices.len() == {}, committees_per_epoch: {}",
|
||||
active_validator_indices.len(),
|
||||
committees_per_epoch
|
||||
);
|
||||
|
||||
let mut shuffled_active_validator_indices = vec![0; active_validator_indices.len()];
|
||||
for &i in &active_validator_indices {
|
||||
let shuffled_i = get_permutated_index(
|
||||
i,
|
||||
@@ -320,9 +340,17 @@ impl BeaconState {
|
||||
+ 1;
|
||||
let latest_index_root = current_epoch + spec.entry_exit_delay;
|
||||
|
||||
trace!(
|
||||
"get_active_index_root: epoch: {}, earliest: {}, latest: {}",
|
||||
epoch,
|
||||
earliest_index_root,
|
||||
latest_index_root
|
||||
);
|
||||
|
||||
if (epoch >= earliest_index_root) & (epoch <= latest_index_root) {
|
||||
Some(self.latest_index_roots[epoch.as_usize() % spec.latest_index_roots_length])
|
||||
} else {
|
||||
trace!("get_active_index_root: epoch out of range.");
|
||||
None
|
||||
}
|
||||
}
|
||||
@@ -367,29 +395,28 @@ impl BeaconState {
|
||||
) -> Result<Vec<(Vec<usize>, u64)>, BeaconStateError> {
|
||||
let epoch = slot.epoch(spec.epoch_length);
|
||||
let current_epoch = self.current_epoch(spec);
|
||||
let previous_epoch = if current_epoch == spec.genesis_epoch {
|
||||
current_epoch
|
||||
} else {
|
||||
current_epoch.saturating_sub(1_u64)
|
||||
};
|
||||
let previous_epoch = self.previous_epoch(spec);
|
||||
let next_epoch = self.next_epoch(spec);
|
||||
|
||||
let (committees_per_epoch, seed, shuffling_epoch, shuffling_start_shard) =
|
||||
if epoch == previous_epoch {
|
||||
(
|
||||
self.get_previous_epoch_committee_count(spec),
|
||||
self.previous_epoch_seed,
|
||||
self.previous_calculation_epoch,
|
||||
self.previous_epoch_start_shard,
|
||||
)
|
||||
} else if epoch == current_epoch {
|
||||
if epoch == current_epoch {
|
||||
trace!("get_crosslink_committees_at_slot: current_epoch");
|
||||
(
|
||||
self.get_current_epoch_committee_count(spec),
|
||||
self.current_epoch_seed,
|
||||
self.current_calculation_epoch,
|
||||
self.current_epoch_start_shard,
|
||||
)
|
||||
} else if epoch == previous_epoch {
|
||||
trace!("get_crosslink_committees_at_slot: previous_epoch");
|
||||
(
|
||||
self.get_previous_epoch_committee_count(spec),
|
||||
self.previous_epoch_seed,
|
||||
self.previous_calculation_epoch,
|
||||
self.previous_epoch_start_shard,
|
||||
)
|
||||
} else if epoch == next_epoch {
|
||||
trace!("get_crosslink_committees_at_slot: next_epoch");
|
||||
let current_committees_per_epoch = self.get_current_epoch_committee_count(spec);
|
||||
let epochs_since_last_registry_update =
|
||||
current_epoch - self.validator_registry_update_epoch;
|
||||
@@ -426,6 +453,13 @@ impl BeaconState {
|
||||
let slot_start_shard =
|
||||
(shuffling_start_shard + committees_per_slot * offset) % spec.shard_count;
|
||||
|
||||
trace!(
|
||||
"get_crosslink_committees_at_slot: committees_per_slot: {}, slot_start_shard: {}, seed: {}",
|
||||
committees_per_slot,
|
||||
slot_start_shard,
|
||||
seed
|
||||
);
|
||||
|
||||
let mut crosslinks_at_slot = vec![];
|
||||
for i in 0..committees_per_slot {
|
||||
let tuple = (
|
||||
@@ -477,6 +511,11 @@ impl BeaconState {
|
||||
spec: &ChainSpec,
|
||||
) -> Result<usize, BeaconStateError> {
|
||||
let committees = self.get_crosslink_committees_at_slot(slot, false, spec)?;
|
||||
trace!(
|
||||
"get_beacon_proposer_index: slot: {}, committees_count: {}",
|
||||
slot,
|
||||
committees.len()
|
||||
);
|
||||
committees
|
||||
.first()
|
||||
.ok_or(BeaconStateError::InsufficientValidators)
|
||||
@@ -930,33 +969,37 @@ impl From<AttestationParticipantsError> for InclusionError {
|
||||
}
|
||||
|
||||
impl TreeHash for BeaconState {
|
||||
fn hash_tree_root(&self) -> Vec<u8> {
|
||||
fn hash_tree_root_internal(&self) -> Vec<u8> {
|
||||
let mut result: Vec<u8> = vec![];
|
||||
result.append(&mut self.slot.hash_tree_root());
|
||||
result.append(&mut self.genesis_time.hash_tree_root());
|
||||
result.append(&mut self.fork.hash_tree_root());
|
||||
result.append(&mut self.validator_registry.hash_tree_root());
|
||||
result.append(&mut self.validator_balances.hash_tree_root());
|
||||
result.append(&mut self.validator_registry_update_epoch.hash_tree_root());
|
||||
result.append(&mut self.latest_randao_mixes.hash_tree_root());
|
||||
result.append(&mut self.previous_epoch_start_shard.hash_tree_root());
|
||||
result.append(&mut self.current_epoch_start_shard.hash_tree_root());
|
||||
result.append(&mut self.previous_calculation_epoch.hash_tree_root());
|
||||
result.append(&mut self.current_calculation_epoch.hash_tree_root());
|
||||
result.append(&mut self.previous_epoch_seed.hash_tree_root());
|
||||
result.append(&mut self.current_epoch_seed.hash_tree_root());
|
||||
result.append(&mut self.previous_justified_epoch.hash_tree_root());
|
||||
result.append(&mut self.justified_epoch.hash_tree_root());
|
||||
result.append(&mut self.justification_bitfield.hash_tree_root());
|
||||
result.append(&mut self.finalized_epoch.hash_tree_root());
|
||||
result.append(&mut self.latest_crosslinks.hash_tree_root());
|
||||
result.append(&mut self.latest_block_roots.hash_tree_root());
|
||||
result.append(&mut self.latest_index_roots.hash_tree_root());
|
||||
result.append(&mut self.latest_penalized_balances.hash_tree_root());
|
||||
result.append(&mut self.latest_attestations.hash_tree_root());
|
||||
result.append(&mut self.batched_block_roots.hash_tree_root());
|
||||
result.append(&mut self.latest_eth1_data.hash_tree_root());
|
||||
result.append(&mut self.eth1_data_votes.hash_tree_root());
|
||||
result.append(&mut self.slot.hash_tree_root_internal());
|
||||
result.append(&mut self.genesis_time.hash_tree_root_internal());
|
||||
result.append(&mut self.fork.hash_tree_root_internal());
|
||||
result.append(&mut self.validator_registry.hash_tree_root_internal());
|
||||
result.append(&mut self.validator_balances.hash_tree_root_internal());
|
||||
result.append(
|
||||
&mut self
|
||||
.validator_registry_update_epoch
|
||||
.hash_tree_root_internal(),
|
||||
);
|
||||
result.append(&mut self.latest_randao_mixes.hash_tree_root_internal());
|
||||
result.append(&mut self.previous_epoch_start_shard.hash_tree_root_internal());
|
||||
result.append(&mut self.current_epoch_start_shard.hash_tree_root_internal());
|
||||
result.append(&mut self.previous_calculation_epoch.hash_tree_root_internal());
|
||||
result.append(&mut self.current_calculation_epoch.hash_tree_root_internal());
|
||||
result.append(&mut self.previous_epoch_seed.hash_tree_root_internal());
|
||||
result.append(&mut self.current_epoch_seed.hash_tree_root_internal());
|
||||
result.append(&mut self.previous_justified_epoch.hash_tree_root_internal());
|
||||
result.append(&mut self.justified_epoch.hash_tree_root_internal());
|
||||
result.append(&mut self.justification_bitfield.hash_tree_root_internal());
|
||||
result.append(&mut self.finalized_epoch.hash_tree_root_internal());
|
||||
result.append(&mut self.latest_crosslinks.hash_tree_root_internal());
|
||||
result.append(&mut self.latest_block_roots.hash_tree_root_internal());
|
||||
result.append(&mut self.latest_index_roots.hash_tree_root_internal());
|
||||
result.append(&mut self.latest_penalized_balances.hash_tree_root_internal());
|
||||
result.append(&mut self.latest_attestations.hash_tree_root_internal());
|
||||
result.append(&mut self.batched_block_roots.hash_tree_root_internal());
|
||||
result.append(&mut self.latest_eth1_data.hash_tree_root_internal());
|
||||
result.append(&mut self.eth1_data_votes.hash_tree_root_internal());
|
||||
hash(&result)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,11 +85,11 @@ pub fn test_ssz_round_trip() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_hash_tree_root() {
|
||||
pub fn test_hash_tree_root_internal() {
|
||||
let mut rng = XorShiftRng::from_seed([42; 16]);
|
||||
let original = BeaconState::random_for_test(&mut rng);
|
||||
|
||||
let result = original.hash_tree_root();
|
||||
let result = original.hash_tree_root_internal();
|
||||
|
||||
assert_eq!(result.len(), 32);
|
||||
// TODO: Add further tests
|
||||
|
||||
@@ -12,10 +12,10 @@ pub struct CasperSlashing {
|
||||
}
|
||||
|
||||
impl TreeHash for CasperSlashing {
|
||||
fn hash_tree_root(&self) -> Vec<u8> {
|
||||
fn hash_tree_root_internal(&self) -> Vec<u8> {
|
||||
let mut result: Vec<u8> = vec![];
|
||||
result.append(&mut self.slashable_vote_data_1.hash_tree_root());
|
||||
result.append(&mut self.slashable_vote_data_2.hash_tree_root());
|
||||
result.append(&mut self.slashable_vote_data_1.hash_tree_root_internal());
|
||||
result.append(&mut self.slashable_vote_data_2.hash_tree_root_internal());
|
||||
hash(&result)
|
||||
}
|
||||
}
|
||||
@@ -47,11 +47,11 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_hash_tree_root() {
|
||||
pub fn test_hash_tree_root_internal() {
|
||||
let mut rng = XorShiftRng::from_seed([42; 16]);
|
||||
let original = CasperSlashing::random_for_test(&mut rng);
|
||||
|
||||
let result = original.hash_tree_root();
|
||||
let result = original.hash_tree_root_internal();
|
||||
|
||||
assert_eq!(result.len(), 32);
|
||||
// TODO: Add further tests
|
||||
|
||||
@@ -1,7 +1,96 @@
|
||||
use crate::{Address, ChainSpec, Epoch, Hash256, Signature, Slot};
|
||||
use crate::{Address, Epoch, Hash256, Slot};
|
||||
use bls::Signature;
|
||||
|
||||
const GWEI: u64 = 1_000_000_000;
|
||||
|
||||
/// Holds all the "constants" for a BeaconChain.
|
||||
///
|
||||
/// Spec v0.2.0
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
pub struct ChainSpec {
|
||||
/*
|
||||
* Misc
|
||||
*/
|
||||
pub shard_count: u64,
|
||||
pub target_committee_size: u64,
|
||||
pub max_balance_churn_quotient: u64,
|
||||
pub beacon_chain_shard_number: u64,
|
||||
pub max_indices_per_slashable_vote: u64,
|
||||
pub max_withdrawals_per_epoch: u64,
|
||||
pub shuffle_round_count: u8,
|
||||
|
||||
/*
|
||||
* Deposit contract
|
||||
*/
|
||||
pub deposit_contract_address: Address,
|
||||
pub deposit_contract_tree_depth: u64,
|
||||
|
||||
/*
|
||||
* Gwei values
|
||||
*/
|
||||
pub min_deposit_amount: u64,
|
||||
pub max_deposit_amount: u64,
|
||||
pub fork_choice_balance_increment: u64,
|
||||
pub ejection_balance: u64,
|
||||
|
||||
/*
|
||||
* Initial Values
|
||||
*/
|
||||
pub genesis_fork_version: u64,
|
||||
pub genesis_slot: Slot,
|
||||
pub genesis_epoch: Epoch,
|
||||
pub genesis_start_shard: u64,
|
||||
pub far_future_epoch: Epoch,
|
||||
pub zero_hash: Hash256,
|
||||
pub empty_signature: Signature,
|
||||
pub bls_withdrawal_prefix_byte: u8,
|
||||
|
||||
/*
|
||||
* Time parameters
|
||||
*/
|
||||
pub slot_duration: u64,
|
||||
pub min_attestation_inclusion_delay: u64,
|
||||
pub epoch_length: u64,
|
||||
pub seed_lookahead: Epoch,
|
||||
pub entry_exit_delay: u64,
|
||||
pub eth1_data_voting_period: u64,
|
||||
pub min_validator_withdrawal_epochs: Epoch,
|
||||
|
||||
/*
|
||||
* State list lengths
|
||||
*/
|
||||
pub latest_block_roots_length: usize,
|
||||
pub latest_randao_mixes_length: usize,
|
||||
pub latest_index_roots_length: usize,
|
||||
pub latest_penalized_exit_length: usize,
|
||||
|
||||
/*
|
||||
* Reward and penalty quotients
|
||||
*/
|
||||
pub base_reward_quotient: u64,
|
||||
pub whistleblower_reward_quotient: u64,
|
||||
pub includer_reward_quotient: u64,
|
||||
pub inactivity_penalty_quotient: u64,
|
||||
|
||||
/*
|
||||
* Max operations per block
|
||||
*/
|
||||
pub max_proposer_slashings: u64,
|
||||
pub max_attester_slashings: u64,
|
||||
pub max_attestations: u64,
|
||||
pub max_deposits: u64,
|
||||
pub max_exits: u64,
|
||||
|
||||
/*
|
||||
* Signature domains
|
||||
*/
|
||||
pub domain_deposit: u64,
|
||||
pub domain_attestation: u64,
|
||||
pub domain_proposal: u64,
|
||||
pub domain_exit: u64,
|
||||
pub domain_randao: u64,
|
||||
}
|
||||
|
||||
impl ChainSpec {
|
||||
/// Returns a `ChainSpec` compatible with the specification from Ethereum Foundation.
|
||||
///
|
||||
@@ -100,6 +189,26 @@ impl ChainSpec {
|
||||
}
|
||||
}
|
||||
|
||||
impl ChainSpec {
|
||||
/// Returns a `ChainSpec` compatible with the specification suitable for 8 validators.
|
||||
///
|
||||
/// Spec v0.2.0
|
||||
pub fn few_validators() -> Self {
|
||||
let genesis_slot = Slot::new(2_u64.pow(19));
|
||||
let epoch_length = 8;
|
||||
let genesis_epoch = genesis_slot.epoch(epoch_length);
|
||||
|
||||
Self {
|
||||
shard_count: 1,
|
||||
target_committee_size: 1,
|
||||
genesis_slot,
|
||||
genesis_epoch,
|
||||
epoch_length,
|
||||
..ChainSpec::foundation()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
@@ -22,10 +22,10 @@ impl Crosslink {
|
||||
}
|
||||
|
||||
impl TreeHash for Crosslink {
|
||||
fn hash_tree_root(&self) -> Vec<u8> {
|
||||
fn hash_tree_root_internal(&self) -> Vec<u8> {
|
||||
let mut result: Vec<u8> = vec![];
|
||||
result.append(&mut self.epoch.hash_tree_root());
|
||||
result.append(&mut self.shard_block_root.hash_tree_root());
|
||||
result.append(&mut self.epoch.hash_tree_root_internal());
|
||||
result.append(&mut self.shard_block_root.hash_tree_root_internal());
|
||||
hash(&result)
|
||||
}
|
||||
}
|
||||
@@ -57,11 +57,11 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_hash_tree_root() {
|
||||
pub fn test_hash_tree_root_internal() {
|
||||
let mut rng = XorShiftRng::from_seed([42; 16]);
|
||||
let original = Crosslink::random_for_test(&mut rng);
|
||||
|
||||
let result = original.hash_tree_root();
|
||||
let result = original.hash_tree_root_internal();
|
||||
|
||||
assert_eq!(result.len(), 32);
|
||||
// TODO: Add further tests
|
||||
|
||||
@@ -13,11 +13,11 @@ pub struct Deposit {
|
||||
}
|
||||
|
||||
impl TreeHash for Deposit {
|
||||
fn hash_tree_root(&self) -> Vec<u8> {
|
||||
fn hash_tree_root_internal(&self) -> Vec<u8> {
|
||||
let mut result: Vec<u8> = vec![];
|
||||
result.append(&mut self.branch.hash_tree_root());
|
||||
result.append(&mut self.index.hash_tree_root());
|
||||
result.append(&mut self.deposit_data.hash_tree_root());
|
||||
result.append(&mut self.branch.hash_tree_root_internal());
|
||||
result.append(&mut self.index.hash_tree_root_internal());
|
||||
result.append(&mut self.deposit_data.hash_tree_root_internal());
|
||||
hash(&result)
|
||||
}
|
||||
}
|
||||
@@ -50,11 +50,11 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_hash_tree_root() {
|
||||
pub fn test_hash_tree_root_internal() {
|
||||
let mut rng = XorShiftRng::from_seed([42; 16]);
|
||||
let original = Deposit::random_for_test(&mut rng);
|
||||
|
||||
let result = original.hash_tree_root();
|
||||
let result = original.hash_tree_root_internal();
|
||||
|
||||
assert_eq!(result.len(), 32);
|
||||
// TODO: Add further tests
|
||||
|
||||
@@ -13,11 +13,11 @@ pub struct DepositData {
|
||||
}
|
||||
|
||||
impl TreeHash for DepositData {
|
||||
fn hash_tree_root(&self) -> Vec<u8> {
|
||||
fn hash_tree_root_internal(&self) -> Vec<u8> {
|
||||
let mut result: Vec<u8> = vec![];
|
||||
result.append(&mut self.amount.hash_tree_root());
|
||||
result.append(&mut self.timestamp.hash_tree_root());
|
||||
result.append(&mut self.deposit_input.hash_tree_root());
|
||||
result.append(&mut self.amount.hash_tree_root_internal());
|
||||
result.append(&mut self.timestamp.hash_tree_root_internal());
|
||||
result.append(&mut self.deposit_input.hash_tree_root_internal());
|
||||
hash(&result)
|
||||
}
|
||||
}
|
||||
@@ -50,11 +50,11 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_hash_tree_root() {
|
||||
pub fn test_hash_tree_root_internal() {
|
||||
let mut rng = XorShiftRng::from_seed([42; 16]);
|
||||
let original = DepositData::random_for_test(&mut rng);
|
||||
|
||||
let result = original.hash_tree_root();
|
||||
let result = original.hash_tree_root_internal();
|
||||
|
||||
assert_eq!(result.len(), 32);
|
||||
// TODO: Add further tests
|
||||
|
||||
@@ -14,11 +14,11 @@ pub struct DepositInput {
|
||||
}
|
||||
|
||||
impl TreeHash for DepositInput {
|
||||
fn hash_tree_root(&self) -> Vec<u8> {
|
||||
fn hash_tree_root_internal(&self) -> Vec<u8> {
|
||||
let mut result: Vec<u8> = vec![];
|
||||
result.append(&mut self.pubkey.hash_tree_root());
|
||||
result.append(&mut self.withdrawal_credentials.hash_tree_root());
|
||||
result.append(&mut self.proof_of_possession.hash_tree_root());
|
||||
result.append(&mut self.pubkey.hash_tree_root_internal());
|
||||
result.append(&mut self.withdrawal_credentials.hash_tree_root_internal());
|
||||
result.append(&mut self.proof_of_possession.hash_tree_root_internal());
|
||||
hash(&result)
|
||||
}
|
||||
}
|
||||
@@ -51,11 +51,11 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_hash_tree_root() {
|
||||
pub fn test_hash_tree_root_internal() {
|
||||
let mut rng = XorShiftRng::from_seed([42; 16]);
|
||||
let original = DepositInput::random_for_test(&mut rng);
|
||||
|
||||
let result = original.hash_tree_root();
|
||||
let result = original.hash_tree_root_internal();
|
||||
|
||||
assert_eq!(result.len(), 32);
|
||||
// TODO: Add further tests
|
||||
|
||||
@@ -13,10 +13,10 @@ pub struct Eth1Data {
|
||||
}
|
||||
|
||||
impl TreeHash for Eth1Data {
|
||||
fn hash_tree_root(&self) -> Vec<u8> {
|
||||
fn hash_tree_root_internal(&self) -> Vec<u8> {
|
||||
let mut result: Vec<u8> = vec![];
|
||||
result.append(&mut self.deposit_root.hash_tree_root());
|
||||
result.append(&mut self.block_hash.hash_tree_root());
|
||||
result.append(&mut self.deposit_root.hash_tree_root_internal());
|
||||
result.append(&mut self.block_hash.hash_tree_root_internal());
|
||||
hash(&result)
|
||||
}
|
||||
}
|
||||
@@ -48,11 +48,11 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_hash_tree_root() {
|
||||
pub fn test_hash_tree_root_internal() {
|
||||
let mut rng = XorShiftRng::from_seed([42; 16]);
|
||||
let original = Eth1Data::random_for_test(&mut rng);
|
||||
|
||||
let result = original.hash_tree_root();
|
||||
let result = original.hash_tree_root_internal();
|
||||
|
||||
assert_eq!(result.len(), 32);
|
||||
// TODO: Add further tests
|
||||
|
||||
@@ -13,10 +13,10 @@ pub struct Eth1DataVote {
|
||||
}
|
||||
|
||||
impl TreeHash for Eth1DataVote {
|
||||
fn hash_tree_root(&self) -> Vec<u8> {
|
||||
fn hash_tree_root_internal(&self) -> Vec<u8> {
|
||||
let mut result: Vec<u8> = vec![];
|
||||
result.append(&mut self.eth1_data.hash_tree_root());
|
||||
result.append(&mut self.vote_count.hash_tree_root());
|
||||
result.append(&mut self.eth1_data.hash_tree_root_internal());
|
||||
result.append(&mut self.vote_count.hash_tree_root_internal());
|
||||
hash(&result)
|
||||
}
|
||||
}
|
||||
@@ -48,11 +48,11 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_hash_tree_root() {
|
||||
pub fn test_hash_tree_root_internal() {
|
||||
let mut rng = XorShiftRng::from_seed([42; 16]);
|
||||
let original = Eth1DataVote::random_for_test(&mut rng);
|
||||
|
||||
let result = original.hash_tree_root();
|
||||
let result = original.hash_tree_root_internal();
|
||||
|
||||
assert_eq!(result.len(), 32);
|
||||
// TODO: Add further tests
|
||||
|
||||
@@ -13,11 +13,11 @@ pub struct Exit {
|
||||
}
|
||||
|
||||
impl TreeHash for Exit {
|
||||
fn hash_tree_root(&self) -> Vec<u8> {
|
||||
fn hash_tree_root_internal(&self) -> Vec<u8> {
|
||||
let mut result: Vec<u8> = vec![];
|
||||
result.append(&mut self.epoch.hash_tree_root());
|
||||
result.append(&mut self.validator_index.hash_tree_root());
|
||||
result.append(&mut self.signature.hash_tree_root());
|
||||
result.append(&mut self.epoch.hash_tree_root_internal());
|
||||
result.append(&mut self.validator_index.hash_tree_root_internal());
|
||||
result.append(&mut self.signature.hash_tree_root_internal());
|
||||
hash(&result)
|
||||
}
|
||||
}
|
||||
@@ -50,11 +50,11 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_hash_tree_root() {
|
||||
pub fn test_hash_tree_root_internal() {
|
||||
let mut rng = XorShiftRng::from_seed([42; 16]);
|
||||
let original = Exit::random_for_test(&mut rng);
|
||||
|
||||
let result = original.hash_tree_root();
|
||||
let result = original.hash_tree_root_internal();
|
||||
|
||||
assert_eq!(result.len(), 32);
|
||||
// TODO: Add further tests
|
||||
|
||||
@@ -12,11 +12,11 @@ pub struct Fork {
|
||||
}
|
||||
|
||||
impl TreeHash for Fork {
|
||||
fn hash_tree_root(&self) -> Vec<u8> {
|
||||
fn hash_tree_root_internal(&self) -> Vec<u8> {
|
||||
let mut result: Vec<u8> = vec![];
|
||||
result.append(&mut self.previous_version.hash_tree_root());
|
||||
result.append(&mut self.current_version.hash_tree_root());
|
||||
result.append(&mut self.epoch.hash_tree_root());
|
||||
result.append(&mut self.previous_version.hash_tree_root_internal());
|
||||
result.append(&mut self.current_version.hash_tree_root_internal());
|
||||
result.append(&mut self.epoch.hash_tree_root_internal());
|
||||
hash(&result)
|
||||
}
|
||||
}
|
||||
@@ -49,11 +49,11 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_hash_tree_root() {
|
||||
pub fn test_hash_tree_root_internal() {
|
||||
let mut rng = XorShiftRng::from_seed([42; 16]);
|
||||
let original = Fork::random_for_test(&mut rng);
|
||||
|
||||
let result = original.hash_tree_root();
|
||||
let result = original.hash_tree_root_internal();
|
||||
|
||||
assert_eq!(result.len(), 32);
|
||||
// TODO: Add further tests
|
||||
|
||||
@@ -8,6 +8,7 @@ pub mod beacon_block;
|
||||
pub mod beacon_block_body;
|
||||
pub mod beacon_state;
|
||||
pub mod casper_slashing;
|
||||
pub mod chain_spec;
|
||||
pub mod crosslink;
|
||||
pub mod deposit;
|
||||
pub mod deposit_data;
|
||||
@@ -28,7 +29,6 @@ pub mod slashable_vote_data;
|
||||
pub mod slot_epoch_macros;
|
||||
pub mod slot_epoch;
|
||||
pub mod slot_height;
|
||||
pub mod spec;
|
||||
pub mod validator;
|
||||
pub mod validator_registry;
|
||||
pub mod validator_registry_delta_block;
|
||||
@@ -44,6 +44,7 @@ pub use crate::beacon_block::BeaconBlock;
|
||||
pub use crate::beacon_block_body::BeaconBlockBody;
|
||||
pub use crate::beacon_state::BeaconState;
|
||||
pub use crate::casper_slashing::CasperSlashing;
|
||||
pub use crate::chain_spec::ChainSpec;
|
||||
pub use crate::crosslink::Crosslink;
|
||||
pub use crate::deposit::Deposit;
|
||||
pub use crate::deposit_data::DepositData;
|
||||
@@ -60,7 +61,6 @@ pub use crate::slashable_attestation::SlashableAttestation;
|
||||
pub use crate::slashable_vote_data::SlashableVoteData;
|
||||
pub use crate::slot_epoch::{Epoch, Slot};
|
||||
pub use crate::slot_height::SlotHeight;
|
||||
pub use crate::spec::ChainSpec;
|
||||
pub use crate::validator::{StatusFlags as ValidatorStatusFlags, Validator};
|
||||
pub use crate::validator_registry_delta_block::ValidatorRegistryDeltaBlock;
|
||||
|
||||
|
||||
@@ -14,12 +14,12 @@ pub struct PendingAttestation {
|
||||
}
|
||||
|
||||
impl TreeHash for PendingAttestation {
|
||||
fn hash_tree_root(&self) -> Vec<u8> {
|
||||
fn hash_tree_root_internal(&self) -> Vec<u8> {
|
||||
let mut result: Vec<u8> = vec![];
|
||||
result.append(&mut self.aggregation_bitfield.hash_tree_root());
|
||||
result.append(&mut self.data.hash_tree_root());
|
||||
result.append(&mut self.custody_bitfield.hash_tree_root());
|
||||
result.append(&mut self.inclusion_slot.hash_tree_root());
|
||||
result.append(&mut self.aggregation_bitfield.hash_tree_root_internal());
|
||||
result.append(&mut self.data.hash_tree_root_internal());
|
||||
result.append(&mut self.custody_bitfield.hash_tree_root_internal());
|
||||
result.append(&mut self.inclusion_slot.hash_tree_root_internal());
|
||||
hash(&result)
|
||||
}
|
||||
}
|
||||
@@ -53,11 +53,11 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_hash_tree_root() {
|
||||
pub fn test_hash_tree_root_internal() {
|
||||
let mut rng = XorShiftRng::from_seed([42; 16]);
|
||||
let original = PendingAttestation::random_for_test(&mut rng);
|
||||
|
||||
let result = original.hash_tree_root();
|
||||
let result = original.hash_tree_root_internal();
|
||||
|
||||
assert_eq!(result.len(), 32);
|
||||
// TODO: Add further tests
|
||||
|
||||
@@ -13,11 +13,11 @@ pub struct ProposalSignedData {
|
||||
}
|
||||
|
||||
impl TreeHash for ProposalSignedData {
|
||||
fn hash_tree_root(&self) -> Vec<u8> {
|
||||
fn hash_tree_root_internal(&self) -> Vec<u8> {
|
||||
let mut result: Vec<u8> = vec![];
|
||||
result.append(&mut self.slot.hash_tree_root());
|
||||
result.append(&mut self.shard.hash_tree_root());
|
||||
result.append(&mut self.block_root.hash_tree_root());
|
||||
result.append(&mut self.slot.hash_tree_root_internal());
|
||||
result.append(&mut self.shard.hash_tree_root_internal());
|
||||
result.append(&mut self.block_root.hash_tree_root_internal());
|
||||
hash(&result)
|
||||
}
|
||||
}
|
||||
@@ -50,11 +50,11 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_hash_tree_root() {
|
||||
pub fn test_hash_tree_root_internal() {
|
||||
let mut rng = XorShiftRng::from_seed([42; 16]);
|
||||
let original = ProposalSignedData::random_for_test(&mut rng);
|
||||
|
||||
let result = original.hash_tree_root();
|
||||
let result = original.hash_tree_root_internal();
|
||||
|
||||
assert_eq!(result.len(), 32);
|
||||
// TODO: Add further tests
|
||||
|
||||
@@ -16,13 +16,13 @@ pub struct ProposerSlashing {
|
||||
}
|
||||
|
||||
impl TreeHash for ProposerSlashing {
|
||||
fn hash_tree_root(&self) -> Vec<u8> {
|
||||
fn hash_tree_root_internal(&self) -> Vec<u8> {
|
||||
let mut result: Vec<u8> = vec![];
|
||||
result.append(&mut self.proposer_index.hash_tree_root());
|
||||
result.append(&mut self.proposal_data_1.hash_tree_root());
|
||||
result.append(&mut self.proposal_signature_1.hash_tree_root());
|
||||
result.append(&mut self.proposal_data_2.hash_tree_root());
|
||||
result.append(&mut self.proposal_signature_2.hash_tree_root());
|
||||
result.append(&mut self.proposer_index.hash_tree_root_internal());
|
||||
result.append(&mut self.proposal_data_1.hash_tree_root_internal());
|
||||
result.append(&mut self.proposal_signature_1.hash_tree_root_internal());
|
||||
result.append(&mut self.proposal_data_2.hash_tree_root_internal());
|
||||
result.append(&mut self.proposal_signature_2.hash_tree_root_internal());
|
||||
hash(&result)
|
||||
}
|
||||
}
|
||||
@@ -57,11 +57,11 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_hash_tree_root() {
|
||||
pub fn test_hash_tree_root_internal() {
|
||||
let mut rng = XorShiftRng::from_seed([42; 16]);
|
||||
let original = ProposerSlashing::random_for_test(&mut rng);
|
||||
|
||||
let result = original.hash_tree_root();
|
||||
let result = original.hash_tree_root_internal();
|
||||
|
||||
assert_eq!(result.len(), 32);
|
||||
// TODO: Add further tests
|
||||
|
||||
@@ -12,11 +12,11 @@ pub struct ShardReassignmentRecord {
|
||||
}
|
||||
|
||||
impl TreeHash for ShardReassignmentRecord {
|
||||
fn hash_tree_root(&self) -> Vec<u8> {
|
||||
fn hash_tree_root_internal(&self) -> Vec<u8> {
|
||||
let mut result: Vec<u8> = vec![];
|
||||
result.append(&mut self.validator_index.hash_tree_root());
|
||||
result.append(&mut self.shard.hash_tree_root());
|
||||
result.append(&mut self.slot.hash_tree_root());
|
||||
result.append(&mut self.validator_index.hash_tree_root_internal());
|
||||
result.append(&mut self.shard.hash_tree_root_internal());
|
||||
result.append(&mut self.slot.hash_tree_root_internal());
|
||||
hash(&result)
|
||||
}
|
||||
}
|
||||
@@ -49,11 +49,11 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_hash_tree_root() {
|
||||
pub fn test_hash_tree_root_internal() {
|
||||
let mut rng = XorShiftRng::from_seed([42; 16]);
|
||||
let original = ShardReassignmentRecord::random_for_test(&mut rng);
|
||||
|
||||
let result = original.hash_tree_root();
|
||||
let result = original.hash_tree_root_internal();
|
||||
|
||||
assert_eq!(result.len(), 32);
|
||||
// TODO: Add further tests
|
||||
|
||||
@@ -13,12 +13,12 @@ pub struct SlashableAttestation {
|
||||
}
|
||||
|
||||
impl TreeHash for SlashableAttestation {
|
||||
fn hash_tree_root(&self) -> Vec<u8> {
|
||||
fn hash_tree_root_internal(&self) -> Vec<u8> {
|
||||
let mut result: Vec<u8> = vec![];
|
||||
result.append(&mut self.validator_indices.hash_tree_root());
|
||||
result.append(&mut self.data.hash_tree_root());
|
||||
result.append(&mut self.custody_bitfield.hash_tree_root());
|
||||
result.append(&mut self.aggregate_signature.hash_tree_root());
|
||||
result.append(&mut self.validator_indices.hash_tree_root_internal());
|
||||
result.append(&mut self.data.hash_tree_root_internal());
|
||||
result.append(&mut self.custody_bitfield.hash_tree_root_internal());
|
||||
result.append(&mut self.aggregate_signature.hash_tree_root_internal());
|
||||
hash(&result)
|
||||
}
|
||||
}
|
||||
@@ -52,11 +52,11 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_hash_tree_root() {
|
||||
pub fn test_hash_tree_root_internal() {
|
||||
let mut rng = XorShiftRng::from_seed([42; 16]);
|
||||
let original = SlashableAttestation::random_for_test(&mut rng);
|
||||
|
||||
let result = original.hash_tree_root();
|
||||
let result = original.hash_tree_root_internal();
|
||||
|
||||
assert_eq!(result.len(), 32);
|
||||
// TODO: Add further tests
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use super::AttestationData;
|
||||
use crate::chain_spec::ChainSpec;
|
||||
use crate::test_utils::TestRandom;
|
||||
use bls::AggregateSignature;
|
||||
use rand::RngCore;
|
||||
@@ -14,13 +15,34 @@ pub struct SlashableVoteData {
|
||||
pub aggregate_signature: AggregateSignature,
|
||||
}
|
||||
|
||||
impl SlashableVoteData {
|
||||
/// Check if ``attestation_data_1`` and ``attestation_data_2`` have the same target.
|
||||
///
|
||||
/// Spec v0.3.0
|
||||
pub fn is_double_vote(&self, other: &SlashableVoteData, spec: &ChainSpec) -> bool {
|
||||
self.data.slot.epoch(spec.epoch_length) == other.data.slot.epoch(spec.epoch_length)
|
||||
}
|
||||
|
||||
/// Check if ``attestation_data_1`` surrounds ``attestation_data_2``.
|
||||
///
|
||||
/// Spec v0.3.0
|
||||
pub fn is_surround_vote(&self, other: &SlashableVoteData, spec: &ChainSpec) -> bool {
|
||||
let source_epoch_1 = self.data.justified_epoch;
|
||||
let source_epoch_2 = other.data.justified_epoch;
|
||||
let target_epoch_1 = self.data.slot.epoch(spec.epoch_length);
|
||||
let target_epoch_2 = other.data.slot.epoch(spec.epoch_length);
|
||||
|
||||
(source_epoch_1 < source_epoch_2) && (target_epoch_2 < target_epoch_1)
|
||||
}
|
||||
}
|
||||
|
||||
impl TreeHash for SlashableVoteData {
|
||||
fn hash_tree_root(&self) -> Vec<u8> {
|
||||
fn hash_tree_root_internal(&self) -> Vec<u8> {
|
||||
let mut result: Vec<u8> = vec![];
|
||||
result.append(&mut self.custody_bit_0_indices.hash_tree_root());
|
||||
result.append(&mut self.custody_bit_1_indices.hash_tree_root());
|
||||
result.append(&mut self.data.hash_tree_root());
|
||||
result.append(&mut self.aggregate_signature.hash_tree_root());
|
||||
result.append(&mut self.custody_bit_0_indices.hash_tree_root_internal());
|
||||
result.append(&mut self.custody_bit_1_indices.hash_tree_root_internal());
|
||||
result.append(&mut self.data.hash_tree_root_internal());
|
||||
result.append(&mut self.aggregate_signature.hash_tree_root_internal());
|
||||
hash(&result)
|
||||
}
|
||||
}
|
||||
@@ -39,9 +61,83 @@ impl<T: RngCore> TestRandom<T> for SlashableVoteData {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::chain_spec::ChainSpec;
|
||||
use crate::slot_epoch::{Epoch, Slot};
|
||||
use crate::test_utils::{SeedableRng, TestRandom, XorShiftRng};
|
||||
use ssz::ssz_encode;
|
||||
|
||||
#[test]
|
||||
pub fn test_is_double_vote_true() {
|
||||
let spec = ChainSpec::foundation();
|
||||
let slashable_vote_first = create_slashable_vote_data(1, 1, &spec);
|
||||
let slashable_vote_second = create_slashable_vote_data(1, 1, &spec);
|
||||
|
||||
assert_eq!(
|
||||
slashable_vote_first.is_double_vote(&slashable_vote_second, &spec),
|
||||
true
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_is_double_vote_false() {
|
||||
let spec = ChainSpec::foundation();
|
||||
let slashable_vote_first = create_slashable_vote_data(1, 1, &spec);
|
||||
let slashable_vote_second = create_slashable_vote_data(2, 1, &spec);
|
||||
|
||||
assert_eq!(
|
||||
slashable_vote_first.is_double_vote(&slashable_vote_second, &spec),
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_is_surround_vote_true() {
|
||||
let spec = ChainSpec::foundation();
|
||||
let slashable_vote_first = create_slashable_vote_data(2, 1, &spec);
|
||||
let slashable_vote_second = create_slashable_vote_data(1, 2, &spec);
|
||||
|
||||
assert_eq!(
|
||||
slashable_vote_first.is_surround_vote(&slashable_vote_second, &spec),
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_is_surround_vote_true_realistic() {
|
||||
let spec = ChainSpec::foundation();
|
||||
let slashable_vote_first = create_slashable_vote_data(4, 1, &spec);
|
||||
let slashable_vote_second = create_slashable_vote_data(3, 2, &spec);
|
||||
|
||||
assert_eq!(
|
||||
slashable_vote_first.is_surround_vote(&slashable_vote_second, &spec),
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_is_surround_vote_false_source_epoch_fails() {
|
||||
let spec = ChainSpec::foundation();
|
||||
let slashable_vote_first = create_slashable_vote_data(2, 2, &spec);
|
||||
let slashable_vote_second = create_slashable_vote_data(1, 1, &spec);
|
||||
|
||||
assert_eq!(
|
||||
slashable_vote_first.is_surround_vote(&slashable_vote_second, &spec),
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_is_surround_vote_false_target_epoch_fails() {
|
||||
let spec = ChainSpec::foundation();
|
||||
let slashable_vote_first = create_slashable_vote_data(1, 1, &spec);
|
||||
let slashable_vote_second = create_slashable_vote_data(2, 2, &spec);
|
||||
|
||||
assert_eq!(
|
||||
slashable_vote_first.is_surround_vote(&slashable_vote_second, &spec),
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_ssz_round_trip() {
|
||||
let mut rng = XorShiftRng::from_seed([42; 16]);
|
||||
@@ -54,14 +150,27 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_hash_tree_root() {
|
||||
pub fn test_hash_tree_root_internal() {
|
||||
let mut rng = XorShiftRng::from_seed([42; 16]);
|
||||
let original = SlashableVoteData::random_for_test(&mut rng);
|
||||
|
||||
let result = original.hash_tree_root();
|
||||
let result = original.hash_tree_root_internal();
|
||||
|
||||
assert_eq!(result.len(), 32);
|
||||
// TODO: Add further tests
|
||||
// https://github.com/sigp/lighthouse/issues/170
|
||||
}
|
||||
|
||||
fn create_slashable_vote_data(
|
||||
slot_factor: u64,
|
||||
justified_epoch: u64,
|
||||
spec: &ChainSpec,
|
||||
) -> SlashableVoteData {
|
||||
let mut rng = XorShiftRng::from_seed([42; 16]);
|
||||
let mut slashable_vote = SlashableVoteData::random_for_test(&mut rng);
|
||||
|
||||
slashable_vote.data.slot = Slot::new(slot_factor * spec.epoch_length);
|
||||
slashable_vote.data.justified_epoch = Epoch::new(justified_epoch);
|
||||
slashable_vote
|
||||
}
|
||||
}
|
||||
|
||||
@@ -224,9 +224,9 @@ macro_rules! impl_ssz {
|
||||
}
|
||||
|
||||
impl TreeHash for $type {
|
||||
fn hash_tree_root(&self) -> Vec<u8> {
|
||||
fn hash_tree_root_internal(&self) -> Vec<u8> {
|
||||
let mut result: Vec<u8> = vec![];
|
||||
result.append(&mut self.0.hash_tree_root());
|
||||
result.append(&mut self.0.hash_tree_root_internal());
|
||||
hash(&result)
|
||||
}
|
||||
}
|
||||
@@ -560,11 +560,11 @@ macro_rules! ssz_tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_hash_tree_root() {
|
||||
pub fn test_hash_tree_root_internal() {
|
||||
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.hash_tree_root_internal();
|
||||
|
||||
assert_eq!(result.len(), 32);
|
||||
// TODO: Add further tests
|
||||
|
||||
@@ -1,92 +0,0 @@
|
||||
mod foundation;
|
||||
|
||||
use crate::{Address, Epoch, Hash256, Slot};
|
||||
use bls::Signature;
|
||||
|
||||
/// Holds all the "constants" for a BeaconChain.
|
||||
///
|
||||
/// Spec v0.2.0
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
pub struct ChainSpec {
|
||||
/*
|
||||
* Misc
|
||||
*/
|
||||
pub shard_count: u64,
|
||||
pub target_committee_size: u64,
|
||||
pub max_balance_churn_quotient: u64,
|
||||
pub beacon_chain_shard_number: u64,
|
||||
pub max_indices_per_slashable_vote: u64,
|
||||
pub max_withdrawals_per_epoch: u64,
|
||||
pub shuffle_round_count: u8,
|
||||
|
||||
/*
|
||||
* Deposit contract
|
||||
*/
|
||||
pub deposit_contract_address: Address,
|
||||
pub deposit_contract_tree_depth: u64,
|
||||
|
||||
/*
|
||||
* Gwei values
|
||||
*/
|
||||
pub min_deposit_amount: u64,
|
||||
pub max_deposit_amount: u64,
|
||||
pub fork_choice_balance_increment: u64,
|
||||
pub ejection_balance: u64,
|
||||
|
||||
/*
|
||||
* Initial Values
|
||||
*/
|
||||
pub genesis_fork_version: u64,
|
||||
pub genesis_slot: Slot,
|
||||
pub genesis_epoch: Epoch,
|
||||
pub genesis_start_shard: u64,
|
||||
pub far_future_epoch: Epoch,
|
||||
pub zero_hash: Hash256,
|
||||
pub empty_signature: Signature,
|
||||
pub bls_withdrawal_prefix_byte: u8,
|
||||
|
||||
/*
|
||||
* Time parameters
|
||||
*/
|
||||
pub slot_duration: u64,
|
||||
pub min_attestation_inclusion_delay: u64,
|
||||
pub epoch_length: u64,
|
||||
pub seed_lookahead: Epoch,
|
||||
pub entry_exit_delay: u64,
|
||||
pub eth1_data_voting_period: u64,
|
||||
pub min_validator_withdrawal_epochs: Epoch,
|
||||
|
||||
/*
|
||||
* State list lengths
|
||||
*/
|
||||
pub latest_block_roots_length: usize,
|
||||
pub latest_randao_mixes_length: usize,
|
||||
pub latest_index_roots_length: usize,
|
||||
pub latest_penalized_exit_length: usize,
|
||||
|
||||
/*
|
||||
* Reward and penalty quotients
|
||||
*/
|
||||
pub base_reward_quotient: u64,
|
||||
pub whistleblower_reward_quotient: u64,
|
||||
pub includer_reward_quotient: u64,
|
||||
pub inactivity_penalty_quotient: u64,
|
||||
|
||||
/*
|
||||
* Max operations per block
|
||||
*/
|
||||
pub max_proposer_slashings: u64,
|
||||
pub max_attester_slashings: u64,
|
||||
pub max_attestations: u64,
|
||||
pub max_deposits: u64,
|
||||
pub max_exits: u64,
|
||||
|
||||
/*
|
||||
* Signature domains
|
||||
*/
|
||||
pub domain_deposit: u64,
|
||||
pub domain_attestation: u64,
|
||||
pub domain_proposal: u64,
|
||||
pub domain_exit: u64,
|
||||
pub domain_randao: u64,
|
||||
}
|
||||
@@ -122,15 +122,17 @@ impl Decodable for Validator {
|
||||
}
|
||||
|
||||
impl TreeHash for Validator {
|
||||
fn hash_tree_root(&self) -> Vec<u8> {
|
||||
fn hash_tree_root_internal(&self) -> Vec<u8> {
|
||||
let mut result: Vec<u8> = vec![];
|
||||
result.append(&mut self.pubkey.hash_tree_root());
|
||||
result.append(&mut self.withdrawal_credentials.hash_tree_root());
|
||||
result.append(&mut self.activation_epoch.hash_tree_root());
|
||||
result.append(&mut self.exit_epoch.hash_tree_root());
|
||||
result.append(&mut self.withdrawal_epoch.hash_tree_root());
|
||||
result.append(&mut self.penalized_epoch.hash_tree_root());
|
||||
result.append(&mut u64::from(status_flag_to_byte(self.status_flags)).hash_tree_root());
|
||||
result.append(&mut self.pubkey.hash_tree_root_internal());
|
||||
result.append(&mut self.withdrawal_credentials.hash_tree_root_internal());
|
||||
result.append(&mut self.activation_epoch.hash_tree_root_internal());
|
||||
result.append(&mut self.exit_epoch.hash_tree_root_internal());
|
||||
result.append(&mut self.withdrawal_epoch.hash_tree_root_internal());
|
||||
result.append(&mut self.penalized_epoch.hash_tree_root_internal());
|
||||
result.append(
|
||||
&mut u64::from(status_flag_to_byte(self.status_flags)).hash_tree_root_internal(),
|
||||
);
|
||||
hash(&result)
|
||||
}
|
||||
}
|
||||
@@ -190,11 +192,11 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_hash_tree_root() {
|
||||
pub fn test_hash_tree_root_internal() {
|
||||
let mut rng = XorShiftRng::from_seed([42; 16]);
|
||||
let original = Validator::random_for_test(&mut rng);
|
||||
|
||||
let result = original.hash_tree_root();
|
||||
let result = original.hash_tree_root_internal();
|
||||
|
||||
assert_eq!(result.len(), 32);
|
||||
// TODO: Add further tests
|
||||
|
||||
@@ -29,13 +29,13 @@ impl Default for ValidatorRegistryDeltaBlock {
|
||||
}
|
||||
|
||||
impl TreeHash for ValidatorRegistryDeltaBlock {
|
||||
fn hash_tree_root(&self) -> Vec<u8> {
|
||||
fn hash_tree_root_internal(&self) -> Vec<u8> {
|
||||
let mut result: Vec<u8> = vec![];
|
||||
result.append(&mut self.latest_registry_delta_root.hash_tree_root());
|
||||
result.append(&mut self.validator_index.hash_tree_root());
|
||||
result.append(&mut self.pubkey.hash_tree_root());
|
||||
result.append(&mut self.slot.hash_tree_root());
|
||||
result.append(&mut self.flag.hash_tree_root());
|
||||
result.append(&mut self.latest_registry_delta_root.hash_tree_root_internal());
|
||||
result.append(&mut self.validator_index.hash_tree_root_internal());
|
||||
result.append(&mut self.pubkey.hash_tree_root_internal());
|
||||
result.append(&mut self.slot.hash_tree_root_internal());
|
||||
result.append(&mut self.flag.hash_tree_root_internal());
|
||||
hash(&result)
|
||||
}
|
||||
}
|
||||
@@ -70,11 +70,11 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_hash_tree_root() {
|
||||
pub fn test_hash_tree_root_internal() {
|
||||
let mut rng = XorShiftRng::from_seed([42; 16]);
|
||||
let original = ValidatorRegistryDeltaBlock::random_for_test(&mut rng);
|
||||
|
||||
let result = original.hash_tree_root();
|
||||
let result = original.hash_tree_root_internal();
|
||||
|
||||
assert_eq!(result.len(), 32);
|
||||
// TODO: Add further tests
|
||||
|
||||
Reference in New Issue
Block a user