implement scoring mechanisms and plumbing

This commit is contained in:
hopinheimer
2026-02-24 17:40:11 -05:00
parent 3e3ccba1a6
commit d5c5077a31
26 changed files with 1573 additions and 413 deletions

View File

@@ -1,7 +1,7 @@
use crate::proto_array::ProposerBoost;
use crate::{
Error, JustifiedBalances,
proto_array::{ProtoArray, ProtoNodeV17},
proto_array::{ProtoArray, ProtoNode, ProtoNodeV17},
proto_array_fork_choice::{ElasticList, ProtoArrayForkChoice, VoteTracker},
};
use ssz::{Encode, four_byte_option_impl};
@@ -14,14 +14,15 @@ use types::{Checkpoint, Hash256};
// selector.
four_byte_option_impl!(four_byte_option_checkpoint, Checkpoint);
pub type SszContainer = SszContainerV28;
pub type SszContainer = SszContainerV29;
// Legacy containers (V17/V28) for backward compatibility with older schema versions.
#[superstruct(
variants(V17, V28),
variant_attributes(derive(Encode, Decode, Clone)),
no_enum
)]
pub struct SszContainer {
pub struct SszContainerLegacy {
pub votes: Vec<VoteTracker>,
#[superstruct(only(V17))]
pub balances: Vec<u64>,
@@ -35,7 +36,21 @@ pub struct SszContainer {
pub previous_proposer_boost: ProposerBoost,
}
impl SszContainer {
/// Current container version. Uses union-encoded `ProtoNode` to support mixed V17/V29 nodes.
#[derive(Encode, Decode, Clone)]
pub struct SszContainerV29 {
pub votes: Vec<VoteTracker>,
pub prune_threshold: usize,
// Deprecated, remove in a future schema migration
justified_checkpoint: Checkpoint,
// Deprecated, remove in a future schema migration
finalized_checkpoint: Checkpoint,
pub nodes: Vec<ProtoNode>,
pub indices: Vec<(Hash256, usize)>,
pub previous_proposer_boost: ProposerBoost,
}
impl SszContainerV29 {
pub fn from_proto_array(
from: &ProtoArrayForkChoice,
justified_checkpoint: Checkpoint,
@@ -55,10 +70,10 @@ impl SszContainer {
}
}
impl TryFrom<(SszContainer, JustifiedBalances)> for ProtoArrayForkChoice {
impl TryFrom<(SszContainerV29, JustifiedBalances)> for ProtoArrayForkChoice {
type Error = Error;
fn try_from((from, balances): (SszContainer, JustifiedBalances)) -> Result<Self, Error> {
fn try_from((from, balances): (SszContainerV29, JustifiedBalances)) -> Result<Self, Error> {
let proto_array = ProtoArray {
prune_threshold: from.prune_threshold,
nodes: from.nodes,
@@ -74,9 +89,9 @@ impl TryFrom<(SszContainer, JustifiedBalances)> for ProtoArrayForkChoice {
}
}
// Convert V17 to V28 by dropping balances.
impl From<SszContainerV17> for SszContainerV28 {
fn from(v17: SszContainerV17) -> Self {
// Convert legacy V17 to V28 by dropping balances.
impl From<SszContainerLegacyV17> for SszContainerLegacyV28 {
fn from(v17: SszContainerLegacyV17) -> Self {
Self {
votes: v17.votes,
prune_threshold: v17.prune_threshold,
@@ -89,9 +104,9 @@ impl From<SszContainerV17> for SszContainerV28 {
}
}
// Convert V28 to V17 by re-adding balances.
impl From<(SszContainerV28, JustifiedBalances)> for SszContainerV17 {
fn from((v28, balances): (SszContainerV28, JustifiedBalances)) -> Self {
// Convert legacy V28 to V17 by re-adding balances.
impl From<(SszContainerLegacyV28, JustifiedBalances)> for SszContainerLegacyV17 {
fn from((v28, balances): (SszContainerLegacyV28, JustifiedBalances)) -> Self {
Self {
votes: v28.votes,
balances: balances.effective_balances.clone(),
@@ -104,3 +119,40 @@ impl From<(SszContainerV28, JustifiedBalances)> for SszContainerV17 {
}
}
}
// Convert legacy V28 to current V29.
impl From<SszContainerLegacyV28> for SszContainerV29 {
fn from(v28: SszContainerLegacyV28) -> Self {
Self {
votes: v28.votes,
prune_threshold: v28.prune_threshold,
justified_checkpoint: v28.justified_checkpoint,
finalized_checkpoint: v28.finalized_checkpoint,
nodes: v28.nodes.into_iter().map(ProtoNode::V17).collect(),
indices: v28.indices,
previous_proposer_boost: v28.previous_proposer_boost,
}
}
}
// Downgrade current V29 to legacy V28 (lossy: V29 nodes lose payload-specific fields).
impl From<SszContainerV29> for SszContainerLegacyV28 {
fn from(v29: SszContainerV29) -> Self {
Self {
votes: v29.votes,
prune_threshold: v29.prune_threshold,
justified_checkpoint: v29.justified_checkpoint,
finalized_checkpoint: v29.finalized_checkpoint,
nodes: v29
.nodes
.into_iter()
.filter_map(|node| match node {
ProtoNode::V17(v17) => Some(v17),
ProtoNode::V29(_) => None,
})
.collect(),
indices: v29.indices,
previous_proposer_boost: v29.previous_proposer_boost,
}
}
}