Skip to content

Commit

Permalink
Add ExecutionWitness to Payload
Browse files Browse the repository at this point in the history
  • Loading branch information
Mac L committed May 13, 2024
1 parent 969d12d commit bb06a34
Show file tree
Hide file tree
Showing 17 changed files with 682 additions and 30 deletions.
3 changes: 1 addition & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ validator_dir = { path = "common/validator_dir" }
warp_utils = { path = "common/warp_utils" }

[patch.crates-io]
ssz_types = { git = "https://github.com/macladson/ssz_types.git", branch = "optional" }
yamux = { git = "https://github.com/sigp/rust-yamux.git" }

[profile.maxperf]
Expand Down
20 changes: 9 additions & 11 deletions beacon_node/client/src/notifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -549,17 +549,15 @@ async fn electra_readiness_logging<T: BeaconChainTypes>(
beacon_chain: &BeaconChain<T>,
log: &Logger,
) {
// TODO(electra): Once Electra has features, this code can be swapped back.
let electra_completed = false;
//let electra_completed = beacon_chain
// .canonical_head
// .cached_head()
// .snapshot
// .beacon_block
// .message()
// .body()
// .execution_payload()
// .map_or(false, |payload| payload.electra_placeholder().is_ok());
let electra_completed = beacon_chain
.canonical_head
.cached_head()
.snapshot
.beacon_block
.message()
.body()
.execution_payload()
.map_or(false, |payload| payload.execution_witness_root().is_ok());

let has_execution_layer = beacon_chain.execution_layer.is_some();

Expand Down
4 changes: 4 additions & 0 deletions beacon_node/execution_layer/src/block_hash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ pub fn calculate_execution_block_hash<E: EthSpec>(
None
};

// TODO(mac): Fix rlp calc
let rlp_execution_witness_root = None;

let rlp_blob_gas_used = payload.blob_gas_used().ok();
let rlp_excess_blob_gas = payload.excess_blob_gas().ok();

Expand All @@ -48,6 +51,7 @@ pub fn calculate_execution_block_hash<E: EthSpec>(
rlp_blob_gas_used,
rlp_excess_blob_gas,
parent_beacon_block_root,
rlp_execution_witness_root,
);

// Hash the RLP encoding of the block header.
Expand Down
212 changes: 211 additions & 1 deletion beacon_node/execution_layer/src/engine_api/json_structures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,15 @@ use strum::EnumString;
use superstruct::superstruct;
use types::beacon_block_body::KzgCommitments;
use types::blob_sidecar::BlobsList;
use types::{FixedVector, Unsigned};
use types::{
execution_witness::{
BanderwagonFieldElement, BanderwagonGroupElement, IpaProof, StateDiff, StateDiffValue,
Stem, StemStateDiff, StemValue, SuffixStateDiff, VerkleProof,
},
ExecutionPayload, ExecutionPayloadCapella, ExecutionPayloadElectra, ExecutionPayloadMerge,
ExecutionWitness,
};
use types::{FixedVector, Option, Unsigned, VariableList};

#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
Expand Down Expand Up @@ -101,6 +109,8 @@ pub struct JsonExecutionPayload<E: EthSpec> {
#[superstruct(only(V3, V4))]
#[serde(with = "serde_utils::u64_hex_be")]
pub excess_blob_gas: u64,
#[superstruct(only(V4))]
pub execution_witness: JsonExecutionWitness<E>,
}

impl<E: EthSpec> From<ExecutionPayloadMerge<E>> for JsonExecutionPayloadV1<E> {
Expand Down Expand Up @@ -203,6 +213,7 @@ impl<E: EthSpec> From<ExecutionPayloadElectra<E>> for JsonExecutionPayloadV4<E>
.into(),
blob_gas_used: payload.blob_gas_used,
excess_blob_gas: payload.excess_blob_gas,
execution_witness: payload.execution_witness,
}
}
}
Expand Down Expand Up @@ -319,6 +330,7 @@ impl<E: EthSpec> From<JsonExecutionPayloadV4<E>> for ExecutionPayloadElectra<E>
.into(),
blob_gas_used: payload.blob_gas_used,
excess_blob_gas: payload.excess_blob_gas,
execution_witness: payload.execution_witness,
}
}
}
Expand Down Expand Up @@ -691,6 +703,7 @@ pub struct JsonExecutionPayloadBodyV1<E: EthSpec> {
#[serde(with = "ssz_types::serde_utils::list_of_hex_var_list")]
pub transactions: Transactions<E>,
pub withdrawals: Option<VariableList<JsonWithdrawal, E::MaxWithdrawalsPerPayload>>,
pub execution_witness: Option<JsonExecutionWitness<E>>,
}

impl<E: EthSpec> From<JsonExecutionPayloadBodyV1<E>> for ExecutionPayloadBodyV1<E> {
Expand All @@ -705,6 +718,7 @@ impl<E: EthSpec> From<JsonExecutionPayloadBodyV1<E>> for ExecutionPayloadBodyV1<
.collect::<Vec<_>>(),
)
}),
execution_witness: value.execution_witness.map(Into::into),
}
}
}
Expand Down Expand Up @@ -747,3 +761,199 @@ pub mod serde_logs_bloom {
.map_err(|e| serde::de::Error::custom(format!("invalid logs bloom: {:?}", e)))
}
}

pub fn serde_execution_witness<'de, D, T>(deserializer: D) -> Result<T, D::Error>
where
T: Default + Deserialize<'de>,
D: serde::Deserializer<'de>,
{
let opt = Option::deserialize(deserializer)?;
Ok(opt.unwrap_or_default())
}

/// Execution Witness JSON types.
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
#[serde(bound = "E: EthSpec", rename_all = "camelCase")]
pub struct JsonSuffixStateDiff<E: EthSpec> {
//#[serde(with = "eth2_serde_utils::quoted_u8")]
suffix: u8,
// `None` means not currently present.
current_value: Optional<StateDiffValue<E>>,
// `None` means value is not updated.
new_value: Optional<StateDiffValue<E>>,
}

impl<E: EthSpec> From<JsonSuffixStateDiff<E>> for SuffixStateDiff<E> {
fn from(value: JsonSuffixStateDiff<E>) -> Self {
Self {
suffix: value.suffix,
current_value: value.current_value,
new_value: value.new_value,
}
}
}

impl<E: EthSpec> From<SuffixStateDiff<E>> for JsonSuffixStateDiff<E> {
fn from(value: SuffixStateDiff<E>) -> Self {
Self {
suffix: value.suffix,
current_value: value.current_value,
new_value: value.new_value,
}
}
}

#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
#[serde(bound = "E: EthSpec", rename_all = "camelCase")]
pub struct JsonStemStateDiff<E: EthSpec> {
stem: Stem<E>,
suffix_diffs: VariableList<JsonSuffixStateDiff<E>, E::MaxVerkleWidth>,
}

impl<E: EthSpec> From<JsonStemStateDiff<E>> for StemStateDiff<E> {
fn from(value: JsonStemStateDiff<E>) -> Self {
Self {
stem: value.stem,
suffix_diffs: value
.suffix_diffs
.into_iter()
.map(Into::into)
.collect::<Vec<_>>()
.into(),
}
}
}

impl<E: EthSpec> From<StemStateDiff<E>> for JsonStemStateDiff<E> {
fn from(value: StemStateDiff<E>) -> Self {
Self {
stem: value.stem,
suffix_diffs: value
.suffix_diffs
.into_iter()
.map(Into::into)
.collect::<Vec<_>>()
.into(),
}
}
}

#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
#[serde(bound = "E: EthSpec", rename_all = "camelCase")]
pub struct JsonIpaProof<E: EthSpec> {
cl: FixedVector<BanderwagonGroupElement<E>, E::IpaProofDepth>,
cr: FixedVector<BanderwagonGroupElement<E>, E::IpaProofDepth>,
final_evaluation: BanderwagonFieldElement<E>,
}

impl<E: EthSpec> From<JsonIpaProof<E>> for IpaProof<E> {
fn from(value: JsonIpaProof<E>) -> Self {
Self {
cl: value.cl,
cr: value.cr,
final_evaluation: value.final_evaluation,
}
}
}

impl<E: EthSpec> From<IpaProof<E>> for JsonIpaProof<E> {
fn from(value: IpaProof<E>) -> Self {
Self {
cl: value.cl,
cr: value.cr,
final_evaluation: value.final_evaluation,
}
}
}

#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
#[serde(bound = "E: EthSpec", rename_all = "camelCase")]
pub struct JsonVerkleProof<E: EthSpec> {
other_stems: VariableList<StemValue<E>, E::MaxStems>,
#[serde(with = "ssz_types::serde_utils::hex_var_list")]
depth_extension_present: VariableList<u8, E::MaxStems>,
commitments_by_path: VariableList<BanderwagonGroupElement<E>, E::MaxCommittments>,
d: BanderwagonGroupElement<E>,
ipa_proof: JsonIpaProof<E>,
}

impl<E: EthSpec> From<JsonVerkleProof<E>> for VerkleProof<E> {
fn from(value: JsonVerkleProof<E>) -> Self {
Self {
other_stems: value.other_stems,
depth_extension_present: value.depth_extension_present,
commitments_by_path: value.commitments_by_path,
d: value.d,
ipa_proof: IpaProof::<E>::from(value.ipa_proof),
}
}
}

impl<E: EthSpec> From<VerkleProof<E>> for JsonVerkleProof<E> {
fn from(value: VerkleProof<E>) -> Self {
Self {
other_stems: value.other_stems,
depth_extension_present: value.depth_extension_present,
commitments_by_path: value.commitments_by_path,
d: value.d,
ipa_proof: JsonIpaProof::<E>::from(value.ipa_proof),
}
}
}

#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
#[serde(bound = "E: EthSpec", transparent)]
pub struct JsonStateDiff<E: EthSpec> {
inner: VariableList<JsonStemStateDiff<E>, E::MaxStems>,
}

impl<E: EthSpec> From<JsonStateDiff<E>> for StateDiff<E> {
fn from(value: JsonStateDiff<E>) -> Self {
Self {
inner: value
.inner
.into_iter()
.map(Into::into)
.collect::<Vec<_>>()
.into(),
}
}
}

impl<E: EthSpec> From<StateDiff<E>> for JsonStateDiff<E> {
fn from(value: StateDiff<E>) -> Self {
Self {
inner: value
.inner
.into_iter()
.map(Into::into)
.collect::<Vec<_>>()
.into(),
}
}
}

#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
#[serde(bound = "E: EthSpec", rename_all = "camelCase")]
pub struct JsonExecutionWitness<E: EthSpec> {
state_diff: JsonStateDiff<E>,
verkle_proof: JsonVerkleProof<E>,
}

impl<E: EthSpec> From<JsonExecutionWitness<E>> for ExecutionWitness<E> {
fn from(value: JsonExecutionWitness<E>) -> Self {
Self {
state_diff: StateDiff::<E>::from(value.state_diff),
verkle_proof: VerkleProof::<E>::from(value.verkle_proof),
}
}
}

impl<E: EthSpec> From<ExecutionWitness<E>> for JsonExecutionWitness<E> {
fn from(value: ExecutionWitness<E>) -> Self {
Self {
state_diff: JsonStateDiff::<E>::from(value.state_diff),
verkle_proof: JsonVerkleProof::<E>::from(value.verkle_proof),
}
}
}
1 change: 1 addition & 0 deletions beacon_node/execution_layer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1974,6 +1974,7 @@ impl<E: EthSpec> ExecutionLayer<E> {
withdrawals,
blob_gas_used: electra_block.blob_gas_used,
excess_blob_gas: electra_block.excess_blob_gas,
execution_witness: electra_block.execution_witness.into(),
})
}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use tree_hash_derive::TreeHash;
use types::{
Blob, ChainSpec, EthSpec, ExecutionBlockHash, ExecutionPayload, ExecutionPayloadCapella,
ExecutionPayloadDeneb, ExecutionPayloadElectra, ExecutionPayloadHeader, ExecutionPayloadMerge,
ForkName, Hash256, Transaction, Transactions, Uint256,
ExecutionWitness, ForkName, Hash256, Transaction, Transactions, Uint256,
};

use super::DEFAULT_TERMINAL_BLOCK;
Expand Down Expand Up @@ -646,6 +646,7 @@ impl<E: EthSpec> ExecutionBlockGenerator<E> {
withdrawals: pa.withdrawals.clone().into(),
blob_gas_used: 0,
excess_blob_gas: 0,
execution_witness: ExecutionWitness::default(),
}),
_ => unreachable!(),
},
Expand Down
1 change: 1 addition & 0 deletions beacon_node/execution_layer/src/test_utils/handle_rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,7 @@ pub async fn handle_rpc<E: EthSpec>(
.withdrawals()
.ok()
.map(|withdrawals| VariableList::from(withdrawals.clone())),
execution_witness: block.execution_witness().ok().cloned(),
}));
}
None => response.push(None),
Expand Down
13 changes: 8 additions & 5 deletions beacon_node/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -412,9 +412,11 @@ pub fn get_config<E: EthSpec>(
.map_err(|_| "auto-compact-db takes a boolean".to_string())?;
}

if let Some(prune_payloads) = clap_utils::parse_optional(cli_args, "prune-payloads")? {
client_config.store.prune_payloads = prune_payloads;
}
//TODO(mac): Re-enable prune payloads once Geth supports it.
client_config.store.prune_payloads = false;
//if let Some(prune_payloads) = clap_utils::parse_optional(cli_args, "prune-payloads")? {
// client_config.store.prune_payloads = prune_payloads;
//}

if let Some(epochs_per_migration) =
clap_utils::parse_optional(cli_args, "epochs-per-migration")?
Expand Down Expand Up @@ -825,8 +827,9 @@ pub fn get_config<E: EthSpec>(
}

// Optimistic finalized sync.
client_config.chain.optimistic_finalized_sync =
!cli_args.is_present("disable-optimistic-finalized-sync");
client_config.chain.optimistic_finalized_sync = false;
// TODO(mac) remove this once optimistic finalized sync is working.
// !cli_args.is_present("disable-optimistic-finalized-sync");

if cli_args.is_present("genesis-backfill") {
client_config.chain.genesis_backfill = true;
Expand Down
Loading

0 comments on commit bb06a34

Please sign in to comment.