Skip to content

Commit

Permalink
feat: more beacon types
Browse files Browse the repository at this point in the history
  • Loading branch information
mattsse committed Nov 4, 2023
1 parent 219b7db commit 8de4c3f
Show file tree
Hide file tree
Showing 8 changed files with 272 additions and 3 deletions.
4 changes: 4 additions & 0 deletions crates/rpc/rpc-types/src/beacon/constants.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
pub const BLS_DST: &[u8] = b"BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_";
pub const BLS_PUBLIC_KEY_BYTES_LEN: usize = 48;
pub const BLS_SECRET_KEY_BYTES_LEN: usize = 32;
pub const BLS_SIGNATURE_BYTES_LEN: usize = 96;
24 changes: 24 additions & 0 deletions crates/rpc/rpc-types/src/beacon/macros.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@

/// A helper type that generates helper types for the beacon API.
macro_rules! beacon_serde_glue {
// Named-Struct
(
$( #[$meta:meta] )*
$vis:vis struct $name:ident {
$(
$( #[$field_meta:meta] )*
$field_vis:vis $field_name:ident : $field_ty:ty
),*
$(,)? }
) => {
$( #[$meta] )*
$vis struct Beacon$name {
$(
$( #[$field_meta] )*
$field_vis $field_name : $field_ty
),*
}
}
}

pub(crate) use beacon_serde_glue;
15 changes: 15 additions & 0 deletions crates/rpc/rpc-types/src/beacon/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#![allow(missing_docs)]
//! Types for the Ethereum 2.0 RPC protocol (beacon chain)
use alloy_primitives::FixedBytes;
use constants::{BLS_PUBLIC_KEY_BYTES_LEN, BLS_SIGNATURE_BYTES_LEN};

pub mod constants;
pub mod macros;
pub mod payload;

/// BLS signature type
pub type BlsSignature = FixedBytes<BLS_SIGNATURE_BYTES_LEN>;

/// BLS public key type
pub type BlsPublicKey = FixedBytes<BLS_PUBLIC_KEY_BYTES_LEN>;
96 changes: 96 additions & 0 deletions crates/rpc/rpc-types/src/beacon/payload.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
#![allow(missing_docs)]
//! Payload support for the beacon API.
//!
//! Internal helper module to deserialize/serialize the payload attributes for the beacon API, which
//! uses snake case and quoted decimals.
//!
//! This is necessary because we don't want to allow a mixture of both formats, hence `serde`
//! aliases are not an option.
pub use crate::Withdrawal;
use crate::{
eth::{transaction::BlobTransactionSidecar, withdrawal::BeaconAPIWithdrawal},
ExecutionPayloadV1,
};
use alloy_primitives::{Address, Bloom, Bytes, B256, B64, U256, U64};
use c_kzg::{Blob, Bytes48};
use serde::{ser::SerializeMap, Deserialize, Deserializer, Serialize, Serializer};
use serde_with::{serde_as, DisplayFromStr};

#[derive(Serialize, Deserialize)]
pub(crate) struct BeaconExecutionPayloadV1 {
pub(crate) parent_hash: B256,
pub(crate) fee_recipient: Address,
pub(crate) state_root: B256,
pub(crate) receipts_root: B256,
pub(crate) logs_bloom: Bloom,
pub(crate) prev_randao: B256,
pub(crate) block_number: U64,
pub(crate) gas_limit: U64,
pub(crate) gas_used: U64,
pub(crate) timestamp: U64,
pub(crate) extra_data: Bytes,
pub(crate) base_fee_per_gas: U256,
pub(crate) block_hash: B256,
pub(crate) transactions: Vec<Bytes>,
}

impl From<BeaconExecutionPayloadV1> for ExecutionPayloadV1 {
fn from(payload: BeaconExecutionPayloadV1) -> Self {
let BeaconExecutionPayloadV1 {
parent_hash,
fee_recipient,
state_root,
receipts_root,
logs_bloom,
prev_randao,
block_number,
gas_limit,
gas_used,
timestamp,
extra_data,
base_fee_per_gas,
block_hash,
transactions,
} = payload;
ExecutionPayloadV1 {
parent_hash,
fee_recipient,
state_root,
receipts_root,
logs_bloom,
prev_randao,
block_number,
gas_limit,
gas_used,
timestamp,
extra_data,
base_fee_per_gas,
block_hash,
transactions,
}
}
}

/// A helper serde module to convert from/to the Beacon API which uses quoted decimals rather than
/// big-endian hex.
pub mod beacon_payload_v1 {
use super::*;
use serde::{Deserialize, Deserializer, Serialize, Serializer};

/// Serialize the payload attributes for the beacon API.
pub fn serialize<S>(payload_attributes: &Withdrawal, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
todo!()
}

/// Deserialize the payload attributes for the beacon API.
pub fn deserialize<'de, D>(deserializer: D) -> Result<Withdrawal, D::Error>
where
D: Deserializer<'de>,
{
todo!()
}
}
38 changes: 36 additions & 2 deletions crates/rpc/rpc-types/src/eth/engine/payload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::eth::{transaction::BlobTransactionSidecar, withdrawal::BeaconAPIWithd
pub use crate::Withdrawal;
use alloy_primitives::{Address, Bloom, Bytes, B256, B64, U256, U64};
use c_kzg::{Blob, Bytes48};
use serde::{ser::SerializeMap, Deserialize, Serialize, Serializer};
use serde::{ser::SerializeMap, Deserialize, Deserializer, Serialize, Serializer};
use serde_with::{serde_as, DisplayFromStr};

/// The execution payload body response that allows for `null` values.
Expand Down Expand Up @@ -229,7 +229,8 @@ impl BlobsBundleV1 {

/// An execution payload, which can be either [ExecutionPayloadV1], [ExecutionPayloadV2], or
/// [ExecutionPayloadV3].
#[derive(Clone, Debug, PartialEq, Eq)]
#[derive(Clone, Debug, PartialEq, Eq, Serialize)]
#[serde(untagged)]
pub enum ExecutionPayload {
/// V1 payload
V1(ExecutionPayloadV1),
Expand Down Expand Up @@ -304,6 +305,27 @@ impl From<ExecutionPayloadV3> for ExecutionPayload {
}
}

// Deserializes untagged ExecutionPayload by trying each variant in falling order
impl<'de> Deserialize<'de> for ExecutionPayload {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
#[derive(Deserialize)]
#[serde(untagged)]
enum ExecutionPayloadDesc {
V3(ExecutionPayloadV3),
V2(ExecutionPayloadV2),
V1(ExecutionPayloadV1),
}
match ExecutionPayloadDesc::deserialize(deserializer)? {
ExecutionPayloadDesc::V3(payload) => Ok(Self::V3(payload)),
ExecutionPayloadDesc::V2(payload) => Ok(Self::V2(payload)),
ExecutionPayloadDesc::V1(payload) => Ok(Self::V1(payload)),
}
}
}

/// Error that can occur when handling payloads.
#[derive(thiserror::Error, Debug)]
pub enum PayloadError {
Expand Down Expand Up @@ -682,6 +704,9 @@ mod tests {
let s = r#"{"parentHash":"0x67ead97eb79b47a1638659942384143f36ed44275d4182799875ab5a87324055","feeRecipient":"0x0000000000000000000000000000000000000000","stateRoot":"0x0000000000000000000000000000000000000000000000000000000000000000","receiptsRoot":"0x4e3c608a9f2e129fccb91a1dae7472e78013b8e654bccc8d224ce3d63ae17006","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","prevRandao":"0x44bb4b98c59dbb726f96ffceb5ee028dcbe35b9bba4f9ffd56aeebf8d1e4db62","blockNumber":"0x1","gasLimit":"0x2fefd8","gasUsed":"0xa860","timestamp":"0x1235","extraData":"0x8b726574682f76302e312e30","baseFeePerGas":"0x342770c0","blockHash":"0x5655011482546f16b2312ef18e9fad03d6a52b1be95401aea884b222477f9e64","transactions":["0xf865808506fc23ac00830124f8940000000000000000000000000000000000000316018032a044b25a8b9b247d01586b3d59c71728ff49c9b84928d9e7fa3377ead3b5570b5da03ceac696601ff7ee6f5fe8864e2998db9babdf5eeba1a0cd5b4d44b3fcbd181b"]}"#;
let payload: ExecutionPayloadV1 = serde_json::from_str(s).unwrap();
assert_eq!(serde_json::to_string(&payload).unwrap(), s);

let any_payload: ExecutionPayload = serde_json::from_str(s).unwrap();
assert_eq!(any_payload, payload.into());
}

#[test]
Expand All @@ -690,6 +715,9 @@ mod tests {
let s = r#"{"parentHash":"0x67ead97eb79b47a1638659942384143f36ed44275d4182799875ab5a87324055","feeRecipient":"0x0000000000000000000000000000000000000000","stateRoot":"0x0000000000000000000000000000000000000000000000000000000000000000","receiptsRoot":"0x4e3c608a9f2e129fccb91a1dae7472e78013b8e654bccc8d224ce3d63ae17006","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","prevRandao":"0x44bb4b98c59dbb726f96ffceb5ee028dcbe35b9bba4f9ffd56aeebf8d1e4db62","blockNumber":"0x1","gasLimit":"0x2fefd8","gasUsed":"0xa860","timestamp":"0x1235","extraData":"0x8b726574682f76302e312e30","baseFeePerGas":"0x342770c0","blockHash":"0x5655011482546f16b2312ef18e9fad03d6a52b1be95401aea884b222477f9e64","transactions":["0xf865808506fc23ac00830124f8940000000000000000000000000000000000000316018032a044b25a8b9b247d01586b3d59c71728ff49c9b84928d9e7fa3377ead3b5570b5da03ceac696601ff7ee6f5fe8864e2998db9babdf5eeba1a0cd5b4d44b3fcbd181b"],"withdrawals":[],"blobGasUsed":"0xb10b","excessBlobGas":"0xb10b"}"#;
let payload: ExecutionPayloadV3 = serde_json::from_str(s).unwrap();
assert_eq!(serde_json::to_string(&payload).unwrap(), s);

let any_payload: ExecutionPayload = serde_json::from_str(s).unwrap();
assert_eq!(any_payload, payload.into());
}

#[test]
Expand All @@ -698,6 +726,9 @@ mod tests {
let s = r#"{"parentHash":"0x67ead97eb79b47a1638659942384143f36ed44275d4182799875ab5a87324055","feeRecipient":"0x0000000000000000000000000000000000000000","stateRoot":"0x76a03cbcb7adce07fd284c61e4fa31e5e786175cefac54a29e46ec8efa28ea41","receiptsRoot":"0x4e3c608a9f2e129fccb91a1dae7472e78013b8e654bccc8d224ce3d63ae17006","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","prevRandao":"0x028111cb7d25918386a69656b3d17b2febe95fd0f11572c1a55c14f99fdfe3df","blockNumber":"0x1","gasLimit":"0x2fefd8","gasUsed":"0xa860","timestamp":"0x1235","extraData":"0x8b726574682f76302e312e30","baseFeePerGas":"0x342770c0","blockHash":"0xa6f40ed042e61e88e76125dede8fff8026751ea14454b68fb534cea99f2b2a77","transactions":["0xf865808506fc23ac00830124f8940000000000000000000000000000000000000316018032a044b25a8b9b247d01586b3d59c71728ff49c9b84928d9e7fa3377ead3b5570b5da03ceac696601ff7ee6f5fe8864e2998db9babdf5eeba1a0cd5b4d44b3fcbd181b"]}"#;
let payload: ExecutionPayloadV1 = serde_json::from_str(s).unwrap();
assert_eq!(serde_json::to_string(&payload).unwrap(), s);

let any_payload: ExecutionPayload = serde_json::from_str(s).unwrap();
assert_eq!(any_payload, payload.into());
}

#[test]
Expand All @@ -706,6 +737,9 @@ mod tests {
let s = r#"{"parentHash":"0x67ead97eb79b47a1638659942384143f36ed44275d4182799875ab5a87324055","feeRecipient":"0x0000000000000000000000000000000000000000","stateRoot":"0x76a03cbcb7adce07fd284c61e4fa31e5e786175cefac54a29e46ec8efa28ea41","receiptsRoot":"0x4e3c608a9f2e129fccb91a1dae7472e78013b8e654bccc8d224ce3d63ae17006","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","prevRandao":"0x028111cb7d25918386a69656b3d17b2febe95fd0f11572c1a55c14f99fdfe3df","blockNumber":"0x1","gasLimit":"0x2fefd8","gasUsed":"0xa860","timestamp":"0x1235","extraData":"0x8b726574682f76302e312e30","baseFeePerGas":"0x342770c0","blockHash":"0xa6f40ed042e61e88e76125dede8fff8026751ea14454b68fb534cea99f2b2a77","transactions":["0xf865808506fc23ac00830124f8940000000000000000000000000000000000000316018032a044b25a8b9b247d01586b3d59c71728ff49c9b84928d9e7fa3377ead3b5570b5da03ceac696601ff7ee6f5fe8864e2998db9babdf5eeba1a0cd5b4d44b3fcbd181b"],"withdrawals":[],"blobGasUsed":"0xb10b","excessBlobGas":"0xb10b"}"#;
let payload: ExecutionPayloadV3 = serde_json::from_str(s).unwrap();
assert_eq!(serde_json::to_string(&payload).unwrap(), s);

let any_payload: ExecutionPayload = serde_json::from_str(s).unwrap();
assert_eq!(any_payload, payload.into());
}

#[test]
Expand Down
2 changes: 1 addition & 1 deletion crates/rpc/rpc-types/src/eth/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ pub mod raw_log;
pub mod state;
mod syncing;
pub mod trace;
mod transaction;
pub mod transaction;
pub mod txpool;
pub mod withdrawal;
mod work;
Expand Down
2 changes: 2 additions & 0 deletions crates/rpc/rpc-types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@
#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]

mod admin;
pub mod beacon;
mod eth;
mod mev;
mod net;
mod otterscan;
mod peer;
pub mod relay;
mod rpc;
mod serde_helpers;

Expand Down
94 changes: 94 additions & 0 deletions crates/rpc/rpc-types/src/relay.rs

Large diffs are not rendered by default.

0 comments on commit 8de4c3f

Please sign in to comment.