Complete attestation_validation, bar tests
This commit is contained in:
parent
a8bfa4d733
commit
0f9482f9d1
@ -37,6 +37,7 @@ pub fn validate_attestation_for_block(
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
/*
|
||||
* Invalid::AttestationTooOld tests.
|
||||
*/
|
@ -1,42 +1,25 @@
|
||||
use super::db::stores::{BeaconBlockAtSlotError, BeaconBlockStore};
|
||||
use super::db::ClientDB;
|
||||
use super::types::AttestationData;
|
||||
use super::types::Hash256;
|
||||
use super::types::{AttestationData, BeaconState};
|
||||
use super::{Error, Invalid, Outcome};
|
||||
use std::sync::Arc;
|
||||
|
||||
/// Check that an attestation is valid with reference to some state.
|
||||
pub fn validate_attestation_data_for_state<T>(
|
||||
/// Verify that a attestation's `data.justified_block_hash` matches the local hash of the block at the
|
||||
/// attestation's `data.justified_slot`.
|
||||
///
|
||||
/// `chain_tip_block_hash` is the tip of the chain in which the justified block hash should exist
|
||||
/// locally. As Lightouse stores multiple chains locally, it is possible to have multiple blocks at
|
||||
/// the same slot. `chain_tip_block_hash` serves to restrict the lookup to a single chain, where
|
||||
/// each slot may have exactly zero or one blocks.
|
||||
pub fn validate_attestation_justified_block_hash<T>(
|
||||
data: &AttestationData,
|
||||
chain_tip_block_hash: &Hash256,
|
||||
state: &BeaconState,
|
||||
block_store: &Arc<BeaconBlockStore<T>>,
|
||||
) -> Result<Outcome, Error>
|
||||
where
|
||||
T: ClientDB + Sized,
|
||||
{
|
||||
/*
|
||||
* The attestation's `justified_slot` must be the same as the last justified slot known to this
|
||||
* client.
|
||||
*
|
||||
* In the case that an attestation references a slot _before_ the latest state transition, it
|
||||
* is acceptable for the attestation to reference the previous known `justified_slot`. If this
|
||||
* were not the case, all attestations created _prior_ to the last state recalculation would be
|
||||
* rejected if a block was justified in that state recalculation. It is both ideal and likely
|
||||
* that blocks will be justified during a state recalcuation.
|
||||
*/
|
||||
{
|
||||
let permissable_justified_slot = if data.slot >= state.latest_state_recalculation_slot {
|
||||
state.justified_slot
|
||||
} else {
|
||||
state.previous_justified_slot
|
||||
};
|
||||
verify_or!(
|
||||
data.justified_slot == permissable_justified_slot,
|
||||
reject!(Invalid::JustifiedSlotImpermissable)
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* The `justified_block_hash` in the attestation must match exactly the hash of the block at
|
||||
* that slot in the local chain.
|
||||
@ -53,28 +36,6 @@ where
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* The `shard_block_hash` in the state's `latest_crosslinks` must match either the
|
||||
* `latest_crosslink_hash` or the `shard_block_hash` on the attestation.
|
||||
*
|
||||
* TODO: figure out the reasoning behind this.
|
||||
*/
|
||||
match state.latest_crosslinks.get(data.shard as usize) {
|
||||
None => reject!(Invalid::UnknownShard),
|
||||
Some(crosslink) => {
|
||||
let local_shard_block_hash = crosslink.shard_block_hash;
|
||||
let shard_block_hash_is_permissable = {
|
||||
(local_shard_block_hash == data.latest_crosslink_hash)
|
||||
|| (local_shard_block_hash == data.shard_block_hash)
|
||||
};
|
||||
verify_or!(
|
||||
shard_block_hash_is_permissable,
|
||||
reject!(Invalid::ShardBlockHashMismatch)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
accept!()
|
||||
}
|
||||
|
||||
@ -105,3 +66,15 @@ impl From<BeaconBlockAtSlotError> for Error {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
/*
|
||||
* TODO: Implement tests.
|
||||
*
|
||||
* These tests will require the `BeaconBlock` and `BeaconBlockBody` updates, which are not
|
||||
* yet included in the code base. Adding tests now will result in duplicated work.
|
||||
*
|
||||
* https://github.com/sigp/lighthouse/issues/97
|
||||
*/
|
||||
}
|
38
beacon_chain/attestation_validation/src/justified_slot.rs
Normal file
38
beacon_chain/attestation_validation/src/justified_slot.rs
Normal file
@ -0,0 +1,38 @@
|
||||
use super::types::{AttestationData, BeaconState};
|
||||
use super::{Error, Invalid, Outcome};
|
||||
|
||||
/// Verify that an attestation's `data.justified_slot` matches the justified slot known to the
|
||||
/// `state`.
|
||||
///
|
||||
/// In the case that an attestation references a slot _before_ the latest state transition, is
|
||||
/// acceptable for the attestation to reference the previous known `justified_slot`. If this were
|
||||
/// not the case, all attestations created _prior_ to the last state recalculation would be rejected
|
||||
/// if a block was justified in that state recalculation. It is both ideal and likely that blocks
|
||||
/// will be justified during a state recalcuation.
|
||||
pub fn validate_attestation_justified_slot(
|
||||
data: &AttestationData,
|
||||
state: &BeaconState,
|
||||
) -> Result<Outcome, Error> {
|
||||
let permissable_justified_slot = if data.slot >= state.latest_state_recalculation_slot {
|
||||
state.justified_slot
|
||||
} else {
|
||||
state.previous_justified_slot
|
||||
};
|
||||
verify_or!(
|
||||
data.justified_slot == permissable_justified_slot,
|
||||
reject!(Invalid::JustifiedSlotImpermissable)
|
||||
);
|
||||
accept!()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
/*
|
||||
* TODO: Implement tests.
|
||||
*
|
||||
* These tests will require the `BeaconBlock` and `BeaconBlockBody` updates, which are not
|
||||
* yet included in the code base. Adding tests now will result in duplicated work.
|
||||
*
|
||||
* https://github.com/sigp/lighthouse/issues/97
|
||||
*/
|
||||
}
|
@ -7,12 +7,17 @@ extern crate types;
|
||||
|
||||
#[macro_use]
|
||||
mod macros;
|
||||
|
||||
mod block_inclusion;
|
||||
mod enums;
|
||||
mod validate_for_block;
|
||||
mod validate_for_state;
|
||||
mod validate_signature;
|
||||
mod justified_block;
|
||||
mod justified_slot;
|
||||
mod shard_block;
|
||||
mod signature;
|
||||
|
||||
pub use enums::{Invalid, Outcome, Error};
|
||||
pub use validate_for_block::validate_attestation_for_block;
|
||||
pub use validate_for_state::validate_attestation_data_for_state;
|
||||
pub use validate_signature::validate_attestation_signature;
|
||||
pub use block_inclusion::validate_attestation_for_block;
|
||||
pub use justified_slot::validate_attestation_justified_slot;
|
||||
pub use justified_block::validate_attestation_justified_block_hash;
|
||||
pub use signature::validate_attestation_signature;
|
||||
pub use shard_block::validate_attestation_data_shard_block_hash;
|
||||
|
46
beacon_chain/attestation_validation/src/shard_block.rs
Normal file
46
beacon_chain/attestation_validation/src/shard_block.rs
Normal file
@ -0,0 +1,46 @@
|
||||
use super::db::ClientDB;
|
||||
use super::types::{AttestationData, BeaconState};
|
||||
use super::{Error, Invalid, Outcome};
|
||||
|
||||
/// Check that an attestation is valid with reference to some state.
|
||||
pub fn validate_attestation_data_shard_block_hash<T>(
|
||||
data: &AttestationData,
|
||||
state: &BeaconState,
|
||||
) -> Result<Outcome, Error>
|
||||
where
|
||||
T: ClientDB + Sized,
|
||||
{
|
||||
/*
|
||||
* The `shard_block_hash` in the state's `latest_crosslinks` must match either the
|
||||
* `latest_crosslink_hash` or the `shard_block_hash` on the attestation.
|
||||
*
|
||||
* TODO: figure out the reasoning behind this.
|
||||
*/
|
||||
match state.latest_crosslinks.get(data.shard as usize) {
|
||||
None => reject!(Invalid::UnknownShard),
|
||||
Some(crosslink) => {
|
||||
let local_shard_block_hash = crosslink.shard_block_hash;
|
||||
let shard_block_hash_is_permissable = {
|
||||
(local_shard_block_hash == data.latest_crosslink_hash)
|
||||
|| (local_shard_block_hash == data.shard_block_hash)
|
||||
};
|
||||
verify_or!(
|
||||
shard_block_hash_is_permissable,
|
||||
reject!(Invalid::ShardBlockHashMismatch)
|
||||
);
|
||||
}
|
||||
};
|
||||
accept!()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
/*
|
||||
* TODO: Implement tests.
|
||||
*
|
||||
* These tests will require the `BeaconBlock` and `BeaconBlockBody` updates, which are not
|
||||
* yet included in the code base. Adding tests now will result in duplicated work.
|
||||
*
|
||||
* https://github.com/sigp/lighthouse/issues/97
|
||||
*/
|
||||
}
|
@ -12,7 +12,7 @@ pub const SSZ_ATTESTION_DATA_LENGTH: usize = {
|
||||
32 // justified_block_hash
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[derive(Debug, Clone, PartialEq, Default)]
|
||||
pub struct AttestationData {
|
||||
pub slot: u64,
|
||||
pub shard: u64,
|
||||
|
@ -15,7 +15,7 @@ pub const MIN_SSZ_BLOCK_LENGTH: usize = {
|
||||
};
|
||||
pub const MAX_SSZ_BLOCK_LENGTH: usize = MIN_SSZ_BLOCK_LENGTH + (1 << 24);
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
#[derive(Debug, PartialEq, Clone, Default)]
|
||||
pub struct BeaconBlock {
|
||||
pub slot: u64,
|
||||
pub randao_reveal: Hash256,
|
||||
|
0
beacon_chain/types/src/beacon_block_body.rs
Normal file
0
beacon_chain/types/src/beacon_block_body.rs
Normal file
Loading…
Reference in New Issue
Block a user