From 296e50b0d1da1d97781452d39faf21fb0e30f752 Mon Sep 17 00:00:00 2001 From: Michael Sproul Date: Thu, 27 Mar 2025 23:23:25 +1100 Subject: [PATCH] WIP --- beacon_node/beacon_chain/src/test_utils.rs | 38 +++++--- beacon_node/beacon_chain/tests/electra.rs | 106 +++++++++++++++++++++ beacon_node/beacon_chain/tests/main.rs | 1 + 3 files changed, 132 insertions(+), 13 deletions(-) create mode 100644 beacon_node/beacon_chain/tests/electra.rs diff --git a/beacon_node/beacon_chain/src/test_utils.rs b/beacon_node/beacon_chain/src/test_utils.rs index fa26c9dbd9..dee1f2a4a7 100644 --- a/beacon_node/beacon_chain/src/test_utils.rs +++ b/beacon_node/beacon_chain/src/test_utils.rs @@ -2228,6 +2228,23 @@ where ((Arc::new(signed_block), blobs), state) } + pub fn make_deposit_data( + &self, + keypair: &Keypair, + withdrawal_credentials: Hash256, + amount: u64, + ) -> DepositData { + let pubkey = PublicKeyBytes::from(keypair.pk.clone()); + let mut data = DepositData { + pubkey, + withdrawal_credentials, + amount, + signature: SignatureBytes::empty(), + }; + data.signature = data.create_signature(&keypair.sk, &self.spec); + data + } + pub fn make_deposits<'a>( &self, state: &'a mut BeaconState, @@ -2239,19 +2256,14 @@ where for _ in 0..num_deposits { let keypair = Keypair::random(); - let pubkeybytes = PublicKeyBytes::from(keypair.pk.clone()); - - let mut data = DepositData { - pubkey: pubkeybytes, - withdrawal_credentials: Hash256::from_slice( - &get_withdrawal_credentials(&keypair.pk, self.spec.bls_withdrawal_prefix_byte) - [..], - ), - amount: self.spec.min_deposit_amount, - signature: SignatureBytes::empty(), - }; - - data.signature = data.create_signature(&keypair.sk, &self.spec); + let withdrawal_credentials = Hash256::from_slice( + &get_withdrawal_credentials(&keypair.pk, self.spec.bls_withdrawal_prefix_byte)[..], + ); + let mut data = self.make_deposit_data( + &keypair, + withdrawal_credentials, + self.spec.min_deposit_amount, + ); if let Some(invalid_pubkey) = invalid_pubkey { data.pubkey = invalid_pubkey; diff --git a/beacon_node/beacon_chain/tests/electra.rs b/beacon_node/beacon_chain/tests/electra.rs new file mode 100644 index 0000000000..3fe873f7ce --- /dev/null +++ b/beacon_node/beacon_chain/tests/electra.rs @@ -0,0 +1,106 @@ +#![cfg(not(debug_assertions))] // Tests run too slow in debug. + +use beacon_chain::test_utils::BeaconChainHarness; +use state_processing::{ + per_block_processing, BlockSignatureStrategy, ConsensusContext, VerifyBlockRoot, +}; +use std::sync::Arc; +use types::*; + +type E = MainnetEthSpec; + +#[tokio::test] +async fn signature_verify_chain_segment_pubkey_cache() { + let initial_validator_count = 32; + + let deposit_slot = Slot::new(4 * E::slots_per_epoch() - 1); + let pre_deposit_slot = deposit_slot - 1; + let spec = Arc::new(ForkName::Electra.make_genesis_spec(E::default_spec())); + + let harness = BeaconChainHarness::builder(E::default()) + .spec(spec.clone()) + .logger(logging::test_logger()) + .deterministic_keypairs(initial_validator_count) + .fresh_ephemeral_store() + .mock_execution_layer() + .build(); + + harness + .execution_block_generator() + .move_to_terminal_block() + .unwrap(); + + Box::pin(harness.extend_to_slot(pre_deposit_slot)).await; + + // Create a block with a deposit for a new validator. + let pre_deposit_state = harness.get_current_state(); + assert_eq!(pre_deposit_state.slot(), pre_deposit_slot); + assert_eq!(pre_deposit_state.fork_name_unchecked(), ForkName::Electra); + + // FIXME: Probably need to make this deterministic? + let new_keypair = Keypair::random(); + let withdrawal_credentials = Hash256::ZERO; + let amount = spec.max_effective_balance_electra; + let deposit_data = harness.make_deposit_data(&new_keypair, withdrawal_credentials, amount); + let deposit_request = DepositRequest { + pubkey: deposit_data.pubkey, + withdrawal_credentials: deposit_data.withdrawal_credentials, + amount: deposit_data.amount, + signature: deposit_data.signature, + index: 0, + }; + + let ((jank_block, blobs), mut state) = harness + .make_block_with_modifier(pre_deposit_state, deposit_slot, |block| { + block + .body_mut() + .execution_requests_mut() + .unwrap() + .deposits + .push(deposit_request) + .unwrap(); + }) + .await; + + // Compute correct state root. + // FIXME: this is kinda nasty + let mut ctxt = ConsensusContext::new(jank_block.slot()); + per_block_processing( + &mut state, + &jank_block, + BlockSignatureStrategy::VerifyIndividual, + VerifyBlockRoot::True, + &mut ctxt, + &spec, + ) + .unwrap(); + let (mut block, _) = (*jank_block).clone().deconstruct(); + *block.state_root_mut() = state.update_tree_hash_cache().unwrap(); + let proposer_index = block.proposer_index() as usize; + let signed_block = Arc::new(block.sign( + &harness.validator_keypairs[proposer_index].sk, + &state.fork(), + state.genesis_validators_root(), + &spec, + )); + let block_root = signed_block.canonical_root(); + let block_contents = (signed_block, blobs); + + harness + .process_block(deposit_slot, block_root, block_contents) + .await + .unwrap(); + + let post_block_state = harness.get_current_state(); + assert_eq!(post_block_state.pending_deposits().unwrap().len(), 1); + assert_eq!(post_block_state.validators().len(), initial_validator_count); + + // Finalize deposit. + // FIXME(sproul): this was intended just for testing, but it doesn't work yet + Box::pin(harness.extend_to_slot(deposit_slot + 2 * E::slots_per_epoch() + 2)).await; + let finalized_deposit_state = harness.get_current_state(); + assert_eq!( + finalized_deposit_state.validators().len(), + initial_validator_count + 1 + ); +} diff --git a/beacon_node/beacon_chain/tests/main.rs b/beacon_node/beacon_chain/tests/main.rs index 942ce81684..06e15e03af 100644 --- a/beacon_node/beacon_chain/tests/main.rs +++ b/beacon_node/beacon_chain/tests/main.rs @@ -3,6 +3,7 @@ mod attestation_verification; mod bellatrix; mod block_verification; mod capella; +mod electra; mod events; mod op_verification; mod payload_invalidation;