diff --git a/beacon_node/beacon_chain/src/block_production/gloas.rs b/beacon_node/beacon_chain/src/block_production/gloas.rs index df8d19d214..f895120eac 100644 --- a/beacon_node/beacon_chain/src/block_production/gloas.rs +++ b/beacon_node/beacon_chain/src/block_production/gloas.rs @@ -444,9 +444,9 @@ impl BeaconChain { /// Complete a block by computing its state root, and /// - /// Return `(block, pending_state, block_value)` where: + /// Return `(block, post_block_state, block_value)` where: /// - /// - `pending_state` is the state post block application (prior to payload application) + /// - `post_block_state` is the state post block application /// - `block_value` is the consensus-layer rewards for `block` #[allow(clippy::type_complexity)] #[instrument(skip_all, level = "debug")] @@ -571,9 +571,6 @@ impl BeaconChain { drop(state_root_timer); - // Clone the Pending state (post-block, pre-envelope) for callers that need it. - let pending_state = state.clone(); - let (mut block, _) = signed_beacon_block.deconstruct(); *block.state_root_mut() = state_root; @@ -628,7 +625,7 @@ impl BeaconChain { "Produced beacon block" ); - Ok((block, pending_state, consensus_block_value)) + Ok((block, state, consensus_block_value)) } // TODO(gloas) introduce `ProposerPreferences` so we can build out trustless diff --git a/beacon_node/beacon_chain/src/test_utils.rs b/beacon_node/beacon_chain/src/test_utils.rs index e84f9ad983..00a2ed64f1 100644 --- a/beacon_node/beacon_chain/src/test_utils.rs +++ b/beacon_node/beacon_chain/src/test_utils.rs @@ -1102,7 +1102,7 @@ where } /// Returns a newly created block, signed by the proposer for the given slot, - /// along with the execution payload envelope (for Gloas) and the pending state. + /// along with the execution payload envelope (for Gloas) and the post-block state. /// /// For pre-Gloas forks, the envelope is `None` and this behaves like `make_block`. pub async fn make_block_with_envelope( @@ -1142,7 +1142,7 @@ where ) }; - let (block, pending_state, _consensus_block_value) = self + let (block, post_block_state, _consensus_block_value) = self .chain .produce_block_on_state_gloas( state, @@ -1159,8 +1159,8 @@ where let signed_block = Arc::new(block.sign( &self.validator_keypairs[proposer_index].sk, - &pending_state.fork(), - pending_state.genesis_validators_root(), + &post_block_state.fork(), + post_block_state.genesis_validators_root(), &self.spec, )); @@ -1175,8 +1175,8 @@ where let domain = self.spec.get_domain( epoch, Domain::BeaconBuilder, - &pending_state.fork(), - pending_state.genesis_validators_root(), + &post_block_state.fork(), + post_block_state.genesis_validators_root(), ); let message = envelope.signing_root(domain); let signature = self.validator_keypairs[proposer_index].sk.sign(message); @@ -1187,7 +1187,7 @@ where }); let block_contents: SignedBlockContentsTuple = (signed_block, None); - (block_contents, signed_envelope, pending_state) + (block_contents, signed_envelope, post_block_state) } else { let (block_contents, state) = self.make_block(state, slot).await; (block_contents, None, state) diff --git a/beacon_node/beacon_chain/tests/store_tests.rs b/beacon_node/beacon_chain/tests/store_tests.rs index 47bda60eb8..86adf50995 100644 --- a/beacon_node/beacon_chain/tests/store_tests.rs +++ b/beacon_node/beacon_chain/tests/store_tests.rs @@ -5693,7 +5693,7 @@ async fn test_gloas_block_and_envelope_storage_generic( check_db_invariants(&harness); } -/// Test block replay with and without envelopes. +/// Test that Gloas block replay works without envelopes. #[tokio::test] async fn test_gloas_block_replay_with_envelopes() { if !fork_name_from_env().is_some_and(|f| f.gloas_enabled()) { @@ -5709,14 +5709,13 @@ async fn test_gloas_block_replay_with_envelopes() { let mut state = genesis_state.clone(); let mut last_block_root = Hash256::zero(); - let mut pending_states = HashMap::new(); - let mut full_states = HashMap::new(); + let mut states = HashMap::new(); for i in 1..=num_blocks { let slot = Slot::new(i); harness.advance_slot(); - let (block_contents, envelope, pending_state) = + let (block_contents, envelope, mut block_state) = harness.make_block_with_envelope(state, slot).await; let block_root = block_contents.0.canonical_root(); @@ -5725,18 +5724,16 @@ async fn test_gloas_block_replay_with_envelopes() { .await .unwrap(); - let pending_state_root = pending_state.clone().update_tree_hash_cache().unwrap(); - pending_states.insert(slot, (pending_state_root, pending_state.clone())); + let state_root = block_state.update_tree_hash_cache().unwrap(); + states.insert(slot, (state_root, block_state.clone())); let envelope = envelope.expect("Gloas block should have envelope"); - let full_state = pending_state; harness - .process_envelope(block_root, envelope, &full_state, pending_state_root) + .process_envelope(block_root, envelope, &block_state, state_root) .await; - full_states.insert(slot, (pending_state_root, full_state.clone())); last_block_root = block_root; - state = full_state; + state = block_state; } let end_slot = Slot::new(num_blocks); @@ -5756,7 +5753,7 @@ async fn test_gloas_block_replay_with_envelopes() { .into_state(); replayed.apply_pending_mutations().unwrap(); - let (_, mut expected) = pending_states.get(&end_slot).unwrap().clone(); + let (_, mut expected) = states.get(&end_slot).unwrap().clone(); expected.apply_pending_mutations().unwrap(); replayed.drop_all_caches().unwrap(); @@ -5782,8 +5779,7 @@ async fn test_gloas_hot_state_hierarchy() { // Build enough blocks to span multiple epochs. With MinimalEthSpec (8 slots/epoch), // 40 slots covers 5 epochs. let num_blocks = E::slots_per_epoch() * 5; - // TODO(gloas): enable finalisation by increasing this threshold - let some_validators = (0..LOW_VALIDATOR_COUNT).collect::>(); + let all_validators = (0..LOW_VALIDATOR_COUNT).collect::>(); let (genesis_state, _genesis_state_root) = harness.get_current_state_and_root(); @@ -5796,7 +5792,7 @@ async fn test_gloas_hot_state_hierarchy() { let slot = Slot::new(i); harness.advance_slot(); - let (block_contents, envelope, mut pending_state) = + let (block_contents, envelope, mut block_state) = harness.make_block_with_envelope(state.clone(), slot).await; let block_root = block_contents.0.canonical_root(); let signed_block = block_contents.0.clone(); @@ -5809,24 +5805,22 @@ async fn test_gloas_hot_state_hierarchy() { // Attest to the current block at its own slot (same-slot attestation). // In Gloas, same-slot attestations have index=0 and route to Pending in // fork choice, correctly propagating weight through the Full path. - // Use pending_state (at slot i) so the target root resolves correctly. - let pending_state_root = pending_state.update_tree_hash_cache().unwrap(); + let state_root = block_state.update_tree_hash_cache().unwrap(); harness.attest_block( - &pending_state, - pending_state_root, + &block_state, + state_root, block_root.into(), &signed_block, - &some_validators, + &all_validators, ); let envelope = envelope.expect("Gloas block should have envelope"); - let full_state = pending_state; harness - .process_envelope(block_root, envelope, &full_state, pending_state_root) + .process_envelope(block_root, envelope, &block_state, state_root) .await; last_block_root = block_root; - state = full_state; + state = block_state; } // Head should be the block at slot 40 with full payload. diff --git a/beacon_node/http_api/src/produce_block.rs b/beacon_node/http_api/src/produce_block.rs index 70475de130..7173eb698f 100644 --- a/beacon_node/http_api/src/produce_block.rs +++ b/beacon_node/http_api/src/produce_block.rs @@ -70,7 +70,7 @@ pub async fn produce_block_v4( let graffiti_settings = GraffitiSettings::new(query.graffiti, query.graffiti_policy); - let (block, _pending_state, consensus_block_value) = chain + let (block, _block_state, consensus_block_value) = chain .produce_block_with_verification_gloas( randao_reveal, slot,