mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-03 00:31:50 +00:00
Add restrictions to RuntimeVariableList api
This commit is contained in:
@@ -266,7 +266,6 @@ impl<E: EthSpec> BlobSidecar<E> {
|
||||
|
||||
pub type BlobSidecarList<E> = RuntimeVariableList<Arc<BlobSidecar<E>>>;
|
||||
/// Alias for a non length-constrained list of `BlobSidecar`s.
|
||||
pub type BlobSidecarVec<E> = Vec<Arc<BlobSidecar<E>>>;
|
||||
pub type FixedBlobSidecarList<E> = RuntimeFixedList<Option<Arc<BlobSidecar<E>>>>;
|
||||
pub type BlobsList<E> = VariableList<Blob<E>, <E as EthSpec>::MaxBlobCommitmentsPerBlock>;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use crate::beacon_block_body::{KzgCommitments, BLOB_KZG_COMMITMENTS_INDEX};
|
||||
use crate::test_utils::TestRandom;
|
||||
use crate::{BeaconBlockHeader, Epoch, EthSpec, Hash256, KzgProofs, SignedBeaconBlockHeader, Slot};
|
||||
use crate::{BeaconStateError, ChainSpec};
|
||||
use crate::BeaconStateError;
|
||||
use crate::{BeaconBlockHeader, EthSpec, Hash256, KzgProofs, SignedBeaconBlockHeader, Slot};
|
||||
use bls::Signature;
|
||||
use derivative::Derivative;
|
||||
use kzg::Error as KzgError;
|
||||
@@ -11,7 +11,6 @@ use safe_arith::ArithError;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ssz::Encode;
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use ssz_types::typenum::Unsigned;
|
||||
use ssz_types::Error as SszError;
|
||||
use ssz_types::{FixedVector, VariableList};
|
||||
use std::hash::Hash;
|
||||
|
||||
@@ -2,7 +2,7 @@ use derivative::Derivative;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ssz::Decode;
|
||||
use ssz_types::Error;
|
||||
use std::ops::{Deref, DerefMut, Index, IndexMut};
|
||||
use std::ops::{Deref, Index, IndexMut};
|
||||
use std::slice::SliceIndex;
|
||||
|
||||
/// Emulates a SSZ `List`.
|
||||
@@ -41,8 +41,10 @@ use std::slice::SliceIndex;
|
||||
#[serde(transparent)]
|
||||
pub struct RuntimeVariableList<T> {
|
||||
vec: Vec<T>,
|
||||
/// A `None` here indicates an uninitialized `Self`.
|
||||
/// No mutating operation will be allowed until `max_len` is Some
|
||||
#[serde(skip)]
|
||||
max_len: usize,
|
||||
max_len: Option<usize>,
|
||||
}
|
||||
|
||||
impl<T> RuntimeVariableList<T> {
|
||||
@@ -50,7 +52,10 @@ impl<T> RuntimeVariableList<T> {
|
||||
/// `Err(OutOfBounds { .. })`.
|
||||
pub fn new(vec: Vec<T>, max_len: usize) -> Result<Self, Error> {
|
||||
if vec.len() <= max_len {
|
||||
Ok(Self { vec, max_len })
|
||||
Ok(Self {
|
||||
vec,
|
||||
max_len: Some(max_len),
|
||||
})
|
||||
} else {
|
||||
Err(Error::OutOfBounds {
|
||||
i: vec.len(),
|
||||
@@ -62,14 +67,17 @@ impl<T> RuntimeVariableList<T> {
|
||||
pub fn from_vec(mut vec: Vec<T>, max_len: usize) -> Self {
|
||||
vec.truncate(max_len);
|
||||
|
||||
Self { vec, max_len }
|
||||
Self {
|
||||
vec,
|
||||
max_len: Some(max_len),
|
||||
}
|
||||
}
|
||||
|
||||
/// Create an empty list.
|
||||
pub fn empty(max_len: usize) -> Self {
|
||||
Self {
|
||||
vec: vec![],
|
||||
max_len,
|
||||
max_len: Some(max_len),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,6 +85,28 @@ impl<T> RuntimeVariableList<T> {
|
||||
self.vec.as_slice()
|
||||
}
|
||||
|
||||
pub fn as_mut_slice(&mut self) -> Option<&mut [T]> {
|
||||
if self.max_len.is_none() {
|
||||
return None;
|
||||
};
|
||||
Some(self.vec.as_mut_slice())
|
||||
}
|
||||
|
||||
/// Returns an instance of `Self` with max_len = None.
|
||||
///
|
||||
/// No mutating operation can be performed on an uninitialized instance
|
||||
/// without first setting max_len.
|
||||
pub fn empty_uninitialized() -> Self {
|
||||
Self {
|
||||
vec: vec![],
|
||||
max_len: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_max_len(&mut self, max_len: usize) {
|
||||
self.max_len = Some(max_len);
|
||||
}
|
||||
|
||||
/// Returns the number of values presently in `self`.
|
||||
pub fn len(&self) -> usize {
|
||||
self.vec.len()
|
||||
@@ -88,7 +118,9 @@ impl<T> RuntimeVariableList<T> {
|
||||
}
|
||||
|
||||
/// Returns the type-level maximum length.
|
||||
pub fn max_len(&self) -> usize {
|
||||
///
|
||||
/// Returns `None` if self is uninitialized with a max_len.
|
||||
pub fn max_len(&self) -> Option<usize> {
|
||||
self.max_len
|
||||
}
|
||||
|
||||
@@ -96,13 +128,17 @@ impl<T> RuntimeVariableList<T> {
|
||||
///
|
||||
/// Returns `Err(())` when appending `value` would exceed the maximum length.
|
||||
pub fn push(&mut self, value: T) -> Result<(), Error> {
|
||||
if self.vec.len() < self.max_len {
|
||||
let Some(max_len) = self.max_len else {
|
||||
// TODO(pawan): set a better error
|
||||
return Err(Error::MissingLengthInformation);
|
||||
};
|
||||
if self.vec.len() < max_len {
|
||||
self.vec.push(value);
|
||||
Ok(())
|
||||
} else {
|
||||
Err(Error::OutOfBounds {
|
||||
i: self.vec.len().saturating_add(1),
|
||||
len: self.max_len,
|
||||
len: max_len,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -135,7 +171,10 @@ impl<T: Decode> RuntimeVariableList<T> {
|
||||
} else {
|
||||
ssz::decode_list_of_variable_length_items(bytes, Some(max_len))?
|
||||
};
|
||||
Ok(Self { vec, max_len })
|
||||
Ok(Self {
|
||||
vec,
|
||||
max_len: Some(max_len),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,12 +208,6 @@ impl<T> Deref for RuntimeVariableList<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> DerefMut for RuntimeVariableList<T> {
|
||||
fn deref_mut(&mut self) -> &mut [T] {
|
||||
&mut self.vec[..]
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> IntoIterator for &'a RuntimeVariableList<T> {
|
||||
type Item = &'a T;
|
||||
type IntoIter = std::slice::Iter<'a, T>;
|
||||
@@ -221,7 +254,6 @@ pub struct RuntimeFixedList<T> {
|
||||
}
|
||||
|
||||
impl<T: Clone> RuntimeFixedList<T> {
|
||||
// TODO(pawan): no need to take len
|
||||
pub fn new(vec: Vec<T>) -> Self {
|
||||
let len = vec.len();
|
||||
Self { vec, len }
|
||||
@@ -280,6 +312,7 @@ mod test {
|
||||
use super::*;
|
||||
use ssz::*;
|
||||
use std::fmt::Debug;
|
||||
use tree_hash::TreeHash;
|
||||
|
||||
#[test]
|
||||
fn new() {
|
||||
@@ -358,4 +391,12 @@ mod test {
|
||||
round_trip::<u16>(RuntimeVariableList::from_vec(vec![42; 8], 8));
|
||||
round_trip::<u16>(RuntimeVariableList::from_vec(vec![0; 8], 8));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_empty_list_encoding() {
|
||||
use ssz_types::{typenum::U16, VariableList};
|
||||
|
||||
let a: RuntimeVariableList<u64> = RuntimeVariableList::from_vec(vec![], 16);
|
||||
dbg!(a.tree_hash_root());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user