mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-19 21:04:41 +00:00
Retrospective invalidation of exec. payloads for opt. sync (#2837)
## Issue Addressed
NA
## Proposed Changes
Adds the functionality to allow blocks to be validated/invalidated after their import as per the [optimistic sync spec](https://github.com/ethereum/consensus-specs/blob/dev/sync/optimistic.md#how-to-optimistically-import-blocks). This means:
- Updating `ProtoArray` to allow flipping the `execution_status` of ancestors/descendants based on payload validity updates.
- Creating separation between `execution_layer` and the `beacon_chain` by creating a `PayloadStatus` struct.
- Refactoring how the `execution_layer` selects a `PayloadStatus` from the multiple statuses returned from multiple EEs.
- Adding testing framework for optimistic imports.
- Add `ExecutionBlockHash(Hash256)` new-type struct to avoid confusion between *beacon block roots* and *execution payload hashes*.
- Add `merge` to [`FORKS`](c3a793fd73/Makefile (L17)) in the `Makefile` to ensure we test the beacon chain with merge settings.
- Fix some tests here that were failing due to a missing execution layer.
## TODO
- [ ] Balance tests
Co-authored-by: Mark Mackey <mark@sigmaprime.io>
This commit is contained in:
@@ -144,7 +144,7 @@ pub struct ChainSpec {
|
||||
/// The Merge fork epoch is optional, with `None` representing "Merge never happens".
|
||||
pub bellatrix_fork_epoch: Option<Epoch>,
|
||||
pub terminal_total_difficulty: Uint256,
|
||||
pub terminal_block_hash: Hash256,
|
||||
pub terminal_block_hash: ExecutionBlockHash,
|
||||
pub terminal_block_hash_activation_epoch: Epoch,
|
||||
|
||||
/*
|
||||
@@ -549,7 +549,7 @@ impl ChainSpec {
|
||||
// `Uint256::MAX` which is `2*256- 1`.
|
||||
.checked_add(Uint256::one())
|
||||
.expect("addition does not overflow"),
|
||||
terminal_block_hash: Hash256::zero(),
|
||||
terminal_block_hash: ExecutionBlockHash::zero(),
|
||||
terminal_block_hash_activation_epoch: Epoch::new(u64::MAX),
|
||||
|
||||
/*
|
||||
@@ -746,7 +746,7 @@ impl ChainSpec {
|
||||
// `Uint256::MAX` which is `2*256- 1`.
|
||||
.checked_add(Uint256::one())
|
||||
.expect("addition does not overflow"),
|
||||
terminal_block_hash: Hash256::zero(),
|
||||
terminal_block_hash: ExecutionBlockHash::zero(),
|
||||
terminal_block_hash_activation_epoch: Epoch::new(u64::MAX),
|
||||
|
||||
/*
|
||||
@@ -787,7 +787,7 @@ pub struct Config {
|
||||
pub terminal_total_difficulty: Uint256,
|
||||
// TODO(merge): remove this default
|
||||
#[serde(default = "default_terminal_block_hash")]
|
||||
pub terminal_block_hash: Hash256,
|
||||
pub terminal_block_hash: ExecutionBlockHash,
|
||||
// TODO(merge): remove this default
|
||||
#[serde(default = "default_terminal_block_hash_activation_epoch")]
|
||||
pub terminal_block_hash_activation_epoch: Epoch,
|
||||
@@ -870,8 +870,8 @@ const fn default_terminal_total_difficulty() -> Uint256 {
|
||||
])
|
||||
}
|
||||
|
||||
fn default_terminal_block_hash() -> Hash256 {
|
||||
Hash256::zero()
|
||||
fn default_terminal_block_hash() -> ExecutionBlockHash {
|
||||
ExecutionBlockHash::zero()
|
||||
}
|
||||
|
||||
fn default_terminal_block_hash_activation_epoch() -> Epoch {
|
||||
|
||||
101
consensus/types/src/execution_block_hash.rs
Normal file
101
consensus/types/src/execution_block_hash.rs
Normal file
@@ -0,0 +1,101 @@
|
||||
use crate::test_utils::TestRandom;
|
||||
use crate::Hash256;
|
||||
use rand::RngCore;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use ssz::{Decode, DecodeError, Encode};
|
||||
use std::fmt;
|
||||
|
||||
#[cfg_attr(feature = "arbitrary-fuzz", derive(arbitrary::Arbitrary))]
|
||||
#[derive(Default, Debug, Clone, Copy, Serialize, Deserialize, Eq, PartialEq, Hash)]
|
||||
#[serde(transparent)]
|
||||
pub struct ExecutionBlockHash(Hash256);
|
||||
|
||||
impl ExecutionBlockHash {
|
||||
pub fn zero() -> Self {
|
||||
Self(Hash256::zero())
|
||||
}
|
||||
|
||||
pub fn repeat_byte(b: u8) -> Self {
|
||||
Self(Hash256::repeat_byte(b))
|
||||
}
|
||||
|
||||
pub fn from_root(root: Hash256) -> Self {
|
||||
Self(root)
|
||||
}
|
||||
|
||||
pub fn into_root(self) -> Hash256 {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for ExecutionBlockHash {
|
||||
fn is_ssz_fixed_len() -> bool {
|
||||
<Hash256 as Encode>::is_ssz_fixed_len()
|
||||
}
|
||||
|
||||
fn ssz_fixed_len() -> usize {
|
||||
<Hash256 as Encode>::ssz_fixed_len()
|
||||
}
|
||||
|
||||
fn ssz_bytes_len(&self) -> usize {
|
||||
self.0.ssz_bytes_len()
|
||||
}
|
||||
|
||||
fn ssz_append(&self, buf: &mut Vec<u8>) {
|
||||
self.0.ssz_append(buf)
|
||||
}
|
||||
}
|
||||
|
||||
impl Decode for ExecutionBlockHash {
|
||||
fn is_ssz_fixed_len() -> bool {
|
||||
<Hash256 as Decode>::is_ssz_fixed_len()
|
||||
}
|
||||
|
||||
fn ssz_fixed_len() -> usize {
|
||||
<Hash256 as Decode>::ssz_fixed_len()
|
||||
}
|
||||
|
||||
fn from_ssz_bytes(bytes: &[u8]) -> Result<Self, DecodeError> {
|
||||
Hash256::from_ssz_bytes(bytes).map(Self)
|
||||
}
|
||||
}
|
||||
|
||||
impl tree_hash::TreeHash for ExecutionBlockHash {
|
||||
fn tree_hash_type() -> tree_hash::TreeHashType {
|
||||
Hash256::tree_hash_type()
|
||||
}
|
||||
|
||||
fn tree_hash_packed_encoding(&self) -> Vec<u8> {
|
||||
self.0.tree_hash_packed_encoding()
|
||||
}
|
||||
|
||||
fn tree_hash_packing_factor() -> usize {
|
||||
Hash256::tree_hash_packing_factor()
|
||||
}
|
||||
|
||||
fn tree_hash_root(&self) -> tree_hash::Hash256 {
|
||||
self.0.tree_hash_root()
|
||||
}
|
||||
}
|
||||
|
||||
impl TestRandom for ExecutionBlockHash {
|
||||
fn random_for_test(rng: &mut impl RngCore) -> Self {
|
||||
Self(Hash256::random_for_test(rng))
|
||||
}
|
||||
}
|
||||
|
||||
impl std::str::FromStr for ExecutionBlockHash {
|
||||
type Err = String;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
Hash256::from_str(s)
|
||||
.map(Self)
|
||||
.map_err(|e| format!("{:?}", e))
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for ExecutionBlockHash {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}", self.0)
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,7 @@ pub type Transaction<T> = VariableList<u8, T>;
|
||||
#[derivative(PartialEq, Hash(bound = "T: EthSpec"))]
|
||||
#[serde(bound = "T: EthSpec")]
|
||||
pub struct ExecutionPayload<T: EthSpec> {
|
||||
pub parent_hash: Hash256,
|
||||
pub parent_hash: ExecutionBlockHash,
|
||||
pub fee_recipient: Address,
|
||||
pub state_root: Hash256,
|
||||
pub receipts_root: Hash256,
|
||||
@@ -34,7 +34,7 @@ pub struct ExecutionPayload<T: EthSpec> {
|
||||
pub extra_data: VariableList<u8, T::MaxExtraDataBytes>,
|
||||
#[serde(with = "eth2_serde_utils::quoted_u256")]
|
||||
pub base_fee_per_gas: Uint256,
|
||||
pub block_hash: Hash256,
|
||||
pub block_hash: ExecutionBlockHash,
|
||||
#[serde(with = "ssz_types::serde_utils::list_of_hex_var_list")]
|
||||
pub transactions:
|
||||
VariableList<Transaction<T::MaxBytesPerTransaction>, T::MaxTransactionsPerPayload>,
|
||||
|
||||
@@ -9,7 +9,7 @@ use tree_hash_derive::TreeHash;
|
||||
Default, Debug, Clone, PartialEq, Serialize, Deserialize, Encode, Decode, TreeHash, TestRandom,
|
||||
)]
|
||||
pub struct ExecutionPayloadHeader<T: EthSpec> {
|
||||
pub parent_hash: Hash256,
|
||||
pub parent_hash: ExecutionBlockHash,
|
||||
pub fee_recipient: Address,
|
||||
pub state_root: Hash256,
|
||||
pub receipts_root: Hash256,
|
||||
@@ -28,7 +28,7 @@ pub struct ExecutionPayloadHeader<T: EthSpec> {
|
||||
pub extra_data: VariableList<u8, T::MaxExtraDataBytes>,
|
||||
#[serde(with = "eth2_serde_utils::quoted_u256")]
|
||||
pub base_fee_per_gas: Uint256,
|
||||
pub block_hash: Hash256,
|
||||
pub block_hash: ExecutionBlockHash,
|
||||
pub transactions_root: Hash256,
|
||||
}
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ pub mod deposit_message;
|
||||
pub mod enr_fork_id;
|
||||
pub mod eth1_data;
|
||||
pub mod eth_spec;
|
||||
pub mod execution_block_hash;
|
||||
pub mod execution_payload;
|
||||
pub mod execution_payload_header;
|
||||
pub mod fork;
|
||||
@@ -113,6 +114,7 @@ pub use crate::deposit_message::DepositMessage;
|
||||
pub use crate::enr_fork_id::EnrForkId;
|
||||
pub use crate::eth1_data::Eth1Data;
|
||||
pub use crate::eth_spec::EthSpecId;
|
||||
pub use crate::execution_block_hash::ExecutionBlockHash;
|
||||
pub use crate::execution_payload::{ExecutionPayload, Transaction};
|
||||
pub use crate::execution_payload_header::ExecutionPayloadHeader;
|
||||
pub use crate::fork::Fork;
|
||||
|
||||
Reference in New Issue
Block a user