Update beacon_block_store for new block struct
This commit is contained in:
parent
b95395d1e1
commit
f140e2938f
@ -1,9 +1,8 @@
|
|||||||
extern crate ssz_helpers;
|
|
||||||
|
|
||||||
use self::ssz_helpers::ssz_beacon_block::SszBeaconBlock;
|
|
||||||
use super::BLOCKS_DB_COLUMN as DB_COLUMN;
|
use super::BLOCKS_DB_COLUMN as DB_COLUMN;
|
||||||
use super::{ClientDB, DBError};
|
use super::{ClientDB, DBError};
|
||||||
|
use ssz::{Decodable, DecodeError};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
use types::Hash256;
|
||||||
|
|
||||||
type BeaconBlockHash = Vec<u8>;
|
type BeaconBlockHash = Vec<u8>;
|
||||||
type BeaconBlockSsz = Vec<u8>;
|
type BeaconBlockSsz = Vec<u8>;
|
||||||
@ -60,21 +59,29 @@ impl<T: ClientDB> BeaconBlockStore<T> {
|
|||||||
match self.get_serialized_block(head_hash)? {
|
match self.get_serialized_block(head_hash)? {
|
||||||
None => Err(BeaconBlockAtSlotError::UnknownBeaconBlock),
|
None => Err(BeaconBlockAtSlotError::UnknownBeaconBlock),
|
||||||
Some(ssz) => {
|
Some(ssz) => {
|
||||||
let block = SszBeaconBlock::from_slice(&ssz)
|
let (retrieved_slot, parent_hash) = slot_and_parent_from_block_ssz(&ssz, 0)
|
||||||
.map_err(|_| BeaconBlockAtSlotError::InvalidBeaconBlock)?;
|
.map_err(|_| BeaconBlockAtSlotError::InvalidBeaconBlock)?;
|
||||||
match block.slot() {
|
match retrieved_slot {
|
||||||
s if s == slot => Ok(Some((head_hash.to_vec(), ssz.to_vec()))),
|
s if s == slot => Ok(Some((head_hash.to_vec(), ssz.to_vec()))),
|
||||||
s if s < slot => Ok(None),
|
s if s < slot => Ok(None),
|
||||||
_ => match block.parent_hash() {
|
_ => self.block_at_slot(&parent_hash, slot),
|
||||||
Some(parent_hash) => self.block_at_slot(parent_hash, slot),
|
|
||||||
None => Err(BeaconBlockAtSlotError::UnknownBeaconBlock),
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Read `block.slot` and `block.parent_root` from a SSZ-encoded block bytes.
|
||||||
|
///
|
||||||
|
/// Assumes the block starts at byte `i`.
|
||||||
|
fn slot_and_parent_from_block_ssz(ssz: &[u8], i: usize) -> Result<(u64, Hash256), DecodeError> {
|
||||||
|
// Assuming the slot is the first field on a block.
|
||||||
|
let (slot, i) = u64::ssz_decode(&ssz, i)?;
|
||||||
|
// Assuming the parent has is the second field on a block.
|
||||||
|
let (parent_root, _) = Hash256::ssz_decode(&ssz, i)?;
|
||||||
|
Ok((slot, parent_root))
|
||||||
|
}
|
||||||
|
|
||||||
impl From<DBError> for BeaconBlockAtSlotError {
|
impl From<DBError> for BeaconBlockAtSlotError {
|
||||||
fn from(e: DBError) -> Self {
|
fn from(e: DBError) -> Self {
|
||||||
BeaconBlockAtSlotError::DBError(e.message)
|
BeaconBlockAtSlotError::DBError(e.message)
|
||||||
@ -83,19 +90,17 @@ impl From<DBError> for BeaconBlockAtSlotError {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
extern crate ssz;
|
|
||||||
extern crate types;
|
|
||||||
|
|
||||||
use self::ssz::SszStream;
|
|
||||||
use self::types::attestation::Attestation;
|
|
||||||
use self::types::beacon_block::BeaconBlock;
|
|
||||||
use self::types::Hash256;
|
|
||||||
|
|
||||||
use super::super::super::MemoryDB;
|
use super::super::super::MemoryDB;
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::thread;
|
use std::thread;
|
||||||
|
|
||||||
|
use ssz::ssz_encode;
|
||||||
|
use types::test_utils::{SeedableRng, TestRandom, XorShiftRng};
|
||||||
|
use types::BeaconBlock;
|
||||||
|
use types::Hash256;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_put_serialized_block() {
|
fn test_put_serialized_block() {
|
||||||
let db = Arc::new(MemoryDB::open());
|
let db = Arc::new(MemoryDB::open());
|
||||||
@ -247,60 +252,58 @@ mod tests {
|
|||||||
fn test_block_at_slot() {
|
fn test_block_at_slot() {
|
||||||
let db = Arc::new(MemoryDB::open());
|
let db = Arc::new(MemoryDB::open());
|
||||||
let bs = Arc::new(BeaconBlockStore::new(db.clone()));
|
let bs = Arc::new(BeaconBlockStore::new(db.clone()));
|
||||||
|
let mut rng = XorShiftRng::from_seed([42; 16]);
|
||||||
|
|
||||||
let blocks = (0..5).into_iter().map(|_| {
|
// Specify test block parameters.
|
||||||
let mut block = BeaconBlock::zero();
|
|
||||||
let ar = Attestation::zero();
|
|
||||||
block.attestations.push(ar);
|
|
||||||
block
|
|
||||||
});
|
|
||||||
|
|
||||||
let hashes = [
|
let hashes = [
|
||||||
Hash256::from("zero".as_bytes()),
|
Hash256::from(&[0; 32][..]),
|
||||||
Hash256::from("one".as_bytes()),
|
Hash256::from(&[1; 32][..]),
|
||||||
Hash256::from("two".as_bytes()),
|
Hash256::from(&[2; 32][..]),
|
||||||
Hash256::from("three".as_bytes()),
|
Hash256::from(&[3; 32][..]),
|
||||||
Hash256::from("four".as_bytes()),
|
Hash256::from(&[4; 32][..]),
|
||||||
];
|
];
|
||||||
|
|
||||||
let parent_hashes = [
|
let parent_hashes = [
|
||||||
Hash256::from("genesis".as_bytes()),
|
Hash256::from(&[255; 32][..]), // Genesis block.
|
||||||
Hash256::from("zero".as_bytes()),
|
Hash256::from(&[0; 32][..]),
|
||||||
Hash256::from("one".as_bytes()),
|
Hash256::from(&[1; 32][..]),
|
||||||
Hash256::from("two".as_bytes()),
|
Hash256::from(&[2; 32][..]),
|
||||||
Hash256::from("three".as_bytes()),
|
Hash256::from(&[3; 32][..]),
|
||||||
];
|
];
|
||||||
|
|
||||||
let slots = [0, 1, 3, 4, 5];
|
let slots = [0, 1, 3, 4, 5];
|
||||||
|
|
||||||
for (i, mut block) in blocks.enumerate() {
|
// Generate a vec of random blocks and store them in the DB.
|
||||||
block.ancestor_hashes.push(parent_hashes[i]);
|
let block_count = 5;
|
||||||
|
let mut blocks: Vec<BeaconBlock> = Vec::with_capacity(5);
|
||||||
|
for i in 0..block_count {
|
||||||
|
let mut block = BeaconBlock::random_for_test(&mut rng);
|
||||||
|
|
||||||
|
block.parent_root = parent_hashes[i];
|
||||||
block.slot = slots[i];
|
block.slot = slots[i];
|
||||||
let mut s = SszStream::new();
|
|
||||||
s.append(&block);
|
let ssz = ssz_encode(&block);
|
||||||
let ssz = s.drain();
|
|
||||||
db.put(DB_COLUMN, &hashes[i].to_vec(), &ssz).unwrap();
|
db.put(DB_COLUMN, &hashes[i].to_vec(), &ssz).unwrap();
|
||||||
|
|
||||||
|
// Ensure the slot and parent_root decoding fn works correctly.
|
||||||
|
let (decoded_slot, decoded_parent_root) =
|
||||||
|
slot_and_parent_from_block_ssz(&ssz, 0).unwrap();
|
||||||
|
assert_eq!(decoded_slot, block.slot);
|
||||||
|
assert_eq!(decoded_parent_root, block.parent_root);
|
||||||
|
|
||||||
|
blocks.push(block);
|
||||||
}
|
}
|
||||||
|
|
||||||
let tuple = bs.block_at_slot(&hashes[4], 5).unwrap().unwrap();
|
// Test that certain slots can be reached from certain hashes.
|
||||||
let block = SszBeaconBlock::from_slice(&tuple.1).unwrap();
|
let test_cases = vec![(4, 4), (4, 3), (4, 2), (4, 1), (4, 0)];
|
||||||
assert_eq!(block.slot(), 5);
|
for (hashes_index, slot_index) in test_cases {
|
||||||
assert_eq!(tuple.0, hashes[4].to_vec());
|
let (matched_block_hash, matched_block_ssz) = bs
|
||||||
|
.block_at_slot(&hashes[hashes_index], slots[slot_index])
|
||||||
let tuple = bs.block_at_slot(&hashes[4], 4).unwrap().unwrap();
|
.unwrap()
|
||||||
let block = SszBeaconBlock::from_slice(&tuple.1).unwrap();
|
.unwrap();
|
||||||
assert_eq!(block.slot(), 4);
|
let (retrieved_slot, _) =
|
||||||
assert_eq!(tuple.0, hashes[3].to_vec());
|
slot_and_parent_from_block_ssz(&matched_block_ssz, 0).unwrap();
|
||||||
|
assert_eq!(retrieved_slot, slots[slot_index]);
|
||||||
let tuple = bs.block_at_slot(&hashes[4], 3).unwrap().unwrap();
|
assert_eq!(matched_block_hash, hashes[slot_index].to_vec());
|
||||||
let block = SszBeaconBlock::from_slice(&tuple.1).unwrap();
|
}
|
||||||
assert_eq!(block.slot(), 3);
|
|
||||||
assert_eq!(tuple.0, hashes[2].to_vec());
|
|
||||||
|
|
||||||
let tuple = bs.block_at_slot(&hashes[4], 0).unwrap().unwrap();
|
|
||||||
let block = SszBeaconBlock::from_slice(&tuple.1).unwrap();
|
|
||||||
assert_eq!(block.slot(), 0);
|
|
||||||
assert_eq!(tuple.0, hashes[0].to_vec());
|
|
||||||
|
|
||||||
let ssz = bs.block_at_slot(&hashes[4], 2).unwrap();
|
let ssz = bs.block_at_slot(&hashes[4], 2).unwrap();
|
||||||
assert_eq!(ssz, None);
|
assert_eq!(ssz, None);
|
||||||
|
Loading…
Reference in New Issue
Block a user