From 8ad59f0af0a8785b842b70dbf05d988058633dbf Mon Sep 17 00:00:00 2001 From: leruaa Date: Sun, 24 Mar 2024 13:37:13 +0000 Subject: [PATCH 1/8] feat: add `AnyNetwork` --- crates/network/src/any/builder.rs | 109 ++++++++++++++++++ crates/network/src/any/mod.rs | 35 ++++++ crates/network/src/ethereum/builder.rs | 63 +++++----- crates/network/src/ethereum/mod.rs | 1 + crates/network/src/lib.rs | 3 + .../rpc-types/src/eth/transaction/request.rs | 8 +- crates/rpc-types/src/extra.rs | 44 +++++++ crates/rpc-types/src/lib.rs | 3 + 8 files changed, 238 insertions(+), 28 deletions(-) create mode 100644 crates/network/src/any/builder.rs create mode 100644 crates/network/src/any/mod.rs create mode 100644 crates/rpc-types/src/extra.rs diff --git a/crates/network/src/any/builder.rs b/crates/network/src/any/builder.rs new file mode 100644 index 00000000000..9fa0084bf85 --- /dev/null +++ b/crates/network/src/any/builder.rs @@ -0,0 +1,109 @@ +use std::ops::{Deref, DerefMut}; + +use alloy_primitives::U256; +use alloy_rpc_types::TransactionRequest; + +use crate::{ethereum::build_unsigned, BuilderResult, Network, TransactionBuilder}; + +use super::{AnyNetwork, Extra}; + +impl TransactionBuilder for Extra { + fn chain_id(&self) -> Option { + self.deref().chain_id() + } + + fn set_chain_id(&mut self, chain_id: alloy_primitives::ChainId) { + self.deref_mut().set_chain_id(chain_id) + } + + fn nonce(&self) -> Option { + self.deref().nonce() + } + + fn set_nonce(&mut self, nonce: u64) { + self.deref_mut().set_nonce(nonce) + } + + fn input(&self) -> Option<&alloy_primitives::Bytes> { + self.deref().input() + } + + fn set_input(&mut self, input: alloy_primitives::Bytes) { + self.deref_mut().set_input(input); + } + + fn from(&self) -> Option { + self.deref().from() + } + + fn set_from(&mut self, from: alloy_primitives::Address) { + self.deref_mut().set_from(from); + } + + fn to(&self) -> Option { + self.deref().to() + } + + fn set_to(&mut self, to: alloy_primitives::TxKind) { + self.deref_mut().set_to(to) + } + + fn value(&self) -> Option { + self.deref().value() + } + + fn set_value(&mut self, value: alloy_primitives::U256) { + self.deref_mut().set_value(value) + } + + fn gas_price(&self) -> Option { + self.deref().gas_price() + } + + fn set_gas_price(&mut self, gas_price: U256) { + self.deref_mut().set_gas_price(gas_price); + } + + fn max_fee_per_gas(&self) -> Option { + self.deref().max_fee_per_gas() + } + + fn set_max_fee_per_gas(&mut self, max_fee_per_gas: U256) { + self.deref_mut().set_max_fee_per_gas(max_fee_per_gas); + } + + fn max_priority_fee_per_gas(&self) -> Option { + self.deref().max_priority_fee_per_gas() + } + + fn set_max_priority_fee_per_gas(&mut self, max_priority_fee_per_gas: U256) { + self.deref_mut().set_max_priority_fee_per_gas(max_priority_fee_per_gas); + } + + fn max_fee_per_blob_gas(&self) -> Option { + self.deref().max_fee_per_blob_gas() + } + + fn set_max_fee_per_blob_gas(&mut self, max_fee_per_blob_gas: U256) { + self.deref_mut().set_max_fee_per_blob_gas(max_fee_per_blob_gas) + } + + fn gas_limit(&self) -> Option { + self.deref().gas_limit() + } + + fn set_gas_limit(&mut self, gas_limit: U256) { + self.deref_mut().set_gas_limit(gas_limit); + } + + fn build_unsigned(self) -> BuilderResult<::UnsignedTx> { + build_unsigned::(self.unwrap()) + } + + async fn build>( + self, + signer: &S, + ) -> BuilderResult { + Ok(signer.sign_transaction(self.build_unsigned()?).await?) + } +} diff --git a/crates/network/src/any/mod.rs b/crates/network/src/any/mod.rs new file mode 100644 index 00000000000..ed166d60657 --- /dev/null +++ b/crates/network/src/any/mod.rs @@ -0,0 +1,35 @@ +use alloy_rpc_types::{Extra, Header, Transaction, TransactionReceipt, TransactionRequest}; + +use crate::{Network, ReceiptResponse}; + +mod builder; + +/// Types for a catch-all network. +#[derive(Debug, Clone, Copy)] +pub struct AnyNetwork { + _private: (), +} + +impl Network for AnyNetwork { + type TxEnvelope = alloy_consensus::TxEnvelope; + + type UnsignedTx = alloy_consensus::TypedTransaction; + + type ReceiptEnvelope = alloy_consensus::ReceiptEnvelope; + + type Header = alloy_consensus::Header; + + type TransactionRequest = Extra; + + type TransactionResponse = Extra; + + type ReceiptResponse = Extra; + + type HeaderResponse = Extra
; +} + +impl ReceiptResponse for Extra { + fn contract_address(&self) -> Option { + self.contract_address + } +} diff --git a/crates/network/src/ethereum/builder.rs b/crates/network/src/ethereum/builder.rs index 771788b27a8..84f9926aafc 100644 --- a/crates/network/src/ethereum/builder.rs +++ b/crates/network/src/ethereum/builder.rs @@ -30,10 +30,6 @@ impl TransactionBuilder for alloy_rpc_types::TransactionRequest { self.input.input = Some(input); } - fn to(&self) -> Option { - self.to.map(TxKind::Call).or(Some(TxKind::Create)) - } - fn from(&self) -> Option
{ self.from } @@ -42,6 +38,10 @@ impl TransactionBuilder for alloy_rpc_types::TransactionRequest { self.from = Some(from); } + fn to(&self) -> Option { + self.to.map(TxKind::Call).or(Some(TxKind::Create)) + } + fn set_to(&mut self, to: alloy_primitives::TxKind) { match to { TxKind::Create => self.to = None, @@ -98,29 +98,7 @@ impl TransactionBuilder for alloy_rpc_types::TransactionRequest { } fn build_unsigned(self) -> BuilderResult<::UnsignedTx> { - match ( - self.gas_price.as_ref(), - self.max_fee_per_gas.as_ref(), - self.access_list.as_ref(), - self.max_fee_per_blob_gas.as_ref(), - self.blob_versioned_hashes.as_ref(), - self.sidecar.as_ref(), - ) { - // Legacy transaction - (Some(_), None, None, None, None, None) => build_legacy(self).map(Into::into), - // EIP-2930 - // If only accesslist is set, and there are no EIP-1559 fees - (_, None, Some(_), None, None, None) => build_2930(self).map(Into::into), - // EIP-1559 - // If EIP-4844 fields are missing - (None, _, _, None, None, None) => build_1559(self).map(Into::into), - // EIP-4844 - // All blob fields required - (None, _, _, Some(_), Some(_), Some(_)) => { - build_4844(self).map(TxEip4844Variant::from).map(Into::into) - } - _ => build_legacy(self).map(Into::into), - } + build_unsigned::(self) } async fn build>( @@ -131,6 +109,37 @@ impl TransactionBuilder for alloy_rpc_types::TransactionRequest { } } +/// Build an unsigned transaction +pub(crate) fn build_unsigned(request: TransactionRequest) -> BuilderResult +where + N: Network, + N::UnsignedTx: From + From + From + From, +{ + match ( + request.gas_price.as_ref(), + request.max_fee_per_gas.as_ref(), + request.access_list.as_ref(), + request.max_fee_per_blob_gas.as_ref(), + request.blob_versioned_hashes.as_ref(), + request.sidecar.as_ref(), + ) { + // Legacy transaction + (Some(_), None, None, None, None, None) => build_legacy(request).map(Into::into), + // EIP-2930 + // If only accesslist is set, and there are no EIP-1559 fees + (_, None, Some(_), None, None, None) => build_2930(request).map(Into::into), + // EIP-1559 + // If EIP-4844 fields are missing + (None, _, _, None, None, None) => build_1559(request).map(Into::into), + // EIP-4844 + // All blob fields required + (None, _, _, Some(_), Some(_), Some(_)) => { + build_4844(request).map(TxEip4844Variant::from).map(Into::into) + } + _ => build_legacy(request).map(Into::into), + } +} + /// Build a legacy transaction. fn build_legacy(request: TransactionRequest) -> Result { Ok(TxLegacy { diff --git a/crates/network/src/ethereum/mod.rs b/crates/network/src/ethereum/mod.rs index 2479ef19cca..c6dd57d6e43 100644 --- a/crates/network/src/ethereum/mod.rs +++ b/crates/network/src/ethereum/mod.rs @@ -1,6 +1,7 @@ use crate::{Network, ReceiptResponse}; mod builder; +pub(crate) use builder::build_unsigned; mod signer; pub use signer::EthereumSigner; diff --git a/crates/network/src/lib.rs b/crates/network/src/lib.rs index 44479b442db..7a1dc54af16 100644 --- a/crates/network/src/lib.rs +++ b/crates/network/src/lib.rs @@ -28,6 +28,9 @@ pub use transaction::{ mod ethereum; pub use ethereum::{Ethereum, EthereumSigner}; +mod any; +pub use any::AnyNetwork; + pub use alloy_eips::eip2718; /// A list of transactions, either hydrated or hashes. diff --git a/crates/rpc-types/src/eth/transaction/request.rs b/crates/rpc-types/src/eth/transaction/request.rs index 4bb2ba3a1c8..ab6df3535c5 100644 --- a/crates/rpc-types/src/eth/transaction/request.rs +++ b/crates/rpc-types/src/eth/transaction/request.rs @@ -1,7 +1,7 @@ //! Alloy basic Transaction Request type. use crate::{ - eth::transaction::AccessList, other::OtherFields, BlobTransactionSidecar, Transaction, + eth::transaction::AccessList, other::OtherFields, BlobTransactionSidecar, Extra, Transaction, }; use alloy_primitives::{Address, Bytes, ChainId, B256, U256, U8}; use serde::{Deserialize, Serialize}; @@ -81,6 +81,12 @@ impl Hash for TransactionRequest { } } +impl Default for Extra { + fn default() -> Self { + Extra::new(TransactionRequest::default()) + } +} + // == impl TransactionRequest == impl TransactionRequest { diff --git a/crates/rpc-types/src/extra.rs b/crates/rpc-types/src/extra.rs new file mode 100644 index 00000000000..329390c4841 --- /dev/null +++ b/crates/rpc-types/src/extra.rs @@ -0,0 +1,44 @@ +use std::{ + collections::HashMap, + ops::{Deref, DerefMut}, +}; + +use serde::{Deserialize, Serialize}; +use serde_json::Value; + +#[derive(Debug, Clone, Serialize, Deserialize)] +/// Wrapper allowing to catch all fields missing on the inner struct while +/// deserialize. +pub struct Extra { + #[serde(flatten)] + inner: T, + /// All fields not present in the inner struct. + #[serde(flatten)] + pub other: HashMap, +} + +impl Extra { + /// Create a new `Extra`. + pub fn new(inner: T) -> Self { + Self { inner, other: HashMap::default() } + } + + /// Unwrap the inner struct. + pub fn unwrap(self) -> T { + self.inner + } +} + +impl Deref for Extra { + type Target = T; + + fn deref(&self) -> &Self::Target { + &self.inner + } +} + +impl DerefMut for Extra { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.inner + } +} diff --git a/crates/rpc-types/src/lib.rs b/crates/rpc-types/src/lib.rs index 578e8dbec91..14dbde301a6 100644 --- a/crates/rpc-types/src/lib.rs +++ b/crates/rpc-types/src/lib.rs @@ -23,3 +23,6 @@ mod eth; pub use alloy_serde as serde_helpers; pub use eth::*; + +mod extra; +pub use extra::Extra; From a788c4f94ce35a13d0280856056be84e18093f7d Mon Sep 17 00:00:00 2001 From: leruaa Date: Sun, 24 Mar 2024 22:07:48 +0000 Subject: [PATCH 2/8] fix: apply requested changes --- crates/network/src/any/builder.rs | 6 +-- crates/network/src/any/mod.rs | 18 +++++--- crates/rpc-types/src/eth/other.rs | 43 ++++++++++++++++++ crates/rpc-types/src/eth/transaction/mod.rs | 1 - .../rpc-types/src/eth/transaction/receipt.rs | 5 +-- .../rpc-types/src/eth/transaction/request.rs | 21 ++------- crates/rpc-types/src/extra.rs | 44 ------------------- crates/rpc-types/src/lib.rs | 3 -- 8 files changed, 63 insertions(+), 78 deletions(-) delete mode 100644 crates/rpc-types/src/extra.rs diff --git a/crates/network/src/any/builder.rs b/crates/network/src/any/builder.rs index 9fa0084bf85..2f0b10ddbb3 100644 --- a/crates/network/src/any/builder.rs +++ b/crates/network/src/any/builder.rs @@ -1,13 +1,13 @@ use std::ops::{Deref, DerefMut}; use alloy_primitives::U256; -use alloy_rpc_types::TransactionRequest; +use alloy_rpc_types::{other::WithOtherFields, TransactionRequest}; use crate::{ethereum::build_unsigned, BuilderResult, Network, TransactionBuilder}; -use super::{AnyNetwork, Extra}; +use super::AnyNetwork; -impl TransactionBuilder for Extra { +impl TransactionBuilder for WithOtherFields { fn chain_id(&self) -> Option { self.deref().chain_id() } diff --git a/crates/network/src/any/mod.rs b/crates/network/src/any/mod.rs index ed166d60657..26387221f77 100644 --- a/crates/network/src/any/mod.rs +++ b/crates/network/src/any/mod.rs @@ -1,10 +1,16 @@ -use alloy_rpc_types::{Extra, Header, Transaction, TransactionReceipt, TransactionRequest}; +use alloy_rpc_types::{ + other::WithOtherFields, Header, Transaction, TransactionReceipt, TransactionRequest, +}; use crate::{Network, ReceiptResponse}; mod builder; /// Types for a catch-all network. +/// +/// Essentially just returns the regular Ethereum types + a catch all field. +/// This [`Network`] should be used only when the network is not known at +/// compile time. #[derive(Debug, Clone, Copy)] pub struct AnyNetwork { _private: (), @@ -19,16 +25,16 @@ impl Network for AnyNetwork { type Header = alloy_consensus::Header; - type TransactionRequest = Extra; + type TransactionRequest = WithOtherFields; - type TransactionResponse = Extra; + type TransactionResponse = WithOtherFields; - type ReceiptResponse = Extra; + type ReceiptResponse = WithOtherFields; - type HeaderResponse = Extra
; + type HeaderResponse = WithOtherFields
; } -impl ReceiptResponse for Extra { +impl ReceiptResponse for WithOtherFields { fn contract_address(&self) -> Option { self.contract_address } diff --git a/crates/rpc-types/src/eth/other.rs b/crates/rpc-types/src/eth/other.rs index e8bd32f7b83..e7ab1b2419b 100644 --- a/crates/rpc-types/src/eth/other.rs +++ b/crates/rpc-types/src/eth/other.rs @@ -137,3 +137,46 @@ impl<'a> IntoIterator for &'a OtherFields { self.as_ref().iter() } } + +#[derive(Debug, Clone, Serialize, Deserialize)] +/// Wrapper allowing to catch all fields missing on the inner struct while +/// deserialize. +pub struct WithOtherFields { + #[serde(flatten)] + inner: T, + /// All fields not present in the inner struct. + #[serde(flatten)] + pub other: OtherFields, +} + +impl WithOtherFields { + /// Create a new `Extra`. + pub fn new(inner: T) -> Self { + Self { inner, other: OtherFields::default() } + } + + /// Unwrap the inner struct. + pub fn unwrap(self) -> T { + self.inner + } +} + +impl Deref for WithOtherFields { + type Target = T; + + fn deref(&self) -> &Self::Target { + &self.inner + } +} + +impl DerefMut for WithOtherFields { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.inner + } +} + +impl Default for WithOtherFields { + fn default() -> Self { + WithOtherFields::new(T::default()) + } +} diff --git a/crates/rpc-types/src/eth/transaction/mod.rs b/crates/rpc-types/src/eth/transaction/mod.rs index 30b394ac254..10e1d9ac899 100644 --- a/crates/rpc-types/src/eth/transaction/mod.rs +++ b/crates/rpc-types/src/eth/transaction/mod.rs @@ -114,7 +114,6 @@ impl Transaction { max_fee_per_blob_gas: self.max_fee_per_blob_gas, blob_versioned_hashes: Some(self.blob_versioned_hashes), sidecar: None, - other: OtherFields::default(), } } } diff --git a/crates/rpc-types/src/eth/transaction/receipt.rs b/crates/rpc-types/src/eth/transaction/receipt.rs index b2ae4d6c3b3..a0dede4556a 100644 --- a/crates/rpc-types/src/eth/transaction/receipt.rs +++ b/crates/rpc-types/src/eth/transaction/receipt.rs @@ -1,4 +1,4 @@ -use crate::{other::OtherFields, Log}; +use crate::Log; use alloy_primitives::{Address, Bloom, B256, U128, U256, U64, U8}; use serde::{Deserialize, Serialize}; @@ -53,9 +53,6 @@ pub struct TransactionReceipt { /// For legacy transactions this returns `0`. For EIP-2718 transactions this returns the type. #[serde(rename = "type")] pub transaction_type: U8, - /// Arbitrary extra fields. - #[serde(flatten)] - pub other: OtherFields, } impl TransactionReceipt { diff --git a/crates/rpc-types/src/eth/transaction/request.rs b/crates/rpc-types/src/eth/transaction/request.rs index ab6df3535c5..60acd8b4ad5 100644 --- a/crates/rpc-types/src/eth/transaction/request.rs +++ b/crates/rpc-types/src/eth/transaction/request.rs @@ -1,8 +1,6 @@ //! Alloy basic Transaction Request type. -use crate::{ - eth::transaction::AccessList, other::OtherFields, BlobTransactionSidecar, Extra, Transaction, -}; +use crate::{eth::transaction::AccessList, BlobTransactionSidecar, Transaction}; use alloy_primitives::{Address, Bytes, ChainId, B256, U256, U8}; use serde::{Deserialize, Serialize}; use std::hash::Hash; @@ -52,9 +50,6 @@ pub struct TransactionRequest { /// Blob sidecar for EIP-4844 transactions. #[serde(skip_serializing_if = "Option::is_none")] pub sidecar: Option, - /// Support for arbitrary additional fields. - #[serde(flatten)] - pub other: OtherFields, } impl Hash for TransactionRequest { @@ -74,16 +69,6 @@ impl Hash for TransactionRequest { self.transaction_type.hash(state); self.blob_versioned_hashes.hash(state); self.sidecar.hash(state); - for (k, v) in self.other.iter() { - k.hash(state); - v.to_string().hash(state); - } - } -} - -impl Default for Extra { - fn default() -> Self { - Extra::new(TransactionRequest::default()) } } @@ -261,6 +246,8 @@ pub struct TransactionInputError; #[cfg(test)] mod tests { + use crate::other::WithOtherFields; + use super::*; use alloy_primitives::b256; @@ -300,7 +287,7 @@ mod tests { #[test] fn serde_tx_request_additional_fields() { let s = r#"{"accessList":[],"data":"0x0902f1ac","to":"0xa478c2975ab1ea89e8196811f51a7b7ade33eb11","type":"0x02","sourceHash":"0xbf7e331f7f7c1dd2e05159666b3bf8bc7a8a3a9eb1d518969eab529dd9b88c1a"}"#; - let req = serde_json::from_str::(s).unwrap(); + let req = serde_json::from_str::>(s).unwrap(); assert_eq!( req.other.get_deserialized::("sourceHash").unwrap().unwrap(), b256!("bf7e331f7f7c1dd2e05159666b3bf8bc7a8a3a9eb1d518969eab529dd9b88c1a") diff --git a/crates/rpc-types/src/extra.rs b/crates/rpc-types/src/extra.rs deleted file mode 100644 index 329390c4841..00000000000 --- a/crates/rpc-types/src/extra.rs +++ /dev/null @@ -1,44 +0,0 @@ -use std::{ - collections::HashMap, - ops::{Deref, DerefMut}, -}; - -use serde::{Deserialize, Serialize}; -use serde_json::Value; - -#[derive(Debug, Clone, Serialize, Deserialize)] -/// Wrapper allowing to catch all fields missing on the inner struct while -/// deserialize. -pub struct Extra { - #[serde(flatten)] - inner: T, - /// All fields not present in the inner struct. - #[serde(flatten)] - pub other: HashMap, -} - -impl Extra { - /// Create a new `Extra`. - pub fn new(inner: T) -> Self { - Self { inner, other: HashMap::default() } - } - - /// Unwrap the inner struct. - pub fn unwrap(self) -> T { - self.inner - } -} - -impl Deref for Extra { - type Target = T; - - fn deref(&self) -> &Self::Target { - &self.inner - } -} - -impl DerefMut for Extra { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.inner - } -} diff --git a/crates/rpc-types/src/lib.rs b/crates/rpc-types/src/lib.rs index 14dbde301a6..578e8dbec91 100644 --- a/crates/rpc-types/src/lib.rs +++ b/crates/rpc-types/src/lib.rs @@ -23,6 +23,3 @@ mod eth; pub use alloy_serde as serde_helpers; pub use eth::*; - -mod extra; -pub use extra::Extra; From 17db0c09207a1127132ff27e60f40e40eddf275e Mon Sep 17 00:00:00 2001 From: leruaa Date: Mon, 25 Mar 2024 17:25:16 +0000 Subject: [PATCH 3/8] nit: reorder docs --- crates/rpc-types/src/eth/other.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/rpc-types/src/eth/other.rs b/crates/rpc-types/src/eth/other.rs index e7ab1b2419b..61c70967701 100644 --- a/crates/rpc-types/src/eth/other.rs +++ b/crates/rpc-types/src/eth/other.rs @@ -138,9 +138,9 @@ impl<'a> IntoIterator for &'a OtherFields { } } -#[derive(Debug, Clone, Serialize, Deserialize)] /// Wrapper allowing to catch all fields missing on the inner struct while /// deserialize. +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct WithOtherFields { #[serde(flatten)] inner: T, From 6591100c2168a0095fcb3633cb639d431aae6076 Mon Sep 17 00:00:00 2001 From: leruaa Date: Mon, 25 Mar 2024 17:45:17 +0000 Subject: [PATCH 4/8] nit: move `WithOtherFields` out of eth namespace --- crates/network/src/any/builder.rs | 2 +- crates/rpc-types/src/eth/other.rs | 43 ----------------- .../rpc-types/src/eth/transaction/request.rs | 2 +- crates/rpc-types/src/lib.rs | 3 ++ crates/rpc-types/src/with_other.rs | 48 +++++++++++++++++++ 5 files changed, 53 insertions(+), 45 deletions(-) create mode 100644 crates/rpc-types/src/with_other.rs diff --git a/crates/network/src/any/builder.rs b/crates/network/src/any/builder.rs index 2f0b10ddbb3..877f4bc990c 100644 --- a/crates/network/src/any/builder.rs +++ b/crates/network/src/any/builder.rs @@ -1,7 +1,7 @@ use std::ops::{Deref, DerefMut}; use alloy_primitives::U256; -use alloy_rpc_types::{other::WithOtherFields, TransactionRequest}; +use alloy_rpc_types::{TransactionRequest, WithOtherFields}; use crate::{ethereum::build_unsigned, BuilderResult, Network, TransactionBuilder}; diff --git a/crates/rpc-types/src/eth/other.rs b/crates/rpc-types/src/eth/other.rs index 61c70967701..e8bd32f7b83 100644 --- a/crates/rpc-types/src/eth/other.rs +++ b/crates/rpc-types/src/eth/other.rs @@ -137,46 +137,3 @@ impl<'a> IntoIterator for &'a OtherFields { self.as_ref().iter() } } - -/// Wrapper allowing to catch all fields missing on the inner struct while -/// deserialize. -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct WithOtherFields { - #[serde(flatten)] - inner: T, - /// All fields not present in the inner struct. - #[serde(flatten)] - pub other: OtherFields, -} - -impl WithOtherFields { - /// Create a new `Extra`. - pub fn new(inner: T) -> Self { - Self { inner, other: OtherFields::default() } - } - - /// Unwrap the inner struct. - pub fn unwrap(self) -> T { - self.inner - } -} - -impl Deref for WithOtherFields { - type Target = T; - - fn deref(&self) -> &Self::Target { - &self.inner - } -} - -impl DerefMut for WithOtherFields { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.inner - } -} - -impl Default for WithOtherFields { - fn default() -> Self { - WithOtherFields::new(T::default()) - } -} diff --git a/crates/rpc-types/src/eth/transaction/request.rs b/crates/rpc-types/src/eth/transaction/request.rs index 60acd8b4ad5..9d43bfe727d 100644 --- a/crates/rpc-types/src/eth/transaction/request.rs +++ b/crates/rpc-types/src/eth/transaction/request.rs @@ -246,7 +246,7 @@ pub struct TransactionInputError; #[cfg(test)] mod tests { - use crate::other::WithOtherFields; + use crate::WithOtherFields; use super::*; use alloy_primitives::b256; diff --git a/crates/rpc-types/src/lib.rs b/crates/rpc-types/src/lib.rs index 578e8dbec91..3632f39256e 100644 --- a/crates/rpc-types/src/lib.rs +++ b/crates/rpc-types/src/lib.rs @@ -23,3 +23,6 @@ mod eth; pub use alloy_serde as serde_helpers; pub use eth::*; + +mod with_other; +pub use with_other::WithOtherFields; diff --git a/crates/rpc-types/src/with_other.rs b/crates/rpc-types/src/with_other.rs new file mode 100644 index 00000000000..207d3234020 --- /dev/null +++ b/crates/rpc-types/src/with_other.rs @@ -0,0 +1,48 @@ +use std::ops::{Deref, DerefMut}; + +use serde::{Deserialize, Serialize}; + +use crate::other::OtherFields; + +/// Wrapper allowing to catch all fields missing on the inner struct while +/// deserialize. +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct WithOtherFields { + #[serde(flatten)] + inner: T, + /// All fields not present in the inner struct. + #[serde(flatten)] + pub other: OtherFields, +} + +impl WithOtherFields { + /// Create a new `Extra`. + pub fn new(inner: T) -> Self { + Self { inner, other: OtherFields::default() } + } + + /// Unwrap the inner struct. + pub fn unwrap(self) -> T { + self.inner + } +} + +impl Deref for WithOtherFields { + type Target = T; + + fn deref(&self) -> &Self::Target { + &self.inner + } +} + +impl DerefMut for WithOtherFields { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.inner + } +} + +impl Default for WithOtherFields { + fn default() -> Self { + WithOtherFields::new(T::default()) + } +} From f9bd90e5853b47cf5281cd73fe7f80cf3924bd2b Mon Sep 17 00:00:00 2001 From: leruaa Date: Mon, 25 Mar 2024 17:50:06 +0000 Subject: [PATCH 5/8] fix: module --- crates/network/src/any/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/network/src/any/mod.rs b/crates/network/src/any/mod.rs index 26387221f77..f26e1f3bfda 100644 --- a/crates/network/src/any/mod.rs +++ b/crates/network/src/any/mod.rs @@ -1,5 +1,5 @@ use alloy_rpc_types::{ - other::WithOtherFields, Header, Transaction, TransactionReceipt, TransactionRequest, + Header, Transaction, TransactionReceipt, TransactionRequest, WithOtherFields, }; use crate::{Network, ReceiptResponse}; From 341d287e732e93632523178c849da737701b27e4 Mon Sep 17 00:00:00 2001 From: leruaa Date: Thu, 28 Mar 2024 21:12:20 +0000 Subject: [PATCH 6/8] fix: impl `blob_sidecar` methods --- crates/network/src/any/builder.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/crates/network/src/any/builder.rs b/crates/network/src/any/builder.rs index 877f4bc990c..b39ccae8148 100644 --- a/crates/network/src/any/builder.rs +++ b/crates/network/src/any/builder.rs @@ -1,5 +1,6 @@ use std::ops::{Deref, DerefMut}; +use alloy_consensus::BlobTransactionSidecar; use alloy_primitives::U256; use alloy_rpc_types::{TransactionRequest, WithOtherFields}; @@ -100,6 +101,14 @@ impl TransactionBuilder for WithOtherFields { build_unsigned::(self.unwrap()) } + fn get_blob_sidecar(&self) -> Option<&BlobTransactionSidecar> { + self.deref().get_blob_sidecar() + } + + fn set_blob_sidecar(&mut self, sidecar: BlobTransactionSidecar) { + self.deref_mut().set_blob_sidecar(sidecar) + } + async fn build>( self, signer: &S, From 32d379cf62a66b5c13650a65b6af5d14c3570221 Mon Sep 17 00:00:00 2001 From: leruaa Date: Fri, 29 Mar 2024 06:49:35 +0000 Subject: [PATCH 7/8] nit: squash imports together --- crates/network/src/any/builder.rs | 6 +++--- crates/network/src/any/mod.rs | 3 +-- crates/rpc-types/src/eth/transaction/request.rs | 3 +-- crates/rpc-types/src/with_other.rs | 6 ++---- 4 files changed, 7 insertions(+), 11 deletions(-) diff --git a/crates/network/src/any/builder.rs b/crates/network/src/any/builder.rs index b39ccae8148..fb8acf76c80 100644 --- a/crates/network/src/any/builder.rs +++ b/crates/network/src/any/builder.rs @@ -4,9 +4,9 @@ use alloy_consensus::BlobTransactionSidecar; use alloy_primitives::U256; use alloy_rpc_types::{TransactionRequest, WithOtherFields}; -use crate::{ethereum::build_unsigned, BuilderResult, Network, TransactionBuilder}; - -use super::AnyNetwork; +use crate::{ + any::AnyNetwork, ethereum::build_unsigned, BuilderResult, Network, TransactionBuilder, +}; impl TransactionBuilder for WithOtherFields { fn chain_id(&self) -> Option { diff --git a/crates/network/src/any/mod.rs b/crates/network/src/any/mod.rs index f26e1f3bfda..2fd837ab912 100644 --- a/crates/network/src/any/mod.rs +++ b/crates/network/src/any/mod.rs @@ -1,9 +1,8 @@ +use crate::{Network, ReceiptResponse}; use alloy_rpc_types::{ Header, Transaction, TransactionReceipt, TransactionRequest, WithOtherFields, }; -use crate::{Network, ReceiptResponse}; - mod builder; /// Types for a catch-all network. diff --git a/crates/rpc-types/src/eth/transaction/request.rs b/crates/rpc-types/src/eth/transaction/request.rs index 9d43bfe727d..0ef12a61c7c 100644 --- a/crates/rpc-types/src/eth/transaction/request.rs +++ b/crates/rpc-types/src/eth/transaction/request.rs @@ -246,9 +246,8 @@ pub struct TransactionInputError; #[cfg(test)] mod tests { - use crate::WithOtherFields; - use super::*; + use crate::WithOtherFields; use alloy_primitives::b256; // diff --git a/crates/rpc-types/src/with_other.rs b/crates/rpc-types/src/with_other.rs index 207d3234020..a0c7cfb0dd3 100644 --- a/crates/rpc-types/src/with_other.rs +++ b/crates/rpc-types/src/with_other.rs @@ -1,8 +1,6 @@ -use std::ops::{Deref, DerefMut}; - -use serde::{Deserialize, Serialize}; - use crate::other::OtherFields; +use serde::{Deserialize, Serialize}; +use std::ops::{Deref, DerefMut}; /// Wrapper allowing to catch all fields missing on the inner struct while /// deserialize. From b4a32b60d49fb686417e028825789131c4af4b97 Mon Sep 17 00:00:00 2001 From: leruaa Date: Fri, 29 Mar 2024 16:45:44 +0000 Subject: [PATCH 8/8] fix: make `inner` pub --- crates/network/src/any/builder.rs | 2 +- crates/rpc-types/src/with_other.rs | 8 ++------ 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/crates/network/src/any/builder.rs b/crates/network/src/any/builder.rs index fb8acf76c80..426933e5ddf 100644 --- a/crates/network/src/any/builder.rs +++ b/crates/network/src/any/builder.rs @@ -98,7 +98,7 @@ impl TransactionBuilder for WithOtherFields { } fn build_unsigned(self) -> BuilderResult<::UnsignedTx> { - build_unsigned::(self.unwrap()) + build_unsigned::(self.inner) } fn get_blob_sidecar(&self) -> Option<&BlobTransactionSidecar> { diff --git a/crates/rpc-types/src/with_other.rs b/crates/rpc-types/src/with_other.rs index a0c7cfb0dd3..8c8cdf60346 100644 --- a/crates/rpc-types/src/with_other.rs +++ b/crates/rpc-types/src/with_other.rs @@ -6,8 +6,9 @@ use std::ops::{Deref, DerefMut}; /// deserialize. #[derive(Debug, Clone, Serialize, Deserialize)] pub struct WithOtherFields { + /// The inner struct. #[serde(flatten)] - inner: T, + pub inner: T, /// All fields not present in the inner struct. #[serde(flatten)] pub other: OtherFields, @@ -18,11 +19,6 @@ impl WithOtherFields { pub fn new(inner: T) -> Self { Self { inner, other: OtherFields::default() } } - - /// Unwrap the inner struct. - pub fn unwrap(self) -> T { - self.inner - } } impl Deref for WithOtherFields {