mirror of
https://github.com/sigp/lighthouse.git
synced 2026-07-04 05:14:33 +00:00
Merge branch 'unstable' into gloas-http-tests
This commit is contained in:
8
Cargo.lock
generated
8
Cargo.lock
generated
@@ -5266,7 +5266,7 @@ dependencies = [
|
|||||||
"rcgen",
|
"rcgen",
|
||||||
"ring",
|
"ring",
|
||||||
"rustls 0.23.35",
|
"rustls 0.23.35",
|
||||||
"rustls-webpki 0.103.12",
|
"rustls-webpki 0.103.13",
|
||||||
"thiserror 2.0.17",
|
"thiserror 2.0.17",
|
||||||
"x509-parser",
|
"x509-parser",
|
||||||
"yasna",
|
"yasna",
|
||||||
@@ -7678,7 +7678,7 @@ dependencies = [
|
|||||||
"once_cell",
|
"once_cell",
|
||||||
"ring",
|
"ring",
|
||||||
"rustls-pki-types",
|
"rustls-pki-types",
|
||||||
"rustls-webpki 0.103.12",
|
"rustls-webpki 0.103.13",
|
||||||
"subtle",
|
"subtle",
|
||||||
"zeroize",
|
"zeroize",
|
||||||
]
|
]
|
||||||
@@ -7727,9 +7727,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustls-webpki"
|
name = "rustls-webpki"
|
||||||
version = "0.103.12"
|
version = "0.103.13"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8279bb85272c9f10811ae6a6c547ff594d6a7f3c6c6b02ee9726d1d0dcfcdd06"
|
checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ring",
|
"ring",
|
||||||
"rustls-pki-types",
|
"rustls-pki-types",
|
||||||
|
|||||||
2
Makefile
2
Makefile
@@ -330,7 +330,7 @@ install-audit:
|
|||||||
cargo install --force cargo-audit
|
cargo install --force cargo-audit
|
||||||
|
|
||||||
audit-CI:
|
audit-CI:
|
||||||
cargo audit --ignore RUSTSEC-2026-0049 --ignore RUSTSEC-2026-0098 --ignore RUSTSEC-2026-0099
|
cargo audit --ignore RUSTSEC-2026-0049 --ignore RUSTSEC-2026-0098 --ignore RUSTSEC-2026-0099 --ignore RUSTSEC-2026-0104
|
||||||
|
|
||||||
# Runs cargo deny (check for banned crates, duplicate versions, and source restrictions)
|
# Runs cargo deny (check for banned crates, duplicate versions, and source restrictions)
|
||||||
deny: install-deny deny-CI
|
deny: install-deny deny-CI
|
||||||
|
|||||||
@@ -444,9 +444,9 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
|||||||
|
|
||||||
/// Complete a block by computing its state root, and
|
/// 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`
|
/// - `block_value` is the consensus-layer rewards for `block`
|
||||||
#[allow(clippy::type_complexity)]
|
#[allow(clippy::type_complexity)]
|
||||||
#[instrument(skip_all, level = "debug")]
|
#[instrument(skip_all, level = "debug")]
|
||||||
@@ -571,9 +571,6 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
|||||||
|
|
||||||
drop(state_root_timer);
|
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();
|
let (mut block, _) = signed_beacon_block.deconstruct();
|
||||||
*block.state_root_mut() = state_root;
|
*block.state_root_mut() = state_root;
|
||||||
|
|
||||||
@@ -628,7 +625,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
|||||||
"Produced beacon block"
|
"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
|
// TODO(gloas) introduce `ProposerPreferences` so we can build out trustless
|
||||||
@@ -693,13 +690,19 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
|||||||
let parent_bid = state.latest_execution_payload_bid()?;
|
let parent_bid = state.latest_execution_payload_bid()?;
|
||||||
|
|
||||||
// TODO(gloas): need should_extend_payload check here as well
|
// TODO(gloas): need should_extend_payload check here as well
|
||||||
let parent_block_hash = if parent_payload_status == PayloadStatus::Full {
|
let parent_block_slot = state.latest_block_header().slot;
|
||||||
// Build on parent bid's payload.
|
let parent_is_pre_gloas = !self
|
||||||
parent_bid.block_hash
|
.spec
|
||||||
} else {
|
.fork_name_at_slot::<T::EthSpec>(parent_block_slot)
|
||||||
// Skip parent bid's payload. For genesis this is the EL genesis hash.
|
.gloas_enabled();
|
||||||
parent_bid.parent_block_hash
|
let parent_block_hash =
|
||||||
};
|
if parent_payload_status == PayloadStatus::Full || parent_is_pre_gloas {
|
||||||
|
// Build on parent bid's payload.
|
||||||
|
parent_bid.block_hash
|
||||||
|
} else {
|
||||||
|
// Skip parent bid's payload. For genesis this is the EL genesis hash.
|
||||||
|
parent_bid.parent_block_hash
|
||||||
|
};
|
||||||
|
|
||||||
// TODO(gloas) this should be BlockProductionVersion::V4
|
// TODO(gloas) this should be BlockProductionVersion::V4
|
||||||
// V3 is okay for now as long as we're not connected to a builder
|
// V3 is okay for now as long as we're not connected to a builder
|
||||||
|
|||||||
@@ -1124,7 +1124,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a newly created block, signed by the proposer for the given slot,
|
/// 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`.
|
/// For pre-Gloas forks, the envelope is `None` and this behaves like `make_block`.
|
||||||
pub async fn make_block_with_envelope(
|
pub async fn make_block_with_envelope(
|
||||||
@@ -1164,7 +1164,7 @@ where
|
|||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
let (block, pending_state, _consensus_block_value) = self
|
let (block, post_block_state, _consensus_block_value) = self
|
||||||
.chain
|
.chain
|
||||||
.produce_block_on_state_gloas(
|
.produce_block_on_state_gloas(
|
||||||
state,
|
state,
|
||||||
@@ -1181,8 +1181,8 @@ where
|
|||||||
|
|
||||||
let signed_block = Arc::new(block.sign(
|
let signed_block = Arc::new(block.sign(
|
||||||
&self.validator_keypairs[proposer_index].sk,
|
&self.validator_keypairs[proposer_index].sk,
|
||||||
&pending_state.fork(),
|
&post_block_state.fork(),
|
||||||
pending_state.genesis_validators_root(),
|
post_block_state.genesis_validators_root(),
|
||||||
&self.spec,
|
&self.spec,
|
||||||
));
|
));
|
||||||
|
|
||||||
@@ -1197,8 +1197,8 @@ where
|
|||||||
let domain = self.spec.get_domain(
|
let domain = self.spec.get_domain(
|
||||||
epoch,
|
epoch,
|
||||||
Domain::BeaconBuilder,
|
Domain::BeaconBuilder,
|
||||||
&pending_state.fork(),
|
&post_block_state.fork(),
|
||||||
pending_state.genesis_validators_root(),
|
post_block_state.genesis_validators_root(),
|
||||||
);
|
);
|
||||||
let message = envelope.signing_root(domain);
|
let message = envelope.signing_root(domain);
|
||||||
let signature = self.validator_keypairs[proposer_index].sk.sign(message);
|
let signature = self.validator_keypairs[proposer_index].sk.sign(message);
|
||||||
@@ -1209,7 +1209,7 @@ where
|
|||||||
});
|
});
|
||||||
|
|
||||||
let block_contents: SignedBlockContentsTuple<E> = (signed_block, None);
|
let block_contents: SignedBlockContentsTuple<E> = (signed_block, None);
|
||||||
(block_contents, signed_envelope, pending_state)
|
(block_contents, signed_envelope, post_block_state)
|
||||||
} else {
|
} else {
|
||||||
let (block_contents, state) = self.make_block(state, slot).await;
|
let (block_contents, state) = self.make_block(state, slot).await;
|
||||||
(block_contents, None, state)
|
(block_contents, None, state)
|
||||||
|
|||||||
@@ -5693,7 +5693,7 @@ async fn test_gloas_block_and_envelope_storage_generic(
|
|||||||
check_db_invariants(&harness);
|
check_db_invariants(&harness);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Test block replay with and without envelopes.
|
/// Test that Gloas block replay works without envelopes.
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn test_gloas_block_replay_with_envelopes() {
|
async fn test_gloas_block_replay_with_envelopes() {
|
||||||
if !fork_name_from_env().is_some_and(|f| f.gloas_enabled()) {
|
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 state = genesis_state.clone();
|
||||||
|
|
||||||
let mut last_block_root = Hash256::zero();
|
let mut last_block_root = Hash256::zero();
|
||||||
let mut pending_states = HashMap::new();
|
let mut states = HashMap::new();
|
||||||
let mut full_states = HashMap::new();
|
|
||||||
|
|
||||||
for i in 1..=num_blocks {
|
for i in 1..=num_blocks {
|
||||||
let slot = Slot::new(i);
|
let slot = Slot::new(i);
|
||||||
harness.advance_slot();
|
harness.advance_slot();
|
||||||
|
|
||||||
let (block_contents, envelope, pending_state) =
|
let (block_contents, envelope, mut block_state) =
|
||||||
harness.make_block_with_envelope(state, slot).await;
|
harness.make_block_with_envelope(state, slot).await;
|
||||||
let block_root = block_contents.0.canonical_root();
|
let block_root = block_contents.0.canonical_root();
|
||||||
|
|
||||||
@@ -5725,18 +5724,16 @@ async fn test_gloas_block_replay_with_envelopes() {
|
|||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let pending_state_root = pending_state.clone().update_tree_hash_cache().unwrap();
|
let state_root = block_state.update_tree_hash_cache().unwrap();
|
||||||
pending_states.insert(slot, (pending_state_root, pending_state.clone()));
|
states.insert(slot, (state_root, block_state.clone()));
|
||||||
|
|
||||||
let envelope = envelope.expect("Gloas block should have envelope");
|
let envelope = envelope.expect("Gloas block should have envelope");
|
||||||
let full_state = pending_state;
|
|
||||||
harness
|
harness
|
||||||
.process_envelope(block_root, envelope, &full_state, pending_state_root)
|
.process_envelope(block_root, envelope, &block_state, state_root)
|
||||||
.await;
|
.await;
|
||||||
full_states.insert(slot, (pending_state_root, full_state.clone()));
|
|
||||||
|
|
||||||
last_block_root = block_root;
|
last_block_root = block_root;
|
||||||
state = full_state;
|
state = block_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
let end_slot = Slot::new(num_blocks);
|
let end_slot = Slot::new(num_blocks);
|
||||||
@@ -5756,7 +5753,7 @@ async fn test_gloas_block_replay_with_envelopes() {
|
|||||||
.into_state();
|
.into_state();
|
||||||
replayed.apply_pending_mutations().unwrap();
|
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();
|
expected.apply_pending_mutations().unwrap();
|
||||||
|
|
||||||
replayed.drop_all_caches().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),
|
// Build enough blocks to span multiple epochs. With MinimalEthSpec (8 slots/epoch),
|
||||||
// 40 slots covers 5 epochs.
|
// 40 slots covers 5 epochs.
|
||||||
let num_blocks = E::slots_per_epoch() * 5;
|
let num_blocks = E::slots_per_epoch() * 5;
|
||||||
// TODO(gloas): enable finalisation by increasing this threshold
|
let all_validators = (0..LOW_VALIDATOR_COUNT).collect::<Vec<_>>();
|
||||||
let some_validators = (0..LOW_VALIDATOR_COUNT).collect::<Vec<_>>();
|
|
||||||
|
|
||||||
let (genesis_state, _genesis_state_root) = harness.get_current_state_and_root();
|
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);
|
let slot = Slot::new(i);
|
||||||
harness.advance_slot();
|
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;
|
harness.make_block_with_envelope(state.clone(), slot).await;
|
||||||
let block_root = block_contents.0.canonical_root();
|
let block_root = block_contents.0.canonical_root();
|
||||||
let signed_block = block_contents.0.clone();
|
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).
|
// 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
|
// In Gloas, same-slot attestations have index=0 and route to Pending in
|
||||||
// fork choice, correctly propagating weight through the Full path.
|
// fork choice, correctly propagating weight through the Full path.
|
||||||
// Use pending_state (at slot i) so the target root resolves correctly.
|
let state_root = block_state.update_tree_hash_cache().unwrap();
|
||||||
let pending_state_root = pending_state.update_tree_hash_cache().unwrap();
|
|
||||||
harness.attest_block(
|
harness.attest_block(
|
||||||
&pending_state,
|
&block_state,
|
||||||
pending_state_root,
|
state_root,
|
||||||
block_root.into(),
|
block_root.into(),
|
||||||
&signed_block,
|
&signed_block,
|
||||||
&some_validators,
|
&all_validators,
|
||||||
);
|
);
|
||||||
|
|
||||||
let envelope = envelope.expect("Gloas block should have envelope");
|
let envelope = envelope.expect("Gloas block should have envelope");
|
||||||
let full_state = pending_state;
|
|
||||||
harness
|
harness
|
||||||
.process_envelope(block_root, envelope, &full_state, pending_state_root)
|
.process_envelope(block_root, envelope, &block_state, state_root)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
last_block_root = block_root;
|
last_block_root = block_root;
|
||||||
state = full_state;
|
state = block_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Head should be the block at slot 40 with full payload.
|
// Head should be the block at slot 40 with full payload.
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ pub async fn produce_block_v4<T: BeaconChainTypes>(
|
|||||||
|
|
||||||
let graffiti_settings = GraffitiSettings::new(query.graffiti, query.graffiti_policy);
|
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(
|
.produce_block_with_verification_gloas(
|
||||||
randao_reveal,
|
randao_reveal,
|
||||||
slot,
|
slot,
|
||||||
|
|||||||
Reference in New Issue
Block a user