diff --git a/Cargo.lock b/Cargo.lock index 488a23a7..9944bace 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1252,7 +1252,7 @@ checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] name = "beacon-api-client" version = "0.1.0" -source = "git+https://github.com/ralexstokes/ethereum-consensus?rev=cf3c404043230559660810bc0c9d6d5a8498d819#cf3c404043230559660810bc0c9d6d5a8498d819" +source = "git+https://github.com/ralexstokes/ethereum-consensus?rev=3068ca2bab27c39a5a409dcd359e46319d82c431#3068ca2bab27c39a5a409dcd359e46319d82c431" dependencies = [ "clap", "ethereum-consensus", @@ -2731,7 +2731,7 @@ dependencies = [ [[package]] name = "ethereum-consensus" version = "0.1.1" -source = "git+https://github.com/ralexstokes/ethereum-consensus?rev=cf3c404043230559660810bc0c9d6d5a8498d819#cf3c404043230559660810bc0c9d6d5a8498d819" +source = "git+https://github.com/ralexstokes/ethereum-consensus?rev=3068ca2bab27c39a5a409dcd359e46319d82c431#3068ca2bab27c39a5a409dcd359e46319d82c431" dependencies = [ "blst", "bs58 0.4.0", diff --git a/Cargo.toml b/Cargo.toml index efaef28b..42182ef8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,8 +24,8 @@ codegen-units = 1 incremental = false [workspace.dependencies] -ethereum-consensus = { git = "https://github.com/ralexstokes/ethereum-consensus", rev = "cf3c404043230559660810bc0c9d6d5a8498d819" } -beacon-api-client = { git = "https://github.com/ralexstokes/ethereum-consensus", rev = "cf3c404043230559660810bc0c9d6d5a8498d819" } +ethereum-consensus = { git = "https://github.com/ralexstokes/ethereum-consensus", rev = "3068ca2bab27c39a5a409dcd359e46319d82c431" } +beacon-api-client = { git = "https://github.com/ralexstokes/ethereum-consensus", rev = "3068ca2bab27c39a5a409dcd359e46319d82c431" } reth = { git = "https://github.com/paradigmxyz/reth", tag = "v1.0.8" } reth-basic-payload-builder = { git = "https://github.com/paradigmxyz/reth", tag = "v1.0.8" } diff --git a/mev-build-rs/src/auctioneer/service.rs b/mev-build-rs/src/auctioneer/service.rs index f975efa8..7c4d38ee 100644 --- a/mev-build-rs/src/auctioneer/service.rs +++ b/mev-build-rs/src/auctioneer/service.rs @@ -83,6 +83,14 @@ fn prepare_submission( blobs_bundle: to_blobs_bundle(payload.sidecars())?, signature, }), + Fork::Electra => { + SignedBidSubmission::Electra(block_submission::electra::SignedBidSubmission { + message, + execution_payload, + blobs_bundle: to_blobs_bundle(payload.sidecars())?, + signature, + }) + } fork => return Err(Error::UnsupportedFork(fork)), }; Ok(submission) diff --git a/mev-build-rs/src/compat.rs b/mev-build-rs/src/compat.rs index 1a9768c2..15ca90a0 100644 --- a/mev-build-rs/src/compat.rs +++ b/mev-build-rs/src/compat.rs @@ -35,7 +35,7 @@ pub fn to_execution_payload(value: &SealedBlock, fork: Fork) -> Result { + Fork::Deneb | Fork::Electra => { let transactions = transactions .iter() .map(|t| deneb::Transaction::try_from(t.encoded_2718().as_ref()).unwrap()) diff --git a/mev-relay-rs/src/auction_context.rs b/mev-relay-rs/src/auction_context.rs index a26345b5..9f08d7d5 100644 --- a/mev-relay-rs/src/auction_context.rs +++ b/mev-relay-rs/src/auction_context.rs @@ -23,6 +23,7 @@ fn to_header(execution_payload: &ExecutionPayload) -> Result ExecutionPayloadHeader::Capella(payload.try_into()?), ExecutionPayload::Deneb(payload) => ExecutionPayloadHeader::Deneb(payload.try_into()?), + ExecutionPayload::Electra(payload) => ExecutionPayloadHeader::Electra(payload.try_into()?), }; Ok(header) } @@ -89,11 +90,52 @@ pub mod deneb { } } +pub mod electra { + use super::*; + + #[cfg(not(feature = "minimal-preset"))] + use ethereum_consensus::electra::mainnet as electra; + #[cfg(feature = "minimal-preset")] + use ethereum_consensus::electra::minimal as electra; + + #[derive(Debug, PartialEq, Eq)] + pub struct AuctionContext { + pub builder_public_key: BlsPublicKey, + pub bid_trace: BidTrace, + pub receive_duration: Duration, + pub signed_builder_bid: SignedBuilderBid, + pub execution_payload: ExecutionPayload, + pub execution_requests: electra::ExecutionRequests, + pub value: U256, + pub blobs_bundle: BlobsBundle, + } + + impl Hash for AuctionContext { + fn hash(&self, state: &mut H) { + self.builder_public_key.hash(state); + self.bid_trace.hash(state); + self.receive_duration.hash(state); + self.signed_builder_bid.hash(state); + let payload_root = + self.execution_payload.hash_tree_root().expect("can get hash tree root"); + payload_root.hash(state); + let requests_root = + self.execution_requests.hash_tree_root().expect("can get hash tree root"); + requests_root.hash(state); + self.value.hash(state); + let blobs_bundle_root = + self.blobs_bundle.hash_tree_root().expect("can get hash tree root"); + blobs_bundle_root.hash(state); + } + } +} + #[derive(Debug, PartialEq, Eq, Hash)] pub enum AuctionContext { Bellatrix(bellatrix::AuctionContext), Capella(capella::AuctionContext), Deneb(deneb::AuctionContext), + Electra(electra::AuctionContext), } impl AuctionContext { @@ -167,6 +209,16 @@ impl AuctionContext { value, blobs_bundle: submission.blobs_bundle, }), + SignedBidSubmission::Electra(submission) => Self::Electra(electra::AuctionContext { + builder_public_key, + bid_trace: submission.message, + receive_duration, + signed_builder_bid, + execution_payload, + execution_requests: submission.execution_requests, + value, + blobs_bundle: submission.blobs_bundle, + }), }; Ok(auction_context) @@ -177,6 +229,7 @@ impl AuctionContext { Self::Bellatrix(context) => &context.builder_public_key, Self::Capella(context) => &context.builder_public_key, Self::Deneb(context) => &context.builder_public_key, + Self::Electra(context) => &context.builder_public_key, } } @@ -185,6 +238,7 @@ impl AuctionContext { Self::Bellatrix(context) => &context.bid_trace, Self::Capella(context) => &context.bid_trace, Self::Deneb(context) => &context.bid_trace, + Self::Electra(context) => &context.bid_trace, } } @@ -193,6 +247,7 @@ impl AuctionContext { Self::Bellatrix(context) => context.receive_duration, Self::Capella(context) => context.receive_duration, Self::Deneb(context) => context.receive_duration, + Self::Electra(context) => context.receive_duration, } } @@ -201,6 +256,7 @@ impl AuctionContext { Self::Bellatrix(context) => &context.signed_builder_bid, Self::Capella(context) => &context.signed_builder_bid, Self::Deneb(context) => &context.signed_builder_bid, + Self::Electra(context) => &context.signed_builder_bid, } } @@ -209,6 +265,7 @@ impl AuctionContext { Self::Bellatrix(context) => &context.execution_payload, Self::Capella(context) => &context.execution_payload, Self::Deneb(context) => &context.execution_payload, + Self::Electra(context) => &context.execution_payload, } } @@ -217,6 +274,7 @@ impl AuctionContext { Self::Bellatrix(_) => None, Self::Capella(_) => None, Self::Deneb(context) => Some(&context.blobs_bundle), + Self::Electra(context) => Some(&context.blobs_bundle), } } @@ -225,6 +283,7 @@ impl AuctionContext { Self::Bellatrix(context) => context.value, Self::Capella(context) => context.value, Self::Deneb(context) => context.value, + Self::Electra(context) => context.value, } } @@ -240,6 +299,12 @@ impl AuctionContext { blobs_bundle: context.blobs_bundle.clone(), }) } + Self::Electra(context) => { + AuctionContents::El(auction_contents::deneb::AuctionContents { + execution_payload: context.execution_payload.clone(), + blobs_bundle: context.blobs_bundle.clone(), + }) + } } } } diff --git a/mev-rs/src/types/auction_contents.rs b/mev-rs/src/types/auction_contents.rs index ec11cef2..097f24f9 100644 --- a/mev-rs/src/types/auction_contents.rs +++ b/mev-rs/src/types/auction_contents.rs @@ -40,6 +40,39 @@ pub mod deneb { } } +pub mod electra { + use super::ExecutionPayload; + use ethereum_consensus::{ + crypto::{KzgCommitment, KzgProof}, + ssz::prelude::*, + }; + + #[cfg(not(feature = "minimal-preset"))] + use ethereum_consensus::electra::mainnet::{ + Blob, ExecutionRequests, MAX_BLOB_COMMITMENTS_PER_BLOCK, + }; + #[cfg(feature = "minimal-preset")] + use ethereum_consensus::electra::minimal::{ + Blob, ExecutionRequests, MAX_BLOB_COMMITMENTS_PER_BLOCK, + }; + + #[derive(Clone, Debug, Default, Serializable, HashTreeRoot, PartialEq, Eq)] + #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] + pub struct BlobsBundle { + pub commitments: List, + pub proofs: List, + pub blobs: List, + } + + #[derive(Debug)] + #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] + pub struct AuctionContents { + pub execution_payload: ExecutionPayload, + pub execution_requests: ExecutionRequests, + pub blobs_bundle: BlobsBundle, + } +} + #[derive(Debug)] #[cfg_attr(feature = "serde", derive(serde::Serialize))] #[serde(untagged)] @@ -47,6 +80,7 @@ pub enum AuctionContents { Bellatrix(bellatrix::AuctionContents), Capella(capella::AuctionContents), Deneb(deneb::AuctionContents), + Electra(deneb::AuctionContents), } impl<'de> serde::Deserialize<'de> for AuctionContents { @@ -55,6 +89,9 @@ impl<'de> serde::Deserialize<'de> for AuctionContents { D: serde::Deserializer<'de>, { let value = serde_json::Value::deserialize(deserializer)?; + if let Ok(inner) = <_ as serde::Deserialize>::deserialize(&value) { + return Ok(Self::Electra(inner)) + } if let Ok(inner) = <_ as serde::Deserialize>::deserialize(&value) { return Ok(Self::Deneb(inner)) } @@ -74,6 +111,7 @@ impl AuctionContents { Self::Bellatrix(..) => Fork::Bellatrix, Self::Capella(..) => Fork::Capella, Self::Deneb(..) => Fork::Deneb, + Self::Electra(..) => Fork::Electra, } } @@ -82,12 +120,14 @@ impl AuctionContents { Self::Bellatrix(inner) => inner, Self::Capella(inner) => inner, Self::Deneb(inner) => &inner.execution_payload, + Self::Electra(inner) => &inner.execution_payload, } } pub fn blobs_bundle(&self) -> Option<&BlobsBundle> { match self { Self::Deneb(inner) => Some(&inner.blobs_bundle), + Self::Electra(inner) => Some(&inner.blobs_bundle), _ => None, } }