Implement new BeaconStateTypes trait in types

This commit is contained in:
Paul Hauner
2019-05-08 13:08:37 +10:00
parent 009d05cafd
commit 5ba069c774
52 changed files with 323 additions and 144 deletions

View File

@@ -0,0 +1,70 @@
use super::*;
// use cached_tree_hash::CachedTreeHash;
// use ssz::{Decodable, Encodable};
// use tree_hash::TreeHash;
impl<T, N: Unsigned> tree_hash::TreeHash for FixedLenVec<T, N>
where
T: tree_hash::TreeHash,
{
fn tree_hash_type() -> tree_hash::TreeHashType {
tree_hash::TreeHashType::Vector
}
fn tree_hash_packed_encoding(&self) -> Vec<u8> {
unreachable!("Vector should never be packed.")
}
fn tree_hash_packing_factor() -> usize {
unreachable!("Vector should never be packed.")
}
fn tree_hash_root(&self) -> Vec<u8> {
tree_hash::impls::vec_tree_hash_root(&self.vec)
}
}
impl<T, N: Unsigned> cached_tree_hash::CachedTreeHash for FixedLenVec<T, N>
where
T: cached_tree_hash::CachedTreeHash + tree_hash::TreeHash,
{
fn new_tree_hash_cache(
&self,
depth: usize,
) -> Result<cached_tree_hash::TreeHashCache, cached_tree_hash::Error> {
let (cache, _overlay) = cached_tree_hash::vec::new_tree_hash_cache(&self.vec, depth)?;
Ok(cache)
}
fn tree_hash_cache_schema(&self, depth: usize) -> cached_tree_hash::BTreeSchema {
cached_tree_hash::vec::produce_schema(&self.vec, depth)
}
fn update_tree_hash_cache(
&self,
cache: &mut cached_tree_hash::TreeHashCache,
) -> Result<(), cached_tree_hash::Error> {
cached_tree_hash::vec::update_tree_hash_cache(&self.vec, cache)?;
Ok(())
}
}
impl<T, N: Unsigned> ssz::Encodable for FixedLenVec<T, N>
where
T: ssz::Encodable,
{
fn ssz_append(&self, s: &mut ssz::SszStream) {
s.append_vec(&self.vec)
}
}
impl<T, N: Unsigned> ssz::Decodable for FixedLenVec<T, N>
where
T: ssz::Decodable + Default,
{
fn ssz_decode(bytes: &[u8], index: usize) -> Result<(Self, usize), ssz::DecodeError> {
ssz::decode_ssz_list(bytes, index).and_then(|(vec, i)| Ok((vec.into(), i)))
}
}

View File

@@ -0,0 +1,111 @@
use serde_derive::{Deserialize, Serialize};
use std::marker::PhantomData;
use std::ops::{Index, IndexMut};
use std::slice::SliceIndex;
use typenum::Unsigned;
pub use typenum;
mod impls;
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
pub struct FixedLenVec<T, N>
where
N: Unsigned,
{
vec: Vec<T>,
_phantom: PhantomData<N>,
}
impl<T: Default, N: Unsigned> From<Vec<T>> for FixedLenVec<T, N> {
fn from(mut vec: Vec<T>) -> Self {
dbg!(Self::capacity());
vec.resize_with(Self::capacity(), Default::default);
Self {
vec,
_phantom: PhantomData,
}
}
}
impl<T, N: Unsigned> Into<Vec<T>> for FixedLenVec<T, N> {
fn into(self) -> Vec<T> {
self.vec
}
}
impl<T, N: Unsigned> Default for FixedLenVec<T, N> {
fn default() -> Self {
Self {
vec: Vec::default(),
_phantom: PhantomData,
}
}
}
impl<T, N: Unsigned> FixedLenVec<T, N> {
pub fn capacity() -> usize {
N::to_usize()
}
}
impl<T, N: Unsigned, I: SliceIndex<[T]>> Index<I> for FixedLenVec<T, N> {
type Output = I::Output;
#[inline]
fn index(&self, index: I) -> &Self::Output {
Index::index(&self.vec, index)
}
}
impl<T, N: Unsigned, I: SliceIndex<[T]>> IndexMut<I> for FixedLenVec<T, N> {
#[inline]
fn index_mut(&mut self, index: I) -> &mut Self::Output {
IndexMut::index_mut(&mut self.vec, index)
}
}
#[cfg(test)]
mod test {
use super::*;
use typenum::*;
#[test]
fn indexing() {
let vec = vec![1, 2];
let mut fixed: FixedLenVec<u64, U8192> = vec.clone().into();
assert_eq!(fixed[0], 1);
assert_eq!(&fixed[0..1], &vec[0..1]);
assert_eq!((&fixed[..]).len(), 8192);
fixed[1] = 3;
assert_eq!(fixed[1], 3);
}
#[test]
fn length() {
let vec = vec![42; 5];
let fixed: FixedLenVec<u64, U4> = FixedLenVec::from(vec.clone());
assert_eq!(&fixed[..], &vec[0..4]);
let vec = vec![42; 3];
let fixed: FixedLenVec<u64, U4> = FixedLenVec::from(vec.clone());
assert_eq!(&fixed[0..3], &vec[..]);
assert_eq!(&fixed[..], &vec![42, 42, 42, 0][..]);
let vec = vec![];
let fixed: FixedLenVec<u64, U4> = FixedLenVec::from(vec.clone());
assert_eq!(&fixed[..], &vec![0, 0, 0, 0][..]);
}
}
#[cfg(test)]
mod tests {
#[test]
fn it_works() {
assert_eq!(2 + 2, 4);
}
}