Refactor block val. into "BlockValidationContext"
This commit is contained in:
parent
bc27be147f
commit
0b99951bf8
@ -5,7 +5,7 @@ use self::test::Bencher;
|
||||
use std::sync::Arc;
|
||||
|
||||
use super::{
|
||||
validate_ssz_block,
|
||||
BlockValidationContext,
|
||||
AttesterMap,
|
||||
ProposerMap,
|
||||
};
|
||||
@ -50,17 +50,18 @@ fn bench_block_validation_scenario<F>(
|
||||
let proposer_map = Arc::new(proposer_map);
|
||||
let attester_map = Arc::new(attester_map);
|
||||
b.iter(|| {
|
||||
validate_ssz_block(
|
||||
&ssz_block,
|
||||
validation_slot,
|
||||
params.cycle_length,
|
||||
validation_last_justified_slot,
|
||||
&parent_hashes.clone(),
|
||||
&proposer_map.clone(),
|
||||
&attester_map.clone(),
|
||||
&stores.block.clone(),
|
||||
&stores.validator.clone(),
|
||||
&stores.pow_chain.clone())
|
||||
let context = BlockValidationContext {
|
||||
present_slot: validation_slot,
|
||||
cycle_length: params.cycle_length,
|
||||
last_justified_slot: validation_last_justified_slot,
|
||||
parent_hashes: parent_hashes.clone(),
|
||||
proposer_map: proposer_map.clone(),
|
||||
attester_map: attester_map.clone(),
|
||||
block_store: stores.block.clone(),
|
||||
validator_store: stores.validator.clone(),
|
||||
pow_store: stores.pow_chain.clone()
|
||||
};
|
||||
context.validate_ssz_block(&ssz_block)
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,7 @@ use super::common::maps::{
|
||||
ProposerMap,
|
||||
};
|
||||
pub use self::validate_ssz_block::{
|
||||
validate_ssz_block,
|
||||
BlockValidationContext,
|
||||
SszBlockValidationError,
|
||||
BlockStatus,
|
||||
};
|
||||
|
@ -5,7 +5,7 @@ use self::ssz::{
|
||||
};
|
||||
use std::sync::Arc;
|
||||
use super::{
|
||||
validate_ssz_block,
|
||||
BlockValidationContext,
|
||||
SszBlockValidationError,
|
||||
BlockStatus,
|
||||
AttesterMap,
|
||||
@ -101,21 +101,7 @@ pub fn setup_block_validation_scenario(params: &TestParams)
|
||||
proposer_map.insert(block_slot, validator_index);
|
||||
proposer_map
|
||||
};
|
||||
/*
|
||||
let attestation_slot = block_slot - 1;
|
||||
let (attester_map, attestations, _keypairs) =
|
||||
generate_attestations_for_slot(
|
||||
attestation_slot,
|
||||
block_slot,
|
||||
shards_per_slot,
|
||||
validators_per_shard,
|
||||
cycle_length,
|
||||
&parent_hashes,
|
||||
&Hash256::from("shard_hash".as_bytes()),
|
||||
&justified_block_hash,
|
||||
attestations_justified_slot,
|
||||
&stores);
|
||||
*/
|
||||
|
||||
let (attester_map, attestations, _keypairs) = {
|
||||
let mut i = 0;
|
||||
let attestation_slot = block_slot - 1;
|
||||
@ -244,17 +230,18 @@ pub fn run_block_validation_scenario<F>(
|
||||
let ssz_block = SszBlock::from_slice(&ssz_bytes[..])
|
||||
.unwrap();
|
||||
|
||||
validate_ssz_block(
|
||||
&ssz_block,
|
||||
validation_slot,
|
||||
params.cycle_length,
|
||||
validation_last_justified_slot,
|
||||
&Arc::new(parent_hashes),
|
||||
&Arc::new(proposer_map),
|
||||
&Arc::new(attester_map),
|
||||
&stores.block.clone(),
|
||||
&stores.validator.clone(),
|
||||
&stores.pow_chain.clone())
|
||||
let context = BlockValidationContext {
|
||||
present_slot: validation_slot,
|
||||
cycle_length: params.cycle_length,
|
||||
last_justified_slot: validation_last_justified_slot,
|
||||
parent_hashes: Arc::new(parent_hashes),
|
||||
proposer_map: Arc::new(proposer_map),
|
||||
attester_map: Arc::new(attester_map),
|
||||
block_store: stores.block.clone(),
|
||||
validator_store: stores.validator.clone(),
|
||||
pow_store: stores.pow_chain.clone()
|
||||
};
|
||||
context.validate_ssz_block(&ssz_block)
|
||||
}
|
||||
|
||||
fn get_simple_params() -> TestParams {
|
||||
|
@ -60,43 +60,61 @@ pub enum SszBlockValidationError {
|
||||
DatabaseError(String),
|
||||
}
|
||||
|
||||
/// Validate some SszBlock. An SszBlock varies from a Block in that is a read-only structure
|
||||
/// that reads directly from encoded SSZ.
|
||||
///
|
||||
/// The reason to validate an SzzBlock is to avoid decoding it in its entirety if there is
|
||||
/// a suspicion that the block might be invalid. Such a suspicion should be applied to
|
||||
/// all blocks coming from the network.
|
||||
///
|
||||
/// Of course, this function will only be more efficient if a block is already serialized.
|
||||
/// Serializing a complete block and then validating with this function will be less
|
||||
/// efficient than just validating the original block.
|
||||
///
|
||||
/// This function will determine if the block is new, already known or invalid (either
|
||||
/// intrinsically or due to some application error.)
|
||||
///
|
||||
/// Note: this function does not implement randao_reveal checking as it is not in the
|
||||
/// specification.
|
||||
#[allow(dead_code)]
|
||||
pub fn validate_ssz_block<T>(b: &SszBlock,
|
||||
expected_slot: u64,
|
||||
cycle_length: u8,
|
||||
last_justified_slot: u64,
|
||||
parent_hashes: &Arc<Vec<Hash256>>,
|
||||
proposer_map: &Arc<ProposerMap>,
|
||||
attester_map: &Arc<AttesterMap>,
|
||||
block_store: &Arc<BlockStore<T>>,
|
||||
validator_store: &Arc<ValidatorStore<T>>,
|
||||
pow_store: &Arc<PoWChainStore<T>>)
|
||||
-> Result<(BlockStatus, Option<Block>), SszBlockValidationError>
|
||||
/// The context against which a block should be validated.
|
||||
pub struct BlockValidationContext<T>
|
||||
where T: ClientDB + Sized
|
||||
{
|
||||
/// The slot as determined by the system time.
|
||||
pub present_slot: u64,
|
||||
/// The cycle_length as determined by the chain configuration.
|
||||
pub cycle_length: u8,
|
||||
/// The last justified slot as per the client's view of the canonical chain.
|
||||
pub last_justified_slot: u64,
|
||||
/// A vec of the hashes of the blocks preceeding the present slot.
|
||||
pub parent_hashes: Arc<Vec<Hash256>>,
|
||||
/// A map of slots to a block proposer validation index.
|
||||
pub proposer_map: Arc<ProposerMap>,
|
||||
/// A map of (slot, shard_id) to the attestation set of validation indices.
|
||||
pub attester_map: Arc<AttesterMap>,
|
||||
/// The store containing block information.
|
||||
pub block_store: Arc<BlockStore<T>>,
|
||||
/// The store containing validator information.
|
||||
pub validator_store: Arc<ValidatorStore<T>>,
|
||||
/// The store containing information about the proof-of-work chain.
|
||||
pub pow_store: Arc<PoWChainStore<T>>,
|
||||
}
|
||||
|
||||
impl<T> BlockValidationContext<T>
|
||||
where T: ClientDB
|
||||
{
|
||||
/// Validate some SszBlock against a block validation context. An SszBlock varies from a Block in
|
||||
/// that is a read-only structure that reads directly from encoded SSZ.
|
||||
///
|
||||
/// The reason to validate an SzzBlock is to avoid decoding it in its entirety if there is
|
||||
/// a suspicion that the block might be invalid. Such a suspicion should be applied to
|
||||
/// all blocks coming from the network.
|
||||
///
|
||||
/// Of course, this function will only be more efficient if a block is already serialized.
|
||||
/// Serializing a complete block and then validating with this function will be less
|
||||
/// efficient than just validating the original block.
|
||||
///
|
||||
/// This function will determine if the block is new, already known or invalid (either
|
||||
/// intrinsically or due to some application error.)
|
||||
///
|
||||
/// Note: this function does not implement randao_reveal checking as it is not in the
|
||||
/// specification.
|
||||
#[allow(dead_code)]
|
||||
pub fn validate_ssz_block(&self, b: &SszBlock)
|
||||
-> Result<(BlockStatus, Option<Block>), SszBlockValidationError>
|
||||
where T: ClientDB + Sized
|
||||
{
|
||||
|
||||
/*
|
||||
* If the block slot corresponds to a slot in the future (according to the local time),
|
||||
* drop it.
|
||||
*/
|
||||
let block_slot = b.slot_number();
|
||||
if block_slot > expected_slot {
|
||||
if block_slot > self.present_slot {
|
||||
return Err(SszBlockValidationError::FutureSlot);
|
||||
}
|
||||
|
||||
@ -104,7 +122,7 @@ pub fn validate_ssz_block<T>(b: &SszBlock,
|
||||
* If this block is already known, return immediately.
|
||||
*/
|
||||
let block_hash = &b.block_hash();
|
||||
if block_store.block_exists(&block_hash)? {
|
||||
if self.block_store.block_exists(&block_hash)? {
|
||||
return Ok((BlockStatus::KnownBlock, None));
|
||||
}
|
||||
|
||||
@ -118,7 +136,7 @@ pub fn validate_ssz_block<T>(b: &SszBlock,
|
||||
* it means "sufficienty deep in the canonical PoW chain".
|
||||
*/
|
||||
let pow_chain_ref = b.pow_chain_ref();
|
||||
if !pow_store.block_hash_exists(b.pow_chain_ref())? {
|
||||
if !self.pow_store.block_hash_exists(b.pow_chain_ref())? {
|
||||
return Err(SszBlockValidationError::UnknownPoWChainRef);
|
||||
}
|
||||
|
||||
@ -146,12 +164,12 @@ pub fn validate_ssz_block<T>(b: &SszBlock,
|
||||
let attestation_voters = validate_attestation(
|
||||
&first_attestation,
|
||||
block_slot,
|
||||
cycle_length,
|
||||
last_justified_slot,
|
||||
&parent_hashes,
|
||||
&block_store,
|
||||
&validator_store,
|
||||
&attester_map)?;
|
||||
self.cycle_length,
|
||||
self.last_justified_slot,
|
||||
&self.parent_hashes,
|
||||
&self.block_store,
|
||||
&self.validator_store,
|
||||
&self.attester_map)?;
|
||||
|
||||
/*
|
||||
* If the set of voters is None, the attestation was invalid.
|
||||
@ -163,7 +181,7 @@ pub fn validate_ssz_block<T>(b: &SszBlock,
|
||||
/*
|
||||
* Read the proposer from the map of slot -> validator index.
|
||||
*/
|
||||
let proposer = proposer_map.get(&block_slot)
|
||||
let proposer = self.proposer_map.get(&block_slot)
|
||||
.ok_or(SszBlockValidationError::BadProposerMap)?;
|
||||
|
||||
/*
|
||||
@ -222,12 +240,12 @@ pub fn validate_ssz_block<T>(b: &SszBlock,
|
||||
let result = validate_attestation(
|
||||
&attestation,
|
||||
block_slot,
|
||||
cycle_length,
|
||||
last_justified_slot,
|
||||
&parent_hashes,
|
||||
&block_store,
|
||||
&validator_store,
|
||||
&attester_map);
|
||||
self.cycle_length,
|
||||
self.last_justified_slot,
|
||||
&self.parent_hashes,
|
||||
&self.block_store,
|
||||
&self.validator_store,
|
||||
&self.attester_map);
|
||||
match result {
|
||||
/*
|
||||
* Attestation validation failed with some error.
|
||||
@ -276,7 +294,7 @@ pub fn validate_ssz_block<T>(b: &SszBlock,
|
||||
* new block in the canonical chain. Otherwise, it's a new block in a fork chain.
|
||||
*/
|
||||
let parent_hash = b.parent_hash();
|
||||
let status = if block_store.block_exists_in_canonical_chain(&parent_hash)? {
|
||||
let status = if self.block_store.block_exists_in_canonical_chain(&parent_hash)? {
|
||||
BlockStatus::NewBlockInCanonicalChain
|
||||
} else {
|
||||
BlockStatus::NewBlockInForkChain
|
||||
@ -291,6 +309,7 @@ pub fn validate_ssz_block<T>(b: &SszBlock,
|
||||
crystallized_state_root: Hash256::from(b.cry_state_root()),
|
||||
};
|
||||
Ok((status, Some(block)))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<DBError> for SszBlockValidationError {
|
||||
|
Loading…
Reference in New Issue
Block a user