Merge remote-tracking branch 'origin/unstable' into tree-states

This commit is contained in:
Michael Sproul
2022-09-14 13:51:23 +10:00
404 changed files with 28947 additions and 12000 deletions

View File

@@ -1,12 +1,13 @@
use crate::attestation_id::AttestationId;
use crate::attestation_storage::AttestationMap;
use crate::sync_aggregate_id::SyncAggregateId;
use crate::OpPoolError;
use crate::OperationPool;
use derivative::Derivative;
use parking_lot::RwLock;
use serde_derive::{Deserialize, Serialize};
use ssz::{Decode, Encode};
use ssz_derive::{Decode, Encode};
use state_processing::SigVerifiedOp;
use store::{DBColumn, Error as StoreError, StoreItem};
use types::*;
@@ -17,32 +18,42 @@ type PersistedSyncContributions<T> = Vec<(SyncAggregateId, Vec<SyncCommitteeCont
/// Operations are stored in arbitrary order, so it's not a good idea to compare instances
/// of this type (or its encoded form) for equality. Convert back to an `OperationPool` first.
#[superstruct(
variants(Altair),
variants(V5, V12),
variant_attributes(
derive(Derivative, PartialEq, Debug, Serialize, Deserialize, Encode, Decode),
serde(bound = "T: EthSpec", deny_unknown_fields),
derive(Derivative, PartialEq, Debug, Encode, Decode),
derivative(Clone),
),
partial_getter_error(ty = "OpPoolError", expr = "OpPoolError::IncorrectOpPoolVariant")
)]
#[derive(PartialEq, Debug, Serialize, Deserialize, Encode)]
#[serde(untagged)]
#[serde(bound = "T: EthSpec")]
#[derive(PartialEq, Debug, Encode)]
#[ssz(enum_behaviour = "transparent")]
pub struct PersistedOperationPool<T: EthSpec> {
/// Mapping from attestation ID to attestation mappings.
// We could save space by not storing the attestation ID, but it might
// be difficult to make that roundtrip due to eager aggregation.
attestations: Vec<(AttestationId, Vec<Attestation<T>>)>,
/// [DEPRECATED] Mapping from attestation ID to attestation mappings.
#[superstruct(only(V5))]
pub attestations_v5: Vec<(AttestationId, Vec<Attestation<T>>)>,
/// Attestations and their attesting indices.
#[superstruct(only(V12))]
pub attestations: Vec<(Attestation<T>, Vec<u64>)>,
/// Mapping from sync contribution ID to sync contributions and aggregate.
#[superstruct(only(Altair))]
sync_contributions: PersistedSyncContributions<T>,
pub sync_contributions: PersistedSyncContributions<T>,
/// [DEPRECATED] Attester slashings.
#[superstruct(only(V5))]
pub attester_slashings_v5: Vec<(AttesterSlashing<T>, ForkVersion)>,
/// Attester slashings.
attester_slashings: Vec<(AttesterSlashing<T>, ForkVersion)>,
/// Proposer slashings.
proposer_slashings: Vec<ProposerSlashing>,
/// Voluntary exits.
voluntary_exits: Vec<SignedVoluntaryExit>,
#[superstruct(only(V12))]
pub attester_slashings: Vec<SigVerifiedOp<AttesterSlashing<T>, T>>,
/// [DEPRECATED] Proposer slashings.
#[superstruct(only(V5))]
pub proposer_slashings_v5: Vec<ProposerSlashing>,
/// Proposer slashings with fork information.
#[superstruct(only(V12))]
pub proposer_slashings: Vec<SigVerifiedOp<ProposerSlashing, T>>,
/// [DEPRECATED] Voluntary exits.
#[superstruct(only(V5))]
pub voluntary_exits_v5: Vec<SignedVoluntaryExit>,
/// Voluntary exits with fork information.
#[superstruct(only(V12))]
pub voluntary_exits: Vec<SigVerifiedOp<SignedVoluntaryExit, T>>,
}
impl<T: EthSpec> PersistedOperationPool<T> {
@@ -52,7 +63,12 @@ impl<T: EthSpec> PersistedOperationPool<T> {
.attestations
.read()
.iter()
.map(|(att_id, att)| (att_id.clone(), att.clone()))
.map(|att| {
(
att.clone_as_attestation(),
att.indexed.attesting_indices.clone(),
)
})
.collect();
let sync_contributions = operation_pool
@@ -83,7 +99,7 @@ impl<T: EthSpec> PersistedOperationPool<T> {
.map(|(_, exit)| exit.clone())
.collect();
PersistedOperationPool::Altair(PersistedOperationPoolAltair {
PersistedOperationPool::V12(PersistedOperationPoolV12 {
attestations,
sync_contributions,
attester_slashings,
@@ -92,46 +108,62 @@ impl<T: EthSpec> PersistedOperationPool<T> {
})
}
/// Reconstruct an `OperationPool`. Sets `sync_contributions` to its `Default` if `self` matches
/// `PersistedOperationPool::Base`.
/// Reconstruct an `OperationPool`.
pub fn into_operation_pool(self) -> Result<OperationPool<T>, OpPoolError> {
let attestations = RwLock::new(self.attestations().iter().cloned().collect());
let attester_slashings = RwLock::new(self.attester_slashings().iter().cloned().collect());
let attester_slashings = RwLock::new(self.attester_slashings()?.iter().cloned().collect());
let proposer_slashings = RwLock::new(
self.proposer_slashings()
self.proposer_slashings()?
.iter()
.cloned()
.map(|slashing| (slashing.signed_header_1.message.proposer_index, slashing))
.map(|slashing| (slashing.as_inner().proposer_index(), slashing))
.collect(),
);
let voluntary_exits = RwLock::new(
self.voluntary_exits()
self.voluntary_exits()?
.iter()
.cloned()
.map(|exit| (exit.message.validator_index, exit))
.map(|exit| (exit.as_inner().message.validator_index, exit))
.collect(),
);
let op_pool = match self {
PersistedOperationPool::Altair(_) => {
let sync_contributions =
RwLock::new(self.sync_contributions()?.iter().cloned().collect());
OperationPool {
attestations,
sync_contributions,
attester_slashings,
proposer_slashings,
voluntary_exits,
reward_cache: Default::default(),
_phantom: Default::default(),
let sync_contributions = RwLock::new(self.sync_contributions().iter().cloned().collect());
let attestations = match self {
PersistedOperationPool::V5(_) => return Err(OpPoolError::IncorrectOpPoolVariant),
PersistedOperationPool::V12(pool) => {
let mut map = AttestationMap::default();
for (att, attesting_indices) in pool.attestations {
map.insert(att, attesting_indices);
}
RwLock::new(map)
}
};
let op_pool = OperationPool {
attestations,
sync_contributions,
attester_slashings,
proposer_slashings,
voluntary_exits,
reward_cache: Default::default(),
_phantom: Default::default(),
};
Ok(op_pool)
}
}
/// Deserialization for `PersistedOperationPool` defaults to `PersistedOperationPool::Altair`.
impl<T: EthSpec> StoreItem for PersistedOperationPoolV5<T> {
fn db_column() -> DBColumn {
DBColumn::OpPool
}
fn as_store_bytes(&self) -> Result<Vec<u8>, StoreError> {
Ok(self.as_ssz_bytes())
}
fn from_store_bytes(bytes: &[u8]) -> Result<Self, StoreError> {
PersistedOperationPoolV5::from_ssz_bytes(bytes).map_err(Into::into)
}
}
/// Deserialization for `PersistedOperationPool` defaults to `PersistedOperationPool::V12`.
impl<T: EthSpec> StoreItem for PersistedOperationPool<T> {
fn db_column() -> DBColumn {
DBColumn::OpPool
@@ -142,9 +174,9 @@ impl<T: EthSpec> StoreItem for PersistedOperationPool<T> {
}
fn from_store_bytes(bytes: &[u8]) -> Result<Self, StoreError> {
// Default deserialization to the Altair variant.
PersistedOperationPoolAltair::from_ssz_bytes(bytes)
.map(Self::Altair)
// Default deserialization to the latest variant.
PersistedOperationPoolV12::from_ssz_bytes(bytes)
.map(Self::V12)
.map_err(Into::into)
}
}