mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-18 12:22:51 +00:00
More variable-variable lists
This commit is contained in:
@@ -18,6 +18,10 @@ use self::UpdatePattern::*;
|
||||
use crate::*;
|
||||
use ssz::{Decode, Encode};
|
||||
use typenum::Unsigned;
|
||||
use types::VList;
|
||||
|
||||
#[cfg(feature = "milhouse")]
|
||||
use types::milhouse::ImmList;
|
||||
|
||||
/// Description of how a `BeaconState` field is updated during state processing.
|
||||
///
|
||||
@@ -318,7 +322,7 @@ field!(
|
||||
|_| OncePerNSlots {
|
||||
n: T::SlotsPerHistoricalRoot::to_u64()
|
||||
},
|
||||
|state: &BeaconState<_>, index, _| safe_modulo_index(state.historical_roots(), index)
|
||||
|state: &BeaconState<_>, index, _| safe_modulo_index_tree(state.historical_roots(), index)
|
||||
);
|
||||
|
||||
field!(
|
||||
@@ -533,7 +537,7 @@ pub fn load_variable_list_from_db<F: VariableLengthField<E>, E: EthSpec, S: KeyV
|
||||
store: &S,
|
||||
slot: Slot,
|
||||
spec: &ChainSpec,
|
||||
) -> Result<VariableList<F::Value, F::Length>, Error> {
|
||||
) -> Result<VList<F::Value, F::Length>, Error> {
|
||||
let chunk_size = F::chunk_size();
|
||||
let (start_vindex, end_vindex) = F::start_and_end_vindex(slot, spec);
|
||||
let start_cindex = start_vindex / chunk_size;
|
||||
@@ -541,19 +545,19 @@ pub fn load_variable_list_from_db<F: VariableLengthField<E>, E: EthSpec, S: KeyV
|
||||
|
||||
let chunks: Vec<Chunk<F::Value>> = range_query(store, F::column(), start_cindex, end_cindex)?;
|
||||
|
||||
let mut result = Vec::with_capacity(chunk_size * chunks.len());
|
||||
let mut result = VList::empty();
|
||||
|
||||
for (chunk_index, chunk) in chunks.into_iter().enumerate() {
|
||||
for (i, value) in chunk.values.into_iter().enumerate() {
|
||||
let vindex = chunk_index * chunk_size + i;
|
||||
|
||||
if vindex >= start_vindex && vindex < end_vindex {
|
||||
result.push(value);
|
||||
result.push(value)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(result.into())
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
/// Index into a field of the state, avoiding out of bounds and division by 0.
|
||||
@@ -565,6 +569,21 @@ fn safe_modulo_index<T: Copy>(values: &[T], index: u64) -> Result<T, ChunkError>
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "milhouse"))]
|
||||
use safe_modulo_index as safe_modulo_index_tree;
|
||||
|
||||
#[cfg(feature = "milhouse")]
|
||||
fn safe_modulo_index_tree<V: ImmList<T>, T: Copy>(values: &V, index: u64) -> Result<T, ChunkError> {
|
||||
if values.is_empty() {
|
||||
Err(ChunkError::ZeroLengthVector)
|
||||
} else {
|
||||
values
|
||||
.get(index as usize % values.len())
|
||||
.copied()
|
||||
.ok_or(ChunkError::OutOfBounds)
|
||||
}
|
||||
}
|
||||
|
||||
/// A chunk of a fixed-size vector from the `BeaconState`, stored in the database.
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct Chunk<T> {
|
||||
@@ -679,6 +698,7 @@ pub enum ChunkError {
|
||||
end_vindex: usize,
|
||||
length: usize,
|
||||
},
|
||||
OutOfBounds,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -4,6 +4,9 @@ use crate::hot_cold_store::HotColdDBError;
|
||||
use ssz::DecodeError;
|
||||
use types::{BeaconStateError, Hash256, Slot};
|
||||
|
||||
#[cfg(feature = "milhouse")]
|
||||
use types::milhouse;
|
||||
|
||||
pub type Result<T> = std::result::Result<T, Error>;
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -39,6 +42,8 @@ pub enum Error {
|
||||
expected: Hash256,
|
||||
computed: Hash256,
|
||||
},
|
||||
#[cfg(feature = "milhouse")]
|
||||
MilhouseError(milhouse::Error),
|
||||
}
|
||||
|
||||
pub trait HandleUnavailable<T> {
|
||||
@@ -91,6 +96,13 @@ impl From<StoreConfigError> for Error {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "milhouse")]
|
||||
impl From<milhouse::Error> for Error {
|
||||
fn from(e: milhouse::Error) -> Self {
|
||||
Self::MilhouseError(e)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct DBError {
|
||||
pub message: String,
|
||||
|
||||
@@ -39,15 +39,15 @@ where
|
||||
pub state_roots: Option<FixedVector<Hash256, T::SlotsPerHistoricalRoot>>,
|
||||
|
||||
#[ssz(skip_serializing, skip_deserializing)]
|
||||
pub historical_roots: Option<VariableList<Hash256, T::HistoricalRootsLimit>>,
|
||||
pub historical_roots: Option<VList<Hash256, T::HistoricalRootsLimit>>,
|
||||
|
||||
// Ethereum 1.0 chain data
|
||||
pub eth1_data: Eth1Data,
|
||||
pub eth1_data_votes: VariableList<Eth1Data, T::SlotsPerEth1VotingPeriod>,
|
||||
pub eth1_data_votes: VList<Eth1Data, T::SlotsPerEth1VotingPeriod>,
|
||||
pub eth1_deposit_index: u64,
|
||||
|
||||
// Registry
|
||||
pub validators: VariableList<Validator, T::ValidatorRegistryLimit>,
|
||||
pub validators: VList<Validator, T::ValidatorRegistryLimit>,
|
||||
pub balances: VariableList<u64, T::ValidatorRegistryLimit>,
|
||||
|
||||
// Shuffling
|
||||
@@ -61,9 +61,9 @@ where
|
||||
|
||||
// Attestations (genesis fork only)
|
||||
#[superstruct(only(Base))]
|
||||
pub previous_epoch_attestations: VariableList<PendingAttestation<T>, T::MaxPendingAttestations>,
|
||||
pub previous_epoch_attestations: VList<PendingAttestation<T>, T::MaxPendingAttestations>,
|
||||
#[superstruct(only(Base))]
|
||||
pub current_epoch_attestations: VariableList<PendingAttestation<T>, T::MaxPendingAttestations>,
|
||||
pub current_epoch_attestations: VList<PendingAttestation<T>, T::MaxPendingAttestations>,
|
||||
|
||||
// Participation (Altair and later)
|
||||
#[superstruct(only(Altair))]
|
||||
@@ -297,6 +297,7 @@ macro_rules! impl_try_into_beacon_state {
|
||||
committee_caches: <_>::default(),
|
||||
pubkey_cache: <_>::default(),
|
||||
exit_cache: <_>::default(),
|
||||
#[cfg(not(feature = "milhouse"))]
|
||||
tree_hash_cache: <_>::default(),
|
||||
|
||||
// Variant-specific fields
|
||||
|
||||
Reference in New Issue
Block a user