Start reorg of per_epoch_processing

This commit is contained in:
Paul Hauner 2019-03-06 17:14:54 +11:00
parent 521d48d37c
commit 17210faf3a
No known key found for this signature in database
GPG Key ID: D362883A9218FCC6
14 changed files with 136 additions and 129 deletions

View File

@ -1,12 +1,12 @@
#[macro_use] #[macro_use]
mod macros; mod macros;
pub mod per_block_processing; pub mod per_block_processing;
// mod epoch_processable; pub mod per_epoch_processing;
pub mod errors;
// mod slot_processable; // mod slot_processable;
pub use errors::{BlockInvalid, BlockProcessingError};
pub use per_block_processing::{ pub use per_block_processing::{
errors::{BlockInvalid, BlockProcessingError},
per_block_processing, per_block_processing_without_verifying_block_signature, per_block_processing, per_block_processing_without_verifying_block_signature,
}; };
// pub use epoch_processable::{EpochProcessable, Error as EpochProcessingError}; // pub use epoch_processable::{EpochProcessable, Error as EpochProcessingError};

View File

@ -1,5 +1,5 @@
use self::verify_proposer_slashing::verify_proposer_slashing; use self::verify_proposer_slashing::verify_proposer_slashing;
use crate::errors::{BlockInvalid as Invalid, BlockProcessingError as Error, IntoWithIndex}; use errors::{BlockInvalid as Invalid, BlockProcessingError as Error, IntoWithIndex};
use hashing::hash; use hashing::hash;
use log::debug; use log::debug;
use ssz::{ssz_encode, SignedRoot, TreeHash}; use ssz::{ssz_encode, SignedRoot, TreeHash};
@ -11,6 +11,7 @@ pub use verify_deposit::verify_deposit;
pub use verify_exit::verify_exit; pub use verify_exit::verify_exit;
pub use verify_transfer::verify_transfer; pub use verify_transfer::verify_transfer;
pub mod errors;
mod validate_attestation; mod validate_attestation;
mod verify_attester_slashing; mod verify_attester_slashing;
mod verify_deposit; mod verify_deposit;

View File

@ -1,4 +1,4 @@
use crate::errors::{AttestationInvalid as Invalid, AttestationValidationError as Error}; use super::errors::{AttestationInvalid as Invalid, AttestationValidationError as Error};
use ssz::TreeHash; use ssz::TreeHash;
use types::beacon_state::helpers::*; use types::beacon_state::helpers::*;
use types::*; use types::*;

View File

@ -1,5 +1,5 @@
use super::errors::{AttesterSlashingInvalid as Invalid, AttesterSlashingValidationError as Error};
use super::verify_slashable_attestation::verify_slashable_attestation; use super::verify_slashable_attestation::verify_slashable_attestation;
use crate::errors::{AttesterSlashingInvalid as Invalid, AttesterSlashingValidationError as Error};
use types::*; use types::*;
/// Indicates if an `AttesterSlashing` is valid to be included in a block in the current epoch of the given /// Indicates if an `AttesterSlashing` is valid to be included in a block in the current epoch of the given

View File

@ -1,4 +1,4 @@
use crate::errors::{DepositInvalid as Invalid, DepositValidationError as Error}; use super::errors::{DepositInvalid as Invalid, DepositValidationError as Error};
use types::*; use types::*;
/// Indicates if a `Deposit` is valid to be included in a block in the current epoch of the given /// Indicates if a `Deposit` is valid to be included in a block in the current epoch of the given

View File

@ -1,4 +1,4 @@
use crate::errors::{ExitInvalid as Invalid, ExitValidationError as Error}; use super::errors::{ExitInvalid as Invalid, ExitValidationError as Error};
use ssz::SignedRoot; use ssz::SignedRoot;
use types::*; use types::*;

View File

@ -1,4 +1,4 @@
use crate::errors::{ProposerSlashingInvalid as Invalid, ProposerSlashingValidationError as Error}; use super::errors::{ProposerSlashingInvalid as Invalid, ProposerSlashingValidationError as Error};
use ssz::SignedRoot; use ssz::SignedRoot;
use types::*; use types::*;

View File

@ -1,4 +1,4 @@
use crate::errors::{ use super::errors::{
SlashableAttestationInvalid as Invalid, SlashableAttestationValidationError as Error, SlashableAttestationInvalid as Invalid, SlashableAttestationValidationError as Error,
}; };
use ssz::TreeHash; use ssz::TreeHash;

View File

@ -1,4 +1,4 @@
use crate::errors::{TransferInvalid as Invalid, TransferValidationError as Error}; use super::errors::{TransferInvalid as Invalid, TransferValidationError as Error};
use types::*; use types::*;
/// Indicates if a `Transfer` is valid to be included in a block in the current epoch of the given /// Indicates if a `Transfer` is valid to be included in a block in the current epoch of the given

View File

@ -1,3 +1,4 @@
use errors::EpochProcessingError as Error;
use integer_sqrt::IntegerSquareRoot; use integer_sqrt::IntegerSquareRoot;
use log::{debug, trace}; use log::{debug, trace};
use rayon::prelude::*; use rayon::prelude::*;
@ -9,7 +10,9 @@ use types::{
Crosslink, Epoch, Hash256, InclusionError, PendingAttestation, RelativeEpoch, Crosslink, Epoch, Hash256, InclusionError, PendingAttestation, RelativeEpoch,
}; };
mod errors;
mod tests; mod tests;
mod winning_root;
macro_rules! safe_add_assign { macro_rules! safe_add_assign {
($a: expr, $b: expr) => { ($a: expr, $b: expr) => {
@ -22,31 +25,6 @@ macro_rules! safe_sub_assign {
}; };
} }
#[derive(Debug, PartialEq)]
pub enum Error {
UnableToDetermineProducer,
NoBlockRoots,
BaseRewardQuotientIsZero,
NoRandaoSeed,
BeaconStateError(BeaconStateError),
InclusionError(InclusionError),
WinningRootError(WinningRootError),
}
#[derive(Debug, PartialEq)]
pub enum WinningRootError {
NoWinningRoot,
BeaconStateError(BeaconStateError),
}
#[derive(Clone)]
pub struct WinningRoot {
pub shard_block_root: Hash256,
pub attesting_validator_indices: Vec<usize>,
pub total_balance: u64,
pub total_attesting_balance: u64,
}
pub trait EpochProcessable { pub trait EpochProcessable {
fn per_epoch_processing(&mut self, spec: &ChainSpec) -> Result<(), Error>; fn per_epoch_processing(&mut self, spec: &ChainSpec) -> Result<(), Error>;
} }
@ -628,96 +606,3 @@ impl EpochProcessable for BeaconState {
fn hash_tree_root<T: TreeHash>(input: Vec<T>) -> Hash256 { fn hash_tree_root<T: TreeHash>(input: Vec<T>) -> Hash256 {
Hash256::from(&input.hash_tree_root()[..]) Hash256::from(&input.hash_tree_root()[..])
} }
fn winning_root(
state: &BeaconState,
shard: u64,
current_epoch_attestations: &[&PendingAttestation],
previous_epoch_attestations: &[&PendingAttestation],
spec: &ChainSpec,
) -> Result<WinningRoot, WinningRootError> {
let mut attestations = current_epoch_attestations.to_vec();
attestations.append(&mut previous_epoch_attestations.to_vec());
let mut candidates: HashMap<Hash256, WinningRoot> = HashMap::new();
let mut highest_seen_balance = 0;
for a in &attestations {
if a.data.shard != shard {
continue;
}
let shard_block_root = &a.data.shard_block_root;
if candidates.contains_key(shard_block_root) {
continue;
}
let attesting_validator_indices = attestations
.iter()
.try_fold::<_, _, Result<_, BeaconStateError>>(vec![], |mut acc, a| {
if (a.data.shard == shard) && (a.data.shard_block_root == *shard_block_root) {
acc.append(&mut state.get_attestation_participants(
&a.data,
&a.aggregation_bitfield,
spec,
)?);
}
Ok(acc)
})?;
let total_balance: u64 = attesting_validator_indices
.iter()
.fold(0, |acc, i| acc + state.get_effective_balance(*i, spec));
let total_attesting_balance: u64 = attesting_validator_indices
.iter()
.fold(0, |acc, i| acc + state.get_effective_balance(*i, spec));
if total_attesting_balance > highest_seen_balance {
highest_seen_balance = total_attesting_balance;
}
let candidate_root = WinningRoot {
shard_block_root: *shard_block_root,
attesting_validator_indices,
total_attesting_balance,
total_balance,
};
candidates.insert(*shard_block_root, candidate_root);
}
Ok(candidates
.iter()
.filter_map(|(_hash, candidate)| {
if candidate.total_attesting_balance == highest_seen_balance {
Some(candidate)
} else {
None
}
})
.min_by_key(|candidate| candidate.shard_block_root)
.ok_or_else(|| WinningRootError::NoWinningRoot)?
// TODO: avoid clone.
.clone())
}
impl From<InclusionError> for Error {
fn from(e: InclusionError) -> Error {
Error::InclusionError(e)
}
}
impl From<BeaconStateError> for Error {
fn from(e: BeaconStateError) -> Error {
Error::BeaconStateError(e)
}
}
impl From<BeaconStateError> for WinningRootError {
fn from(e: BeaconStateError) -> WinningRootError {
WinningRootError::BeaconStateError(e)
}
}

View File

@ -0,0 +1,36 @@
use types::*;
#[derive(Debug, PartialEq)]
pub enum WinningRootError {
NoWinningRoot,
BeaconStateError(BeaconStateError),
}
#[derive(Debug, PartialEq)]
pub enum EpochProcessingError {
UnableToDetermineProducer,
NoBlockRoots,
BaseRewardQuotientIsZero,
NoRandaoSeed,
BeaconStateError(BeaconStateError),
InclusionError(InclusionError),
WinningRootError(WinningRootError),
}
impl From<InclusionError> for EpochProcessingError {
fn from(e: InclusionError) -> EpochProcessingError {
EpochProcessingError::InclusionError(e)
}
}
impl From<BeaconStateError> for EpochProcessingError {
fn from(e: BeaconStateError) -> EpochProcessingError {
EpochProcessingError::BeaconStateError(e)
}
}
impl From<BeaconStateError> for WinningRootError {
fn from(e: BeaconStateError) -> WinningRootError {
WinningRootError::BeaconStateError(e)
}
}

View File

@ -0,0 +1,85 @@
use super::WinningRootError;
use types::*;
#[derive(Clone)]
pub struct WinningRoot {
pub shard_block_root: Hash256,
pub attesting_validator_indices: Vec<usize>,
pub total_balance: u64,
pub total_attesting_balance: u64,
}
fn winning_root(
state: &BeaconState,
shard: u64,
current_epoch_attestations: &[&PendingAttestation],
previous_epoch_attestations: &[&PendingAttestation],
spec: &ChainSpec,
) -> Result<WinningRoot, WinningRootError> {
let mut attestations = current_epoch_attestations.to_vec();
attestations.append(&mut previous_epoch_attestations.to_vec());
let mut candidates: HashMap<Hash256, WinningRoot> = HashMap::new();
let mut highest_seen_balance = 0;
for a in &attestations {
if a.data.shard != shard {
continue;
}
let shard_block_root = &a.data.shard_block_root;
if candidates.contains_key(shard_block_root) {
continue;
}
let attesting_validator_indices = attestations
.iter()
.try_fold::<_, _, Result<_, BeaconStateError>>(vec![], |mut acc, a| {
if (a.data.shard == shard) && (a.data.shard_block_root == *shard_block_root) {
acc.append(&mut state.get_attestation_participants(
&a.data,
&a.aggregation_bitfield,
spec,
)?);
}
Ok(acc)
})?;
let total_balance: u64 = attesting_validator_indices
.iter()
.fold(0, |acc, i| acc + state.get_effective_balance(*i, spec));
let total_attesting_balance: u64 = attesting_validator_indices
.iter()
.fold(0, |acc, i| acc + state.get_effective_balance(*i, spec));
if total_attesting_balance > highest_seen_balance {
highest_seen_balance = total_attesting_balance;
}
let candidate_root = WinningRoot {
shard_block_root: *shard_block_root,
attesting_validator_indices,
total_attesting_balance,
total_balance,
};
candidates.insert(*shard_block_root, candidate_root);
}
Ok(candidates
.iter()
.filter_map(|(_hash, candidate)| {
if candidate.total_attesting_balance == highest_seen_balance {
Some(candidate)
} else {
None
}
})
.min_by_key(|candidate| candidate.shard_block_root)
.ok_or_else(|| WinningRootError::NoWinningRoot)?
// TODO: avoid clone.
.clone())
}