Skip to content

Commit

Permalink
feat(engine): Optional Serde (#1283)
Browse files Browse the repository at this point in the history
* feat: optional serde

* fix: beacon types

* fix: provider

* fix: eip7547

* fix: run ci
  • Loading branch information
refcell authored Sep 13, 2024
1 parent 8c5aff5 commit e7ea61d
Show file tree
Hide file tree
Showing 10 changed files with 121 additions and 76 deletions.
2 changes: 1 addition & 1 deletion crates/eip7547/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ workspace = true

[dependencies]
alloy-primitives = { workspace = true, features = ["rlp", "serde"] }
alloy-rpc-types-engine = { workspace = true }
alloy-rpc-types-engine = { workspace = true, features = ["serde"] }
alloy-serde = { workspace = true }

# serde
Expand Down
2 changes: 1 addition & 1 deletion crates/provider/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ alloy-rpc-types-anvil = { workspace = true, optional = true }
alloy-rpc-types-eth = { workspace = true, features = ["serde"] }
alloy-rpc-types-trace = { workspace = true, optional = true }
alloy-rpc-types-txpool = { workspace = true, optional = true }
alloy-rpc-types-engine = { workspace = true, optional = true }
alloy-rpc-types-engine = { workspace = true, optional = true, features = ["serde"] }
alloy-rpc-types = { workspace = true, optional = true }
alloy-transport-http = { workspace = true, optional = true }
alloy-transport-ipc = { workspace = true, optional = true }
Expand Down
2 changes: 1 addition & 1 deletion crates/rpc-types-beacon/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ workspace = true
[dependencies]
# ethereum
alloy-eips = { workspace = true, features = ["serde"] }
alloy-rpc-types-engine.workspace = true
alloy-rpc-types-engine = { workspace = true, features = ["serde"] }
alloy-primitives.workspace = true

# ssz
Expand Down
9 changes: 6 additions & 3 deletions crates/rpc-types-engine/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,18 @@ workspace = true

[dependencies]
# ethereum
alloy-serde.workspace = true
alloy-rlp = { workspace = true, features = ["arrayvec", "derive"] }
alloy-primitives = { workspace = true, features = ["rlp", "serde"] }
alloy-consensus = { workspace = true, features = ["serde"] }
alloy-eips = { workspace = true, features = ["serde"] }

# misc
serde = { workspace = true, features = ["derive"] }
derive_more = { workspace = true, features = ["display"] }

# serde
alloy-serde = { workspace = true, optional = true }
serde = { workspace = true, features = ["derive"], optional = true }

# ssz
ethereum_ssz_derive = { workspace = true, optional = true }
ethereum_ssz = { workspace = true, optional = true }
Expand All @@ -42,8 +44,9 @@ rand = { workspace = true, optional = true }
jsonwebtoken = { version = "9.3.0", optional = true }

[features]
default = ["jwt", "std"]
default = ["jwt", "std", "serde"]
std = ["alloy-consensus/std", "derive_more/std"]
serde = ["dep:serde", "dep:alloy-serde"]
jwt = ["dep:jsonwebtoken", "dep:rand"]
jsonrpsee-types = ["dep:jsonrpsee-types"]
ssz = ["std", "dep:ethereum_ssz", "dep:ethereum_ssz_derive", "alloy-eips/ssz"]
Expand Down
3 changes: 2 additions & 1 deletion crates/rpc-types-engine/src/cancun.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ use alloy_primitives::B256;
///
/// See also:
/// <https://github.com/ethereum/execution-apis/blob/fe8e13c288c592ec154ce25c534e26cb7ce0530d/src/engine/cancun.md#request>
#[derive(Clone, Debug, Default, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct CancunPayloadFields {
/// The parent beacon block root.
pub parent_beacon_block_root: B256,
Expand Down
11 changes: 6 additions & 5 deletions crates/rpc-types-engine/src/forkchoice.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use super::{PayloadStatus, PayloadStatusEnum};
use crate::PayloadId;
use alloy_primitives::B256;
use serde::{Deserialize, Serialize};

/// invalid forkchoice state error code.
pub const INVALID_FORK_CHOICE_STATE_ERROR: i32 = -38002;
Expand All @@ -19,8 +18,9 @@ pub const INVALID_PAYLOAD_ATTRIBUTES_ERROR_MSG: &str = "Invalid payload attribut
pub type ForkChoiceUpdateResult = Result<ForkchoiceUpdated, ForkchoiceUpdateError>;

/// This structure encapsulates the fork choice state
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
pub struct ForkchoiceState {
/// Hash of the head block.
pub head_block_hash: B256,
Expand Down Expand Up @@ -116,8 +116,9 @@ impl From<ForkchoiceUpdateError> for jsonrpsee_types::error::ErrorObject<'static
/// Represents a successfully _processed_ forkchoice state update.
///
/// Note: this can still be INVALID if the provided payload was invalid.
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
pub struct ForkchoiceUpdated {
/// Represents the outcome of the validation of the payload, independently of the payload being
/// valid or not.
Expand Down
10 changes: 6 additions & 4 deletions crates/rpc-types-engine/src/identification.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
use alloc::string::{String, ToString};
use core::str::FromStr;
use serde::{Deserialize, Serialize};

/// This enum defines a standard for specifying a client with just two letters. Clients teams which
/// have a code reserved in this list MUST use this code when identifying themselves.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum ClientCode {
/// Besu
BU,
Expand Down Expand Up @@ -101,8 +101,9 @@ impl core::fmt::Display for ClientCode {
}

/// Contains information which identifies a client implementation.
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
pub struct ClientVersionV1 {
/// Client code, e.g. GE for Geth
pub code: ClientCode,
Expand All @@ -120,6 +121,7 @@ mod tests {
use super::*;

#[test]
#[cfg(feature = "serde")]
fn client_id_serde() {
let s = r#"{"code":"RH","name":"Reth","version":"v1.10.8","commit":"fa4ff922"}"#;
let v: ClientVersionV1 = serde_json::from_str(s).unwrap();
Expand Down
14 changes: 11 additions & 3 deletions crates/rpc-types-engine/src/jwt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ use jsonwebtoken::{
decode, errors::ErrorKind, get_current_timestamp, Algorithm, DecodingKey, Validation,
};
use rand::Rng;
use serde::{Deserialize, Serialize};
#[cfg(feature = "std")]
use std::{
fs, io,
Expand Down Expand Up @@ -117,7 +116,8 @@ const JWT_SIGNATURE_ALGO: Algorithm = Algorithm::HS256;
///
/// The Engine API spec requires that just the `iat` (issued-at) claim is provided.
/// It ignores claims that are optional or additional for this specification.
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Claims {
/// The "iat" value MUST be a number containing a NumericDate value.
/// According to the RFC A NumericDate represents the number of seconds since
Expand Down Expand Up @@ -215,6 +215,7 @@ impl JwtSecret {
/// - The JWT `exp` (expiration time) claim is validated by default if defined.
///
/// See also: [JWT Claims - Engine API specs](https://github.com/ethereum/execution-apis/blob/main/src/engine/authentication.md#jwt-claims)
#[cfg(feature = "serde")]
pub fn validate(&self, jwt: &str) -> Result<(), JwtError> {
// Create a new validation object with the required signature algorithm
// and ensure that the `iat` claim is present. The `exp` claim is validated if defined.
Expand Down Expand Up @@ -250,6 +251,7 @@ impl JwtSecret {

/// Encode the header and claims given and sign the payload using the algorithm from the header
/// and the key.
#[cfg(feature = "serde")]
pub fn encode(&self, claims: &Claims) -> Result<String, jsonwebtoken::errors::Error> {
let bytes = &self.0;
let key = jsonwebtoken::EncodingKey::from_secret(bytes);
Expand Down Expand Up @@ -331,6 +333,7 @@ mod tests {
}

#[test]
#[cfg(feature = "serde")]
fn validation_ok() {
let secret = JwtSecret::random();
let claims = Claims { iat: get_current_timestamp(), exp: Some(10000000000) };
Expand All @@ -342,6 +345,7 @@ mod tests {
}

#[test]
#[cfg(feature = "serde")]
fn validation_with_current_time_ok() {
let secret = JwtSecret::random();
let claims = Claims::default();
Expand All @@ -353,7 +357,7 @@ mod tests {
}

#[test]
#[cfg(feature = "std")]
#[cfg(all(feature = "std", feature = "serde"))]
fn validation_error_iat_out_of_window() {
let secret = JwtSecret::random();

Expand All @@ -379,6 +383,7 @@ mod tests {
}

#[test]
#[cfg(feature = "serde")]
fn validation_error_exp_expired() {
let secret = JwtSecret::random();
let claims = Claims { iat: get_current_timestamp(), exp: Some(1) };
Expand All @@ -390,6 +395,7 @@ mod tests {
}

#[test]
#[cfg(feature = "serde")]
fn validation_error_wrong_signature() {
let secret_1 = JwtSecret::random();
let claims = Claims { iat: get_current_timestamp(), exp: Some(10000000000) };
Expand All @@ -402,6 +408,7 @@ mod tests {
}

#[test]
#[cfg(feature = "serde")]
fn validation_error_unsupported_algorithm() {
let secret = JwtSecret::random();
let bytes = &secret.0;
Expand All @@ -417,6 +424,7 @@ mod tests {
}

#[test]
#[cfg(feature = "serde")]
fn valid_without_exp_claim() {
let secret = JwtSecret::random();

Expand Down
Loading

0 comments on commit e7ea61d

Please sign in to comment.