Merge branch 'unstable' into gloas-parent-envelope-unknown-lookup

This commit is contained in:
Eitan Seri-Levi
2026-05-04 16:01:26 +02:00
committed by GitHub
26 changed files with 899 additions and 88 deletions

View File

@@ -252,11 +252,11 @@ fn make_signed_preferences(
) -> Arc<SignedProposerPreferences> {
Arc::new(SignedProposerPreferences {
message: ProposerPreferences {
dependent_root: Hash256::ZERO,
proposal_slot,
validator_index,
fee_recipient,
gas_limit,
..ProposerPreferences::default()
},
signature: Signature::empty(),
})

View File

@@ -64,7 +64,7 @@ impl GossipVerifiedProposerPreferences {
ctx: &GossipVerificationContext<'_, T>,
) -> Result<Self, ProposerPreferencesError> {
let proposal_slot = signed_preferences.message.proposal_slot;
let checkpoint_root = signed_preferences.message.checkpoint_root;
let dependent_root = signed_preferences.message.dependent_root;
let validator_index = signed_preferences.message.validator_index;
let cached_head = ctx.canonical_head.cached_head();
let current_slot = ctx
@@ -75,7 +75,7 @@ impl GossipVerifiedProposerPreferences {
if ctx
.gossip_verified_proposer_preferences_cache
.get_seen_validator(&proposal_slot, checkpoint_root, validator_index)
.get_seen_validator(&proposal_slot, dependent_root, validator_index)
{
return Err(ProposerPreferencesError::AlreadySeen {
validator_index,
@@ -154,7 +154,9 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
#[cfg(test)]
mod tests {
use types::{Address, BeaconState, EthSpec, MinimalEthSpec, ProposerPreferences, Slot};
use types::{
Address, BeaconState, EthSpec, Hash256, MinimalEthSpec, ProposerPreferences, Slot,
};
use super::verify_preferences_consistency;
use crate::proposer_preferences_verification::ProposerPreferencesError;
@@ -163,7 +165,7 @@ mod tests {
fn make_preferences(proposal_slot: Slot, validator_index: u64) -> ProposerPreferences {
ProposerPreferences {
checkpoint_root: types::Hash256::ZERO,
dependent_root: Hash256::ZERO,
proposal_slot,
validator_index,
fee_recipient: Address::ZERO,

View File

@@ -37,24 +37,24 @@ impl GossipVerifiedProposerPreferenceCache {
pub fn get_seen_validator(
&self,
slot: &Slot,
checkpoint_root: Hash256,
dependent_root: Hash256,
validator_index: u64,
) -> bool {
self.seen
.read()
.get(slot)
.is_some_and(|seen| seen.contains(&(checkpoint_root, validator_index)))
.is_some_and(|seen| seen.contains(&(dependent_root, validator_index)))
}
pub fn insert_seen_validator(&self, preferences: &GossipVerifiedProposerPreferences) {
let slot = preferences.signed_preferences.message.proposal_slot;
let checkpoint_root = preferences.signed_preferences.message.checkpoint_root;
let dependent_root = preferences.signed_preferences.message.dependent_root;
let validator_index = preferences.signed_preferences.message.validator_index;
self.seen
.write()
.entry(slot)
.or_default()
.insert((checkpoint_root, validator_index));
.insert((dependent_root, validator_index));
}
pub fn prune(&self, current_slot: Slot) {
@@ -70,20 +70,24 @@ mod tests {
use std::sync::Arc;
use bls::Signature;
use types::{Address, ProposerPreferences, SignedProposerPreferences, Slot};
use types::{Address, Hash256, ProposerPreferences, SignedProposerPreferences, Slot};
use super::GossipVerifiedProposerPreferenceCache;
use crate::proposer_preferences_verification::gossip_verified_proposer_preferences::GossipVerifiedProposerPreferences;
fn make_gossip_verified(slot: Slot, validator_index: u64) -> GossipVerifiedProposerPreferences {
fn make_gossip_verified(
slot: Slot,
validator_index: u64,
dependent_root: Hash256,
) -> GossipVerifiedProposerPreferences {
GossipVerifiedProposerPreferences {
signed_preferences: Arc::new(SignedProposerPreferences {
message: ProposerPreferences {
dependent_root,
proposal_slot: slot,
validator_index,
fee_recipient: Address::ZERO,
gas_limit: 30_000_000,
..ProposerPreferences::default()
},
signature: Signature::empty(),
}),
@@ -93,9 +97,10 @@ mod tests {
#[test]
fn prune_removes_old_retains_current() {
let cache = GossipVerifiedProposerPreferenceCache::default();
let root = Hash256::ZERO;
for slot in [1, 2, 3, 7, 8, 9, 10] {
let verified = make_gossip_verified(Slot::new(slot), slot);
let verified = make_gossip_verified(Slot::new(slot), slot, root);
cache.insert_seen_validator(&verified);
cache.insert_preferences(verified);
}
@@ -104,11 +109,26 @@ mod tests {
for slot in [1, 2, 3, 7] {
assert!(cache.get_preferences(&Slot::new(slot)).is_none());
assert!(!cache.get_seen_validator(&Slot::new(slot), types::Hash256::ZERO, slot));
assert!(!cache.get_seen_validator(&Slot::new(slot), root, slot));
}
for slot in [8, 9, 10] {
assert!(cache.get_preferences(&Slot::new(slot)).is_some());
assert!(cache.get_seen_validator(&Slot::new(slot), types::Hash256::ZERO, slot));
assert!(cache.get_seen_validator(&Slot::new(slot), root, slot));
}
}
#[test]
fn different_dependent_roots_not_deduped() {
let cache = GossipVerifiedProposerPreferenceCache::default();
let slot = Slot::new(5);
let root_a = Hash256::repeat_byte(0xaa);
let root_b = Hash256::repeat_byte(0xbb);
let validator_index = 42;
let verified_a = make_gossip_verified(slot, validator_index, root_a);
cache.insert_seen_validator(&verified_a);
assert!(cache.get_seen_validator(&slot, root_a, validator_index));
assert!(!cache.get_seen_validator(&slot, root_b, validator_index));
}
}

View File

@@ -127,11 +127,11 @@ fn make_signed_preferences(
) -> Arc<SignedProposerPreferences> {
Arc::new(SignedProposerPreferences {
message: ProposerPreferences {
dependent_root: Hash256::ZERO,
proposal_slot,
validator_index,
fee_recipient: Address::ZERO,
gas_limit: 30_000_000,
..ProposerPreferences::default()
},
signature: Signature::empty(),
})
@@ -231,11 +231,10 @@ fn correct_proposer_bad_signature() {
result,
Err(ProposerPreferencesError::BadSignature)
));
assert!(!ctx.preferences_cache.get_seen_validator(
&slot,
types::Hash256::ZERO,
actual_proposer
));
assert!(
!ctx.preferences_cache
.get_seen_validator(&slot, Hash256::ZERO, actual_proposer)
);
assert!(ctx.preferences_cache.get_preferences(&slot).is_none());
}
@@ -256,6 +255,41 @@ fn validator_index_out_of_bounds() {
));
}
/// Same (slot, validator_index) but different dependent_root should NOT be deduplicated.
#[test]
fn same_validator_different_dependent_root_not_deduplicated() {
if !fork_name_from_env().is_some_and(|f| f.gloas_enabled()) {
return;
}
let ctx = TestContext::new();
let slot = Slot::new(1);
let verified_a = GossipVerifiedProposerPreferences {
signed_preferences: Arc::new(SignedProposerPreferences {
message: ProposerPreferences {
proposal_slot: slot,
validator_index: 42,
dependent_root: Hash256::repeat_byte(0xaa),
fee_recipient: Address::ZERO,
gas_limit: 30_000_000,
},
signature: Signature::empty(),
}),
};
ctx.preferences_cache.insert_seen_validator(&verified_a);
// Different dependent_root — should not be seen.
assert!(
!ctx.preferences_cache
.get_seen_validator(&slot, Hash256::repeat_byte(0xbb), 42,)
);
// Same dependent_root — should be seen.
assert!(
ctx.preferences_cache
.get_seen_validator(&slot, Hash256::repeat_byte(0xaa), 42,)
);
}
// TODO(gloas) add successful proposer preferences check once we have proposer preferences signing logic
#[test]