Electra attestation changes rm decode impl (#5856)

* Remove Crappy Decode impl for Attestation

* Remove Inefficient Attestation Decode impl

* Implement Schema Upgrade / Downgrade

* Update beacon_node/beacon_chain/src/schema_change/migration_schema_v20.rs

Co-authored-by: Michael Sproul <micsproul@gmail.com>

---------

Co-authored-by: Michael Sproul <micsproul@gmail.com>
This commit is contained in:
ethDreamer
2024-05-30 17:34:14 +02:00
committed by GitHub
parent 3e10e68c1d
commit 75432e1135
10 changed files with 354 additions and 130 deletions

View File

@@ -12,7 +12,9 @@ use smallvec::{smallvec, SmallVec};
use ssz::{Decode, Encode};
use ssz_derive::{Decode, Encode};
use std::marker::PhantomData;
use types::{AttesterSlashing, AttesterSlashingOnDisk, AttesterSlashingRefOnDisk};
use types::{
AttesterSlashing, AttesterSlashingBase, AttesterSlashingOnDisk, AttesterSlashingRefOnDisk,
};
use types::{
BeaconState, ChainSpec, Epoch, EthSpec, Fork, ForkVersion, ProposerSlashing,
SignedBlsToExecutionChange, SignedVoluntaryExit,
@@ -366,6 +368,49 @@ impl<E: EthSpec> TransformPersist for AttesterSlashing<E> {
}
}
// TODO: Remove this once we no longer support DB schema version 17
impl<E: EthSpec> TransformPersist for types::AttesterSlashingBase<E> {
type Persistable = Self;
type PersistableRef<'a> = &'a Self;
fn as_persistable_ref(&self) -> Self::PersistableRef<'_> {
self
}
fn from_persistable(persistable: Self::Persistable) -> Self {
persistable
}
}
// TODO: Remove this once we no longer support DB schema version 17
impl<E: EthSpec> From<SigVerifiedOp<AttesterSlashingBase<E>, E>>
for SigVerifiedOp<AttesterSlashing<E>, E>
{
fn from(base: SigVerifiedOp<AttesterSlashingBase<E>, E>) -> Self {
SigVerifiedOp {
op: AttesterSlashing::Base(base.op),
verified_against: base.verified_against,
_phantom: PhantomData,
}
}
}
// TODO: Remove this once we no longer support DB schema version 17
impl<E: EthSpec> TryFrom<SigVerifiedOp<AttesterSlashing<E>, E>>
for SigVerifiedOp<AttesterSlashingBase<E>, E>
{
type Error = String;
fn try_from(slashing: SigVerifiedOp<AttesterSlashing<E>, E>) -> Result<Self, Self::Error> {
match slashing.op {
AttesterSlashing::Base(base) => Ok(SigVerifiedOp {
op: base,
verified_against: slashing.verified_against,
_phantom: PhantomData,
}),
AttesterSlashing::Electra(_) => Err("non-base attester slashing".to_string()),
}
}
}
impl TransformPersist for ProposerSlashing {
type Persistable = Self;
type PersistableRef<'a> = &'a Self;

View File

@@ -4,7 +4,6 @@ use derivative::Derivative;
use rand::RngCore;
use safe_arith::ArithError;
use serde::{Deserialize, Serialize};
use ssz::Decode;
use ssz_derive::{Decode, Encode};
use ssz_types::BitVector;
use std::hash::{Hash, Hasher};
@@ -72,26 +71,6 @@ pub struct Attestation<E: EthSpec> {
pub signature: AggregateSignature,
}
impl<E: EthSpec> Decode for Attestation<E> {
fn is_ssz_fixed_len() -> bool {
false
}
fn from_ssz_bytes(bytes: &[u8]) -> Result<Self, ssz::DecodeError> {
if let Ok(result) = AttestationBase::from_ssz_bytes(bytes) {
return Ok(Attestation::Base(result));
}
if let Ok(result) = AttestationElectra::from_ssz_bytes(bytes) {
return Ok(Attestation::Electra(result));
}
Err(ssz::DecodeError::BytesInvalid(String::from(
"bytes not valid for any fork variant",
)))
}
}
// TODO(electra): think about how to handle fork variants here
impl<E: EthSpec> TestRandom for Attestation<E> {
fn random_for_test(rng: &mut impl RngCore) -> Self {
@@ -417,6 +396,65 @@ impl<'a, E: EthSpec> SlotData for AttestationRef<'a, E> {
}
}
#[derive(Debug, Clone, Encode, Decode, PartialEq)]
#[ssz(enum_behaviour = "union")]
pub enum AttestationOnDisk<E: EthSpec> {
Base(AttestationBase<E>),
Electra(AttestationElectra<E>),
}
impl<E: EthSpec> AttestationOnDisk<E> {
pub fn to_ref(&self) -> AttestationRefOnDisk<E> {
match self {
AttestationOnDisk::Base(att) => AttestationRefOnDisk::Base(att),
AttestationOnDisk::Electra(att) => AttestationRefOnDisk::Electra(att),
}
}
}
#[derive(Debug, Clone, Encode)]
#[ssz(enum_behaviour = "union")]
pub enum AttestationRefOnDisk<'a, E: EthSpec> {
Base(&'a AttestationBase<E>),
Electra(&'a AttestationElectra<E>),
}
impl<E: EthSpec> From<Attestation<E>> for AttestationOnDisk<E> {
fn from(attestation: Attestation<E>) -> Self {
match attestation {
Attestation::Base(attestation) => Self::Base(attestation),
Attestation::Electra(attestation) => Self::Electra(attestation),
}
}
}
impl<E: EthSpec> From<AttestationOnDisk<E>> for Attestation<E> {
fn from(attestation: AttestationOnDisk<E>) -> Self {
match attestation {
AttestationOnDisk::Base(attestation) => Self::Base(attestation),
AttestationOnDisk::Electra(attestation) => Self::Electra(attestation),
}
}
}
impl<'a, E: EthSpec> From<AttestationRef<'a, E>> for AttestationRefOnDisk<'a, E> {
fn from(attestation: AttestationRef<'a, E>) -> Self {
match attestation {
AttestationRef::Base(attestation) => Self::Base(attestation),
AttestationRef::Electra(attestation) => Self::Electra(attestation),
}
}
}
impl<'a, E: EthSpec> From<AttestationRefOnDisk<'a, E>> for AttestationRef<'a, E> {
fn from(attestation: AttestationRefOnDisk<'a, E>) -> Self {
match attestation {
AttestationRefOnDisk::Base(attestation) => Self::Base(attestation),
AttestationRefOnDisk::Electra(attestation) => Self::Electra(attestation),
}
}
}
#[cfg(test)]
mod tests {
use super::*;