Skip to content

Commit bb06a34

Browse files
author
Mac L
committed
Add ExecutionWitness to Payload
1 parent 969d12d commit bb06a34

File tree

17 files changed

+682
-30
lines changed

17 files changed

+682
-30
lines changed

Cargo.lock

Lines changed: 1 addition & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@ validator_dir = { path = "common/validator_dir" }
234234
warp_utils = { path = "common/warp_utils" }
235235

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

239240
[profile.maxperf]

beacon_node/client/src/notifier.rs

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -549,17 +549,15 @@ async fn electra_readiness_logging<T: BeaconChainTypes>(
549549
beacon_chain: &BeaconChain<T>,
550550
log: &Logger,
551551
) {
552-
// TODO(electra): Once Electra has features, this code can be swapped back.
553-
let electra_completed = false;
554-
//let electra_completed = beacon_chain
555-
// .canonical_head
556-
// .cached_head()
557-
// .snapshot
558-
// .beacon_block
559-
// .message()
560-
// .body()
561-
// .execution_payload()
562-
// .map_or(false, |payload| payload.electra_placeholder().is_ok());
552+
let electra_completed = beacon_chain
553+
.canonical_head
554+
.cached_head()
555+
.snapshot
556+
.beacon_block
557+
.message()
558+
.body()
559+
.execution_payload()
560+
.map_or(false, |payload| payload.execution_witness_root().is_ok());
563561

564562
let has_execution_layer = beacon_chain.execution_layer.is_some();
565563

beacon_node/execution_layer/src/block_hash.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ pub fn calculate_execution_block_hash<E: EthSpec>(
3636
None
3737
};
3838

39+
// TODO(mac): Fix rlp calc
40+
let rlp_execution_witness_root = None;
41+
3942
let rlp_blob_gas_used = payload.blob_gas_used().ok();
4043
let rlp_excess_blob_gas = payload.excess_blob_gas().ok();
4144

@@ -48,6 +51,7 @@ pub fn calculate_execution_block_hash<E: EthSpec>(
4851
rlp_blob_gas_used,
4952
rlp_excess_blob_gas,
5053
parent_beacon_block_root,
54+
rlp_execution_witness_root,
5155
);
5256

5357
// Hash the RLP encoding of the block header.

beacon_node/execution_layer/src/engine_api/json_structures.rs

Lines changed: 211 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,15 @@ use strum::EnumString;
44
use superstruct::superstruct;
55
use types::beacon_block_body::KzgCommitments;
66
use types::blob_sidecar::BlobsList;
7-
use types::{FixedVector, Unsigned};
7+
use types::{
8+
execution_witness::{
9+
BanderwagonFieldElement, BanderwagonGroupElement, IpaProof, StateDiff, StateDiffValue,
10+
Stem, StemStateDiff, StemValue, SuffixStateDiff, VerkleProof,
11+
},
12+
ExecutionPayload, ExecutionPayloadCapella, ExecutionPayloadElectra, ExecutionPayloadMerge,
13+
ExecutionWitness,
14+
};
15+
use types::{FixedVector, Option, Unsigned, VariableList};
816

917
#[derive(Debug, PartialEq, Serialize, Deserialize)]
1018
#[serde(rename_all = "camelCase")]
@@ -101,6 +109,8 @@ pub struct JsonExecutionPayload<E: EthSpec> {
101109
#[superstruct(only(V3, V4))]
102110
#[serde(with = "serde_utils::u64_hex_be")]
103111
pub excess_blob_gas: u64,
112+
#[superstruct(only(V4))]
113+
pub execution_witness: JsonExecutionWitness<E>,
104114
}
105115

106116
impl<E: EthSpec> From<ExecutionPayloadMerge<E>> for JsonExecutionPayloadV1<E> {
@@ -203,6 +213,7 @@ impl<E: EthSpec> From<ExecutionPayloadElectra<E>> for JsonExecutionPayloadV4<E>
203213
.into(),
204214
blob_gas_used: payload.blob_gas_used,
205215
excess_blob_gas: payload.excess_blob_gas,
216+
execution_witness: payload.execution_witness,
206217
}
207218
}
208219
}
@@ -319,6 +330,7 @@ impl<E: EthSpec> From<JsonExecutionPayloadV4<E>> for ExecutionPayloadElectra<E>
319330
.into(),
320331
blob_gas_used: payload.blob_gas_used,
321332
excess_blob_gas: payload.excess_blob_gas,
333+
execution_witness: payload.execution_witness,
322334
}
323335
}
324336
}
@@ -691,6 +703,7 @@ pub struct JsonExecutionPayloadBodyV1<E: EthSpec> {
691703
#[serde(with = "ssz_types::serde_utils::list_of_hex_var_list")]
692704
pub transactions: Transactions<E>,
693705
pub withdrawals: Option<VariableList<JsonWithdrawal, E::MaxWithdrawalsPerPayload>>,
706+
pub execution_witness: Option<JsonExecutionWitness<E>>,
694707
}
695708

696709
impl<E: EthSpec> From<JsonExecutionPayloadBodyV1<E>> for ExecutionPayloadBodyV1<E> {
@@ -705,6 +718,7 @@ impl<E: EthSpec> From<JsonExecutionPayloadBodyV1<E>> for ExecutionPayloadBodyV1<
705718
.collect::<Vec<_>>(),
706719
)
707720
}),
721+
execution_witness: value.execution_witness.map(Into::into),
708722
}
709723
}
710724
}
@@ -747,3 +761,199 @@ pub mod serde_logs_bloom {
747761
.map_err(|e| serde::de::Error::custom(format!("invalid logs bloom: {:?}", e)))
748762
}
749763
}
764+
765+
pub fn serde_execution_witness<'de, D, T>(deserializer: D) -> Result<T, D::Error>
766+
where
767+
T: Default + Deserialize<'de>,
768+
D: serde::Deserializer<'de>,
769+
{
770+
let opt = Option::deserialize(deserializer)?;
771+
Ok(opt.unwrap_or_default())
772+
}
773+
774+
/// Execution Witness JSON types.
775+
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
776+
#[serde(bound = "E: EthSpec", rename_all = "camelCase")]
777+
pub struct JsonSuffixStateDiff<E: EthSpec> {
778+
//#[serde(with = "eth2_serde_utils::quoted_u8")]
779+
suffix: u8,
780+
// `None` means not currently present.
781+
current_value: Optional<StateDiffValue<E>>,
782+
// `None` means value is not updated.
783+
new_value: Optional<StateDiffValue<E>>,
784+
}
785+
786+
impl<E: EthSpec> From<JsonSuffixStateDiff<E>> for SuffixStateDiff<E> {
787+
fn from(value: JsonSuffixStateDiff<E>) -> Self {
788+
Self {
789+
suffix: value.suffix,
790+
current_value: value.current_value,
791+
new_value: value.new_value,
792+
}
793+
}
794+
}
795+
796+
impl<E: EthSpec> From<SuffixStateDiff<E>> for JsonSuffixStateDiff<E> {
797+
fn from(value: SuffixStateDiff<E>) -> Self {
798+
Self {
799+
suffix: value.suffix,
800+
current_value: value.current_value,
801+
new_value: value.new_value,
802+
}
803+
}
804+
}
805+
806+
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
807+
#[serde(bound = "E: EthSpec", rename_all = "camelCase")]
808+
pub struct JsonStemStateDiff<E: EthSpec> {
809+
stem: Stem<E>,
810+
suffix_diffs: VariableList<JsonSuffixStateDiff<E>, E::MaxVerkleWidth>,
811+
}
812+
813+
impl<E: EthSpec> From<JsonStemStateDiff<E>> for StemStateDiff<E> {
814+
fn from(value: JsonStemStateDiff<E>) -> Self {
815+
Self {
816+
stem: value.stem,
817+
suffix_diffs: value
818+
.suffix_diffs
819+
.into_iter()
820+
.map(Into::into)
821+
.collect::<Vec<_>>()
822+
.into(),
823+
}
824+
}
825+
}
826+
827+
impl<E: EthSpec> From<StemStateDiff<E>> for JsonStemStateDiff<E> {
828+
fn from(value: StemStateDiff<E>) -> Self {
829+
Self {
830+
stem: value.stem,
831+
suffix_diffs: value
832+
.suffix_diffs
833+
.into_iter()
834+
.map(Into::into)
835+
.collect::<Vec<_>>()
836+
.into(),
837+
}
838+
}
839+
}
840+
841+
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
842+
#[serde(bound = "E: EthSpec", rename_all = "camelCase")]
843+
pub struct JsonIpaProof<E: EthSpec> {
844+
cl: FixedVector<BanderwagonGroupElement<E>, E::IpaProofDepth>,
845+
cr: FixedVector<BanderwagonGroupElement<E>, E::IpaProofDepth>,
846+
final_evaluation: BanderwagonFieldElement<E>,
847+
}
848+
849+
impl<E: EthSpec> From<JsonIpaProof<E>> for IpaProof<E> {
850+
fn from(value: JsonIpaProof<E>) -> Self {
851+
Self {
852+
cl: value.cl,
853+
cr: value.cr,
854+
final_evaluation: value.final_evaluation,
855+
}
856+
}
857+
}
858+
859+
impl<E: EthSpec> From<IpaProof<E>> for JsonIpaProof<E> {
860+
fn from(value: IpaProof<E>) -> Self {
861+
Self {
862+
cl: value.cl,
863+
cr: value.cr,
864+
final_evaluation: value.final_evaluation,
865+
}
866+
}
867+
}
868+
869+
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
870+
#[serde(bound = "E: EthSpec", rename_all = "camelCase")]
871+
pub struct JsonVerkleProof<E: EthSpec> {
872+
other_stems: VariableList<StemValue<E>, E::MaxStems>,
873+
#[serde(with = "ssz_types::serde_utils::hex_var_list")]
874+
depth_extension_present: VariableList<u8, E::MaxStems>,
875+
commitments_by_path: VariableList<BanderwagonGroupElement<E>, E::MaxCommittments>,
876+
d: BanderwagonGroupElement<E>,
877+
ipa_proof: JsonIpaProof<E>,
878+
}
879+
880+
impl<E: EthSpec> From<JsonVerkleProof<E>> for VerkleProof<E> {
881+
fn from(value: JsonVerkleProof<E>) -> Self {
882+
Self {
883+
other_stems: value.other_stems,
884+
depth_extension_present: value.depth_extension_present,
885+
commitments_by_path: value.commitments_by_path,
886+
d: value.d,
887+
ipa_proof: IpaProof::<E>::from(value.ipa_proof),
888+
}
889+
}
890+
}
891+
892+
impl<E: EthSpec> From<VerkleProof<E>> for JsonVerkleProof<E> {
893+
fn from(value: VerkleProof<E>) -> Self {
894+
Self {
895+
other_stems: value.other_stems,
896+
depth_extension_present: value.depth_extension_present,
897+
commitments_by_path: value.commitments_by_path,
898+
d: value.d,
899+
ipa_proof: JsonIpaProof::<E>::from(value.ipa_proof),
900+
}
901+
}
902+
}
903+
904+
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
905+
#[serde(bound = "E: EthSpec", transparent)]
906+
pub struct JsonStateDiff<E: EthSpec> {
907+
inner: VariableList<JsonStemStateDiff<E>, E::MaxStems>,
908+
}
909+
910+
impl<E: EthSpec> From<JsonStateDiff<E>> for StateDiff<E> {
911+
fn from(value: JsonStateDiff<E>) -> Self {
912+
Self {
913+
inner: value
914+
.inner
915+
.into_iter()
916+
.map(Into::into)
917+
.collect::<Vec<_>>()
918+
.into(),
919+
}
920+
}
921+
}
922+
923+
impl<E: EthSpec> From<StateDiff<E>> for JsonStateDiff<E> {
924+
fn from(value: StateDiff<E>) -> Self {
925+
Self {
926+
inner: value
927+
.inner
928+
.into_iter()
929+
.map(Into::into)
930+
.collect::<Vec<_>>()
931+
.into(),
932+
}
933+
}
934+
}
935+
936+
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
937+
#[serde(bound = "E: EthSpec", rename_all = "camelCase")]
938+
pub struct JsonExecutionWitness<E: EthSpec> {
939+
state_diff: JsonStateDiff<E>,
940+
verkle_proof: JsonVerkleProof<E>,
941+
}
942+
943+
impl<E: EthSpec> From<JsonExecutionWitness<E>> for ExecutionWitness<E> {
944+
fn from(value: JsonExecutionWitness<E>) -> Self {
945+
Self {
946+
state_diff: StateDiff::<E>::from(value.state_diff),
947+
verkle_proof: VerkleProof::<E>::from(value.verkle_proof),
948+
}
949+
}
950+
}
951+
952+
impl<E: EthSpec> From<ExecutionWitness<E>> for JsonExecutionWitness<E> {
953+
fn from(value: ExecutionWitness<E>) -> Self {
954+
Self {
955+
state_diff: JsonStateDiff::<E>::from(value.state_diff),
956+
verkle_proof: JsonVerkleProof::<E>::from(value.verkle_proof),
957+
}
958+
}
959+
}

beacon_node/execution_layer/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1974,6 +1974,7 @@ impl<E: EthSpec> ExecutionLayer<E> {
19741974
withdrawals,
19751975
blob_gas_used: electra_block.blob_gas_used,
19761976
excess_blob_gas: electra_block.excess_blob_gas,
1977+
execution_witness: electra_block.execution_witness.into(),
19771978
})
19781979
}
19791980
};

beacon_node/execution_layer/src/test_utils/execution_block_generator.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use tree_hash_derive::TreeHash;
2323
use types::{
2424
Blob, ChainSpec, EthSpec, ExecutionBlockHash, ExecutionPayload, ExecutionPayloadCapella,
2525
ExecutionPayloadDeneb, ExecutionPayloadElectra, ExecutionPayloadHeader, ExecutionPayloadMerge,
26-
ForkName, Hash256, Transaction, Transactions, Uint256,
26+
ExecutionWitness, ForkName, Hash256, Transaction, Transactions, Uint256,
2727
};
2828

2929
use super::DEFAULT_TERMINAL_BLOCK;
@@ -646,6 +646,7 @@ impl<E: EthSpec> ExecutionBlockGenerator<E> {
646646
withdrawals: pa.withdrawals.clone().into(),
647647
blob_gas_used: 0,
648648
excess_blob_gas: 0,
649+
execution_witness: ExecutionWitness::default(),
649650
}),
650651
_ => unreachable!(),
651652
},

beacon_node/execution_layer/src/test_utils/handle_rpc.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -569,6 +569,7 @@ pub async fn handle_rpc<E: EthSpec>(
569569
.withdrawals()
570570
.ok()
571571
.map(|withdrawals| VariableList::from(withdrawals.clone())),
572+
execution_witness: block.execution_witness().ok().cloned(),
572573
}));
573574
}
574575
None => response.push(None),

beacon_node/src/config.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -412,9 +412,11 @@ pub fn get_config<E: EthSpec>(
412412
.map_err(|_| "auto-compact-db takes a boolean".to_string())?;
413413
}
414414

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

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

827829
// Optimistic finalized sync.
828-
client_config.chain.optimistic_finalized_sync =
829-
!cli_args.is_present("disable-optimistic-finalized-sync");
830+
client_config.chain.optimistic_finalized_sync = false;
831+
// TODO(mac) remove this once optimistic finalized sync is working.
832+
// !cli_args.is_present("disable-optimistic-finalized-sync");
830833

831834
if cli_args.is_present("genesis-backfill") {
832835
client_config.chain.genesis_backfill = true;

0 commit comments

Comments
 (0)