Fix issue with last_justified_block_hash

Previously we were just checking it exists in the DB. This is incorrect
because the last_justified_block_hash _must_ be in the chain referenced
by the block.

I.e., it's not OK for a block to reference a justified block in another
chain.
This commit is contained in:
Paul Hauner 2018-10-09 12:14:59 +11:00
parent f13a4fffea
commit cf9f8c1e85
No known key found for this signature in database
GPG Key ID: 303E4494BB28068C
5 changed files with 20 additions and 25 deletions

View File

@ -12,10 +12,7 @@ use super::db::{
ClientDB, ClientDB,
DBError DBError
}; };
use super::db::stores::{ use super::db::stores::ValidatorStore;
BlockStore,
ValidatorStore,
};
use super::types::{ use super::types::{
Hash256, Hash256,
}; };
@ -57,10 +54,10 @@ pub struct AttestationValidationContext<T>
pub cycle_length: u8, pub cycle_length: u8,
/// The last justified slot as per the client's view of the canonical chain. /// The last justified slot as per the client's view of the canonical chain.
pub last_justified_slot: u64, pub last_justified_slot: u64,
/// The last justified block hash as per the client's view of the canonical chain.
pub last_justified_block_hash: Hash256,
/// A vec of the hashes of the blocks preceeding the present slot. /// A vec of the hashes of the blocks preceeding the present slot.
pub parent_hashes: Arc<Vec<Hash256>>, pub parent_hashes: Arc<Vec<Hash256>>,
/// The store containing block information.
pub block_store: Arc<BlockStore<T>>,
/// The store containing validator information. /// The store containing validator information.
pub validator_store: Arc<ValidatorStore<T>>, pub validator_store: Arc<ValidatorStore<T>>,
/// A map of (slot, shard_id) to the attestation set of validation indices. /// A map of (slot, shard_id) to the attestation set of validation indices.
@ -104,6 +101,14 @@ impl<T> AttestationValidationContext<T>
return Err(AttestationValidationError::JustifiedSlotIncorrect); return Err(AttestationValidationError::JustifiedSlotIncorrect);
} }
/*
* The specified justified block hash supplied in the attestation must match our knowledge
* of the last justified block this chain.
*/
if a.justified_block_hash != self.last_justified_block_hash {
return Err(AttestationValidationError::UnknownJustifiedBlock)
}
/* /*
* There is no need to include more oblique parents hashes than there are blocks * There is no need to include more oblique parents hashes than there are blocks
* in a cycle. * in a cycle.
@ -142,13 +147,6 @@ impl<T> AttestationValidationContext<T>
return Err(AttestationValidationError::InvalidBitfieldEndBits) return Err(AttestationValidationError::InvalidBitfieldEndBits)
} }
/*
* The specified justified block hash must be known to us
*/
if !self.block_store.block_exists(&a.justified_block_hash)? {
return Err(AttestationValidationError::UnknownJustifiedBlock)
}
let signed_message = { let signed_message = {
let parent_hashes = attestation_parent_hashes( let parent_hashes = attestation_parent_hashes(
self.cycle_length, self.cycle_length,

View File

@ -72,6 +72,8 @@ pub struct BlockValidationContext<T>
pub cycle_length: u8, pub cycle_length: u8,
/// The last justified slot as per the client's view of the canonical chain. /// The last justified slot as per the client's view of the canonical chain.
pub last_justified_slot: u64, pub last_justified_slot: u64,
/// The last justified block hash as per the client's view of the canonical chain.
pub last_justified_block_hash: Hash256,
/// The last finalized slot as per the client's view of the canonical chain. /// The last finalized slot as per the client's view of the canonical chain.
pub last_finalized_slot: u64, pub last_finalized_slot: u64,
/// A vec of the hashes of the blocks preceeding the present slot. /// A vec of the hashes of the blocks preceeding the present slot.
@ -205,8 +207,8 @@ impl<T> BlockValidationContext<T>
block_slot, block_slot,
cycle_length: self.cycle_length, cycle_length: self.cycle_length,
last_justified_slot: self.last_justified_slot, last_justified_slot: self.last_justified_slot,
last_justified_block_hash: self.last_justified_block_hash,
parent_hashes: self.parent_hashes.clone(), parent_hashes: self.parent_hashes.clone(),
block_store: self.block_store.clone(),
validator_store: self.validator_store.clone(), validator_store: self.validator_store.clone(),
attester_map: self.attester_map.clone(), attester_map: self.attester_map.clone(),
}); });

View File

@ -3,10 +3,7 @@ use std::sync::Arc;
use super::db::{ use super::db::{
MemoryDB, MemoryDB,
}; };
use super::db::stores::{ use super::db::stores::ValidatorStore;
BlockStore,
ValidatorStore,
};
use super::types::{ use super::types::{
AttestationRecord, AttestationRecord,
AttesterMap, AttesterMap,
@ -30,18 +27,15 @@ use super::hashing::{
pub struct TestStore { pub struct TestStore {
pub db: Arc<MemoryDB>, pub db: Arc<MemoryDB>,
pub block: Arc<BlockStore<MemoryDB>>,
pub validator: Arc<ValidatorStore<MemoryDB>>, pub validator: Arc<ValidatorStore<MemoryDB>>,
} }
impl TestStore { impl TestStore {
pub fn new() -> Self { pub fn new() -> Self {
let db = Arc::new(MemoryDB::open()); let db = Arc::new(MemoryDB::open());
let block = Arc::new(BlockStore::new(db.clone()));
let validator = Arc::new(ValidatorStore::new(db.clone())); let validator = Arc::new(ValidatorStore::new(db.clone()));
Self { Self {
db, db,
block,
validator, validator,
} }
} }
@ -141,8 +135,6 @@ pub fn setup_attestation_validation_test(shard_id: u16, attester_count: usize)
let justified_block_hash = Hash256::from("justified_block".as_bytes()); let justified_block_hash = Hash256::from("justified_block".as_bytes());
let shard_block_hash = Hash256::from("shard_block".as_bytes()); let shard_block_hash = Hash256::from("shard_block".as_bytes());
stores.block.put_serialized_block(&justified_block_hash.as_ref(), &[42]).unwrap();
let attestation_slot = block_slot - 1; let attestation_slot = block_slot - 1;
let mut keypairs = vec![]; let mut keypairs = vec![];
@ -167,8 +159,8 @@ pub fn setup_attestation_validation_test(shard_id: u16, attester_count: usize)
block_slot, block_slot,
cycle_length, cycle_length,
last_justified_slot, last_justified_slot,
last_justified_block_hash: justified_block_hash,
parent_hashes: parent_hashes.clone(), parent_hashes: parent_hashes.clone(),
block_store: stores.block.clone(),
validator_store: stores.validator.clone(), validator_store: stores.validator.clone(),
attester_map: Arc::new(attester_map), attester_map: Arc::new(attester_map),
}; };

View File

@ -41,6 +41,7 @@ pub struct BlockTestParams {
pub parent_proposer_index: usize, pub parent_proposer_index: usize,
pub validation_context_slot: u64, pub validation_context_slot: u64,
pub validation_context_justified_slot: u64, pub validation_context_justified_slot: u64,
pub validation_context_justified_block_hash: Hash256,
pub validation_context_finalized_slot: u64, pub validation_context_finalized_slot: u64,
} }
@ -93,7 +94,6 @@ pub fn setup_block_validation_scenario(params: &BlockTestParams)
let shard_block_hash = Hash256::from("shard_block_hash".as_bytes()); let shard_block_hash = Hash256::from("shard_block_hash".as_bytes());
stores.pow_chain.put_block_hash(pow_chain_ref.as_ref()).unwrap(); stores.pow_chain.put_block_hash(pow_chain_ref.as_ref()).unwrap();
stores.block.put_serialized_block(justified_block_hash.as_ref(), &vec![42]).unwrap();
/* /*
* Generate a minimum viable parent block and store it in the database. * Generate a minimum viable parent block and store it in the database.
@ -205,6 +205,7 @@ pub fn run_block_validation_scenario<F>(
present_slot: params.validation_context_slot, present_slot: params.validation_context_slot,
cycle_length: params.cycle_length, cycle_length: params.cycle_length,
last_justified_slot: params.validation_context_justified_slot, last_justified_slot: params.validation_context_justified_slot,
last_justified_block_hash: params.validation_context_justified_block_hash,
last_finalized_slot: params.validation_context_finalized_slot, last_finalized_slot: params.validation_context_finalized_slot,
parent_hashes: Arc::new(parent_hashes), parent_hashes: Arc::new(parent_hashes),
proposer_map: Arc::new(proposer_map), proposer_map: Arc::new(proposer_map),

View File

@ -34,6 +34,7 @@ fn get_simple_params() -> BlockTestParams {
let validation_context_slot = block_slot; let validation_context_slot = block_slot;
let validation_context_justified_slot = attestations_justified_slot; let validation_context_justified_slot = attestations_justified_slot;
let validation_context_justified_block_hash = Hash256::from("justified_hash".as_bytes());
let validation_context_finalized_slot = 0; let validation_context_finalized_slot = 0;
BlockTestParams { BlockTestParams {
@ -47,6 +48,7 @@ fn get_simple_params() -> BlockTestParams {
attestations_justified_slot, attestations_justified_slot,
validation_context_slot, validation_context_slot,
validation_context_justified_slot, validation_context_justified_slot,
validation_context_justified_block_hash,
validation_context_finalized_slot, validation_context_finalized_slot,
} }
} }