diff --git a/beacon_node/beacon_chain/src/proposer_preferences_verification/tests.rs b/beacon_node/beacon_chain/src/proposer_preferences_verification/tests.rs index f8fcdcc830..c04685e40e 100644 --- a/beacon_node/beacon_chain/src/proposer_preferences_verification/tests.rs +++ b/beacon_node/beacon_chain/src/proposer_preferences_verification/tests.rs @@ -37,6 +37,7 @@ struct TestContext { slot_clock: TestingSlotClock, spec: ChainSpec, store: Arc>, + head_block_root: Hash256, } impl TestContext { @@ -59,12 +60,17 @@ impl TestContext { }; let mut genesis_block = BeaconBlock::empty(&spec); - *genesis_block.state_root_mut() = state + let genesis_state_root = state .update_tree_hash_cache() .expect("should hash genesis state"); + *genesis_block.state_root_mut() = genesis_state_root; let signed_block = SignedBeaconBlock::from_block(genesis_block, Signature::empty()); let block_root = signed_block.canonical_root(); + store + .put_state(&genesis_state_root, &state) + .expect("should persist genesis state"); + let snapshot = BeaconSnapshot::new( Arc::new(signed_block.clone()), None, @@ -93,6 +99,7 @@ impl TestContext { slot_clock, spec, store, + head_block_root: block_root, } } @@ -127,10 +134,11 @@ impl TestContext { fn make_signed_preferences( proposal_slot: Slot, validator_index: u64, + dependent_root: Hash256, ) -> Arc { Arc::new(SignedProposerPreferences { message: ProposerPreferences { - dependent_root: Hash256::ZERO, + dependent_root, proposal_slot, validator_index, fee_recipient: Address::ZERO, @@ -150,11 +158,11 @@ fn already_seen_validator() { let slot = Slot::new(1); let verified = GossipVerifiedProposerPreferences { - signed_preferences: make_signed_preferences(slot, 42), + signed_preferences: make_signed_preferences(slot, 42, Hash256::ZERO), }; ctx.preferences_cache.insert_seen_validator(&verified); - let prefs = make_signed_preferences(slot, 42); + let prefs = make_signed_preferences(slot, 42, Hash256::ZERO); let result = GossipVerifiedProposerPreferences::new(prefs, &gossip); assert!(matches!( result, @@ -174,7 +182,7 @@ fn invalid_epoch_too_far_ahead() { let gossip = ctx.gossip_ctx(); let far_slot = Slot::new(3 * E::slots_per_epoch()); - let prefs = make_signed_preferences(far_slot, 0); + let prefs = make_signed_preferences(far_slot, 0, Hash256::ZERO); let result = GossipVerifiedProposerPreferences::new(prefs, &gossip); assert!(matches!( result, @@ -190,7 +198,7 @@ fn proposal_slot_already_passed() { let ctx = TestContext::new(); let gossip = ctx.gossip_ctx(); - let prefs = make_signed_preferences(Slot::new(0), 0); + let prefs = make_signed_preferences(Slot::new(0), 0, Hash256::ZERO); let result = GossipVerifiedProposerPreferences::new(prefs, &gossip); assert!(matches!( result, @@ -210,7 +218,7 @@ fn wrong_proposer_for_slot() { let actual_proposer = ctx.proposer_at_slot(slot); let wrong_validator = if actual_proposer == 0 { 1 } else { 0 }; - let prefs = make_signed_preferences(slot, wrong_validator); + let prefs = make_signed_preferences(slot, wrong_validator, ctx.head_block_root); let result = GossipVerifiedProposerPreferences::new(prefs, &gossip); assert!(matches!( result, @@ -228,7 +236,7 @@ fn correct_proposer_bad_signature() { let slot = Slot::new(1); let actual_proposer = ctx.proposer_at_slot(slot); - let prefs = make_signed_preferences(slot, actual_proposer); + let prefs = make_signed_preferences(slot, actual_proposer, ctx.head_block_root); let result = GossipVerifiedProposerPreferences::new(prefs, &gossip); assert!(matches!( result, @@ -236,7 +244,7 @@ fn correct_proposer_bad_signature() { )); assert!( !ctx.preferences_cache - .get_seen_validator(&slot, Hash256::ZERO, actual_proposer) + .get_seen_validator(&slot, ctx.head_block_root, actual_proposer) ); assert!(ctx.preferences_cache.get_preferences(&slot).is_none()); } @@ -250,7 +258,7 @@ fn validator_index_out_of_bounds() { let gossip = ctx.gossip_ctx(); let slot = Slot::new(1); - let prefs = make_signed_preferences(slot, u64::MAX); + let prefs = make_signed_preferences(slot, u64::MAX, ctx.head_block_root); let result = GossipVerifiedProposerPreferences::new(prefs, &gossip); assert!(matches!( result, @@ -293,6 +301,43 @@ fn same_validator_different_dependent_root_not_deduplicated() { ); } +#[test] +fn dependent_root_unknown() { + if !fork_name_from_env().is_some_and(|f| f.gloas_enabled()) { + return; + } + let ctx = TestContext::new(); + let gossip = ctx.gossip_ctx(); + let slot = Slot::new(1); + + let unknown_root = Hash256::repeat_byte(0xff); + let prefs = make_signed_preferences(slot, 0, unknown_root); + let result = GossipVerifiedProposerPreferences::new(prefs, &gossip); + assert!(matches!( + result, + Err(ProposerPreferencesError::DependentRootUnknown { .. }) + )); +} + +#[test] +fn invalid_epoch_too_old() { + if !fork_name_from_env().is_some_and(|f| f.gloas_enabled()) { + return; + } + let ctx = TestContext::new(); + // Advance the clock so that epoch 0 slots are too old. + ctx.slot_clock.set_slot(3 * E::slots_per_epoch()); + let gossip = ctx.gossip_ctx(); + + let old_slot = Slot::new(1); + let prefs = make_signed_preferences(old_slot, 0, Hash256::ZERO); + let result = GossipVerifiedProposerPreferences::new(prefs, &gossip); + assert!(matches!( + result, + Err(ProposerPreferencesError::InvalidProposalEpoch { .. }) + )); +} + // TODO(gloas) add successful proposer preferences check once we have proposer preferences signing logic #[test] @@ -307,7 +352,7 @@ fn preferences_for_next_epoch_slot() { let next_epoch_slot = Slot::new(E::slots_per_epoch() + 1); let actual_proposer = ctx.proposer_at_slot(next_epoch_slot); - let prefs = make_signed_preferences(next_epoch_slot, actual_proposer); + let prefs = make_signed_preferences(next_epoch_slot, actual_proposer, ctx.head_block_root); let result = GossipVerifiedProposerPreferences::new(prefs, &gossip); // Should pass consistency checks but fail on signature (empty sig). assert!(